소스코드 분석
<?php
include "./config.php";
login_chk();
$db = mongodb_connect();
if(preg_match('/prob|_|\(/i', $_GET['id'])) exit("No Hack ~_~");
if(preg_match('/prob|_|\(/i', $_GET['pw'])) exit("No Hack ~_~");
$query = array("$where" => "function(){return obj.id=='{$_GET['id']}'&&obj.pw=='{$_GET['pw']}';}");
echo "<hr>query : <strong>".json_encode($query)."</strong><hr><br>";
$result = mongodb_fetch_array($db->prob_incubus->find($query));
if($result['id']) echo "<h2>Hello {$result['id']}</h2>";
$query = array("id" => "admin");
$result = mongodb_fetch_array($db->prob_incubus->find($query));
if($result['pw'] === $_GET['pw']) solve("incubus");
highlight_file(__FILE__);
?>
1. $db = mongodb_connect();
> DB 환경이 mongodb
2. if($result['pw'] === $_GET['pw']) solve("incubus");
> 쿼리 결과와 요청 파라미터 값을 비교. pw 값을 알 필요가 있음
문제 풀이
이전 문제와 다르게 조금 더 우리에게 친숙한 모습을 하고 있다. where 절 쿼리를 이용하는데 사실상 문법을 알고 적용한 것이 아니라 대충 이런 문법을 가진 게 아닐까 해서 넣었다가 딱딱 맞아떨어져서 풀린 문제기 때문에 step이 억지스러울 수 있다.
mysql의 where 절 쿼리로 생각하자면 id='' and pw='' 일 것이다. and 연산자가 존재한다는 말은? or 연산자도 만들어 두었을 것이라 생각하였다.
따로 검색은 해보지 않았지만 and 연산자의 형태 "&&", 어디선가 많이 봤다.
or 연산자는 || 이라 가정하고 ' or id='admin 형태의 쿼리을 삽입하였을때 admin이 반환된다면 or 연산자는 || 일 것이고, 반환하지 않는다면 잘못 접근한 것이 된다.
다음과 같이 요청한다.
?pw=' || obj.id=='admin
admin을 반환하였으므로 || && 연산자가 존재하는 것을 확인하였다. 물론 테이블 안에 존재하는 admin 패스워드를 알아야 하는 것이 이번 문제의 목적이기 때문에 단순 인증우회만으로는 풀 수 없다. 부등호를 사용할 수 있다면 부등호를 이용한 blind sql injection을 이용할 수 있다.
등호가 존재한다는 것은? 부등호도 존재할 것이라 생각했다.
==이 등호라면 >=는 부등호가 되지 않을까 라고 가정, admin을 반환하는 쿼리가 있다면 부등호가 존재하는 것이고 어떠한 경우에도 반환하지 않는다면 등호만 존재할 것이다.
?pw=g'||obj.id=='admin'&&obj.pw>='1
admin을 반환하였으므로 부등호가 존재하는 것을 확인하였다. (>=는 $gte, 크거나 같다의 의미이고 $gt, $lt의 > , < 도 존재함)
부등호를 사용할 수 있으므로 Blind SQL Injection을 이용할 수 있다.
?pw=b47822ea
클리어
'wargame > Lord Of SQL Injection' 카테고리의 다른 글
[LOS] siren (0) | 2019.07.26 |
---|---|
[LOS] cerberus (0) | 2019.07.26 |
[LOS] kraken (0) | 2019.07.26 |
[LOS] mummy (0) | 2019.07.26 |
[LOS] yeti (0) | 2019.07.26 |