You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构造SQL注入绕过存在SQL拼接漏洞的PHP登录验证

SQL注入登录绕过问题

问题场景

我正在自行搭建的PHP测试站点上开展SQL注入测试,用于演示站点存在的安全漏洞。本次测试的目标是无需输入密码即可通过登录表单校验,若能实现无需输入用户名即可直接通过验证则效果更佳。
站点登录逻辑的后端代码如下,我尝试了多种注入构造方式但均未成功实现绕过:

<?php
$link = @mysqli_connect("localhost", "root", "", "ISdbs");
if (mysqli_connect_errno()) {
    echo "Connessione fallita: " . die(mysqli_connect_error());
}
$query = "SELECT username,password from utenti where username='" . $_POST['user'] . "';";
echo "Ho eseguito la seguente query <b>",$query,"</b>";
$result = @mysqli_query($link, $query);
if (@mysqli_num_rows($result) != 0) {
    while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
        if ($row['password'] == $_POST['pass']) {
            $ID = $_POST['user'];
            echo "<h1 align='center' >benvenuto nell'area riservata</h1>";
            echo "<p align='center'>cosa vuoi fare?</p>";
            echo "<div'><ul'>
                        <li><a href='eliminaUtente.php?id=$ID'>Eliminare l'utente</a></li>
                        <li><a href='visualizzaCF.php?id=$ID'>Visualizza i tuoi dati segreti</a></li>
                       </ul></div>";
        }
        else
            echo "<h1>username o password errati</h1>"; 
    }
}
else
            echo "<h1>username o password errati</h1>";
?>

已知环境信息

  • 站点使用的utenti数据表共包含7个字段:CF、name、surname、phone、address、username、password
  • 登录校验流程仅查询username和password两个字段,密码比对逻辑在PHP代码层执行,没有写入SQL查询条件

绕过原理

代码没有对$_POST['user']参数做任何过滤,直接拼接到SQL语句中,存在字符型SQL注入漏洞。注意和常规“把密码校验写在SQL where条件里”的场景不同,这段代码是先执行SQL查询拿到符合用户名条件的所有记录,再遍历记录逐行比对密码和用户输入的pass参数是否一致。只要构造注入让SQL返回的结果集中,存在一条password字段值和我们提交的密码内容完全一致的记录,就能通过校验。

具体注入构造

通用绕过方法(无需已知用户名、无需输入密码)

  • 用户名输入框填入以下Payload:
    ' UNION SELECT 'test','' -- 
    
  • 密码输入框留空,不填入任何内容
    提交后即可直接通过校验进入受限区域。

执行逻辑说明

注入后拼接生成的完整SQL语句如下:

SELECT username,password from utenti where username='' UNION SELECT 'test','' -- ';

语句执行流程:

  1. 原查询的条件username=''通常匹配不到表内真实用户,返回空结果
  2. UNION会合并我们自定义的查询结果:自定义行的username字段值为test,password字段值为空字符串,和原查询的字段数量完全匹配,不会报字段数错误
  3. 末尾的-- 是MySQL单行注释符,会把后续多余的单引号、分号全部注释,不会触发SQL语法错误
    最终SQL返回的结果集里会包含我们构造的这条记录,PHP遍历结果时,会发现这条记录的password值(空字符串)和我们提交的空密码完全相等,直接判定登录通过。

常见注入失败原因

很多人尝试' OR 1=1 -- 这类万能密码无法生效,核心原因是这类Payload会返回表内所有真实用户的记录,但这些真实用户的password字段都不是空字符串,和我们提交的空密码无法匹配,PHP逐行校验时全部判定密码错误,自然无法绕过。


内容的提问来源于stack exchange,提问作者Timeassassin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:39:13