所需环境:
1、maven
2、jdk1.6 jdk1.8(默认java环境是1.8,1.6是用于配置下面的toolchains)
3、eclipse
下载漏洞示例代码 https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4
解压并使用eclipse导入samples下的web工程(maven工程)。
要配置一下maven,在maven/conf/toolchains.xml中的toolchains 中添加以下代码
<toolchain>
<type>jdk</type>
<provides>
<version>1.6</version>
<vendor>sun</vendor>
</provides>
<configuration>
<jdkHome>C:/Program Files/Java/jdk1.6.0_45</jdkHome>
</configuration>
</toolchain>
然后在pom.xml文件所在目录下执行mvn install命令就可以正常打包编译工程了。
看看漏洞描述
https://issues.apache.org/jira/browse/SHIRO-550
意思就是说shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值-->Base64解码-->AES解密-->反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
三、漏洞分析
1、先看一下org.apache.shiro.web.mgt.CookieRememberMeManager类的结构
发现有getRememberedSerializedIdentity这个方法,从字面意思上来看跟rememberMe和序列化都有关系,那么果断在这个函数上下个断点吧。
2、在eclipse中开启调试模式,在org.apache.shiro.web.mgt.CookieRememberMeManager中的getRememberedSerializedIdentity下断点,发送payload。
运气不错,成功断在了getRememberedSerializedIdentity上。
单步向下跟踪在205行获取到了cookie中的值
函数返回了rememberMe 的base64解码数据。
3、继续单步执行,发现调到了getRememberedPrincipals函数中,接下来调用了convertBytesToPrincipals。
单步步入
看到了deserialize(窃喜)。
4、单步步入decrypt
489行单步步入,跳到了AbstractRememberMeManager中的getDecryptionCipherKey
分析代码发现decryptionCipherKey其实就是DEFAULT_CIPHER_KEY_BYTES,而DEFAULT_CIPHER_KEY_BYTES是硬编码在代码中的。
继续往下走,就到了org.apache.shiro.crypto.JcaCipherService.decrypt(byte[], byte[])中,跟踪到370行
发现AES的初始化向量iv就是rememberMe的base64解码后的前16个字节。
继续跟踪到org.apache.shiro.crypto.JcaCipherService.initNewCipher(int, byte[], byte[], boolean),然后进入org.apache.shiro.crypto.JcaCipherService.newCipherInstance(boolean),
408行 我们看到了AES的填充模式为CBC
这样,对于AES加密算法,我们既知道了密钥又知道了初始化向量和填充方式,那么整个数据包都可以随意构造了。
5、一直跟踪到org.apache.shiro.mgt.AbstractRememberMeManager.decrypt(byte[])函数,返回序列化数据。我们又回到了org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(byte[], SubjectContext)中。
跟进deserialize,成功感觉就在眼前。
跟踪到org.apache.shiro.io.DefaultSerializer.deserialize(byte[]),77行我们看到了熟悉的readObject函数,binggo,成功弹出计算器。
分析了这么多明白的人应该知道怎么构造payload了,前16字节的密钥,后面加入序列化参数 然后AES加密再base64编码,发送cookie即可。