首页 > 编程语言 >php反序列化逃逸

php反序列化逃逸

时间:2023-05-23 22:23:58浏览次数:43  
标签:php name sign 逃逸 pass 字符串 序列化

之前就对字符串逃逸这一块理解的不是很深刻,下面通过一位师傅的博客来进一步深入理解一下有关php字符串逃逸的相关内容。

贴上师傅的博客地址:https://blog.csdn.net/qq_45521281/article/details/107135706

先来说一下什么是字符串逃逸,就是我们可以构造一些恶意代码,让其在反序列化的时候执行我们想让它执行的。在这过程中造成的字符串的增加或者减少称为字符串逃逸。

替换修改后导致字符串长度增加 (逃逸增加)

先来一个代码简单的分析一下:

<?php
function filter($str){
    return str_replace('bb','ccc',$str);
}
class A{
    public $name='aaaa';
    public $pass='123456';
}
$AA=new A();
echo serialize($AA)."\n";
$res=filter(serialize($AA));
$c=unserialize($res);
echo $c->pass;
?>
    看它的返回结果:
O:1:"A":2:{s:4:"name";s:4:"aaaa";s:4:"pass";s:6:"123456";}
123456

若我们在不直接修改pass的前提下,让pass的值变成hacker,我们该如何实现呢?
这里我们就用到了字符串逃逸增加来实现。

我们可以看到str_replace('bb','ccc',$str); 意思就是在变量str中,将每两个b替换成三个c,但序列化之后的字符长度仍然按照没有被替换的。

举个例子说明一下:

<?php
function filter($str){
    return str_replace('bb','ccc',$str);
}
class A{
    public $name='aaaabb';
    public $pass='123456';
}
$AA=new A();
echo serialize($AA)."\n";
$res=filter(serialize($AA));
echo $res;
?>
    运行的结果如下:
O:1:"A":2:{s:4:"name";s:6:"aaaabb";s:4:"pass";s:6:"123456";}
O:1:"A":2:{s:4:"name";s:6:"aaaaccc";s:4:"pass";s:6:"123456";}  //这里我们可以看到aaaaccc明明是7个字符,但前面标的仍然是6个,这里就逃逸出来一个字符。

根据上面的演示,我们可以进行构造代码,通过bb替换成ccc,来进行字符串的逃逸,从而让pass的值为hacker

下面是代码:

<?php
function filter($str){
    return str_replace('bb','ccc',$str);
}
class A{
    public $name='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:4:"pass";s:6:"hacker";}';
    public $pass='123456';
}
$AA=new A();
echo serialize($AA)."\n";
$res=filter(serialize($AA));
$c=unserialize($res);
echo $c->pass;
//echo $res;
?>
    运行的结果:
O:1:"A":2:{s:4:"name";s:81:"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";s:4:"pass";s:6:"hacker";}";s:4:"pass";s:6:"123456";}
hacker
成功的实现目标。

思想就是我们要逃逸出来的字符串是";s:4:"pass";s:6:"hacker";} 总共27个字符串,也就是说需要逃逸27个字符串出来,之前是2b逃逸出来一个,那么这需要逃逸27个,也就需要54b。

替换修改后导致字符串长度减少 (逃逸减少)

字符串逃逸减少就是字符串经过一些变化后,字符长度减少,原来的功能性代码变成普通的字符串,然后我们可以利用逃逸进行构造一些恶意的代码。

下面来一个例子看一下:

<?php
function str_rep($string){
    return preg_replace('/php|test/','',$string);
}
$test['name']=$_GET['name'];
$test['sign']=$_GET['sign'];
$test['number']='2020';
$temp=str_rep(serialize($test));
printf($temp);
$fake=unserialize($temp);
echo '<br>';
print("name:".$fake['name'].'<br>');
print("sign:".$fake['sign'].'<br>');
print("number:".$fake['number'].'<br>');
?>

代码都是上面师傅里面演示的,这里我是根据自己的理解来讲一下。

把这段代码放在本地,可以看到结果为:

这里可以看到name和sign里面都是没有内容的,所以这里是N。

然后我们看到代码中的str_rep()函数,是将变量string中的php和test替换成空。

然后下面有一个经过这段函数的反序列化,这里就构成了反序列化逃逸减少的漏洞。

反序列化逃逸减少不同于增加。

增加是看要构造的恶意代码字符串长度是多少,就举一个例子,如果匹配到了bb,函数是把它替换成ccc,那么就相当于每一个bb可以逃逸出1个字符,如果我们要构造的恶意代码长度是27位,那么我们就需要54个bb。

而减少我个人感觉是比增加复杂一点,但也不多。拿上面的代码进行演示,如果我想让sign的值是eval,并且数字改成2023,那么这就利用到了字符串逃逸减少。

首先构造我们要实现的目标。";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2023";}

减少逃逸是让一些功能性代码变成字符串,这里是让sign变成字符串,而后面构造的sign和number则成为新的功能性代码。

";s:4:"sign";s:xx:"前面的字符一共有19个,我们有两种方法,一种是利用php,另外一种是利用test只不过都需要填充字符罢了 ";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2023";}

";s:4:"sign";s:xx:"这里是需要填充的字符";s:4:"sign";s:4:"eval";s:6:"number";s:4:"2023";}

如果用7个php,也就是可以逃逸21个,上面是19个,那么我们可以填充2个字符。

如果用5个test,逃逸20个,需要填充一个字符。

结果如上。

标签:php,name,sign,逃逸,pass,字符串,序列化
From: https://www.cnblogs.com/mrfs/p/17426555.html

相关文章

  • xctf_easyphp
    easyphp类型:PHP代码审计1.审查传值2.观看分析条件从上往下看:1.if(isset($a)&&intval($a)>6000000&&strlen($a)<=3)2.if(isset($b)&&'8b184b'===substr(md5($b),-6,6))3.$c=(array)json_decode(@$_GET['c'])4.if(is_a......
  • System.Text.Json匿名对象反序列化
    以前就是一直使用Newtonsoft.Json用起来还是挺舒服的。由于JSON的应用越来越广,现在.NETCore都内置了System.Text.Json可以直接对JSON进行操作,不过两个东西的体验依然有点区别。有时候我们会遇到的从第三方传递过来的jsonstring对象,对其进行解析并不需要所有的字段,......
  • PHP用PhpOffice->PhpSpreadsheet导出excel
    phpexcel由于版本陈旧性能低下官方放弃维护转而开发PhpSpreadsheet用了最新得psr标准因而对php版本不向下兼容需要注意!。PhpSpreadsheet是一个用纯PHP编写的库,提供了一组类,使您可以读取和写入不同的电子表格文件格式PhpSpreadsheet提供了丰富的API接口,可以设置诸多单元格以及文......
  • drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类
    1.模块与包#模块与包 模块:一个py文件被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件包:一个文件夹下有__init__.py#模块与包的导入问题'''1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的2.导入任何模块,如果......
  • Thrift 消息序列化分析过程
    序列化浮点型数据流程 bitwise_cast<unsigned__int64,double>(doublefrom)行74 C++ apache::thrift::protocol::TBinaryProtocolT<apache::thrift::transport::TTransport>::writeDouble(constdoubledub)行171 C++ apache::thrift::protocol::TVirtualProtocol<......
  • 一个简单的应用MVC思想的php程序
    <?php//controller.php控制器程序require_once("model.class.php");$type=isset($_GET['type'])?$_GET['type']:3;$modelObj=newDateTime2();switch($type){case1:$str=$modelObj->getD......
  • 【PHP兴趣部落-05】html table(表格)
    一、简介:表格由<table>标签来定义。每个表格均有若干行(由<tr>标签定义),每行被分割为若干单元格(由<td>标签定义)。字母td指表格数据(tabledata),即数据单元格的内容。数据单元格可以包含文本、图片、列表、段落、表单、水平线、表格等等。二、代码<!DOCTYPEhtml><html......
  • 【PHP兴趣部落-09】递归转义
    一、定义addslashes()函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:单引号(’)双引号(”)反斜杠(\)NULL注释:默认地,PHP对所有的GET、POST和COOKIE数据自动运行addslashes()。所以您不应对已转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可......
  • 【PHP兴趣部落-08】PHP中时区设置的三种方法(timezone)
    一、三种方法php中时区默认是格林尼治时间,和中国时差八个小时。现在根据需要将时间设置为中国时间,下面整理了三种方法。方法1:最好的方法在php.ini里加上找到date.timezone项,设置date.timezone=“Asia/Shanghai”,重启环境就ok了。方法2:在需要用到这些时间函数的时候,在页面添......
  • 【PHP兴趣部落-04】html 表单中常用元素
    一、简介html表单中常用的一些元素:比如按钮,输入框、单选框、复选框等控件元素。表单标签:<form>元素标签:<inputtype=”类型”name=”控件名”value=”值”>三、代码<html><head><title>html基本元素学习</title></head><!--表单--><formaction="ok.html"met......