[WebHacking] SQL Injection
SQL injection
SQL injection은 DBMS에서 사용하는 쿼리를 임의로 조작해 데이터베이스의 정보를 획득하는 기법이다. 간단하면서도 정말 많이 일어나는 기법이다.
다음 자료는 OWASP(The Open Web Application Security Project)에서 발표한 2021년 가장 많이 일어난 웹 취약점이다. Injection이 1위를 차지하고 있다는 것을 알 수 있다. 이 injection 기법 중 가장 흔히 일어나는 것이 sql injection이라고 할 수 있다.
Injection flaws, such as SQL, NoSQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query.
The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing data without proper authorization.
인젝션은 단순히 최근의 문제만은 아니다. 2013년부터 계속 취약점 1위를 차지하고 있으며, 오랜시간이 지났음에도 아직도 1위를 차지하고 있다는 것은 그만큼 매우 중요한 것이라는 것을 알 수 있다.
Injection
SQL injection을 이해하기 위해서는 injection이 무엇인지 알아야한다. injection은 '주입', '삽입'이라는 뜻을 가진 단어이다. 인젝션 공격은 그 말의 뜻과 같이 애플리케이션의 처리과정에서 이용자가 입력한 코드가 문법적인 데이터로 해석되어서 발생하는 취약점을 의미한다.
SQL Injection
SQL injection은 injection이 SQL 쿼리 문에서 발생하는 것을 의미한다. SQL injection을 진행하면 데이터베이스에 있는 정보들을 빼내 올 수 있기 때문에 아이디 비밀번호부터 DB에 담겨있는 민감한 정보를 빼내올 수 있다.
SQL을 하나도 모른다면 다음 사이트에서 간단하게 공부를 하는 것도 좋다.
https://www.w3schools.com/sql/default.asp
예시를 보자.
SELECT * FROM information WHERE id= '' and pw = ''
위 코드에서 작은 따옴표 안에 있는 부분에 사용자가 입력한 id와 pw가 입력된다.
그럼 만약,
id = admin'--
pw = 1234
로 입력한다면 어떻게 될까?
SELECT * FROM information WHERE id= 'admin'--' and pw = '1234'
admin 뒤가 주석으로 처리가 되어 id=admin인 곳의 정보를 모두 들고오게 된다. 이렇게 사용자가 부적절한 명령을 삽입하여 부적절한 실행을 일으키는 것이 sql injection의 핵심이다.
어느 사이트나 관리자의 계정이 있을 것이다. 만약 해커가 관리자의 아이디로 로그인을 성공한다면 많은 사람들의 정보는 결코 안전하지 못할 것이다.
Blind SQL injection
앞에서 SQL injection에 대한 예시는 의도하지 않은 결과를 반환해서 인증을 우회하는 공격기법이었다. 이것 외에도 SQL injection은 데이터베이스의 데이터를 직접 알아낼 수도 있다. 하지만, 데이터를 직접 알아내기는 어려운 상황에서 데이터를 한자씩 들고 올 수 있다면 어떨까? 이 상황에서 Blind SQL injection을 사용할 수 있다. 이 기법은 업다운게임이나 스무고개 게임과 유사하다. DBMS가 답변 가능한 형태로 질문하여 참/거짓 반환 결과로 데이터를 획득하는 공격 기법을 Blind SQL injection이라고 한다.
blind SQL injection은 한바이트씩 비교하여 공격하는 방식이기 때문에 다른 공격에 비해 시간이 많이 소요된다. 그렇기 때문에 자동화를 시키는 것이 매우 중요하며 대표적으로는 python의 requests 모듈을 자주 사용한다.
python requests에 대해 자세히 알고 싶다면 아래 문서를 참고하자.
https://docs.python-requests.org/en/latest/
설명을 쉽게 하기 위해 비밀번호를 알아내는 과정이라고 해보자.
비밀번호는 알파벳, 숫자, 특수문자로 이루어지기 때문에 32부터 126까지의 범위로 나타내면된다. 이것을 고려하여 python requests를 이용해 한글자씩 공격하는 코드를 작성할 수 있다.
#!/usr/bin/python3
import requests
import string
url = 'http://example.com/login' # example URL
params = {
'uid': '',
'upw': ''
}
tc = string.ascii_letters + string.digits + string.punctuation # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~
query = '''
admin' and ascii(substr(upw,{idx},1))={val}--
'''
password = ''
for idx in range(0, 20):
for ch in tc:
params['uid'] = query.format(idx=idx, val=ord(ch)).strip("\n")
c = requests.get(url, params=params)
print(c.request.url)
if c.text.find("Login success") != -1:
password += chr(ch)
break
print(f"Password is {password}")
# 출처 : https://dreamhack.io/learn/191#p3136
※ascii() : 문자를 아스키 형태로 변환해주는 함수이다.
ascii('a')
※substr() : 문자열에서 지정한 위치부터 길이까지의 값을 가져온다.
substr(string, position, length)
substr('ABCD', 1, 2) = 'AB'
이번 시간에는 이정도만 다루어 볼 것이고 나중에 기회가 되면 nosql injection 등을 다루어볼 예정이다.
+) SQL injection 내용을 더 공부하고 싶으면 이 사이트의 문제가 도움이 된다. 나도 writeup에 올리도록 노력해야겠다.
[소감]
blind sql injection은 솔직히 듣기만 하고 제대로 공부해본 것은 이번이 처음인 것 같다. 생각보다 쉬운 개념인거 같다. 워게임 풀면서 http requests가 생각보다 자주 쓰이는 것 같다. 이건 내가 모듈을 공부해서 직접 사용도 해보는 추가 공부가 필요할 것 같다.
'Hacking & Security > WebHacking' 카테고리의 다른 글
[WebHacking] NoSQL injection (0) | 2022.03.01 |
---|---|
[WebHacking] CSRF (Cross Site Request Forgery) (0) | 2022.02.03 |
[WebHacking] XSS (Cross-Site-Scripting) (0) | 2022.02.02 |
[WebHacking] Dreamhack 커리큘럼 (0) | 2022.02.02 |