大家好,结合上一篇PHP反序列化的文章,炒一下冷饭,给大家分析一下10月份出的 Typecho 反序列化漏洞。

本文的目的是把反序列化漏洞讲清楚,奶妈级讲解方式,让你看明白。

回顾

PHP反序列化漏洞详细教程及实例(上)

示例漏洞利用的过程:

  1. 需要有一个漏洞触发点 :pets.php 内的 $pet = unserialize($_GET[‘pet_serialized’]);
  2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。log.php (WTFLog 内的__destruct函数)。
  3. 漏洞的效果取决于__destruct 这个魔术函数内的操作,这里的是可以操控的可以删除的log 的 filename。
  4. 构建poc.php ,利用程序,先序列化后,从可控输入$_GET[‘pet_serialized’]输入进去。
  5. 完成。

代码回溯

在本文编写时,Typecho早已发布了很多新版本,让我们从git logs 中,找到存在漏洞的版本。

根据漏洞发生时间:10月左右,commit message : 漏洞 来确定具体的commit是哪一个

2018102918145-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-3-1

可以看到e277141 是已经修复后的commit,那么242fc1a就是我们需要回溯到的版本。

通过git 方式下载仓库以后。切换到目标版本。

20181029181418-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-4-1

漏洞分析

Typecho 反序列化漏洞存在于install.php 文件中,让我们按照之前的思路来分析一下。

1. 寻找可控的反序列化输入点。

在install.php中,通过搜索 unserialize 关键词,发现两个相关点。

20181029181431-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-5-1

看下代码:

install.php

20181029181442-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-6

232行是漏洞关键输入点。那么Typecho_Cookie::get()是啥?

看下代码:

Cookie.php

20181029181452-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-7

A: “获取指定的COOKIE值”

那么,232 行的意思是:反序列化了用base64解码后的key为__typecho_config 的 cookie 内容。

cookie 可控,还有一个关键点是如何进入这段代码。

一起来看一下

2018102918150-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-8-1

执行到232行漏洞触发点的前提:

  1. 设置finish参数
  2. 设置refer,来源于漏洞站就ok

第一步已经搞定。下面来分析第二步。

2. 需要有一个相关联的,有魔术方法(会被自动调用)的类。

我们重新来看下232行开始的代码。

20181029181515-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-6

序列化后的内容赋值给了$config

234行把$config[‘adapter’] , $config[‘prefix’]作为参数传入了Typecho_Db类。

复习一下之前说过的magic method。

  1. __construst()
  2. __destruct()
  3. __toString()

__construst() 方法在每次创建新对象时会被自动调用

__destruct() 方法在使用 exit() 终止脚本运行时也会被自动调用

_toString() 方法在一个类被当成字符串时应怎样回应。例如 _echo $obj; 应该显示些什么。

查看Typecho_Db类查看下源代码。

Db.php

2018102918160-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-db-php-构造函数

 

114 行,$adapterName 作为参数被传进来以后,在120行进行了字符串拼接操作,字符串拼接操作会触发实例化类的toString()方法, 那我们的目标就可以放在toString()这个magic method 的方向上了。

搜索__toString(),

20181029181611-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-feed-php-toString

当我们找到一个符合条件的类的时候,就要确定这个类的magic method 中执行了什么东西。在Typecho_Feed这个类的__toString()中,没有跟上个文章中举例的一样的方法,这里就要另辟蹊径。

3. 寻找能利用的利用点

20181029181622-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-typecho-feed-screenName

在290行,我们可控的$item[‘auther’]调用了一个screenName 这个属性。

在PHP中,如果该实例化的对象访问了一个‘不可访问’的属性的时候,就会调用__get()方法。

这时候我们需要再次寻找 包含 __get() 的类。

20181029181649-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-search-get

20181029181714-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php__get

这里的__get()调用了get()

继续看get()

20181029181723-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-get

298行到310行都是一些赋值操作。

追踪一下_applyFilter()

20181029181730-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-_applyFilter

终于见到了我们想要的可以执行操作的函数call_user_func,

把第一个参数作为回调函数调用

通过这个函数,可以执行函数。

回溯一下参数传递。从后到前。

[Request.php] call_user_func() 的参数 $filter 可控,来自

20181029181942-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-property-filter
$value 参数可控,来自_applyFilter() 的参数 $value。
_appleyFilter() 参数来自get()方法的$key。

20181029181959-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-property-params

20181029182011-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-request-php-get

_get($key) 直接调用get($key)

看下Feed.php。

[Feed.php] $item[‘author’]->screenName 调用了 _get()方法。

$item[‘auther’]->screenName 的$item 来自 $this->_item

20181029182023-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-feed-php-additem

4. 构建Poc.

通过第三点的分析,来构建Poc。

再顺过来整理一遍。

install.php – > Db.php -> Feed.php -> Request.php

  1. install.php 漏洞触发点,存在unserialize()函数,序列化后的结果传给了Typecho_DB()
  2. Db.php 中 120行

$adapterName = ‘Typecho_Db_Adapter_’ . $adapterName;触发了__toString()方法。

  1. 找到存在__toString()并有可以利用的Feed.php,在其中调用了

$item[‘author’]->screenName,调用__get()方法。

  1. 找到__get()方法的Request.php ,调用了get()->调用了_appleyFilter()->call_user_func()
  2. 结束、

Poc:test.php

20181029182040-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-poc

先访问:

20181029182049-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-poc-show

设置cookie __typecho_config 为test的输出值

2018102918211-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-cookie

设置refer & url

20181029182119-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-url

成功写入shell

20181029182128-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-shell2

20181029182146-PHP反序列化漏洞详细教程及实例(下)-Typecho-反序列化漏洞分析-shell1

结语

PHP反序列化漏洞详细教程及实例(下)的分析到这里,就告一段落了。

如果还有疑问,欢迎来讨论。

同时,非常感谢下面的小伙伴的分析。在编写这篇文章的过程中,起到了参考和启发的作用。

Refer

1
2
3
4
5
> http://p0sec.net/index.php/archives/114/
>
> https://paper.seebug.org/424/
>
> https://paper.tuisec.win/detail/c1ecf917be22318.jsp