SQL注入作为OWASP榜单上常年位居前列的高危漏洞,其危害远不止于窃取数据库中的几行数据。从攻击链的完整视角来看,一次精心构造的SQL注入往往只是攻击者的滩头阵地,真正的目标是穿透数据库边界,最终完成对操作系统层面的控制。这条从Web应用到数据库再到服务器的提权路径,在实战中呈现出高度结构化的攻击模式,理解这条路径的每一个节点,对于防御体系的构建至关重要。
当攻击者发现一个SQL注入点时,首先需要完成的是对数据库环境的侦察。通过构造特定的注入语句,可以逐步摸清数据库类型、版本、当前用户权限以及数据库在网络架构中的位置。以MySQL为例,攻击者通常会使用
SELECT @@version, @@datadir, @@hostname这类语句获取基础信息。更关键的是判断当前数据库用户是否具备FILE权限,这是后续写入文件操作的前提条件。在SQL Server环境中,
SELECT IS_SRVROLEMEMBER('sysadmin')可以直接判断是否拥有系统管理员权限。这一阶段的信息收集决定了后续攻击路径的选择范围,权限越高,可用的攻击手法就越多。
通过SQL注入读取敏感文件
如果数据库用户拥有文件读取权限,攻击者可以直接通过SQL语句读取服务器上的文件内容。在MySQL中,LOAD_FILE()函数是读取文件的核心工具。
SELECT LOAD_FILE('/etc/passwd')可以尝试读取Linux系统的用户信息,SELECT LOAD_FILE('C:/Windows/System32/drivers/etc/hosts')则针对Windows环境。读取Web应用配置文件是这一阶段的高价值目标,因为配置文件中通常包含数据库连接凭证、加密密钥、第三方服务密钥等敏感信息。攻击者通过读取application.properties、web.config或.env文件,往往能获取到比当前注入点更高权限的凭证,为横向移动创造条件。
利用SQL注入写入Webshell
写入文件是SQL注入攻击链中最关键的转折点,它将攻击范围从数据库层面扩展到了文件系统层面。使用INTO OUTFILE语句是MySQL环境下最经典的写文件手法。
SELECT '<?php @eval($_POST[\"cmd\"]);?>' INTO OUTFILE '/var/www/html/shell.php'这条语句将一段PHP一句话木马写入Web目录。攻击者需要事先探测Web应用的绝对路径,这可以通过报错信息、数据库存储路径推断、或者读取Apache/Nginx配置文件来实现。对于SQL Server,xp_cmdshell和OLE自动化存储过程是写文件的主要手段,但通常需要sysadmin权限才能启用。PostgreSQL则可以通过COPY命令或lo_export函数实现文件导出。写入Webshell成功后,攻击者便获得了在服务器上执行任意命令的入口。 通过xp_cmdshell直接执行系统命令
在SQL Server环境中,如果当前数据库用户拥有sysadmin角色,攻击者可以直接调用xp_cmdshell存储过程执行操作系统命令,无需写入Webshell这一中间步骤。
EXEC xp_cmdshell 'whoami'可以快速确认当前数据库服务账户的操作系统身份。如果xp_cmdshell被禁用,攻击者会尝试通过sp_configure重新启用它:
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;这条攻击路径的威胁程度极高,因为数据库服务账户通常以较高权限运行,在Windows环境下往往是LocalSystem或NetworkService,在Linux环境下可能是root或具有sudo权限的专用用户。一旦xp_cmdshell可用,攻击者就可以执行PowerShell下载木马、添加管理员账户、导出SAM文件等操作,攻击面瞬间从数据库扩展到整个操作系统。 利用UDF提权实现命令执行
MySQL环境下,当secure_file_priv限制导致INTO OUTFILE无法写入Web目录时,用户自定义函数(UDF)提权是一条高效的替代路径。UDF允许用户创建自定义函数来扩展MySQL的功能,攻击者可以将编译好的共享库文件写入插件目录,然后创建调用该库的函数。具体操作流程是:首先确定插件目录位置,通过
SHOW VARIABLES LIKE 'plugin_dir'获取路径;然后使用INTO DUMPFILE将UDF动态链接库文件写入该目录;最后执行
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll'创建函数。UDF提权的关键在于MySQL服务进程的运行权限,如果mysqld以root身份运行,通过UDF执行的系统命令也将拥有root权限,这意味着攻击者可以直接读取shadow文件、添加root级别的SSH公钥、或者反弹一个高权限shell。 MOF提权与Windows计划任务
在Windows环境下,如果MySQL服务以LocalSystem权限运行,且服务器操作系统版本较旧,攻击者可以利用MOF(Managed Object Format)提权技术。MOF文件是WMI(Windows Management Instrumentation)用来定义系统管理类的文件,系统会定期扫描特定目录并自动编译执行其中的MOF文件。攻击者通过SQL注入将恶意MOF文件写入
C:/Windows/System32/wbem/mof/目录,该文件可以定义每间隔一段时间执行一次指定命令。这种方式不需要写入Web目录,也不依赖Web服务器,完全通过数据库的文件写入能力配合Windows的WMI机制实现持久化命令执行。虽然较新版本的Windows已经修改了MOF自动编译机制,但在内网渗透中仍可能遇到未打补丁的遗留系统。 从数据库凭证到横向移动
数据库本身存储着大量有价值的信息,其中其他系统的登录凭证是最具横向移动价值的目标。攻击者在获得数据库控制权后,会系统性地搜索包含密码字段的表,尤其是用户表、系统配置表、以及应用日志表。很多应用系统在数据库中明文存储后台管理密码、FTP凭证、邮件服务器密码等。即便密码经过哈希处理,对于弱密码也可以使用彩虹表或在线破解服务进行还原。获取到这些凭证后,攻击者可以尝试登录同一网段内的其他服务器、网络设备、或者云服务控制台。数据库服务器往往是内网中连接数最多的节点之一,从它出发的横向移动具有天然的隐蔽性,因为数据库与其他服务器之间的通信通常被安全策略视为合法流量。
利用数据库特性进行权限提升即使数据库服务本身以低权限用户运行,攻击者仍有多种方式尝试本地提权。在Linux环境下,攻击者会检查内核版本是否存在已知的本地提权漏洞,例如DirtyCow、DirtyPipe等经典漏洞。数据库服务账户可能被配置了sudo权限,通过
sudo -l可以查看当前用户可执行的sudo命令。某些情况下,数据库进程属于docker组,这意味着攻击者可以通过挂载宿主机文件系统的方式逃逸容器并获得宿主机root权限。在Windows环境下,攻击者会检查SeImpersonatePrivilege或SeAssignPrimaryTokenPrivilege等特权是否启用,这些特权配合Potato系列工具可以实现从服务账户到SYSTEM的提权。数据库备份文件、定时任务脚本、启动项目录等也是常见的提权突破口,攻击者会系统性地扫描这些位置寻找可写的文件或目录。 防御策略:从攻击链各环节阻断
理解攻击链的目的是构建纵深防御体系。在注入防护层面,参数化查询和预编译语句是根本解决方案,任何字符串拼接构建SQL语句的做法都应当被禁止。Web应用防火墙可以拦截明显的注入探测行为,但不能作为唯一防线。在数据库权限层面,严格遵循最小权限原则,Web应用的数据库账户不应拥有FILE权限、不应具备创建存储过程的权限、更不应拥有系统管理角色。secure_file_priv参数应设置为禁止导出或限制到特定目录,且该目录不应与Web目录重叠。在文件系统层面,Web目录应设置严格的文件创建权限,数据库服务账户不应拥有Web目录的写权限。数据库服务运行账户应使用专用的低权限账户,而非root或LocalSystem。在监控层面,对INTO OUTFILE、LOAD_FILE、xp_cmdshell、sp_configure等敏感操作进行审计告警,对数据库服务进程发起的异常网络连接进行检测,这些行为往往是攻击者正在执行命令或反弹shell的信号。
从攻击链视角审视SQL注入,我们看到的是一条从Web输入点到操作系统完全控制的完整路径。每一个环节都存在攻防双方的博弈点,攻击者只需要找到一个薄弱环节即可推进攻击链,而防御者则需要确保每一个环节都足够坚固。这种不对称性决定了纵深防御的必要性,单一的安全措施无法应对系统性的攻击行为。真正有效的防护,是在理解攻击者完整战术的基础上,在攻击链的多个节点同时设置检测和阻断机制,让攻击者在任何一个环节都面临足够的阻力。
