KhaiTrang1995/Malware-Analysis-Reports-PHP-Backdoor
GitHub: KhaiTrang1995/Malware-Analysis-Reports-PHP-Backdoor
一份针对伪装为文件管理器的多功能 PHP Web Shell 的深度分析报告,涵盖功能矩阵、反取证技术、MITRE ATT&CK 映射、YARA 检测规则及完整修复指南。
Stars: 0 | Forks: 0
# 恶意软件分析报告-PHP-后门
# 🔴 恶意软件分析报告:`[random_name].php`
## 目录
1. [执行摘要](#1-executive-summary)
2. [功能矩阵](#2-capability-matrix)
3. [详细技术分析](#3-detailed-technical-analysis)
- [3.1 操作系统命令执行(远程终端)](#31-os-command-execution-remote-terminal)
- [3.2 数据库管理与数据窃取](#32-database-administration--exfiltration)
- [3.3 任意 PHP 代码执行](#33-arbitrary-php-code-execution)
- [3.4 文件系统操作](#34-file-system-operations)
- [3.5 Web 代理 / 网络枢纽 (SSRF)](#35-web-proxy--network-pivoting-ssrf)
- [3.6 递归侦察与凭证收集](#36-recursive-reconnaissance--credential-harvesting)
- [3.7 归档操作](#37-archive-manipulation)
4. [反取证与规避技术](#4-anti-forensics--evasion-techniques)
- [4.1 时间戳伪造 (Timestomping)](#41-timestomping)
- [4.2 自修改(多态行为)](#42-self-modification-polymorphic-behavior)
- [4.3 单文件封装](#43-single-file-encapsulation)
- [4.4 禁用函数绕过](#44-disabled-function-bypass)
- [4.5 基于 Cookie 的配置持久化](#45-cookie-based-configuration-persistence)
5. [身份验证机制](#5-authentication-mechanism)
6. [失陷指标 (IOCs)](#6-indicators-of-compromise-iocs)
7. [MITRE ATT&CK 映射](#7-mitre-attck-mapping)
8. [修复指南](#8-remediation-guidance)
9. [执行流程图](#9-execution-flow-diagrams)
- [9.1 主请求路由器](#91-main-request-router)
- [9.2 终端命令执行级联](#92-terminal-command-execution-cascade)
- [9.3 反取证管道](#93-anti-forensics-pipeline)
- [9.4 完整攻击杀伤链](#94-full-attack-kill-chain)
## 1. 执行摘要
`[random_name].php` 是一个**多功能 PHP Web Shell**,伪装成合法的文件管理器实用程序。它为攻击者提供了一个完整的后渗透工具包,并作为单个独立的 PHP 文件交付。一旦部署在被攻陷的 Web 服务器上,它就赋予攻击者相当于完全交互式 Shell 访问权限、数据库管理控制权和横向移动能力——所有这些都可以通过标准的 Web 浏览器进行。
该 Shell 衍生自一个开源项目(GitHub 上由 Den1xxx 托管的 "PHP File Manager"),但已被**武器化,注入了终端模拟器**(可通过 `root%deadp00l` 提示签名识别)并增强了反取证能力。原始项目的良性文件管理功能既充当了操作掩护,又为恶意载荷提供了功能性的 UI 框架。
## 2. 功能矩阵
| 功能 | 风险 | 函数/机制 | 行引用 |
|---|---|---|---|
| 远程命令执行 | 🔴 严重 | `passthru`, `system`, `exec`, `shell_exec`, `proc_open`, `popen` | L1135–L1205 |
| 任意 PHP 执行 | 🔴 严重 | 通过 `fm_php()` 调用 `eval()` | L280–L289 |
| SQL 查询执行 | 🔴 严重 | 通过 `fm_sql()` 调用 `mysqli_query()` | L297–L322 |
| 完整数据库导出 | 🔴 严重 | `fm_backup_tables()` | L324–L371 |
| 数据库恢复 | 🟠 高 | `fm_restore_tables()` | L373–L395 |
| 任意文件读取 | 🔴 严重 | 通过 img/download 处理程序调用 `file_get_contents()` | L613–L634 |
| 任意文件写入 | 🔴 严重 | `file_put_contents()`, `fopen()`/`fwrite()` | L581, L603 |
| 任意文件上传 | 🟠 高 | `move_uploaded_file()` | L1218–L1230 |
| 任意文件删除 | 🟠 高 | `fm_del_files()` 递归删除 | L80–L94 |
| 文件权限修改 | 🟠 高 | 通过 `fm_chmod()` 调用 `chmod()` | L164–L173 |
| 目录遍历 | 🟠 高 | `realpath($_REQUEST['path'])` | L8 |
| Web 代理 / SSRF | 🟠 高 | 通过 `fm_proxy` 调用 `curl_exec()` | L642–L671 |
| 递归文件搜索 | 🟡 中 | `find_text_in_files()` | L515–L536 |
| 时间戳伪造 | 🟡 中 | 对被修改的文件调用 `touch()` | L588, L607 |
| 自修改 | 🟠 高 | `file_put_contents(__FILE__, ...)` | L581, L603 |
| 系统信息泄露 | 🟡 中 | `phpinfo()`, `phpversion()`, `php_ini_loaded_file()` | L637–L640 |
| 通过下载数据窃取 | 🟠 高 | 使用强制 MIME 类型的 `fm_download()` | L176–L199 |
| 归档创建 (Zip/Tar/Gz) | 🟡 中 | `PharData`,自定义 `archiveTar` 类 | L1272–L1320, L1747–L2010 |
## 3. 详细技术分析
### 3.1 操作系统命令执行(远程终端)
最危险的组件是注入到文件管理器头部区域的**全交互式终端模拟器**。可以通过硬编码的提示字符串来识别它:
```
root%deadp00l:$
```
**执行流程(大约在第 1120–1210 行):**
1. **基于会话的目录持久化:** Shell 使用 `$_SESSION['cwd']` 在多个 HTTP 请求之间保持攻击者的当前工作目录,从而实现与原生终端会话相同的 `cd` 导航。
2. **级联函数绕过:** 脚本遍历按顺序排列的执行函数数组,以查找未被 `php.ini` 中的 `disable_functions` 阻止的函数:
$execFunctions = [
'passthru', // 优先级 1:直接输出直通
'system', // 优先级 2:带有返回的系统命令
'exec', // 优先级 3:执行并捕获输出数组
'shell_exec', // 优先级 4:等同于反引号的 Shell 执行
'proc_open', // 优先级 5:带有管道的完全进程控制
'popen', // 优先级 6:单向管道
'symlink', // 额外功能:符号链接创建
'dl' // 额外功能:动态 PHP 扩展加载
];
3. **`cd` 命令拦截:** 目录更改命令在客户端通过正则表达式(`/^cd\s*(.*)$/`)进行拦截,并通过使用 `realpath()` 验证更新 `$_SESSION['cwd']` 来处理,而不是生成子进程。
4. **STDERR 捕获:** 所有命令都附加了 `2>&1`,以将标准错误合并到标准输出中,确保攻击者能在 Web 界面中看到错误消息。
### 3.2 数据库管理与数据窃取
该 Shell 提供了一个完整的 **SQL 控制台** 界面,具有直接的 MySQL/MariaDB 交互能力。
#### 连接处理程序 — `fm_sql_connect()` (L292–L295)
使用存储在 Cookie 持久化配置中的凭据建立 `mysqli` 连接:
```
function fm_sql_connect(){
global $fm_config;
return new mysqli(
$fm_config['sql_server'], // Default: 'localhost'
$fm_config['sql_username'], // Default: 'root'
$fm_config['sql_password'], // Default: '' (empty)
$fm_config['sql_db'] // Default: 'test_base'
);
}
```
#### 任意查询执行 — `fm_sql()` (L297–L322)
接受并执行 **任何** SQL 语句,将结果作为格式化的 `var_export()` 转储返回。这里没有任何输入净化或查询类型限制——`DROP`、`ALTER`、`GRANT` 以及所有 DDL/DML 语句都可以完全执行。
#### 完整数据库导出 — `fm_backup_tables()` (L324–L371)
自动化的数据库窃取函数,它会:
1. 通过 `SHOW TABLES` 枚举所有表
2. 通过 `SHOW CREATE TABLE` 捕获模式
3. 使用 `SELECT * FROM ` 迭代所有行
4. 生成一个完整的 `.sql` 转储文件,其中包含 `DROP TABLE IF EXISTS`、`CREATE TABLE` 和 `INSERT INTO` 语句
5. 将转储文件写入具有 Web 可访问权限的目录,文件名带有时间戳(`Y-m-d_H-i-s.sql`)
6. 为攻击者提供直接下载链接
#### 数据库恢复 — `fm_restore_tables()` (L373–L395)
允许导入 `.sql` 转储文件,使攻击者能够**覆盖或注入数据**到数据库中。
### 3.3 任意 PHP 代码执行
`fm_php()` 函数(L280–L289)实现了一个不受限制的 PHP 评估控制台:
```
function fm_php($string){
$display_errors = ini_get('display_errors');
ini_set('display_errors', '1');
ob_start();
eval(trim($string)); // ← CRITICAL: Unrestricted eval()
$text = ob_get_contents();
ob_end_clean();
ini_set('display_errors', $display_errors);
return $text;
}
```
**影响:** 这允许在**不**将其写入磁盘的情况下执行 **任何** PHP 代码。攻击者可以:
- 实例化反向 Shell
- 将额外的恶意载荷加载到内存中
- 绕过 `disable_functions` 访问 PHP 内部函数(通过 FFI、反射等)
- 操纵应用程序状态、会话和内存中的数据
- 通过其他 PHP 通道调用系统调用
该函数还会在执行期间**强制开启 `display_errors`**,为攻击者提供详细的调试输出,包括文件路径、堆栈跟踪和内部状态。
### 3.4 文件系统操作
该 Shell 提供了全面的文件系统控制:
| 操作 | 机制 |
|---|---|
| **浏览** | `fm_scan_dir()` 具有递归列出功能,包括隐藏文件(`$do_not_filter = true`) |
| **读取** | 使用 `file_get_contents()` 进行文本编辑;使用 `getimagesize()` + 原始输出进行图像查看 |
| **写入** | 使用 `file_put_contents()` 通过浏览器内置的 textarea 编辑器进行文件编辑 |
| **创建** | 使用 `fopen($path, "w")` 创建新文件;使用 `mkdir($path, 0777)` 创建目录 |
| **删除** | `fm_del_files()` 通过 `rmdir()` + `unlink()` 递归删除目录 |
| **重命名** | 原生 `rename()` 函数 |
| **上传** | `move_uploaded_file()`,文件名清理仅限于移除 `%` |
| **下载** | 带有强制 `application/octet-stream` MIME 类型的 `fm_download()` |
| **权限** | 带有递归选项和符号到八进制转换的 `chmod()` |
### 3.5 Web 代理 / 网络枢纽 (SSRF)
`fm_proxy` 功能(L642–L671)将被攻陷的服务器转化为 **HTTP 代理中继**:
```
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Den1xxx test proxy');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // SSL verification disabled
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // Certificate validation disabled
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
```
**攻击场景:**
- **服务器端请求伪造 (SSRF):** 访问公共互联网无法触及的内部网络资源(例如,云实例上的 `http://192.168.x.x/admin`、`http://169.254.169.254/latest/meta-data/`)。
- **身份洗钱:** 通过被攻陷服务器的 IP 地址路由攻击,将恶意流量归咎于受害者的基础设施。
- **内部服务枚举:** 探测防火墙后面的内部端口和服务。
- **SSL 剥离:** 禁用 SSL 验证(`CURLOPT_SSL_VERIFYHOST = 0`)允许透明拦截 HTTPS 流量。
代理通过 `fm_url_proxy()`(L464–L488)重写获取到的 HTML 中的所有 `href` 和 `src` 属性,以将后续请求路由回该 Shell,从而创建一个通过被攻陷服务器进行功能正常浏览的会话。
### 3.6 递归侦察与凭证收集
`find_text_in_files()` 函数(L515–L536)实现了对整个文件系统的 **递归 grep**:
```
function find_text_in_files($dir, $mask, $text) {
// Recursively walks all directories
// Reads file contents via file_get_contents()
// Returns array of matching file paths
}
```
**攻击者典型用法:**
- 搜索所有配置文件中的 `DB_PASSWORD`、`DB_HOST`、`API_KEY`、`SECRET_KEY`
- 定位 WordPress `wp-config.php`、Laravel `.env`、Drupal `settings.php`
- 在源代码中查找硬编码的凭证
- 识别共享托管环境上的其他 Web 应用程序
结合文件掩码参数(例如,`*.php`、`*.env`、`*.conf`),这可以快速提取整个 Web 根目录及更深层目录的凭证。
### 3.7 归档操作
该 Shell 包含两种独立的归档机制:
1. **基于 PharData(L1272–L1340):** 使用 PHP 内置的 `PharData` 类创建目录和单个文件的 `.zip` 和 `.tar.gz` 归档。用于批量数据窃取。
2.自定义 `archiveTar` 类(L1747–L2010):** 一个 260 多行的、自包含的 tar 归档实现,从 ReloadCMS 项目移植而来。支持:
- 创建 gzip 压缩的 tar 归档
- 提取带有完整路径恢复的归档
- 长文件名支持(POSIX.1-2001 `././LongLink` 头)
- 校验和验证
- 递归目录打包
## 4. 反取证与规避技术
### 4.1 时间戳伪造
该 Shell 实现了**时间戳操纵**以挫败取证时间线分析:
```
// When editing a file (e.g., injecting backdoor into index.php):
$filemtime = filemtime($fn); // Save original mtime
file_put_contents($fn, $_REQUEST['newcontent']); // Modify file
if (!empty($fm_config['restore_time']))
touch($fn, $filemtime); // Restore original mtime
```
**配置标志:**
- `restore_time` (L39):恢复服务器上**任何被编辑文件**的时间戳
- `fm_restore_time` (L40):在自修改后专门恢复**Shell 文件本身**的时间戳
**影响:** 执行常规文件完整性检查(例如,`find / -mtime -1`)的管理员**将检测不到**最近修改的文件,因为 `Last Modified` 时间戳已被回滚到其遭到入侵之前的值。
此外,Shell 在编辑自身时会硬编码其自身的时间戳:
```
if ($_GET['edit'] == basename(__FILE__)) {
touch(__FILE__, 1415116371); // Fixed timestamp: 2014-11-04T18:32:51Z
}
```
这将 Shell 文件的修改时间锚定在 2014 年 11 月的某个日期,使其看起来像是在攻陷发生之前的旧文件。
### 4.2 自修改(多态行为)
该 Shell 可以使用 `file_put_contents(__FILE__, ...)` 在运行时**重写其自身的源代码**:
1. **凭证轮换 (L573–L589):** 授权设置(登录名、密码、Cookie 名称)作为 JSON 字符串存储在文件内。Shell 使用正则表达式定位此字符串,将其替换为新值,并将修改后的源代码写回磁盘。这使得攻击者无需重新上传文件即可更改其访问凭证。
2. **模板持久化 (L590–L609):** PHP 和 SQL 代码模板(常用命令)以内联方式存储,并通过相同的自修改机制进行更新。
**取证意义:** 每次自修改都会创建一个**新的文件哈希**,使基于哈希的检测签名失效。结合时间戳伪造,这使得基于哈希和基于时间戳的检测均无效。
### 4.3 单文件封装
整个工具包——包括所有 UI 资产——被打包成一个**独立的 PHP 文件**:
- **图标**(文件夹、文件、主页、图像):作为 Base64 编码的 `data:image/png;base64,...` URI 直接嵌入到 CSS 中
- **样式表**:内联 `