二次注入攻击
二次注入攻击的测试地址在本书第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代码审计:入门篇》等。
扫描客服微信 获取更多课件+学习资料
标签:username,二次,代码,页面,SQL,test,php,id,注入 From: https://www.cnblogs.com/ms08067/p/18065442