Java代码审计之Shiro反序列化调用链完整分析
0x01 靶场搭建
https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4
编译好的war文件放到tomcat目录下,访问即可,自动解压出samples-web-1.2.4
访问路径/samples-web-1.2.4
即可
0x02 反序列化调用链完整分析
当输入正确的账号密码时,服务会返回一个cookies,而这个cookie rememberMe记录登录用户的身份认证信息。
输入正确的账号密码
POST /samples-web-1.2.4/login.jsp HTTP/1.1
Host: 192.168.144.27:8080
Content-Length: 56
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.144.27:8080
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.144.27:8080/samples-web-1.2.4/login.jsp
Accept-Language: zh-CN,zh;q=0.9
Connection: close
username=root&password=secret&rememberMe=on&submit=Login
进入到断点
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#onSuccessfulLogin
进入this.rememberIdentity(subject, token, info);
依次进入到
rememberIdentity:321, AbstractRememberMeManager (org.apache.shiro.mgt)
rememberIdentity:346, AbstractRememberMeManager (org.apache.shiro.mgt)
convertPrincipalsToBytes:360, AbstractRememberMeManager (org.apache.shiro.mgt)
接下去进入到this.serialize(principals);
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#serialize
进入到this.getSerializer().serialize(principals)
shiro-core-1.2.4.jar!/org/apache/shiro/io/DefaultSerializer.class
DefaultSerializer#serialize
当认证成功后,将用户名序列化
回到
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#convertPrincipalsToBytes
进入到this.encrypt(bytes)对序列化后的字节数组进行加密
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#encrypt
进入到CipherService cipherService = this.getCipherService();
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
获取到默认密钥kPH+bIxk5D2deZiIxcaaaA==
加密方式AES,CBC模式,填充方式为PKCS5
进入到cipherService.encrypt(serialized, this.getEncryptionCipherKey());
shiro-core-1.2.4.jar!/org/apache/shiro/crypto/JcaCipherService.class
JcaCipherService#encrypt
进入到this.encrypt(plaintext, key, ivBytes, generate)
private ByteSource encrypt(byte[] plaintext, byte[] key, byte[] iv, boolean prependIv)
加密算法,得到密文
回到
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#rememberIdentity
进入到this.rememberSerializedIdentity(subject, bytes)
shiro-web-1.2.4.jar!/org/apache/shiro/web/mgt/CookieRememberMeManager.class
CookieRememberMeManager#rememberSerializedIdentity
将序列化后的密文base64编码返回
0x03 解密调用链分析
用上一步得到的cookies去请求
GET /samples-web-1.2.4/home.jsp HTTP/1.1
Host: 192.168.144.27:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Language: zh-CN,zh;q=0.9
Cookie: rememberMe=TgLpqbMkGZVN63lHTezWn7Yku9vT6liPp5pnCcyEZWm4ztNjmq8NahxpjTcKj5SBQUaeh3wQGkamuNFWN9BemgHSxmeqpHPhymA/HgUyobmd/i4dduvSETQ50GReH5u+NdjqP27Yv1aJXDEoDPaM0gUeE/NkLQ2M+zKSCZpEZztJU6NX/7F9cMaYHVOahfAffUCys6iT29IvVS9aXSH6uaBMe72FUlk/wyw4/dx0XsS6bR+VGAsmD2FkIBcAB7qU205Oi9dQbE0VxI6c5EWEKsRpThI71tZsWt532NjGmovRsnly7hQaSCO7C89Aa0Le0mzBV6JPYsyZ6mFJkWY+nMA/Iqfexj+ft3fVT1LAcuDERqQ7ZtFyicpXEFyg+VwYdQLvPAYi5tlsqf82BcehW+SFlBZNX7ie97FT3l7CkFqagp/TrtPwvFdgJfbwGJAHbHCT+tX5Z36LpJYMuwBM6xr0UtB3qP67EqAiJPWU1+/IUsn6kDO8yvcU9YVNwOZl
Connection: close
shiro-web-1.2.4.jar!/org/apache/shiro/web/mgt/CookieRememberMeManager.class
CookieRememberMeManager#getRememberedSerializedIdentity
读取cookies里的rememberMe的值
读取出来的base64的值进行解码
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#getRememberedPrincipals
进入到this.convertBytesToPrincipals(bytes, subjectContext);
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#convertBytesToPrincipals
进入到bytes = this.decrypt(bytes);解密
回到
shiro-core-1.2.4.jar!/org/apache/shiro/mgt/AbstractRememberMeManager.class
AbstractRememberMeManager#convertBytesToPrincipals
进入到this.deserialize(bytes);反序列化
shiro-core-1.2.4.jar!/org/apache/shiro/io/DefaultSerializer.class
DefaultSerializer#deserialize
readObject()反序列化
0x04 参考链接
https://www.cnblogs.com/nice0e3/p/14183173.html