wargame/Lord Of SQL Injection

[LOS] banshee

LimeLee 2019. 7. 17. 21:24


소스코드 분석


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


1.  $db sqlite_open("./db/banshee.db"); > DB환경이 sqlite


2.  if($result['pw'] === $_GET['pw']) solve("banshee");  > 요청 파라미터 값과 반환값을 엄격한 비교. 패스워드를 알 필요가 있음.


3.  if($result['id']) echo "<h2>login success!</h2>"> 값이 존재하면 고정된 문자열 출력. 존재하지 않으면 출력하지 않음. 참,거짓의 구분으로 Blind SQL Injection 시도 가능



문제 풀이


sqlite 환경에서의 Blind SQL Injection 문제이지만 타 문제의 테이블을 열람하지 못하도록 최소한의 필터링만 존재하여 MYSQL과 많이 다르지 않다.


Blind SQL Injection에서 기본적으로 사용하는 length와 substring함수는 MYSQL 환경과 동일하게 length()와 substr()이다. 필터링을 아무것도 하지 않아 방법은 여러가지가 있겠지만 싱글 쿼터(')를 필터링하지 않으므로 부등호와 싱글쿼터로 Blind SQL Injection을 시도한다.


해당 문제의 테이블(member)에는 guest라는 id를 가진 레코드도 존재한다. 그렇기에 Blind SQL Injection을 시도하면서 guest라는 id의 pw 값(guest)이 참이 되면 제대로 값이 뽑히지 않기 때문에 조건절에 id='admin' AND를 추가한다.


위를 파라미터로 요청한다.

?pw=' or id='admin' and pw>'0'-- -



고정된 문자열이 출력되지 않을 경계를 찾아서 한글자 씩 늘려간다. length()함수를 사용해서 미리 패스워드의 길이를 파악하여도 되고 글자를 하나씩 늘려나가다 모든 글자에 대해 참인 값을 출력하게 되면 바로 전 글자에서 한 글자 다음의 값이 패스워드의 값이라고 유추하여도 된다.


찾은 admin의 패스워드 값을 요청하면 다음과 같다.

?pw=0313091b




'wargame > Lord Of SQL Injection' 카테고리의 다른 글

[LOS] nessie  (0) 2019.07.17
[LOS] poltergeist  (0) 2019.07.17
[LOS] manticore  (0) 2019.07.17
[LOS] chupacabra  (0) 2019.07.16
[LOS] cyclops  (0) 2019.05.10