PHP代码审计 SQL注入专题

常见防御方法

防御原理:输入(解决数字型注入–>即加is_numeric这些去判断)-------转义处理(解决字符型注入)-------输出(解决数据库报错)

1.禁止数据库爆错信息泄露件 php.ini文件中display_errors = Of
2.php内部转义处理函数

mysql_real_escape_string-->能将特殊字符进行转义
mysql_escape_string()
magic_quote_gpc()
addslashes->这个函数会加上转义符
对立函数stripcslashes-->这个函数为删除字符串中存在的\

3.预处理技术进行查询
利用 m y s q l i − > p r e p a r e 和 mysqli->prepare和 mysqli>preparemysqli_stmt->bind_param函数进行去预处理

<?php
$sql = "select id,username,password from users where id=?";创建一个预定义的对象 ?占位
$mysqli_stmt = $mysqli->prepare($sql);
$id=$_REQUEST['id'];
$mysqli_stmt->bind_param("i",$id);绑定参数
$mysqli_stmt->bind_result($id,$username,$password);绑定结果集
$mysqli_stmt->execute();//执行
while($mysqli_stmt->fetch()){ //取出绑定的结果集
echo $id." ".$username ." ". $password;
}
?>

代码分析

== 防御成功的利用这两个函数即可==

 <?php     
 
 if (isset($_GET['Submit'])) { 
 
     // Retrieve data 
 
     $id = $_GET['id']; 
     $id = stripslashes($id); 
     $id = mysql_real_escape_string($id); 
 
     if (is_numeric($id)){ 
 
         $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; 
         $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' ); 
 
         $num = mysql_numrows($result); 
 
         $i=0; 
 
         while ($i < $num) { 
 
             $first = mysql_result($result,$i,"first_name"); 
             $last = mysql_result($result,$i,"last_name"); 
              
             echo '<pre>'; 
             echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last; 
             echo '</pre>'; 
 
             $i++; 
         } 
     } 
 } 
 ?>

如果没有两个过滤函数
利用方法 http://127.0.0.1/?id=1

特殊案例

1.宽字节注入思路
1.1 常规宽字节注入

核心:mysql查询的时候采用宽字节方式查询导致

<?php 

$con = mysql_connect("localhost","root","root");
mysql_query("SET NAMES 'gbk'");
mysql_select_db("test", $con);
$id = isset($_GET['id']) ? addslashes($_GET['id']) : 1;
$query = "SELECT * FROM users WHERE id ='{$id}' ";
?>

因此可以利用
id=%df%27进行去绕


修复方法:
1.将character_set_client设置为binary(二进制)
全部指定为二进制传输
mysql_query("SET character_set_connection=gbk, character_set_results=gbk,character_set_client=binary",
$conn);
2.指定php连接mysql的字符集
mysql_set_charset('gbk',$conn);
id=mysql_real_escape_string(_GET['id']);

1.2php编码转换导致的宽字节注入

导致原理:在字符输入后进行了编码转换进而导致逃逸单引号

<?php
$con = mysql_connect("localhost","root","root");
mysql_query("SET NAMES 'gbk'");
mysql_select_db("test", $con);
mysql_query("SET character_set_connection=gbk,
character_set_results=gbk,character_set_client=binary", $con);
$id = isset($_GET['id']) ? addslashes($_GET['id']) : 1;
$id=iconv('utf-8','gbk',$id);//和上面相比 添加了这个代码
$query = "SELECT * FROM users WHERE id ='{$id}' ";
$result = mysql_query($query)or die('<pre>'.mysql_error().'</pre>');
while($row = mysql_fetch_array($result))
{
echo $row['0'] . " " . $row['1'];
echo "<br />";
}
echo "<br/>";
echo $query;
mysql_close($con);
?>

#绕过语句--> 錦',因为utf-8编码和gbk编码的不同性质,进而导致逃逸,溢出导致sql注入。

2.编码解码导致sql注入

原理:
字符在拼接到sql注入之前进行了解码

例子

<?php
$con = mysql_connect("localhost","root","root");
mysql_select_db("test", $con);
$id = addslashes($_REQUEST['id']);
$id = urldecode($id);//$id = base64_decode($id);#核心导致的原因
$query = "SELECT * FROM users WHERE id = '{$id}'";
$result = mysql_query($query)or die('<pre>'.mysql_error().'</pre>');


#绕过方法
id=1%2527union select 1,2,3,4%23

3.json编码注入绕过
json编码绕过addslashes是因为json编码会把\转换为\ ,admin’ # 被addslashes会变成admin’ # 引号被过滤了转移不了,但是
经过了json_encode后变成admin\’ # 引号成功逃了出来,可以注入
在这里插入图片描述

4.二次注入
导致原理:
1.数据入库后转义符号会无
2.而且在次调用了我们插入的内容去查询

如2018 网鼎杯
5.其他类型的
5.1
stripslashes+addslashes导致的注入
即在入库数据之前做了stripslashes操作
5.2
字符替换导致的addslashes
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

goddemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值