SQL注入的二阶注入攻击与环境搭建+防范方法
2021-09-01 21:10
876 查看
[toc]
什么是二阶注入?
二阶注入是指完成一次SQL注入攻击需要进行两次SQL注入(即至少两个不一样的SQL语句查询) 比如我在a页面进行了SQL注入,注入的结果在b页面进一步利用,并在b页面再进行注入,即可得到我们想要的结果。
所以,想要完成二阶注入的操作,至少需要在多页面互动
下面以一个注册+修改密码的web漏洞进行二阶注入
环境搭建
环境要求:
- 连接数据库
- 需要有一个登录界面,并连上数据库
- 需要一个注册界面,即本质上是在数据库添加内容
- 需要一个修改密码的界面,即本质上是修改数据库的内容
登录界面:
代码放在了上一个博客中 https://www.geek-share.com/detail/2841499520.html
数据库连接代码:
最好出现在每一个文件夹中,这样比较方便:
<?php $con=mysqli_connect('127.0.0.1','root','root') or die("数据库连接失败!"); mysqli_select_db($con,'lab')or die("数据库连接失败"); ?>
注册界面:
register.html
<html> <head> <meta charset="UTF-8"> <title>Login</title> <style> #a { width: 500px; text-align: center; } .b { width: 200px; height: 30px; } </style> </head> <body> <div id=a> <h2>Register a account!</h2> <form name="form_register" method="POST" action="check_register.php"> Username:<input type="text" class="b" name="username" /><br> <br> Password:<input type="password" class="b" name="password" /><br> <input type="submit" name="Submit" value="Submit" /> <input type="reset" name="reset" value="Reset" /> </form> </div> </body> </html>
register.php
<?php include('con_database.php'); $username=isset($_POST['username'])?mysqli_escape_string($con,$_POST['username']):''; $password=isset($_POST['password'])?mysqli_escape_string($con,$_POST['password']):''; if($username=='' || $password==''){ echo "<script>alert('请输入账号和密码!')</script>"; exit; } $sql="select * from users where username='$username';"; $query=mysqli_query($con,$sql) or die(mysqli_error($con)); $num=mysqli_fetch_array($query); if($num){ echo "该用户名已存在"; exit; } $sql="insert into users (username,passcode) values ('$username','$password')"; mysqli_query($con,$sql) or die("注册失败"); echo "注册成功,请<a href='http://127.0.0.1/web/login/login.html'>登录</a>"; mysqli_close($con); ?>
修改密码界面
updatepassword.html
<html> <head> <meta charset="UTF-8"> <title>Login</title> <style> #a { width: 500px; text-align: right; } .b { width: 200px; height: 30px; } </style> </head> <body> <div id=a> <h2>Update Your Password!</h2> <form name="form_updatepassword" method="POST" action="updatepassword.php"> Current_password:<input type="text" class="b" name="current_password" /><br> <br> New_password:<input type="text" class="b" name="password" /><br><br> <input type="submit" name="Submit" value="Submit" /> <input type="reset" name="reset" value="Reset" /> </form> </div> <a href="http://127.0.0.1/web/login/login.html">返回登录首页</a> <br> <a href="http://127.0.0.1/web/register/register.html">返回注册首页</a> </body> </html>
updatepassword.php
<?php session_start(); if(isset($_POST['Submit'])){ include('con_database.php'); $username=$_SESSION['username']; $curr_pass=mysqli_real_escape_string($con,$_POST['current_password']); $pass=mysqli_real_escape_string($con,$_POST['password']); $sql="update users set passcode='$pass' where username='$username' and passcode='$curr_pass'"; $res=mysqli_query($con,$sql) or die(mysqli_error($con)); $row=mysqli_affected_rows($con); if($row!=0){ echo "<script>alert('Change password successfully');history.go(-2)</script>"; }else{ echo "<script>alert('Change password failed!');history.go(-2)</script>"; } } ?>
漏洞复现
先创建一个账户:名字叫admin'# 由于在register.php代码中存在mysqli_escape_string()函数,所以我们的单引号会被转义 注册成功,在数据库中看下我们刚刚注册的内容,意料之中,账户名就叫admin'# 接着,去修改密码: 修改成功后,查询数据表: 发现admin'#的密码并没有被修改,反而是admin的密码被修改成abc了: 于是这样我们都不用知道admin之前的密码,直接就修改了我们想要的密码
漏洞分析
这个二次注入的漏洞原因还是在于updatepassword.php的SQL语句的不合理利用:
$username=$_SESSION['username']; $curr_pass=mysqli_real_escape_string($con,$_POST['current_password']); $pass=mysqli_real_escape_string($con,$_POST['password']); $sql="update users set passcode='$pass' where username='$username' and passcode='$curr_pass'";
尽管对两次输入密码都做了转义,但是并没有对username做转义,这可能基于开发者对第一次已经转义了username的信任。
SQL语句经过调整变成了:
update users set passcode='abc' where username='admin'#' and passcode='$curr_pass'这样一来,后面的passcode验证会被略去,where语句为真,且修改的username为admin
二次注入漏洞都源自于开发者对已经转义的字符不会再造成威胁的刻板认识
漏洞防范
- 对username进行PHP转义函数的转义——就算之前已经转义过一次,还需要再次转义
- 使用MySQLi参数化更新,事先编译的PHP代码能够带来高效的防护效果
相关文章推荐
- Spring中使用事务搭建转账环境方法二 相对简便的注解方法 ——配置文件注入对象属性需要setter方法 注解方法,不需要生成setter方法
- sql注入学习(包括sqlilabs安装搭建注入环境步骤以及sqlmap安装操作说明链接地址)
- Spring中使用事务搭建转账环境方法二 相对简便的注解方法 ——配置文件注入对象属性需要setter方法 注解方法,不需要生成setter方法
- SQL注入系列之环境搭建(一)----ASP+ACCESS注入环境搭建
- SQL注入系列之环境搭建(二)----PHP+Mysql注入环境搭建
- asp防范跨站点脚本攻击的的方法
- solr环境的搭建以及基本的使用方法
- HHvm Apache 2.4 Nginx建站环境搭建方法安装运行WordPress博客
- Android环境搭建——adt无法更新或者无法在线安装的解决方法
- Linux系统Ubuntu下的驱动开发编译环境搭建方法与步骤
- 关于在linux环境中用eclipse搭建c++程序开发平台的方法
- 一种新的攻击方法——Java Web表达式注入
- Android 开发环境搭建 与在编译中遇到错误make Error 45解决方法
- 使用ZendStudio和ZendServer搭建PHP开发环境配置方法
- Qt+VC环境搭建以及使用方法
- 防范 DDoS 攻击的 15 个方法
- 总结一下网站注入与防范的方法
- Spring环境搭建之:控制反转(IoC Inversion of Control)与依赖注入(DI Depenency Injection)
- 在VS Code上搭建Python开发环境的方法
- JavaScript注入攻击介绍和防范