wargame/Lord Of SQL Injection

[LOS] mummy

LimeLee 2019. 7. 26. 10:59

소스코드 분석

<?php
  include "./config.php";
  login_chk();
  $db = mssql_connect("mummy");
  if(preg_match('/master|sys|information|;|\(|\//i', $_GET['query'])) exit("No Hack ~_~");
  for($i=0;$i<strlen($_GET['query']);$i++) if(ord($_GET['query'][$i]) <= 32) exit("%01~%20 can used as whitespace at mssql");
  $query = "select".$_GET['query'];
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
  if($result[0]) echo "<h2>Hello anonymous</h2>";

  $query = "select pw from prob_mummy where id='admin'";
  $result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
  if($result['pw'] === $_GET['pw']) solve("mummy");
  highlight_file(__FILE__);
?>

1. $db = mssql_connect("mummy"); > db환경이 mssql

 

2. for($i=0;$i<strlen($_GET['query']);$i++) if(ord($_GET['query'][$i]) <= 32) exit("%01~%20 can used as whitespace at mssql"); > 공백 사용 불가

 

3. if($result['pw'] === $_GET['pw']) solve("mummy"); > 결과 값과 요청 값을 엄격한 비교. pw 값을 알 필요 있음

문제 풀이

공백을 사용할 수 없다. mysql에서도 사용하는 주석인 /**/와 소괄호()를 이용해 구분을 지어주려고 하였지만 필터링이 되어 있다.

 

그래서 다른 구분자를 이용한다.

 

select와 from과 인접한 table과 columns은 전에 사용한 []로 구분하였다.(더블쿼터 "로도 가능)

 

?query=[pw]from[prob_mummy]

테이블과 컬럼을 구분하는데 까지는 성공했다. 이제 admin의 pw를 추출해야하는데 [pw]>'1'from[prob_mummy] 같은 방법으로 시도해보려고 하니 실패한다.

 

이유는 등호인 [pw]='1'from[prob_mummy]는 pw 컬럼에 존재하는 갯수만큼 '1'을 반환한다.

select절을 이용할 수 없으니 where 절에서 blind sql injection을 시도한다. 컬럼은 []를 이용하여 연산자와 구분을 하고 문자열은 싱글쿼터(')를 이용하여 구분한다.

 

?query=[pw]from[prob_mummy]where[id]='admin'AND[pw]>'0'

 

이런식으로 반복하여 pw 값을 알아낸다.

저렴한 파이썬 코드

부등호 >를 사용하였기 때문에 마지막 글자는 바꿔준다.

 

?pw=0c3cc245

클리어

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

[LOS] cerberus  (0) 2019.07.26
[LOS] kraken  (0) 2019.07.26
[LOS] yeti  (0) 2019.07.26
[LOS] revenant  (1) 2019.07.26
[LOS] nessie  (0) 2019.07.17