ctfshow 反序列化篇
2021-4-6
| 2024-2-3
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
感觉排序不是很友好..因为难度不是相对递增的
 
建议顺序
  1. web254-258、web260、web262-web266、web259、web261、web275-276
  1. 然后 web277-278 是 Python 反序列化,不过比较简单
  1. 最后是 web267-web274 都是框架的反序列化漏洞,分析起来会麻烦些,web267-270 是 Yii 的 CVE 和 绕过,web271-273 是 Laravel 5.7 和 5.8 的反序列化,web274是 thinkphp5.1 的反序列化
 
框架的反序列化有空会(咕咕预订…)额外写文章复现,23333

web254 PHP类简单认识

poc

web255 简单逻辑

nginx/1.16.1 PHP/7.3.11
分析:
即要满足
  • 类成员 isViptrue
  • 传入的 username 和 类成员 username 相等
  • 传入的 password 和 类成员 password 相等
username 和 password 已知,反序列化修改 isVip 即可
poc
notion image

web256 简单逻辑

nginx/1.16.1 PHP/7.3.11
分析:
即要满足
  • 类成员 isVip 为 true
  • 传入的 username 和 类成员 username 相等
  • 传入的 password 和 类成员 password 相等
  • 类的 username 和 password 不等(原来是相等的)
因为通过反序列化修改原有数据即可
poc
notion image

web257 简单POP链

nginx/1.16.1 PHP/7.3.11
分析:
触发 backDoor 即可
poc
notion image

web258 正则

PHP/5.6.40 正则绕过
分析:
绕过正则 /[oc]:\d+:/i , 其实就是 C:数字 或 O:数字 不连续,这里只需让 O:11 不连续即可,比如 O:+11
poc
notion image
图中 %2b+ 的 url编码

web259 SSRF + CRLF + SoapClient

PHP/7.3.11 SSRF CRLF SoapClient
index.php
flag.php (大概如下
分析:
不就 XFF伪造?
notion image
估计给的代码是不完整的,还真实 IP 判断,估计大概是这样的
搜了一波,奇怪的知识增加了,除了XFF,本题还用到 SSRF(SoapClient)+CRLF组合拳,毕竟我们的 index.php 还有用到呢
需要利用 SSRF 访问 flag.php 并构造 XFF 和 POST 数据,SSRF漏洞在哪呢?
SoapClient类 __call 魔术方法
__call() 魔术方法:当调用一个类不存在的方法时候会触发这个魔术方法
当调用 SoapClient 类的 __call() 魔术方法的时候,会发送一个 POST 请求,请求的参数由着 SoapClient 类的一些参数决定。
因此,当我们运行 index.php$vip->getFlag(); 方法时,会因 SoapClient 不存在 getFlag 方法而调用 __call() 魔术方法,进而发送一个 POST 请求
poc
这里注意下,包含特殊字符转义的,比如 \r\n 要用双引号 " 单引号保持原来的语义的。
notion image
warning 没关系
notion image

web260 简单正则

PHP/5.6.40
poc
notion image

(原) web261 SSRF Redis

PHP/7.3.11
index.php
分析:
  • 题目提示:打 Redis,默认端口为 6379
notion image
原来的 web261,不知为啥换成了下面这个。
原本的解题思路大概是在 web259 的基础上,构造 POST包去打 redis

web261 PHP特性

nginx/1.18.0 PHP/7.4.16
分析
__wakeup()
unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。
因这里写着 usernamepassword 必须为非空,否则会退出,所以可以考虑要绕过这里
参考 CVE-2016-7124
  • 影响范围
PHP5 < 5.6.25
PHP7 < 7.0.10
  • 漏洞原理
当反序列化字符串中,表示属性个数的值大于真实属性个数时,会绕过 __wakeup 函数的执行。
但是题目是 PHP 7.4.2 明显不满足要求,
然后guguru了一下比较显眼的 __unserialize 魔术方法,因为没见过
https://www.php.net/manual/en/language.oop5.magic.php#object.unserialize
发现有趣的东西,官方文档是这样介绍的
notion image
就当同时存在 __wakeup__unserialize 魔术方法时,只会调用 __unserialize 魔术方法。
仔细观察析构方法,是个弱比较 $this->code==0x36d
然后 0x36d 的十进制是 877 ,写个小实验
notion image
也就是说弱比较 $code 变量前面是 877 就好了,不管后面加了啥字符串,就可以让 $code == 0x36d 成立了。
构造 POC
会生成 877.php 然后 cat /flag_is_here 即可
notion image
题外
因为 PHP 底层是用 C语言写的,原本想着用 \0 作为字符串截断,这样不会拼接 $passwod 字段,然后发现,如果第一个参数有 \0file_put_contents 会报错。
notion image
然后
__invoke__sleep 在这里的用处不太清楚。。

web262 字符逃逸

PHP/5.6.40 字符逃逸
 
index.php
看注释发现 message.php

第一种做法

poc
notion image

第二种做法

因有一个正则替换,注意是序列化后再替换,且替换每次内容长度增加1,假如输入 t=fuck"
notion image
我们输入的 " 刚刚好可以发前面闭合,也就是说,我们每输入一个 fuck,我们可控的内容就多出 1 个字符。
我们目的构造 $token="admin" 序列化长这样
notion image
s:5:"token";s:5:"admin";
加上闭合
长度为 27
notion image
也就是我们需要输入 27 个 fuck
poc
notion image
notion image

web263 session伪造

PHP/7.3.11 session伪造
 
通过 /www.zip 扫描到源码,这里目录扫描全是 200,建议使用可以看到返回包大小的扫描器,或者有 404 页面识别的扫描器,比如 dirmap
notion image
日常吐槽 fortify,咋啥也扫不出来 (x
seay 发现 file_put_contents 输入可控
notion image
利用前提:
利用点是 session.serialize_handler 与 php.ini 的配置不同引起的反序列化,至于为什么不同,如果相同的也就没必要加上这句设置了(ini_set('session.serialize_handler', 'php');),毕竟是默认配置对吧
目标:
  • file_put_contents 可控点在 inc/inc.phpUser 类,可以通过反序列化触发 __destruct
思路:
  • 首先访问两次首页,抓包可以看到Cookie limit 参数,构造 exp ,使得我们的反序列化数据写入 session 文件(通过 $_SESSION['limit']=base64_decode($_COOKIE['limit']); 写入,这是PHP session 机制,可参考 此链接
  • inc/inc.php 存在 ini_set('session.serialize_handler', 'php');session_start(); ,只要访问即会获取之前写入的 session 数据,然后 check.php 包含 inc/inc.php ,即会触发 User类__destruct方法 ,从而把恶意数据通过 file_put_contents 写入名为 log-$this.username ,内容为 $this.password 的文件。
poc
这里加 '|' 是因为 session.serialize_handler 使用 php引擎 ,session 关联数组的 keyvalue 是通过 '|' 区分的, value 是需要被反序列化的部分。然后默认不是用 php 引擎,所以…. 所以写入是正常字符串,在 inc/inc.php 这读取语义又不一样了。
notion image
随便请求一下 check.php
notion image
image.png
注意是 log-tari.php !
notion image

web264 字符逃逸

PHP/5.6.40 字符逃逸
 
看注释发现 message.php
看注释发现 message.php
一开始没看出和 web262 有啥区别,仔细看了一下发现,反序列化时使用了 session 而不是直接通过 Cookie 接收
做法和 web262中第二种做法一样,虽然不是通过 Cookie 接收,也别忘了了 Cookie 的 msg 字段附加个值,不然不满足
先请求 index.php (这里 poc 不明白怎么构造看一下 web262 第二种做法)
notion image
因为 PHP 的 session 是通过 Cookie 里的 PHPSESSID 获取的(不清除参考 web263 session 伪造),所以要记录下来,然后在 message.php 里带上。
然后请求一下 message.php , 别忘了 Cookie 部分
notion image

web265 变量引用

PHP/5.6.40 变量引用
token 会变,让 password 成为 token 的引用就好了
poc
notion image

web266 类和方法不区分大小写

PHP/7.3.11 PHP特性 类和方法不区分大小写
拦截点:序列化数据不能包括 ctfshow,
PHP特性:函数名和类名不区分大小写,变量名区分,例如
notion image
poc
notion image

web267 Yii 框架 CVE

PHP/7.3.11 框架审计 CVE-2020-15148 Yii登录前
 
弱密码 admin/admin 登录
about 页面有个 <!--?view-source --> 提示
可以通过 index.php?r=site%2Fabout&view-source 查看提示
这是 Yii 的路由规则,传送门 ,咋知道的 Yii?通过 burp 抓包记录看到很多 yii.js php 搜了下 (
notion image
框架反序列化漏洞,网上应该可以搜到,一个不错的复现和挖掘文章,传送门
有空会(咕咕预订…)额外写文章复现 (
poc
notion image
notion image

web268 Yii 框架 CVE 补丁绕过 1

PHP/7.3.11 框架审计 CVE-2020-15148 Yii登录前 补丁绕过
 
思路类似 web267,估计是打过补丁版本
有空会(咕咕预订…)额外写文章复现 (
poc1
notion image
notion image

web269 Yii 框架 CVE 补丁绕过 2

PHP/7.3.11 框架审计 CVE-2020-15148 Yii登录前 补丁绕过
思路类似 web267,估计是打过补丁版本
有空会(咕咕预订…)额外写文章复现 (
poc2
notion image
notion image

web270 Yii 框架 CVE 补丁绕过 3

PHP/7.3.11 框架审计 CVE-2020-15148 Yii登录前 补丁绕过
思路类似 web267,估计是打过补丁版本
有空会(咕咕预订…)额外写文章复现 (
poc3
notion image
notion image

web271 Laravel 5.7 框架 CVE

PHP/7.1.26 框架审计 CVE-2019-9081 Laravel5.7登录前
 
poc
因代码里是通过 POST 的 data 接收,所以这里是用 data POST 过去
notion image

web272 Laravel 5.8 框架 CVE

PHP/7.1.26 框架审计 Laravel5.8登录前
有空会(咕咕预订…)额外写文章复现 (
poc
其实还有挺多链的
https://www.anquanke.com/post/id/189718
notion image

web273 和web273一样

PHP/7.1.32 框架审计 Laravel5.8登录前
emm,说实话除了PHP版本细微差别,还不知道有啥区别,竟然 poc 一毛一样
有空会(咕咕预订…)额外写文章复现 (
notion image

web274 thinkphp5.1

nginx/1.16.1 PHP/7.3.11 框架审计 thinkphp5.1登录前
 
thinkphp 5.1反序列化漏洞
参考文章:https://xz.aliyun.com/t/6619
数据接收方式
notion image
有空会(咕咕预订…)额外写文章复现 (
poc
notion image

web275 命令执行拼接

nginx/1.16.1 PHP/7.3.11
分析:
看似花里胡哨,其实 __destruct 里的 system 可直接拼接,也就是设法让 $this->evilfile 置为 true ,然后拼接命令即可。
notion image
题外:第一眼看去这一读一写,长的这么想被我条件竞争的样子 (

web276 phar反序列化 条件竞争

nginx/1.16.1 PHP/7.3.11 phar反序列化 条件竞争
 
分析:
emm,在上题基础上新增了个判断 $this->admin 然后想着,构造一下序列化不就行了嘛,然后发现没有反序列化函数。。
看了下发现可以通过 file_put_contents 写 phar文件,然后题目中 file_put_contents 第一个参数可控,那么我们可以使用 phar:// 协议,通过 $content 传入 phar 数据,这样在 PHP 通过 phar:// 协议解析数据时,会将 meta-data 部分进行反序列化。
不过题目会删除文件,所以需要在删除文件前执行文件进行以上操作,因此要用到条件竞争,即生成了 phar 文件,在极短时间内文件是存在的,因为执行到 unlink 函数前还有一个 copy 文件操作,磁盘 io 是需要一定时间的。只要我们不断在写入 phar 文件,那么这个文件就可以断断续续访问到~
poc
phar构造如下,会在当前目录生成 evil.phar 文件
条件竞争,py3脚本
notion image
base64解码一下即可
notion image
题外
除了 file_put_contents 外,会把 phar 反序列化的函数还有:
受影响的函数列表
filename
filectime (获取文件的inode更改时间)
file_exists
file_get_contents
file_put_contents
file
filegroup (获取文件的组名)
fopen
fileinode (获取文件inode)
filemtime (获取文件的修改时间)
fileowner
fileperms (获取文件权限)
is_dir
is_executable
is_file
is_link (判断文件名是否为符号链接)
is_readable
is_writable
is_writeable
parse_ini_file (解析配置文件)
copy
unlink
stat (获取文件相关信息)
readfile (输入文件内容)
表格参考自:https://v0w.top/2020/03/12/phar-unsearise/

web277 python 反序列化

Werkzeug/1.0.1 Python/3.7.9 pickle 反序列化
notion image
Python反序列化,之前有过一些研究,晚点把Python反序列化基础链接更新上来~
尝试了很多,发现是无回显的,需要反弹shell
poc
先在服务器上监听
notion image
运行脚本
notion image
回到服务器上 cat 一下即可
notion image

web278 python 反序列化 简单绕过

Werkzeug/1.0.1 Python/3.7.9 pickle 反序列化
和 web277 差不多,只不过过滤了 system,换个函数即可
poc
notion image

一些参考的题解
 
  • CTFSHOW
  • Writeup
  • ctfshow SSRF篇微软威胁建模基础学习
    • GitTalk
    目录