SQL注入漏洞全解(护网实战视角)
SQL注入漏洞全解(护网实战视角)
前言
在历年的护网演练中,SQL注入(SQL Injection)始终是红队打点(Initial Access)的利器之一。由于其可能直接导致敏感数据泄露,甚至通过各种方式直接获取服务器权限(Getshell),它一直是蓝队重点防御和监测的对象。本文将全面梳理SQL注入的成因、危害、防范及常见手法。
一、 漏洞原因分析
SQL注入的根本原因在于“数据与代码未严格分离”。
当Web应用程序在处理用户输入(如GET/POST参数、HTTP请求头、Cookie等)时,没有进行严格的过滤、转义或类型校验,就直接将这些不可信的数据拼接到SQL查询语句中。数据库解析引擎会将这些恶意拼接的字符串当作正常的SQL指令执行,从而改变了原有SQL语句的逻辑。
二、 漏洞危害
在护网场景下,SQL注入通常会导致极为严重的后果,不仅限于单一系统,甚至会波及整个内网:
数据泄露(脱裤): 窃取数据库中的敏感信息,如管理员账号密码、用户个人信息(PII)、商业机密等。
数据篡改与破坏: 恶意修改数据库内容,或执行DROP、TRUNCATE等命令破坏业务数据。
系统接管(Getshell): 通过特定的SQL语句读写系统文件,植入Webshell,直接控制Web服务器。
内网横向移动跳板: 拿到数据库或Web服务器权限后,以此为据点探测内网环境,进一步攻击核心区域。
三、 SQL注入防范(蓝队加固重点)
防守方应采取多纵深防御策略:
代码层:预编译与参数化查询(核心): 使用PDO(PHP)、PreparedStatement(Java)等机制。这是防御SQL注入最根本的方法,它将SQL语句模板与参数完全分离开来。
代码层:严格的输入过滤与类型校验: 对用户输入进行严格的正则匹配、强制类型转换(如将ID强制转为整型),并过滤危险关键字。
系统层:数据库权限最小化: 坚决杜绝使用root或sa等高权限账号连接数据库;禁止数据库用户具备不必要的文件读写权限(如MySQL配置secure_file_priv=NULL)。
架构层:部署WAF/RASP: 在网关处部署Web应用防火墙(WAF),拦截带有恶意SQL特征的请求;在应用层部署RASP,从底层监控异常SQL执行行为。
四、 如何挖掘SQL注入漏洞
红队视角(测试探测):
寻找注入点: 关注所有与数据库交互的输入点,包括但不限于URL参数、表单提交、搜索框、甚至HTTP Header(如User-Agent、X-Forwarded-For)。
FUZZ测试: 提交特殊字符(如 ', ", , ), %bf 等),观察页面是否出现数据库报错、内容缺失、或响应时间异常变长。
闭合测试: 尝试构造如 and 1=1 和 and 1=2,或者利用时间盲注的 sleep(5),根据页面回显或响应延迟的差异来判断是否存在注入。
蓝队视角(流量监测):
重点监控频繁返回 500 错误、大量带有 select、union、sleep、extractvalue 等敏感字符的告警流量,特别是来自同一IP的高频探测。
五、 常见的注入手法
- 联合查询 (Union 注入)
原理: 使用 UNION SELECT 操作符将恶意查询的结果附加到原始查询的结果集中。前提是页面必须有数据回显位,且注入的查询必须与原查询的列数相同。
实战特征: 常常伴随 order by 猜测列数,随后出现 union select 1,2,user(),4... 等流量特征。
- 报错注入
原理: 当页面没有数据直接回显,但会输出数据库的错误信息时,攻击者故意构造语法错误或函数执行错误(如MySQL中的 updatexml(), extractvalue(), floor()),使数据库在报错信息中带出查询结果。
实战特征: 流量中常见特定的报错利用函数,如 and updatexml(1,concat(0x7e,(select user()),0x7e),1)。
- 基于布尔的盲注
原理: 页面不返回数据,也不返回报错信息,但会根据SQL执行的True或False返回不同的页面状态(例如:登录成功或失败,文章存在或不存在)。攻击者通过截取字符并比对ASCII码(如 ascii(substr(user(),1,1))>100),逐个字符猜解数据。
护网注意: 这种注入方式会产生大量的请求日志,容易触发WAF的频率限制策略。
- 基于时间的盲注
原理: 页面连True/False的差异都没有。攻击者利用 sleep() 或 benchmark() 等延时函数。如果条件为真,则执行延时,通过观察HTTP请求的响应时间来判断数据。
护网注意: 极易被蓝队察觉,因为会导致大量的慢查询日志,且请求特征非常明显(包含 sleep 或 waitfor delay)。
- HTTP头注入
原理: 攻击者不在常见的GET/POST参数中注入,而是篡改HTTP Header(如 User-Agent, Referer, Client-IP, X-Forwarded-For)。通常发生在应用程序将这些头部信息记录入库(如日志统计功能)时。
优势: 容易绕过一些只检测常规参数的初级WAF。
-
宽字节注入
原理: 针对防御方使用 addslashes() 或 magic_quotes_gpc 转义单引号(将其变成 ')的情况。如果数据库字符集设置为GBK等双字节编码,攻击者可以输入 %df'。转义后变成 %df'(即 %df%5c%27),由于GBK会将 %df%5c 解析为一个汉字(“縗”),从而“吃掉”了转义符 \,导致单引号 ' 成功逃逸。 -
堆叠查询 (Stacked Queries)
原理: 使用分号 ; 结束当前SQL语句,并紧接着执行另一条全新的SQL语句(如 ; DROP TABLE users;)。
危害: 极大,因为不仅可以查询,还可以直接执行 INSERT, UPDATE, DELETE 甚至系统层面的命令。通常在PDO或某些特定的数据库驱动配置下才支持。
- 二阶注入 (Second-order Injection)
原理: 攻击载荷在首次提交时被安全机制转义或无害化处理,并安全地存储到了数据库中。但是,当应用程序在后续的业务流程中(如后台管理页面)从数据库中读取出该数据,并未经验证再次拼接到另一个SQL查询中时,恶意代码被触发执行。
护网注意: 二阶注入极为隐蔽,常规的边界WAF很难在第一步直接阻断,通常需要结合代码审计或RASP来防御。
六、 SQL注入 Getshell 的几种方式 详情:https://blog.csdn.net/qq_44159028/article/details/116274542
在拿到高危SQL注入后,红队的终极目标通常是获取服务器控制权。以下是常见的理论手法:
利用 INTO OUTFILE 或 DUMPFILE 写入 Webshell (MySQL)
条件: 数据库用户具有 FILE 权限;MySQL配置 secure_file_priv 为空或指向特定目录;知道Web站点的绝对路径;该路径具有写入权限。
方法: union select 1, '' into outfile '/var/www/html/shell.php'
利用全局日志写入 Webshell (MySQL)
条件: 具备数据库DBA权限。
方法: 通过执行SQL语句,开启 general log(全局日志),并将日志文件的存储路径修改为Web目录下的 .php 文件。随后执行一条包含Webshell代码的查询语句,该代码就会被记录到PHP文件中从而Getshell。
set global general_log = 'on';
set global general_log_file = '/var/www/html/shell.php';
select '';
利用 xp_cmdshell 执行系统命令 (SQL Server)
条件: 目标为 SQL Server,且获取了 sa 或高权限。
方法: 开启 xp_cmdshell 扩展存储过程,直接利用SQL注入点执行操作系统命令(如 whoami, echo 写入文件,或下载远控木马)。
浙公网安备 33010602011771号