3

我搜索了整个谷歌,看看如何绕过以下内容(它来自 DVWA 的高级安全性):

$id = $_GET['id']; 
    $id = stripslashes($id); 
    $id = mysql_real_escape_string($id); 

    if (is_numeric($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++; 
    } 
} 

有可能破解吗?

对于那些不熟悉 DVWA 的人,这里有一个关于它的 youtube 视频: http ://www.youtube.com/watch?v=oMV0JZVxvdQ

另外,我的另一个担忧是中等水平。它确实mysql_real_escape_string()有效,但是当您从低级别使用相同的 SQL 注入并删除引号时,它会绕过保护。这是为什么?怎么这么容易绕过mysql_real_escape string

中级的代码(简洁版)是这样的:

   $id = $_GET['id']; 
    $id = mysql_real_escape_string($id); 
    $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";

我想使用 PDO,因为它可能更安全。请让我知道您对此的看法。

提前非常感谢。

4

3 回答 3

2

添加is_numeric不会使这很可能成为全面的 sql 攻击,但is_numeric不是很准确:

is_numeric('0xdeadbeef') // true
is_numeric('10e3') // true

使用过滤器可能更好:

if (false !== ($id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT))) {
}
于 2012-05-30T04:05:34.273 回答
0

在中等级别只需使用:1 and 1=1 order by X.

作者的所有查询都是低级的,但是您可以将表名替换为十六进制代码0x...,例如where table_name=0x12345. 如果我们使用字符串 char 我们将有一个错误,因为这'是不允许的。

于 2013-04-08T01:27:31.017 回答
0

我有同样的问题。我也不知道怎么破解。

但我认为我对中等级别的问题有一个答案,我认为这是程序员的错误。

$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id"

请注意,在低级别和高级别中,您在 $id 中都有引号,而不是在 Medium 中......我认为这就是重点。如果你有这个:

$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"

我很确定在中等级别绕过 mysql_real_escape 字符串不会那么容易。

换句话说,我很确定如果你没有在 High Level 中的引号,你也可以进行注入。

于 2012-11-08T11:14:06.660 回答