代码审计 | SQL注入之过滤器绕过

1. 示例代码

搭建环境:

PHP/5.6.40/Nginx/1.24.0/Mysql/5.0.11

<?php$server="localhost";$username="root";$password="password";$db_connect=mysql_connect($server,$username,$password) or die("Unable to connect to the MySQL!"); mysql_select_db('sql',$db_connect); if(!isset($_POST['mail'])) {    die("POST submission mail.\n");}$mail = $_POST['mail'];
$filter_chain = array(FILTER_DEFAULT, FILTER_SANITIZE_ADD_SLASHES, FILTER_VALIDATE_EMAIL, FILTER_SANITIZE_STRING);
for($i=0; $i < count($filter_chain); $i++){    if(filter_var($mail, $filter_chain[$i]) === false){        die("Invalid Email.\n");    }}
$result = mysql_query("SELECT username FROM users WHERE email='$mail' LIMIT 1");  if ($result) {      while ($row = mysql_fetch_assoc($result)) {          $username=$row['username'];        echo "My name is:" . $username . "<br>";      }  } else {      echo "没有找到匹配的用户";  }?>

请查看上述代码,找出其中的漏洞。

2. 漏洞位置

$filter_chain = array(FILTER_DEFAULT, FILTER_SANITIZE_ADD_SLASHES, FILTER_VALIDATE_EMAIL, FILTER_SANITIZE_STRING);for($i=0; $i < count($filter_chain); $i++){    if(filter_var($mail, $filter_chain[$i]) === false){        die("Invalid Email.\n");    }}$result = mysql_query("SELECT username FROM users WHERE email='$mail' LIMIT 1");  

3. 漏洞原理

在示例代码中,用户输入的参数被直接用于执行SQL查询操作,这种方式存在潜在的安全风险。尽管代码中使用了过滤器进行过滤,但这种方式依然不足以防止攻击者绕过过滤器,从而导致SQL注入漏洞。

由于filter_var的返回值被丢弃,因此唯一相关的过滤器是FILTER_VALIDATE_EMAIL。RFC不是非常严格,允许使用许多特殊字符。

FILTER_VALIDATE_EMAIL:基于RFC822的电子邮件验证;

4. 漏洞复现

在访问示例代码时,可以使用Burpsuite进行抓包。更改请求方式为POST,需要提交一个名为mail的参数。FILTER_VALIDATE_EMAIL过滤器不允许在邮件地址中出现空格符号,可以使用/**/来代替。模拟邮件格式@可以成功注入。

经过测试,以下payload可以成功注入:

Payload:获取表中username字段值

mail='/**/union/**/select/**/username/**/FROM/**/users/**/#'@a.s

图片

Payload:获取表中password字段值

mail='/**/union/**/select/**/password/**/FROM/**/users/**/#'@a.s

图片

5. 修复方案

在进行数据库操作时,需要使用PDO预处理的方式,防止SQL注入漏洞的产生。PDO预处理方式,确保用户输入的值不会被当成sql语句解析。通过使用预处理语句和参数绑定,可以有效地防止恶意用户通过注入恶意代码来篡改查询的意图。

修复示例:

$stmt = $db_connect->prepare("SELECT username FROM users WHERE email=:mail LIMIT 1");  $stmt->bindParam(':mail', $mail);  $stmt->execute();  $result = $stmt->fetchAll(PDO::FETCH_ASSOC);  

作者:Spider-Man

2023年10月20日

洞源实验室

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值