WarGame/Lord of SQL Injection

[LOSI] Lord of SQL Injection Level 32 - Alien

귀여운 외계 생물 이미지를 기대한 독자들에게 미안하지만, 필자는 프로메테우스를 너무 재미있게 봤다. 에일리언 시리즈의 광팬 중 한 명이다.

<출처 : 나무위키 https://namu.wiki/w/%EC%97%90%EC%9D%BC%EB%A6%AC%EC%96%B8>


코드

코드를 보면 아래와 같은 각종 예약어들이 막혀있다.

금지당한 예약어 : administrator, and, or, if, coalesce, case, 언더바(_), 점(.), prob, time

query는 두 가지가 동작하고 있는데, query1은 파라미터가 작은따옴표 처리되어있지 않고, query2는 작음 따옴표 처리되어있으며 각각 두 가지의 조건문을 통과하여야만 solve("alien")이 호출된다.

* coalesce는 주어진 파라미터(여러 개 들어갈 수 있다.)에서 NULL이 아닌 첫 값을 반환한다.... 뭘 막으려고 한 거지?

지X맞다.

여러 가지 시도가 동반될 느낌이 든다.


해결방법

우선은 작은따옴표 문제부터 해결해야 한다. 작은따옴표가 있을 때나 없을 때 둘 다 동일한 결과를 만들 수 있는 방법은 어렵지 않게 떠올릴 수 있다.

example : ?no=1 union select 1-- ' union select '1

query로 보면 다음과 같이 된다.

결국 둘 다 1 union select 1이 실행되는 것이다. 이제 원하는 부분은 1에 대체하면 query1과 query2를 같은 부분으로 만들어 줄 수 있겠다.

 

다음 조건을 해결하기 위해서는 의외의 방법이 사용된다.

일단 이해를 해야 할 부분이 있는데,

쿼리를 시행하고, 그 결과로 id를 받아오며, admin에 대한 조건문은 "순차적"으로 실행된다.

그리고 

쿼리를 시행하는데에는 약간의 오버헤드 시간이 소모된다.

얼추 감이 오는 사람들도 있을 거 같은데, sleep()을 이용해서 쿼리 시간 도중 우리의 파라미터가 변조되게 만들 수 있을 거 같다.

예를 들면 첫 번째가 실행되는 시간 동안에는 "admin"인데 다음에는 "admin"이 아니도록 말이다. 아래는 해당 구현의 구조적인 설명이다. 

* 그렇다! 필자도 시간에 따라 0이 되나 1이 되나 하는 함수는 구글링 했다!  뭐! 쪽팔리지 않다! *

 

실제 파라미터는 다음과 같이 작성되는데 query1과 query2에 기본 offset으로 들어간 것이 각각 97,96 임을 주목하자

Answer Url : 0 union select concat(char(97+(!sleep(1)&&now()%2=1)), 0x646d696e)-- ' union select concat(char(96+(!sleep(1)&&now()%2=1)), 0x646d696e)--%20

이는 query1과 query2에 실행될 각각의 쿼리가 시작되는 첫 번째, 세 번째 조건문이 각각 admin이 들어갈 수 있도록 해준 것이다. 

 

현재 시간에 따라 결과가 달라지는 쿼리이니 아마 여러 번 날려야 정답이 돌아올 것이다. 


기괴한 몬스터였다. 다음 관문에서 여러분들을 기다리겠다.