最新二次注入攻击和代码分析技术

二次注入攻击

二次注入攻击的测试地址在本书第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注入漏洞。

<?php    $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中的代码如下: 

<?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语句中,由于多了一个单引号,所以页面会报错。

 

 

Ms08067安全实验室专注于网络安全知识的普及和培训,是专业的“图书出版+培训”的网络安全在线教育平台,专注于网络安全领域中高端人才培养。

平台已开设Web安全零基础就业,Web高级安全攻防进阶,红队实战攻防特训,Java代码安全审计,恶意代码分析与免杀实战,CTF基础实战特训营,网络安全应急响应,安全工具开发,AI与网络安全等系统培训课程。实验室出版安全图书《Web安全攻防:渗透测试实战指南》、《内网安全攻防:渗透测试实战指南》、《Python安全攻防:渗透测试实战指南》、《Java代码审计:入门篇》等。

扫描客服微信 获取更多课件+学习资料

 

posted @ 2024-03-11 10:03  Ms08067安全实验室  阅读(9)  评论(0编辑  收藏  举报