SQL 注入 Impossible(4):PHP 源码分析与四级对比

概述 DVWA SQL 注入的四个等级中,Impossible 不是让你攻破的——它是安全样例,告诉你"如果一开始就写对,前面那些漏洞根本不会存在"。本文逐一拆解四级源码,以 Impossible 为重点,看它如何从根源上消除 SQL 注入。 一、Low:裸奔 $id = $_REQUEST[ 'id' ]; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); 问题清单 问题 代码体现 后果 无过滤 直接 $_REQUEST['id'] 进 SQL 输入即代码 字符型拼接 WHERE user_id = '$id' — 引号包裹 ' 可用于闭合字符串上下文 报错暴露信息 or die(...mysqli_error()...) 攻击者看到语法错误,帮助调试 payload 为什么 1' or '1'='1' # 能打穿 -- 拼接后: SELECT ... WHERE user_id = '1' or '1'='1' #' -- ↑ 闭合 ↑ 注入 ↑ 注释吞尾 攻击者的 ' 提前结束了字符串字面量,or '1'='1' 进入代码上下文,# 吞掉尾部多余引号。数据越界变成了代码。 ...

August 4, 2026 · 4 min · 692 words

SQL 注入 High(3):分页注入与三级对比总结

High 的变化 DVWA High 的 SQL 注入与 Low/Medium 不同——输入页面和结果页面分开了。 Low/Medium: 一个页面 — 上面输入框,下面结果 High: 两个页面 — Session 页面(输入 payload)→ 结果页面(看输出) 在 SQL Injection 主页面看到的是 “Click here to change your ID”,点击后弹出新页面输入 ID,Submit 后回到主页面看结果。 后端做了什么 High 的 PHP 源码逻辑: // 结果页面(sqli.php): if (isset($_SESSION['id'])) { $id = $_SESSION['id']; $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id'"; // 执行查询,显示结果 } // 输入页面(sqli_session.php): $_SESSION['id'] = $_POST['id']; Payload 存在 PHP session 变量里,两个页面通过 $_SESSION['id'] 共享同一个值。SQL 语句本身没有任何变化——字符型注入,没有任何过滤。 ...

August 4, 2026 · 2 min · 400 words

SQL 注入 Medium(2):数字型注入与 Burp Suite 绕过

Medium 的变化 DVWA Medium 相比 Low 加了三道防线: 防线 Low Medium 有效吗 输入方式 文本框 下拉菜单(1-5) ⚠️ 前端限制,可绕过 请求方式 GET POST ⚠️ 换种发请求的方式 后端过滤 无 mysqli_real_escape_string() 转义 ' ❌ 数字型没有引号可转 关键发现:Medium 后端 SQL 是数字型——WHERE user_id = 1,没有单引号包裹参数。 绕过下拉菜单:curl + Burp Suite 代理 环境 Kali Firefox → Burp Suite (127.0.0.1:8081) → DVWA (127.0.0.1:8080) SSH 隧道:Kali 8080 → mycvm 127.0.0.1:8080(DVWA 容器) Burp 代理:Kali 8081 → 截获/修改请求 → 转发到 8080 Burp Suite 配置 Kali 桌面搜 burp → Burp Suite Community → Temporary project → Use Burp defaults → Start Proxy → Options → Proxy Listeners → 确认/添加 127.0.0.1:8081 Firefox → Settings → Network Settings → Manual proxy → 127.0.0.1:8081 → 勾选 “Also use this proxy for HTTPS” 用 curl 绕过下拉菜单 DVWA Medium 的 SQL Injection 使用 POST 请求。curl 直接发 POST,不受前端下拉菜单限制: ...

August 4, 2026 · 4 min · 650 words

SQL 注入 Low(1):字符型注入与手工测试流程

第一部分:SQL 注入概述 什么是 SQL 注入 SQL 注入(SQL Injection)是将恶意的 SQL 语句片段插入到应用程序的输入参数中,让后端数据库误以为这是合法的查询指令并执行它。 简单说:你的输入被当作代码执行了。 正常请求: 浏览器 → 输入 user_id=1 → 服务器 → SQL: SELECT * FROM users WHERE id='1' → 返回 admin 注入请求: 浏览器 → 输入 user_id=1' or '1'='1' # → 服务器 → SQL 被篡改 → 返回全部用户数据 为什么 SQL 注入能成立 三个条件同时满足: 用户输入直接拼接到 SQL 语句中(没有参数化查询) 输入中的特殊字符('、"、--、#)没有被转义或过滤 数据库把拼接后的字符串当作 SQL 执行 这三个条件缺一个,注入就不成立。 注入的本质:脱离数据上下文,进入代码上下文 SELECT * FROM users WHERE id = '1' │ │ │ └── 后引号(后端写死的) └── 前引号(后端写死的,你的输入从它后面开始) -- 正常输入时,你的数据在引号里——是"数据" -- 你的输入里包含 ' 后,你提前闭合了引号——后面的内容进入了"代码"区域 -- 这就是注入的本质 什么是 Payload Payload = 攻击载荷 = 你精心构造的那段输入字符串。 ...

August 4, 2026 · 5 min · 1027 words

SQL 注入基础:字符型注入与手工测试流程

第一部分:SQL 注入概述 什么是 SQL 注入 SQL 注入(SQL Injection)是将恶意的 SQL 语句片段插入到应用程序的输入参数中,让后端数据库误以为这是合法的查询指令并执行它。 简单说:你的输入被当作代码执行了。 正常请求: 浏览器 → 输入 user_id=1 → 服务器 → SQL: SELECT * FROM users WHERE id='1' → 返回 admin 注入请求: 浏览器 → 输入 user_id=1' or '1'='1' # → 服务器 → SQL 被篡改 → 返回全部用户数据 为什么 SQL 注入能成立 三个条件同时满足: 用户输入直接拼接到 SQL 语句中(没有参数化查询) 输入中的特殊字符('、"、--、#)没有被转义或过滤 数据库把拼接后的字符串当作 SQL 执行 这三个条件缺一个,注入就不成立。 注入的本质:脱离数据上下文,进入代码上下文 SELECT * FROM users WHERE id = '1' │ │ │ └── 后引号(后端写死的) └── 前引号(后端写死的,你的输入从它后面开始) -- 正常输入时,你的数据在引号里——是"数据" -- 你的输入里包含 ' 后,你提前闭合了引号——后面的内容进入了"代码"区域 -- 这就是注入的本质 什么是 Payload Payload = 攻击载荷 = 你精心构造的那段输入字符串。 ...

August 4, 2026 · 5 min · 1027 words