<?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));
?>
思路:
看到unserialize()应该是反序列化
先调用了__construct()给变量赋值,在调用__wakeup(),然后调用了waf(),waf()起了一个过滤匹配的效果,过滤了|,&,;,空格,/,cat,flag,tac,php,ls,最后调用__destruct(),如果method=ping,那么调用ping(),ping()负责将结果输出
先尝试构造payload:
array('l""s')
array('l``s)
过滤方法很多,不局限这两个
出现了两个目录
再次ls flag_1s_here 看是否还有目录
${IFS}可以代替空格绕过正则匹配
cat flag_1s_here/flag_831b69012c67b35f.php 就可获得flag
但/被过滤
可以将其转化为八进制然后再转为ascii码,注意必须是双引号
ab 对应的八进制是141,142
将 cat flag_1s_here/flag_831b69012c67b35f.php 转为8进制
![]()
最后payload: