0x01 WooYun-2014-53384
输入1',直接报错。 使用单引号闭合,尝试使用注释符注释掉后面的单引号--+或者%23,仍然报错。 感觉注释是被替换掉了。使用万能密码1' or '1'='1。 成功了,接着使用了下and,发现and似乎也被过滤了,显示的是空白的。 替换了一下空格,发现可以正常执行了。猜测应该是关键字和空格一起检测的。 经过排除后,发现是关键字后跟空格才会被检测出来,放在前面是没不检测的。 那么接下来语句就使用各种方法替换到空格就好,比如/**/,//,(),''等,当然试着使用双写也有可能绕过。 搞定,最后拿个用户名密码就可以了。
0x02 源码分析
WooYun
-2014-53384 Source
<?php
if(isset($_GET['Submit'])){
$id = $_GET['id'];
$id = tsFilter($id);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
$i = 0;
while ($i < $num) {
$first = mysql_result($result,$i,"first_name");
$last = mysql_result($result,$i,"last_name");
echo '<pre>';
echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
echo '</pre>';
$i++;
}
}
function tsFilter($value){
$value = trim($value);
$words = array();
$words[] = "add ";
$words[] = "and ";
$words[] = "count ";
$words[] = "order ";
$words[] = "table ";
$words[] = "by ";
$words[] = "create ";
$words[] = "delete ";
$words[] = "drop ";
$words[] = "from ";
$words[] = "grant ";
$words[] = "insert ";
$words[] = "select ";
$words[] = "truncate ";
$words[] = "update ";
$words[] = "use ";
$words[] = "--";
$words[] = "#";
$words[] = "group_concat";
$words[] = "column_name";
$words[] = "information_schema.columns";
$words[] = "table_schema";
$words[] = "union ";
$words[] = "where ";
$words[] = "alert";
$value = strtolower($value);
foreach($words as $word){
if(strstr($value,$word)){
$value = str_replace($word,'',$value);
}
}
return $value;
}
?>
这里看的很清楚,是写获取id,再去进行检查的,将上面的关键字都替换为空,也就是过滤,那这里应该是可以使用双写绕过的。1' anand d '1'='1被过滤后就只有1' and '1'='1了。