本文选自《web安全攻防渗透测试实战指南(第2版)》
点击图片五折购书
二次注入攻击的测试地址在本书第2章。
double1.php页面的功能是添加用户。
第一步,输入用户名test'和密码123456,如图4-45所示,单击“send”按钮提交。
图4-45
页面返回链接/4.3/double2.php?id=4,是添加的新用户个人信息的页面,访问该链接,结果如图4-46所示。
图4-46
从返回结果可以看出,服务器端返回了MySQL的错误(多了一个单引号引起的语法错误),这时回到第一步,在用户名处填写test' order by 1%23,提交后,获取一个新的id=5,当再次访问double2.php?id=5时,页面返回正常结果;再次尝试,在用户名处填写test' order by 10%23,提交后,获取一个新的id=6,当再访问double2.php?id=6时,页面返回错误信息(Unknown column '10' in 'order clause'),如图4-47所示。
图4-47
这说明空白页面就是正常返回。不断尝试后,笔者判断数据库表中一共有4个字段。在用户名处填写-test' union select 1,2,3,4%23,提交后,获取一个新的id=7,再访问double2.php?id=7,发现页面返回了union select中的2和3字段,结果如图4-48所示。
图4-48
在2或3的位置,插入我们的语句,比如在用户名处填写-test' union select 1,user(), 3,4#,提交后,获得一个新的id=8,再访问double2.php?id=8,得到user()的结果,如图4-49所示,使用此方法就可以获取数据库中的数据。
图4-49
二次注入中double1.php页面的代码如下所示,实现了简单的用户注册功能,程序先获取GET参数“username”和参数“password”,然后将“username”和“password”拼接到SQL语句中,最后使用insert语句将参数“username”和“password”插入数据库。由于参数“username”使用addslashes函数进行了转义(转义了单引号,导致单引号无法闭合),参数“password”进行了MD5哈希,所以此处不存在SQL注入漏洞。
$con=mysqli_connect("localhost","root","123456","test");
if (mysqli_connect_errno())
{
echo "连接失败: " . mysqli_connect_error();
}
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysqli_query($con,"insert into users(`username`,`password`) values ('".addslashes($username)."','".md5($password)."')");
echo '<a href="/4.3/double2.php?id='. mysqli_insert_id($con) .'">用户信息</a>';
当访问username=test'&password=123456时,执行的SQL语句如下:
insert into users(`username`,`password`) values ('test'', 'e10adc3949ba59abbe56e057f20f883e')
从图4-50所示的数据库中可以看出,插入的用户名是test'。
图4-50
在二次注入中,double2.php中的代码如下:
$con=mysqli_connect("localhost","root","123456","test");
if (mysqli_connect_errno())
{
echo "连接失败: " . mysqli_connect_error();
}
$id = intval($_GET['id']);
$result = mysqli_query($con,"select * from users where `id`=". $id);
$row = mysqli_fetch_array($result);
$username = $row['username'];
$result2 = mysqli_query($con,"select * from winfo where `username`='".$username."'");
if($row2 = mysqli_fetch_array($result2)){
echo $row2['username'] . " : " . $row2['address'];
}else{
echo mysqli_error($con);
}
先将GET参数ID转成int类型(防止拼接到SQL语句时,存在SQL注入漏洞),然后到users表中获取ID对应的username,接着到winfo表中查询username对应的数据。
但是此处没有对$username进行转义,在第一步中注册的用户名是test',此时执行的SQL语句如下:
select * from winfo where `username`='test''
单引号被带入SQL语句中,由于多了一个单引号,所以页面会报错。
— 实验室旗下直播培训课程 —
和20000+位同学加入MS08067一起学习
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...