从shiro-550漏洞品阿里云waf规则引擎
问题背景
shiro-550漏洞利用时,payload在cookie中的rememberMe中,生成过程:原始payload->aes加密->base64编码。
也有人整理出常见的aes加密密钥 top100 来利用此漏洞。
如果要在waf中对这个漏洞利用做防护,我能想到的安全策略是:
- 根据cookie中的rememberMe的值是否过长、是否符合aes加密特征等 来拦截
- 先base64解码,然后aes解密,最后规则匹配原始payload
第二个方法存在两个问题:
aes解密时密钥是啥?会把top100利用时的密钥全部覆盖?
这个方法想起来简单,但是实施起来并不简单。它需要规则引擎支持base64解码和aes解密,并且需要规则中能够很容易描述这个解码顺序。
按照我的理解,waf和poc扫描的规则引擎类似,都支持规则描述文件和代码实现方式两种。如果waf规则引擎只支持规则描述文件的形式,不支持用代码来描述防护规则,那写这么一条规则我觉得还挺费劲的。
下面就是我验证阿里云waf是怎么拦截防护shiro-550漏洞的。
分析过程
测试payload使用下面脚本生成,其中key使用shiro-550默认key
1 | #coding:utf-8 |
测试攻击请求
原始payload是利用ysoerial工具生成: java8 -jar scripts/third_party/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar URLDNS “”
payload在cookie中的rememberMe中,生成过程:原始payload->aes加密→base64编码
发送请求后,阿里云waf拦截
1
2
3
4
5
6GET / HTTP/1.1
Host: xxxx.com
User-Agent: curl/7.70.0
Accept: */*
Cookie: rememberMe=x4xXLguUTO+o2zDz6PKJtR7VQfrG08LE5KTMlw3cViQACMqKZ34wqnB1PIYeWTyiLrx2Dp7Gw3cFHJzwBUdqJXnSWmG7/SC7EH6c6OgPNTCgiplznhs61pwsoFU6X9NTHZi+/xr2Jo3rh/TW1gPqK6y4UGW9nqT6UDFybJLqO4bb7DhNsMkVNB4sZ7SgE1ee4zhY591SECQEDDzkM0EHbc2drf92hgueAEK450IqjUI03s1hq838mziWdE7OtQPQ6CjldBKPrSZ0BNhOGP+epg5SrLpXAjj/iwLVCRFE0lIUFtNDc9m8h5JKg/SLwa/yNTWZ+5DAooRs4+/yy1Z6xIe7d+OunTmTMnNXACNthKd96Y8RA4q9TnnS4aV91HbMoo/Voy/v03expiCm2OBpv72oTUCtV9eoHBByXyUsBDUI9BtN1IfAwjkFYj6fa4w5nAuR4sgbBrVy1KYnbgVN1H3DZ5Lmt8tvz1uhxo+SIQLtJfqhY1NhW10bWNm3F+sSyG7xblEDVgBLWer7ayRwZlv7/LejK1NPsjVPd8MvBTHfBMShNaQmS7LRTQssGaxp
Connection: close测试正常请求
原始payload是 “111111”*400 ,不包含攻击特征。
payload在cookie中的rememberMe中,生成过程:原始payload->aes加密->base64编码
结论:正常请求阿里云waf未拦截
对比拦截和不拦截的情况,可以看出来阿里云waf防护防护规则逻辑:先对cookie中的rememberMe做base64解码,然后用默认key(kPH+bIxk5D2deZiIxcaaaA==”) 来做aes解密,最后规则匹配解密后的内容。
总结
还有一些测试在分析过程中没有写,这里直接写出结论:
- 阿里云waf仅尝试使用一个默认key来解密。(应该是性能考虑)
- 不能根据rememberMe的值过长来拦截,因为正常业务这个值也可能有500+个字节长度。
虽然不能完全防御shiro-100key扫描,但是阿里云waf这条规则还是挺细致的。从支持rsa解密这一点上感觉背后的规则引擎功能很丰富。