滲透測試網站安全漏洞檢測大體方法
近期對平臺安全滲透測試中遇到有JAVA+mysql架構的網站,針對此架構我們Sine安全滲透工程師整理了下具體的漏洞檢測方法和防護修復方法,很多像執行框架漏洞獲取到系統許可權,以及跨許可權寫入木馬後門等等操作,希望大家在滲透測試的道路中發現更多的知識和經驗。
4.2.1. 格式化字串
在Python中,有兩種格式化字串的方式,在Python2的較低版本中,格式化字串的方式為 "this is a %s" % "test" ,之後增加了format的方式, 語法為 "this is a {}".format('test') 或者 "this is a {test}".format(test='test')
當格式化字串由使用者輸入時,則可能會造成一些問題,下面是一個最簡單的例子
>>> 'class of {0} is {0.__class__}'.format(42)
"class of 42 is <class 'int'>"
從上面這個簡單的例子不難知道,當我們可以控制要format的字串時,則可以使用 __init__ / __globals__ 等屬性讀取一些比較敏感的值,甚至任意執行程式碼。
4.2.2. 反序列化
4.2.2.1. pickle
>>> class A(object):
... a = 1
... b = 2
... def __reduce__(self):
... return (subprocess.Popen, (('cmd.exe',),))
>>> cPickle.dumps(A())
"csubprocess\nPopen\np1\n((S'cmd.exe'\np2\ntp3\ntp4\nRp5\n."
4.2.2.2. 其他
- PyYAML
- marshal
- shelve
4.2.3. 沙箱
4.2.3.1. 常用函式
- eval / exec / compile
- dir / type
- globals / locals / vars
- getattr / setattr
4.2.3.2. 繞過
- 最簡單的思路是在已有的模組中import,如果那個模組中已經 import 可以利用的模組就可以使用了
- 在父類中尋找可用的模組,最常見payload是 ().__class__.__bases__[0].__subclasses__() 或者用魔術方法獲取全域性作用域 __init__.__func__.__globals__
- 有些網站沒有過濾 pickle 模組,可以使用 pickle 實現任意程式碼執行,生成 payload 可以使用
- 有的沙箱把相關的模組程式碼都被刪除了,則可以使用libc中的函式,Python 中呼叫一般可以使用 ctypes 或者 cffi。
- "A""B" == "AB"
4.2.3.3. 防禦
Python官方給出了一些防禦的建議
- 使用Jython並嘗試使用Java平臺來鎖定程式的許可權
- 使用fakeroot來避免
- 使用一些rootjail的技術
4.2.4. 框架
4.2.4.1. Django
4.2.4.1.1. 歷史漏洞
- CVE-2016-7401 CSRF Bypass
- CVE-2017-7233/7234 Open redirect vulnerability
- CVE-2017-12794 debug page XSS
4.2.4.1.2. 配置相關
- Nginx 在為 Django 做反向代理時,靜態檔案目錄配置錯誤會導致原始碼洩露。訪問 /static.. 會 301 重定向到 /static../
4.2.4.2. Flask
Flask預設使用客戶端session,使得session可以被偽造
4.2.5. 危險函式 / 模組列表
4.2.5.1. 命令執行
- os.popen
- os.system
- os.spawn
- os.fork
- os.exec
- popen2
- commands
- subprocess
- exec
- execfile
- eval
- timeit.sys
- timeit.timeit
- platform.os
- platform.sys
- platform.
- popen
- pty.spawn
- pty.os
- bdb.os
- cgi.sys
- …
4.2.5.2. 危險第三方庫
- Template
- subprocess32
4.2.5.3. 反序列化
- marshal
- PyYAML
- pickle
- cPickle
- shelve
- PIL
Java
4.3.1. 基本概念
JVM是Java平臺的核心,以機器程式碼來實現,為程式執行提供了所需的所有基本功能,例如位元組碼解析器、JIT編譯器、垃圾收集器等。由於它是機器程式碼實現的,其同樣受到二進位制檔案受到的攻擊。
JCL是JVM自帶的一個標準庫,含有數百個系統類。預設情況下,所有系統類都是可信任的,且擁有所有的特權。
4.3.1.2. JNDI
JNDI(Java Naming and Directory Interface,JAVA命名和目錄介面)是為JAVA應用程式提供命名和目錄訪問服務的API(Application Programing Interface,應用程式程式設計介面)。
4.3.1.3. OGNL
OGNL(Object-Graph Navigation Language,物件導航語言)是一種功能強大的表示式語言,透過簡單一致的表示式語法,提供了存取物件的任意屬性、呼叫物件的方法、遍歷整個物件的結構圖、實現欄位型別轉化等功能。
Struts2中使用了OGNL,提供了一個ValueStack類。ValueStack分為root和context兩部分。root中是當前的action物件,context中是ActionContext裡面所有的內容。
4.3.1.4. RMI
RMI(Remote Method Invocation,遠端方法呼叫)能夠讓在客戶端Java虛擬機器上的物件像呼叫本地物件一樣呼叫服務端java虛擬機器中的物件上的方法。
RMI遠端呼叫步驟:
- 客戶呼叫客戶端輔助物件stub上的方法
- 客戶端輔助物件stub打包呼叫資訊(變數,方法名),透過網路傳送給服務端輔助物件skeleton
- 服務端輔助物件skeleton將客戶端輔助物件傳送來的資訊解包,找出真正被呼叫的方法以及該方法所在物件
- 呼叫真正服務物件上的真正方法,並將結果返回給服務端輔助物件skeleton
- 服務端輔助物件將結果打包,傳送給客戶端輔助物件stub
- 客戶端輔助物件將返回值解包,返回給呼叫者
- 客戶獲得返回值
4.3.2. 框架
4.3.2.1. Servlet
4.3.2.1.1. 簡介
Servlet(Server Applet)是Java Servlet的簡稱,稱為小服務程式或服務聯結器,是用Java編寫的伺服器端程式,主要功能在於互動式地瀏覽和修改資料,生成動態Web內容。
狹義的Servlet是指Java語言實現的一個介面,廣義的Servlet是指任何實現了這個Servlet介面的類,一般情況下,人們將Servlet理解為後者。Servlet執行於支援Java的應用伺服器中。從原理上講,Servlet可以響應任何型別的請求,但絕大多數情況下Servlet只用來擴充套件基於HTTP協議的Web伺服器。
4.3.2.1.2. 生命週期為
- 客戶端請求該 Servlet
- 載入 Servlet 類到記憶體
- 例項化並呼叫init()方法初始化該
- Servlet service()(根據請求方法不同呼叫 doGet() / doPost() / … / destroy()
4.3.2.1.3. 介面
init()
在 Servlet 的生命期中,僅執行一次 init() 方法,在伺服器裝入 Servlet 時執行。
service()
service() 方法是 Servlet 的核心。每當一個客戶請求一個HttpServlet物件,該物件的 service() 方法就要被呼叫,而且傳遞給這個方法一個”請求”(ServletRequest)物件和一個”響應”(ServletResponse)物件作為引數。
4.3.2.2. Struts 2
4.3.2.2.1. 簡介
Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與檢視的資料互動。
4.3.2.2.2. 請求流程
- 客戶端傳送請求的tomcat伺服器
- 請求經過一系列過濾器
- FilterDispatcher呼叫ActionMapper來決定這個請求是否要呼叫某個Action
- ActionMppaer決定呼叫某個ActionFilterDispatcher把請求給ActionProxy
- ActionProxy透過Configuration Manager檢視structs.xml,找到對應的Action類
- ActionProxy建立一個ActionInvocation物件
- ActionInvocation物件回撥Action的execute方法
- Action執行完畢後,ActionInvocation根據返回的字串,找到相應的result,透過HttpServletResponse返回給伺服器
4.3.2.2.3. 相關CVE
- CVE-2016-3081 (S2-032)
- CVE-2016-3687 (S2-033)
- CVE-2016-4438 (S2-037)
- CVE-2017-5638
- CVE-2017-7672
- CVE-2017-9787
- CVE-2017-9793
- CVE-2017-9804
- CVE-2017-9805
- CVE-2017-12611
- CVE-2017-15707
- CVE-2018-1327
- CVE-2018-11776
4.3.2.3. Spring MVC
4.3.2.3.1. 請求流程
- 使用者傳送請求給伺服器
- 伺服器收到請求,使用DispatchServlet處理
- Dispatch使用HandleMapping檢查url是否有對應的Controller,如果有,執行
- 如果Controller返回字串,ViewResolver將字串轉換成相應的檢視物件
- DispatchServlet將檢視物件中的資料,輸出給伺服器 伺服器將
- 資料輸出給客戶端
4.3.3. 容器
常見的Java伺服器有Tomcat、Weblogic、JBoss、GlassFish、Jetty、Resin、IBM Websphere等,這裡對部分框架做一個簡單的說明。
4.3.3.1. Tomcat
Tomcat是一個輕量級應用伺服器,在中小型系統和併發訪問使用者不是很多的場合下被普遍使用,用於開發和除錯JSP程式。
在收到請求後,Tomcat的處理流程如下:
- 客戶端訪問Web伺服器,傳送HTTP請求
- Web伺服器接收到請求後,傳遞給Servlet容器
- Servlet容器載入Servlet,產生Servlet例項後,向其傳遞表示請求和響應的物件
- Servlet例項使用請求物件得到客戶端的請求資訊,然後進行相應的處理
- Servlet例項將處理結果透過響應物件傳送回客戶端,容器負責確保響應正確送出,同時將控制返回給Web伺服器
Tomcat伺服器是由一系列可配置的元件構成的,其中核心元件是Catalina Servlet容器,它是所有其他Tomcat元件的頂層容器。
4.3.3.1.1. 相關CVE
- CVE-2019-0232
- CVE-2017-12615
- CVE-2013-2067
- CVE-2012-4534
- CVE-2012-4431
- CVE-2012-3546
- CVE-2012-3544
- CVE-2012-2733
- CVE-2011-3375
- CVE-2011-3190
- CVE-2008-2938
4.3.3.2. Weblogic
4.3.3.2.1. 簡介
WebLogic是美國Oracle公司出品的一個Application Server,是一個基於Java EE架構的中介軟體,WebLogic是用於開發、整合、部署和管理大型分散式Web應用、網路應用和資料庫應用的Java應用伺服器。其將Java的動態功能和Java Enterprise標準的安全性引入大型網路應用的開發、整合、部署和管理之中。
WebLogic對業內多種標準的全面支援,包括EJB、JSP、Servlet、JMS、JDBC等。
4.3.3.2.2. 相關CVE
- CVE-2019-2658
- CVE-2019-2650
- CVE-2019-2649
- CVE-2019-2648
- CVE-2019-2647
- CVE-2019-2646
- CVE-2019-2645
- CVE-2019-2618
- CVE-2019-2615
- CVE-2019-2568
- CVE-2018-3252
- CVE-2018-3248
- CVE-2018-3245
- CVE-2018-3201
- CVE-2018-3197
- CVE-2018-3191
- CVE-2018-1258
- CVE-2017-10271
- CVE-2017-3248
- CVE-2016-3510
- CVE-2015-4852
4.3.3.3. JBoss
4.3.3.3.1. 簡介
JBoss是一個基於J2EE的管理EJB的容器和伺服器,但JBoss核心服務不包括支援servlet/JSP的WEB容器,一般與Tomcat或Jetty繫結使用。
4.3.3.3.2. 相關CVE
- CVE-2017-12149
4.3.4. 沙箱
4.3.4.1. 簡介
Java實現了一套沙箱環境,使遠端的非可信程式碼只能在受限的環境下執行。
4.3.4.2. 相關CVE
- CVE-2012-0507
- CVE-2012-4681
- CVE-2017-3272
- CVE-2017-3289
4.3.5. 反序列化
4.3.5.1. 簡介
序列化就是把物件轉換成位元組流,便於儲存在記憶體、檔案、資料庫中;反序列化即逆過程,由位元組流還原成物件。Java中的 ObjectOutputStream 類的 writeObject() 方法可以實現序列化,類 ObjectInputStream類的readObject() 方法用於反序列化。
如果要實現類的反序列化,則是對其實現 Serializable 介面。
4.3.5.2. 序列資料結構
- 0xaced 魔術頭
4.3.5.3. 序列化流程
- ObjectOutputStream例項初始化時,將魔術頭和版本號寫入bout (BlockDataOutputStream型別) 中
- 呼叫ObjectOutputStream.writeObject()開始寫物件資料
- ○ObjectStreamClass.lookup()封裝待序列化的類描述 (返回ObjectStreamClass型別) ,獲取包括類名、自定義serialVersionUID、可序列化欄位 (返回ObjectStreamField型別) 和構造方法,以及writeObject、readObject方法等
- ○writeOrdinaryObject()寫入物件資料
- ■寫入物件型別標識
- ■writeClassDesc()進入分支writeNonProxyDesc()寫入類描述資料
- 寫入類描述符標識
- 寫入類名
- 寫入SUID (當SUID為空時,會進行計算並賦值)
- 計算並寫入序列化屬性標誌位
- 寫入欄位資訊資料
- 寫入Block Data結束標識
- 寫入父類描述資料
- ■writeSerialData()寫入物件的序列化資料
- 若類自定義了writeObject(),則呼叫該方法寫物件,否則呼叫defaultWriteFields()寫入物件的欄位資料 (若是非原始型別,則遞迴處理子物件)
4.3.5.4. 反序列化流程
- ObjectInputStream例項初始化時,讀取魔術頭和版本號進行校驗
- 呼叫ObjectInputStream.readObject()開始讀物件資料
- ○讀取物件型別標識
- ○readOrdinaryObject()讀取資料物件
- ■readClassDesc()讀取類描述資料
- 讀取類描述符標識,進入分支readNonProxyDesc()
- 讀取類名
- 讀取SUID
- 讀取並分解序列化屬性標誌位
- 讀取欄位資訊資料
- resolveClass()根據類名獲取待反序列化的類的Class物件,如果獲取失敗,則丟擲ClassNotFoundException
- skipCustomData()迴圈讀取位元組直到Block Data結束標識為止 讀取父類描述資料
- initNonProxy()中判斷物件與本地物件的SUID和類名 (不含包名) 是否相同,若不同,則丟擲InvalidClassException
- ObjectStreamClass.newInstance()獲取並呼叫離物件最近的非■Serializable的父類的無參構造方法 (若不存在,則返回null) 建立物件例項
- ■readSerialData()讀取物件的序列化資料
- 若類自定義了readObject(),則呼叫該方法讀物件,否則呼叫defaultReadFields()讀取並填充物件的欄位資料
4.3.5.5. 相關函式
- ObjectInputStream.readObject
- ObjectInputStream.readUnshared
- XMLDecoder.readObject
- Yaml.load
- XStream.fromXML
- ObjectMapper.readValue
- JSON.parseObject
4.3.5.6. 主流JSON庫
4.3.5.6.1. GSON
Gson預設只能反序列化基本型別,如果是複雜型別,需要程式設計師實現反序列化機制,相對比較安全。
4.3.5.6.2. Jackson
除非指明@jsonAutoDetect,Jackson不會反序列化非public屬性。在防禦時,可以不使用enableDefaultTyping方法。
相關CVE有
- CVE-2017-7525
- CVE-2017-15095
4.3.5.6.3. Fastjson
相關CVE有
- CVE-2017-18349
4.3.5.7. 存在危險的基礎庫
- commons-fileupload 1.3.1
- commons-io 2.4
- commons-collections 3.1
- commons-logging 1.2
- commons-beanutils 1.9.2
- org.slf4j:slf4j-api 1.7.21
- com.mchange:mchange-commons-java 0.2.11
- org.apache.commons:commons-collections 4.0
- com.mchange:c3p0 0.9.5.2
- org.beanshell:bsh 2.0b5
- org.codehaus.groovy:groovy 2.3.9
- org.springframework:spring-aop 4.1.4.RELEASE
4.3.5.8. 網站漏洞修復和防護
4.3.5.8.1. Hook resolveClass
在使用 readObject() 反序列化時會呼叫 resolveClass 方法讀取反序列化的類名,可以透過hook該方法來校驗反序列化的類,一個Demo如下
以上的Demo就只允許序列化 SerialObject ,透過這種方式,就可以設定允許序列化的白名單
4.3.5.8.2. ValidatingObjectInputStream
Apache Commons IO Serialization包中的 ValidatingObjectInputStream 類提供了 accept 方法,可以透過該方法來實現反序列化類白/黑名單控制,一個demo如下
4.3.5.8.3. ObjectInputFilter
Java 9提供了支援序列化資料過濾的新特性,可以繼承 java.io.ObjectInputFilter 類重寫 checkInput方法來實現自定義的過濾器,並使用 ObjectInputStream 物件的 setObjectInputFilter 設定過濾器來實現反序列化類白/黑名單控制,對JAVA漏洞滲透測試有想進一步瞭解的可以諮詢專業的網站安全公司,國內推薦Sinesafe,綠盟,啟明星辰等等專業的安全維護公司。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31542418/viewspace-2661223/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 網站漏洞檢測 滲透測試檢測手法網站
- 網站滲透測試安全檢測漏洞網站
- 網站滲透測試安全檢測方案網站
- 滲透測試對檔案包含漏洞網站檢測網站
- beescms網站滲透測試網站
- 滲透測試公司 對PHP網站安全後門檢測PHP網站
- 網站安全滲透測試檢測認證登入分析網站
- 網站查詢漏洞滲透測試大體流程介紹網站
- 網站安全測試之APP滲透測試漏洞網站APP
- 滲透測試公司談網站安全評估方法網站
- 什麼是滲透測試?網站有必要進行滲透測試嗎?網站
- 網站漏洞滲透測試覆盤檢查結果分析網站
- 如何進行滲透測試XSS跨站攻擊檢測
- 如何學習網站漏洞滲透測試學習網站
- 滲透測試 網站安全測試行業問題分析網站行業
- 軟體滲透測試基礎知識分享,可做滲透測試的軟體檢測公司有哪些?
- 網站安全公司 滲透測試運營之路網站
- 網站滲透測試公司的成長之路網站
- 網站安全滲透測試公司心得總結網站
- 網站安全評估滲透測試手法分析網站
- 網站安全維護對公司網站滲透測試剖析網站
- 網路安全滲透測試
- 滲透測試什麼?滲透測試具體操作流程是什麼
- 網路安全滲透測試的型別!滲透測試入門教程型別
- 什麼是網站系統安全的滲透檢測?網站
- 滲透測試網站安全基礎點講解網站
- 多個角度分析滲透測試網站安全效能網站
- 網站滲透測試漏洞分析程式碼架構網站架構
- 網站滲透測試學習有苦也有甜網站
- 滲透測試會用到哪些工具?滲透測試教程
- 滲透測試對網站漏洞修復執行命令重點檢查網站
- metasploit滲透測試筆記(內網滲透篇)筆記內網
- 邏輯注入漏洞滲透測試檢測辦法
- 內網滲透測試基礎內網
- 軟體滲透測試方法有哪些?獲得CMA、CNAS認證的軟體檢測公司安利
- 網站滲透測試從動感感知系統建立網站
- 企業網站如何做滲透測試服務網站
- 網站滲透測試服務之人工安全防護網站