SQL注入 (SQLi) 是一种安全漏洞,它允许攻击者干扰应用程序对其数据库发出的查询。当用户输入未经过适当清理或参数化而直接包含在 SQL 查询中时,就会出现此漏洞。SQL注入是最常见和最严重的 Web 应用程序安全漏洞之一,它使攻击者能够绕过身份验证、访问未经授权的数据、修改数据库内容,并在某些情况下,在数据库服务器上执行命令。
本文档涵盖了 SQL 注入基础知识、检测方法、利用技术和缓解策略。有关 NoSQL 注入漏洞,请参阅 NoSQL 注入。
入口点检测涉及识别应用程序中可能易受 SQL 注入攻击的用户输入位置。这些通常是表单、URL 参数、HTTP 头或可能与数据库交互的任何其他输入机制。
基于错误测试:输入特殊字符,如 '、"、;、) 或 *,这些字符可能会破坏 SQL 语法并触发数据库错误。
基于布尔值的测试:使用逻辑运算来确定输入是否影响查询执行
基于时间的测试:插入导致响应延迟的命令
在利用 SQL 注入漏洞之前,您需要识别底层数据库管理系统 (DBMS)。
每个 DBMS 都有用于识别的特定函数和语法
| DBMS | SQL Payload |
|---|---|
| MySQL | conv('a',16,2)=conv('a',16,2) |
| MSSQL | @@CONNECTIONS>0 |
| PostgreSQL | 5::int=5 |
| Oracle | ROWNUM=ROWNUM |
| SQLite | sqlite_version()=sqlite_version() |
不同的 DBMS 会产生独特的错误消息
| DBMS | 示例错误消息 |
|---|---|
| MySQL | SQL 语法有误;... 在第 1 行附近 |
| PostgreSQL | 错误:语法错误,在“1”附近 |
| MSSQL | 字符串“’”后面的未关闭引号 |
| Oracle | ORA-00933:SQL 命令未正确结束 |
来源: SQL注入/README.md110-126 SQL注入/README.md184-206
SQL 注入可用于绕过登录表单。考虑一个标准的身份验证机制
攻击者可能输入
' OR '1'='1
导致
由于 '1'='1' 始终为真,因此此查询将返回表中的所有用户,从而可能允许未经授权的访问。
Union注入使用 UNION 操作符将原始查询的结果与攻击者控制的第二个查询结合起来
确定列数:使用 ORDER BY 或迭代 NULL 测试
查找可打印列:尝试通过可注入的列显示数据
提取数据:用实际数据库查询替换数字占位符
来源: SQL注入/README.md184-206 SQL注入/MySQL注入.md111-183
基于错误的注入依赖数据库错误消息来提取信息
| 数据库 | 示例 Payload |
|---|---|
| MySQL | AND UPDATEXML(1,CONCAT('~',(SELECT version()),'~'),1)-- |
| MSSQL | AND CONVERT(int,(SELECT @@version))=1-- |
| PostgreSQL | AND CAST((SELECT version()) AS int)=1-- |
| Oracle | AND EXTRACT(XMLTYPE(CONCAT('<',version(),'>')))=1-- |
来源: SQL注入/README.md208-224 SQL注入/MySQL注入.md234-280
基于布尔值的注入利用条件响应来一次提取一个比特的数据
这会测试第一个用户名的第一个字符的 ASCII 值是否大于 90。
基于时间的注入会引入故意延迟来提取信息
如果第一个字符的 ASCII 值大于 90,查询将休眠 5 秒。
来源: SQL注入/README.md224-257 SQL注入/MySQL注入.md293-420
带外技术使用替代通道(如 DNS 或 HTTP)来窃取数据
这些查询强制数据库建立外部网络连接,将数据传输到攻击者的基础设施。
来源: SQL注入/README.md299-337 SQL注入/MySQL注入.md589-611
MySQL 支持使用 UPDATEXML、EXTRACTVALUE 和 FLOOR(RAND()) 等函数进行基于错误的注入。它可以使用 LOAD_FILE() 和 INTO OUTFILE 读取和写入文件,并通过用户定义函数执行命令。
来源: SQL注入/MySQL注入.md52-233 SQL注入/MySQL注入.md502-553
MSSQL 通过 xp_cmdshell 执行命令,通过 BULK INSERT 进行文件操作,并通过链接服务器提供独特的攻击向量
来源: SQL注入/MSSQL注入.md264-267 SQL注入/MSSQL注入.md350-367
PostgreSQL 提供基于 XML 的错误注入、通过各种函数访问文件以及通过 COPY FROM PROGRAM 执行命令
来源: SQL注入/PostgreSQL注入.md64-94 SQL注入/PostgreSQL注入.md234-246
Oracle 支持 Java 执行、PL/SQL 命令注入和基于 XML 的错误技术
来源: SQL注入/OracleSQL注入.md98-109 SQL注入/OracleSQL注入.md147-195
SQLite 提供独特的基于错误和代码执行的向量
来源:SQL Injection/SQLite Injection.md70-75 SQL Injection/SQLite Injection.md85-92
| 绕过 | 描述 |
|---|---|
?id=1%09and%091=1%09-- | 制表符 |
?id=1%0Aand%0A1=1%0A-- | 换行符 |
?id=1%0Dand%0D1=1%0D-- | 回车符 |
?id=1/*comment*/AND/**/1=1/**/-- | 注释符代替空格 |
| 禁止 | 绕过 |
|---|---|
LIMIT 0,1 | LIMIT 1 OFFSET 0 |
= | LIKE、REGEXP、BETWEEN、IN |
AND | && |
或 | || |
WHERE | HAVING |
来源:SQL Injection/README.md369-441
SQLmap 是最流行的 SQL 注入自动化工具
有关 SQLmap 的详细用法,请参阅 SQLmap 文档。
来源:SQL Injection/README.md40-42 SQL Injection/SQLmap.md29-32 SQL Injection/SQLmap.md38-40
SQLi 测试实验环境可从各种来源获取
如需全面的备忘单和深入的材料,请参阅
来源:SQL Injection/README.md442-461 SQL Injection/README.md462-473