一道shiro反序列化题目引发的思考

💡 原文中文,约7100字,阅读约需17分钟。
📝

内容提要

本文分析银行CTF比赛中的Shiro反序列化题目,涉及CVE-2020-13933权限绕过漏洞和反序列化点。通过构造恶意Cookie触发LogHandler类的toString方法执行命令,详细介绍了黑盒测试、代码审计、Payload构造过程,并补充了Shiro相关知识,最终成功利用漏洞。

🔎

延伸解读

漏洞利用链的关键点

本文的利用链核心在于Shiro的权限绕过漏洞(CVE-2020-13933)与反序列化点的结合。攻击者先通过URL编码绕过权限校验,访问到受保护的/index/*路径,再通过构造恶意Cookie触发反序列化。反序列化链利用BadAttributeValueExpException触发LogHandler的toString方法,进而执行系统命令。理解这条链的关键在于识别反序列化入口和可利用的Gadget。

代码审计中的常见误区

作者在审计过程中最初怀疑SQL注入,但经过测试发现并无数据库操作,排除了该可能。这提醒我们,在代码审计时,应首先确认功能实现是否涉及数据库、命令执行等敏感操作,避免被表面现象误导。同时,对于过滤函数,要思考其绕过方式,但也要结合上下文判断其实际作用。

非预期解法的启示

文章提到一个非预期解法:直接访问/index/admin&&calc即可执行命令。这是因为LogHandler的invoke方法将URL路径直接拼接到命令中,未考虑管道符等特殊字符。这提示开发者,在将外部输入拼接到系统命令时,必须进行严格的过滤和转义,否则即使没有反序列化漏洞,也可能导致命令注入。

Q&A

这道Shiro反序列化CTF题目涉及哪些漏洞?

题目涉及CVE-2020-13933权限绕过漏洞和反序列化漏洞。Shiro版本为1.5.3,存在权限绕过,但无remember反序列化漏洞;反序列化点位于IndexController的index方法中,通过构造恶意Cookie触发LogHandler类的toString方法执行命令。

如何绕过Shiro的权限控制访问受保护页面?

利用CVE-2020-13933权限绕过漏洞,构造特殊URL如`/index/%3b/admin`,其中`%3b`是分号的URL编码,可以绕过`/index/*`的authc过滤器,从而访问受保护的页面。

反序列化点在哪里?如何触发?

反序列化点在IndexController的index方法中,当请求的Cookie中存在名为`hacker`的字段时,会对该字段的值进行Base64解码并反序列化。触发方式是通过构造恶意Cookie,使反序列化时调用LogHandler类的toString方法,从而执行命令。

如何构造最终的Payload?

利用ysoserial中的BadAttributeValueExpException作为封装类,将LogHandler对象作为其val字段的值,通过反射修改LogHandler的readLog字段为要执行的命令(如`calc`),然后序列化并Base64编码,作为Cookie的hacker字段发送。

为什么访问`/index/admin&&calc`会执行命令?

这是因为LogHandler的invoke方法在写入访问日志时,直接将URL路径拼接到命令中执行,没有过滤管道符等特殊字符。当URL路径包含`&&calc`时,命令变成`echo /test >> accessLog.txt && calc`,从而执行了`calc`命令。

在复现该题目时需要注意哪些坑?

需要注意:User类必须实现Serializable接口并定义serialVersionUID;Tools类需要判断操作系统类型,因为tail命令在Windows上不存在;tail命令不要加-f参数,否则会一直读取文件导致不回显;注释掉MyFilter中的@Component可以还原CVE-2020-13933漏洞。

这道题的反序列化利用链是什么?

利用链为:Tools.base64Decode() -> Tools.deserialize() -> ObjectInputStream.readObject() -> BadAttributeValueExpException.readObject() -> LogHandler.toString() -> Tools.exeCmd()。

🏷️

标签

➡️

继续阅读