实验目的
1、了解二次注入的概念和原理
2、掌握其利用方法
实验内容
二次注入
二次注入是SQL注入的一种,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏。
那为什么需要二次注入,因为在字符型注入一般都有单引号的存在,首先构造注入闭合单引号,再通过第二次构造语句,在第一次注入的基础上进行注入。
实验步骤
本实验分两步,第一步进行源码分析,第二步进行验证。
步骤1:代码审计
在之前的审计课程中我们已经对网站的大部分功能进行了审计,因而本次审计从messageSub.php入手,它是留言板的页面,我们首先查看其源码:1
2
3
4
5
6if (isset($_POST['submit']) && !empty($_POST['message']) && isset($_SESSION['username'])) {
$clean_message = clean_input($_POST['message']);
$query = "INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('{$_SESSION['username']}','$clean_message',now())";
mysql_query($query, $conn) or die(mysql_error());
mysql_close($conn);
header('Location: message.php');
可以看到,在处理POST过来的变量时,没有用到sqlwaf,只是对输入的字符串加上了单引号,然后直接就带入了SQL语句进行查询。
在上述中的这种查询语句是双条件、或者多条件的。
我们查询语句并不仅仅指select,条件也并不仅仅指where后面的条件。只要输入的内容,有一定的输入关系和顺序,就可以了。
看这个双条件,分别为:$_SESSION['username']和$clean_message。
我们可以构造如下语句:1$query = "INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('xxx',',(),1);#',now())
首先用用户名截断掉后面的单引号,那么闭合的单引号就会到第二个字符串的前面,可以看到,在comment后查询了三个内容,我们再在values中放入任意的查询内容:1。
这样就达到了截断单引号的目的,再将后面的数据修改为payload,这样就理论上达到了二次注入的条件。
因此payload为:1,(select admin_pass from admin limit 0,1),1);#
当然这一切的前提就是用户名后面有一个,如果没有,就不能转义掉单引号,也就无从谈起了,因此我们需要控制用户名。那么如何控制呢?
可以新注册一个用户,在注册用户名时,添加一个。
因此我们找到设置用户名的地方:也就是注册的地方:regCheck.php。1
2$clean_name = clean_input($_POST['user']);
$clean_pass = clean_input($_POST['passwd']);
可以看到,它使用clean_input函数对我们输入的用户名进行了过滤
我们自然要查看一下如何过滤的,在sys/lib.php中找到了过滤函数:1
2
3function clean_input( $dirty ) {
return mysql_real_escape_string( stripslashes( $dirty ) );
}
它先将我们输入的字符自动转移,再进行反转义,也就是说,比如我们输入xxx,它会转义成为xxx\。但进入数据库的时候,他会是一个还是两个呢?
我们来进行测试,注册账号nice,点击注册:
我们点击注册后,进入用户界面,这时发现账号为nice\,我们再查看数据数据库,却发现是nice。
这是为什么呢?这是因为函数的特性。它是使用mysql的函数进行过滤,因此到数据库就变成了单斜杠,既然是单斜杠,那么我们就可以利用了。
但是在网页上还是nice,因此我们需要重新登录,刷新Session值,因为网页上的名称是以数据库为准的,因此重新登陆即可。
再将我们之前构造好的语句,在留言板提交,理论上是可以将管理员的密码爆出来的。
下一步我们将进行验证
步骤2:漏洞验证
在上一步我们进行了理论的分析代码,下面进行验证:
首先重新登录:
可以看到,登录成功,并且查看右上角的用户名,已经自动同步了数据库。
这时,我们点击留言,并将我们之前构造好的语句:1,(select admin_pass from admin limit 0,1),1);#
插入到留言板中:
可以看到,成功的爆出来管理员的密码。
实验结果分析与总结
修复代码示例1
2
3
4
5
6
7$clean_name = clean_input($_POST['user']);
if (!preg_match("/^[a-zA-Z0-9]+$/",$clean_name)) {
die('用户名只允许w+');
}
$clean_pass = clean_input($_POST['passwd']);
$avatar = '../images/default.jpg';
在注册的地方regcheck.php加限制,使用正则匹配,只允许注册用户时输入英文和数字,不允许输入特殊字符,从而就修复了这个漏洞
1、为所有数据库访问使用参数查询并参数化集成到查询中的每个数据项,可以有效的防御二次注入漏洞对
错
A
2、下列选项对二次注入说法正确的是:当用户输入的恶意数据首次传送给数据库时,将会进行安全的处理,但当应用程序调用时将会以一种危险的方式运行
当用户输入的恶意数据传送给数据库时,应用程序调用时将会以一种危险的方式运行
如果无法注释sql语句则无法进行二次注入攻击
无法闭合单引号是,无法进行二次注入攻击
A
3、截断注入在什么情况下比较适用:无法闭合单引号进行注入时
数据库语句为双条件
当无法闭合单引号进行注入时且为数据库语句为双条件
当无法闭合单引号进行注入时不为数据库语句为双条件
C
第1题:在本实验产生二次注入最主要的原因是没有对用户注册、数据库查询,这两个地方进行严格的过滤。
对
错
A
第2题:在本文中的过滤函数中,其中stripslashes的作用为:
删除
删除&
删除#
A