Skip to content
Kurisu
Go back

文件包含到 RCE:filter chain 与内网实战

基础篇讲过 php://filter 与日志包含;这篇讲三板斧失效时(Docker 日志重定向、无上传点)怎么打,附实战复盘。

0x01 四个包含函数与两个伪协议

include / include_once / require / require_once:once 保证同文件只含一次(重复定义不报错),require 失败终止;攻击面相同,区别只在报错行为。

两个常用伪协议:

// php://filter:读源码(不执行),base64 输出绕过渲染
?file=php://filter/read=convert.base64-encode/resource=config.php

// php://input:把 POST 体当 PHP 执行(需 allow_url_include=On)
?file=php://input    POST: <?php system('whoami');?>

0x02 日志包含在 Docker 里为什么失效

经典路径:往 access.log 注入 <?php eval($_POST[x]);?>(UA 头最干净)再包含日志;Docker 里全灭:

  1. 容器日志被重定向到 stdout/stderr(/var/log/nginx/access.log -> /dev/stdout),文件里没有真实日志;
  2. 多数镜像不带 phpinfo,临时文件包含(PHP_SESSION_UPLOAD_PROGRESS / PHP_VALUE)所需的临时文件名拿不到。

结论:日志包含依赖”日志落盘 + 路径可知”——Docker 化破坏前者,先看容器化程度。

0x03 php://filter chain:不需要上传的 RCE

LFI 最优雅的现代打法:convert.iconv 过滤器级联逐层”变换”出 <?php ...; exit; ?>——绕开”只能包含不能执行”,不写文件:

?file=php://filter/convert.iconv.utf-8.utf-16|convert.iconv...|convert.base64-decode/resource=data:text/plain,<payload>

生成 chain 用 php_filter_chain_generator;原理:字符集编码读写互换产生字节层面的可控变换,级联等价于任意字节序列。触发条件同 php://input(allow_url_include)。

0x04 命令行参数注入(CLI 场景的 LFI 变体)

冷门但加分:PHP CLI 运行时 $_SERVER['argv'] 收集命令行参数;按 RFC,GET 里不含 = 的参数(如 ?/config/create)被某些框架当 argv 传,可构造调用内部工具的路径(config create)。另:php -S 0.0.0.0:7788 的目录少了 index.php 就 404。

0x05 实战复盘:一次高校内网渗透

完整案例(已脱敏),链路值得背下来:

来宾网络(开放无认证)──发现──> 来宾网与内网未隔离
  → 密码喷洒(固定弱密码 + 批量用户名)攻破统一身份认证
  → 统一认证里捡到四字姓名未改密账号
  → 内网横扫(X-Scan/fscan 指纹):SQL Server 弱口令 / 永恒之蓝 / VCenter
  → SQL 注入点 os-shell:sa 被降到 network service(能跑 dir/ipconfig,传不了文件)
  → 找可写目录:ProgramData(默认隐藏 + Everyone 权限,Windows 全系标配)
  → 上传 C2 马:被 360/火绒拦截 → 换轻量免杀 loader(share code 加载)
  → 上线后导出哈希 → VCenter RCE 拿通杀密码 → 登录主站后台

细节:

相关旧文


Share this post:

Previous Post
SSRF 深入利用:gopher 打 Redis 三板斧
Next Post
PHP 反序列化进阶:Session 不一致与 phar