作者:leveryd
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送!
投稿郵箱:paper@seebug.org
背景
看過從shiro-550漏洞品阿里云waf規則引擎文章的,應該知道阿里云是怎么防護shiro反序列化漏洞的利用,那么我們有辦法繞過防護么?
先把上面的問題放一放,看看幾個base64解碼相關的case吧。
base64解碼時,不同語言的接口實現有略微區別,目前知道有兩種"邊界情況":
- 字符串中包含
. %等符號時,是選擇忽略這些符號,還是報錯 - 字符串中包含
=符號,解析到=時,是認為解析完成了,還是忽略"等號"繼續解析
比如: Python base64解碼時,會忽略"="號后面的字符串
import binascii
binascii.a2b_base64(b'aGVsbG8=') # b'hello' (valid)
binascii.a2b_base64(b'aGVsbG8==') # b'hello' (ignoring data)
binascii.a2b_base64(b'aGVsbG8=python') # b'hello' (ignoring data)
PHP base64解碼時,支持編碼中有. % 等符號,會忽略這些符號
P.HNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
P%HNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
我也是從別人給Python提交的這個bug 學到的一些姿勢。
所以,我想研究以下問題:
- 哪些語言受影響?
- 會有什么影響?
- 什么時候會產生繞過?
- 哪些waf可以繞過?
哪些語言受影響?
- 測試思路
有兩個兩個測試目標:
1. 看看"不同語言 對 == 后面是否忽略"
2. 看看"不同語言 對 . 號是否忽略"
因此,對hellobase64編碼并做點變形,得到下面三個測試paylaod
aGVsbG8=test
aGVs.bG8
aGVs.bG8=
另外額外測一下shiro中base64的解碼
- 測試的語言、版本、解碼接口如下
php(7.3.11): base64_decode
python(3.7): binascii.a2b_base64、base64.b64decode
openresty(1.19): ngx.base64.decode_base64url
java(jshell 14.0.1): Base64.getDecoder().decode
shiro(1.5.1): org.apache.shiro.codec.Base64.decode
- 測試結果
| payload | php | python | openresty | java | shiro |
|---|---|---|---|---|---|
aGVsbG8=test |
hello-z? | hello | hello | 拋異常 | hello-z? |
aGVs.bG8 |
hello | 解碼失敗 | 解碼失敗 | 拋異常 | hel |
aGVs.bG8= |
hello | hello | 解碼失敗 | 拋異常 | hello |
aGVsbG8= |
hello | hello | hello | hello | hello |
-
結論
-
php、python、openresty、shiro 都不同程度地受變形payload影響
會有什么影響?
- 什么時候適用這種繞過方式?
以下情況下會存在繞過:
1. waf不能解碼,后端可以解碼
2. waf解碼后,只檢測解碼后的數據,不檢測原始payload
第一種情況的例子:比如發送 PHN.jcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==,如果waf不能解碼,就會放行。
第二種情況的例子:發送a=aGVsbG8=' union select 1 and ',有可能waf解碼成 "hello",認為沒有危害,也會放行
第一種情況很常見,第二種情況目前還沒有遇到案例。
- 哪些waf可以繞過?
只測試了我心中的"最強王者"(阿里云waf和長亭云waf),都存在第一種情況的繞過。
規范
- 規范中是怎么定義"base64解碼時對非字母如何處理"?
rfc規范 中說的是,"沒有特殊情況下,遇到非字母就應該報錯并拒絕繼續解碼"。
看官方文檔 shiro 是根據另外一個郵件相關的規范來做的base64編解碼。
最后
所以,現在你清楚怎么繞過shiro漏洞的防護了么?
另外,如果讀者有第二種情況繞過的案例,歡迎公眾號后臺私信我。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1600/
暫無評論