做者: 我是小三html
博客: http://www.cnblogs.com/2014asm/java
因爲時間和水平有限,本文會存在諸多不足,但願獲得您的及時反饋與指正,多謝!python
1.一個Web應用開發到上線的過程大體需要通過以下步驟:需求分析、架構設計、系統設計、功能設計、編碼實現、測試評估、上線部署、業務運營等關鍵步驟,其中功能設計、編碼測試、發佈部署、系統運營這幾個環節中都會存在安全風險,可是針對各環節出現的安全風險目前尚未一個比較全面的防護產品。目前主流的Web應用安全防禦產品方案較多的是 WAF(Web Application Firewall)和RASP(Runtime Application Self-Protection),WAF是門衛模型,一般部署在Web應用系統的外部邊界,全部正常或惡意流量都須要經過特徵規則和模式識別,經過特定的規則和模式識別出惡意請求,而且把它們拒之門外,拒絕向高風險的Web請求提供服務。web
WAF雖然能夠有效個過濾出絕大多數惡意請求,可是不知道應用運行時的上下文,必然會形成必定程度的誤報。而且WAF嚴重依賴於特徵庫,各類花式繞過,致使特徵編寫很難以不變應萬變。sql
舉個栗子:數據庫
WAF就像門衛保安,每當有人走進時,他只會攔下來問:「你是何人?」而且把這我的的基本樣貌和手裏的冊子(特徵庫)覈對。若是不是黑名單裏的壞人,就直接放行。安全
雖然特徵庫在不停升級,可是從壞人的角度來看,這樣的門衛並不是無懈可擊。若是我是小偷,我能夠裝扮成維修工人或者保潔人員。對於水平通常的WAF來講,極可能「穿上馬甲你就不認識我了」。而智能程度高一些的 WAF,能夠利用技術識別出一些「變裝」伎倆,但這時對方一樣能夠用「整容」甚至「換人」的方法,加大成本再次騙過門衛的眼睛。服務器
若是想精準地阻止壞人,WAF必須以很是高的頻率升級特徵庫,可是永遠追在敵人後面跑且高居不下的誤報率。網絡
2.RASP的不一樣就在於運行在應用之中,就像貼身保鏢同樣與應用融爲一體,能夠獲取到應用運行時的上下文行爲,根據運行時上下文或者敏感行爲操做,對攻擊進行精準的識別或攔截。於此同時,因爲RASP運行在應用之中,只要檢測點選取合理,獲取到的payload已是解碼過的真實payload,能夠減小因爲WAF規則的不完善致使的漏報。架構
仍是舉個栗子:
RASP就像貼身保鏢,當裝扮成維修工人或者保潔人員的小偷進入辦公室以後,卻猛地用錘子砸向保險櫃上面的鎖或者不斷拆電腦裏的硬盤,那麼毋庸多言,保鏢就能夠將其一左勾拳KO即是。
因此門衛沒有攔下假裝者,就是由於他不掌握這我的接下來的行爲信息。而貼身保鏢,倒是有充足信息作出判斷的。
3.WAF存在的問題:」有廣度沒深度」。
通常狀況下黑客攻擊流程主要包含兩個步驟:掃描、實際攻擊。
黑客藉助自動化工具進行的掃描行爲多是實際進攻行爲的萬倍或億倍之多。這是一種典型的「廣種薄收」的策略,絕大多數掃描僅僅停留在掃描。若是你的系統沒有攻擊價值,或沒有黑客掌握的漏洞信息,黑客根本就不會對你採起下一步攻擊動做。
若是黑客只是進行了簡單掃描文件操做,這極可能就是自動化程序進行的掃描,產生威脅的可能性很是小。可是因爲WAF不掌握應用內部的信息,它沒辦法判斷掃描的危害性有多大,所以保險起見只能報警。
1.在2012年的時候,Gartner引入了「Runtime application self-protection」一詞,簡稱爲RASP。它是一種新型應用安全保護技術,它將保護程序像疫苗同樣注入到應用程序中,應用程序融爲一體,它攔截從應用程序到系統的全部調用,能實時檢測和阻斷安全攻擊,使應用程序具有自我保護能力,當應用程序遭受到實際攻擊傷害,就能夠自動對其進行防護。
2.監控點位於應用程序的輸入輸出位置:
輸入點包括用戶請求、文件輸入等;輸出點包括包括數據庫、網絡、文件系統等。
3.RASP能作什麼?
圖1
如圖1所示,RASP能夠防護OWASP漏洞與第三方框架漏洞及應用性能監控等。
1.Java版的RASP技術使用javaagent機制來實現。在服務器啓動時,可動態的修改Java字節碼,對敏感操做的函數進行掛鉤,好比:
數據庫操做、文件讀取、寫入操做、命令執行等等。當服務器發生攻擊,就會觸發這些Hook點,此時RASP agent就能夠獲取到函數的參數,好比要讀取的文件名、要執行的命令等等。
2.RASP啓動流程
a.啓動時首先會進入 javaagent 的 premain 函數,該函數會在 main 函數以前預先執行。
b.初始化字節碼轉換模塊給load class 操做進行插樁操做,當類加載的時候會先進入 agent 進行處理hook指定函數。
3.架構大體如圖2所示,具體技術細節後續分析。
圖2
啓運後hook架構流程圖 三、4所示 :
圖3
圖4
a.由於啓動時候進行了插樁操做,當有類被 ClassLoader 加載時候,因此會把該類的字節碼先交給自定義的 Transformer 處理
b. 自定義 Transformer 會判斷該類是否爲須要 hook 的類,若是是會將該類交給ASM字節碼處理框架進行處理。
c. ASM框架會將類的字節碼依照事件驅動模型逐步解析每一個方法,當觸發了咱們須要hook的方法,咱們會在方法的開頭或者結尾插入進入檢測函數的字節碼
d. 把hook好的字節碼返回給transformer從而載入虛擬機。
上面提到關於jvm方面的知識能夠參考我博客的這兩篇文章
http://www.javashuo.com/article/p-waryjizo-mk.html
http://www.javashuo.com/article/p-mgahhdjt-mq.html
4.一個簡單的RASP實現與攻擊測試
上面咱們已經大體瞭解了總體框架流程,知道了要實現Java的RASP所要具有的能力和技術,在Java中有Javassist、與ASM能夠實現對Java字節碼的修改;有了修改.class字節碼文件的技能,還須要可以在Java運行期間注入咱們的防禦程序,經過上面的流程框架咱們知道Java運行時是發生在JVM中,jdk1.5之後引入了javaAgent技術,javaAgent是運行方法以前的攔截器關鍵方法,只要在JVM中加入啓動參數-javaagent配置Java代理能夠在運行時注入咱們的防禦程序。
咱們需要開發兩個工程,一個是被保護的web程序(webdemo),另外一個是RASP保護程序(RASPDEMO)
a.先簡單實現一個有sql 注入漏洞的javaweb應用程序,Servlet部分關鍵代碼如圖五、6所示:
圖5
圖6
建立數據庫,將工程代碼安裝佈置好。
b.測試sql注入
訪問url: http://localhost:8080/DemoServlet/DemoServlet?userId=1正常返回。再次訪問
「http://localhost:8080/DemoServlet/DemoServlet?userId=1 and 1=1/2邏輯判斷測試是否能注入,存在注入。
執行sqlmap:
python sqlmap.py -u "http://localhost:8080/DemoServlet/DemoServlet?userId=1" --batch –dbs
python sqlmap.py -u "http://localhost:8080/DemoServlet/DemoServlet?userId=1" --batch -D magedu -T userinfo "user, password" --dump
sqlmap順利的找到了漏洞,sqlmap能夠經過漏洞拿到數據庫的信息,圖七、8所示:
圖7
圖8
上面過程主要是利用注入點在原始的sql語句綜合的中間或後面"插入"、"拼接"上攻擊性的sql payload,從而達到提取非法數據等目的。如圖9所示的 paylad。
圖9
c.接下來咱們將實現一個用於保護上面javaweb的RASP保護程序,上面說過只要在JVM的-javaagent參數中配置咱們的保護程序,就可以輕鬆實現Java的RASP,Java代理程序入口類須要有名爲premain的靜態方法,下面是RASP保護程序的入口類,圖10所示:
圖10
ClassTransformer類實現了Java的代理程序機制提供的ClassFileTransformer接口,可以在運行時(Runtime)對類的字節碼進行替換與修改;ClassTransformer也很簡單,只有一個實現方法:transform,此方法中能夠獲取獲得ClassLoader、className、classfileBuffer等,分別爲類加載器、類名、字節碼,此時咱們能夠在transform方法中進行關鍵函數hook,實現咱們的防禦程序,圖十一、12所示。
圖11
圖12
能夠看到咱們在transform方法中關鍵類進行攔截,並經過ASM修改字節碼注入咱們的保護邏輯,圖13代碼是VisitorAdapter類中的onMethodEnter方法實現了經過ASM框架實現上面sql執行函數的hook。當每次有執行sql語句時都會進入filter攔截器。
圖13
在SQL Filter攔截器中,基於SQL語義分析判斷是否存在SQL注入攻擊,圖14 SQL Filter攔截器:
圖14
舉個栗子:
務器接收到以下sql語句
select * from userinfo where id=3 and len(@@version)>0 and '1'='1'
當執行時被SQL Filter攔截器監控到並傳入語法分析引擎進行分析,這條語句被認爲是非法的注入攻擊,由於攻擊者在子句中利用邏輯表達式進行非法的探測注入,該語句就不會被執行。
d.將咱們的保護程序(RASPDEMO)佈置在javaweb程序中,再進行一次攻擊測試。
當輸入攻擊測試sql語句時就會被攔截器監控到,圖15所示日誌信息。
圖15
使用sqlmap 測試仍是會被攔截器監控到,圖1六、17所示。
圖16
圖17
最終咱們成功的防止了SQL的注入,固然也能夠在此基礎上防止其它漏洞攻擊。
e.最後再來一個RASP攔截器檢測流程,圖18 所示 。
圖18
單說明下請求處理的流程
1.服務器收到一個請求,從而進入了服務器的請求hook點。
2.進入SQL Hook點,咱們掛鉤了execute、executeUpdate、executeQuery 等方法,從該方法進入檢測。
3.最後返回處理結果。
1.目前國內外基於RASP的產品已經有5個以上,今天咱們主要來分析下百度的OpenRasp, 從源碼能夠看到啓動時首先會進入 javaagent的premain函數,該函數會在main函數以前預先執行,接着就是初始化js與hook函數了,圖1九、20所示:
圖19
圖20
OpenRASP初始化流程圖21所示:
圖 21
初始完成後就開始走類字節碼修改流程(instrument方式),圖2二、23所示 :
圖22
圖23
2.OpenRASP攻擊檢測流程
在進入到被hook類的函數時,調用事先注入的檢測函數,最終調用pluginCheck函數。
a.pluginCheck(CheckParameter.Type type, Object params);
(type爲檢查的掛載點類型,params爲函數原始調用參數)
b.遍歷執行該掛載點類型的全部JavaScript檢測函數;
c.若是檢測函數沒有返回block,繼續執行;
d.主要分爲java檢測方式與js插件檢測方式,如圖2四、25所示
圖24
圖25
OpenRASP框架大體流程就分析到這,它支持大部分攻擊類型的檢查,可新增JS插件和HooK類進行二次開發。
1.目前RASP還處於發展中階段,沒有像WAF等常見的安全產品同樣有很是明確的功能邊界(scope),此文僅爲技術學習,更多RASP防護技術與新用法還能夠發揮想象,好比日誌監控、管理會話、安全過濾、請求管理等。
2.我的以爲rasp有點像殺毒軟件,實現功能上區別不是太大。 主要仍是規則、監控、攔截。這種方式的弊端,也是沒法檢測未知攻擊。因爲rasp與業務系統需要深度合做,會和業務邏輯緊密結合,可能穩定性問題是需要重點考慮的了,其實不論實現產品的技術是什麼樣的,可能你們實現的方式不同,使用的名稱不同,不過最終的目的就是爲了保護應用程序安全,防止攻擊者入侵,只要能給最終用戶賦能就是好的技術和產品。
3.最後感謝看完本文,若是以爲這篇文章有用可能幫助到你的朋友也歡迎轉載,歡迎掃碼關注公衆號: