freeBuf
主站

分類

漏洞 工具 極客 Web安全 系統安全 網絡安全 無線安全 設備/客戶端安全 數據安全 安全管理 企業安全 工控安全

特色

頭條 人物志 活動 視頻 觀點 招聘 報告 資訊 區塊鏈安全 標準與合規 容器安全 公開課

官方公眾號企業安全新浪微博

FreeBuf.COM網絡安全行業門戶,每日發布專業的安全資訊、技術剖析。

FreeBuf+小程序

FreeBuf+小程序

RASP攻防:RASP安全應用與局限性淺析
2020-09-18 21:39:36

前言

隨著Web應用攻擊手段變得復雜,基于請求特征的防護手段,已經不能滿足企業安全防護需求。在2012年的時候,Gartner引入了“Runtime application self-protection”一詞,簡稱為RASP,屬于一種新型應用安全保護技術,它將防護功能“ 注入”到應用程序中,與應用程序融為一體,使應用程序具備自我防護能力,當應用程序遭受到實際攻擊傷害時,能實時檢測和阻斷安全攻擊,而不需要進行人工干預。

騰訊洋蔥反入侵團隊早在很多年前就研究RASP的應用場景,2014年還在TSRC搞了一次基于rasp的webshell攻防挑戰賽,詳見(https://security.tencent.com/index.php/blog/msg/57);近幾年從PHP逐步擴展到Java,Python,Nodejs等其他語言。RASP通過實時采集Web應用的高風險行為,通過特征規則、上下文語義分析及第三方安全產品數據關聯分析等多種安全模型來提升檢測準確率,相較于傳統Web應用安全產品,RASP從海量的攻擊中排除掉了大量的無效攻擊,聚焦發現真實的已知和未知安全威脅。經過多年的實踐我們發現RASP也存在一些缺陷和不足,本文以PHP RASP作為研究對象拋磚引玉,在此分享RASP的應用場景和問題。本文主要分三個部分:RASP架構原理簡要介紹、RASP安全應用場景介紹 及 RASP對抗淺析。

注意:文中涉及的文章pdf ,代碼,思維導圖存放于https://github.com/qiyeboy/my_tsrc_paper倉庫中,喜歡的朋友可以自取。

一、 RASP架構原理簡要介紹

以PHP語言為例,PHP語言自身提供擴展機制,可以基于擴展機制開發RASP系統。

騰訊自研的TRASP架構示意圖:


TRASP 整個架構大致分為3個部分:1. 客戶端模塊;2. 云端數據分析模塊; 3. 安全處置模塊。

1、客戶端模塊;負責數據采集和規則匹配,數據采集可以配置策略采集需要的數據(如SQL執行/命令執行/代碼執行/文件操作等),RASP可以根據需求配置數據采集策略,需要注意的是采集數據越多資源消耗也會隨之增大;

2、云端數據分析模塊;有些場景通過前端規則無法完全解決,需要上報數據到云端分析進行二次分析,包括使用機器學習算法,關聯分析等;

3、安全處置模塊;負責配置事件安全等級和處置策略,RASP串行在業務中,誤報會影響業務,需要根據安全事件的等級和精準度配置阻斷/異步告警/安全通知等不同的處置策略。

PHP RASP擴展原理和實現簡要介紹:

PHP RASP作為PHP解釋器的擴展,是一個動態庫so文件,PHP語言中類似的動態庫很多,比如:mysql.so,RASP和MYSQL擴展的加載方式和運行原理一樣,集成在PHP解釋器中。接下來從3個方面簡單描述一下TRASP擴展模塊的實現原理。

1. 預加載

任何一個PHP實例都會經過Module init、Request init、Request shutdown和Module shutdown四個過程。

Module init

在所有請求到達前發生,例如啟動Apache服務器,PHP解釋器隨之啟動,相關的各個模塊(Redis、Mysql等)的MINIT方法被調用。僅被調用一次。在開發XXX擴展時,相應的XXX.c文件中將自動生成該方法:

1600436028_5f64b73c4480b40236015.png!small

Request init

每個請求到達時都被觸發。SAPI層將控制權交由PHP層,PHP初始化本次請求執行腳本所需的環境變量,函數列表等,調用所有模塊的RINIT函數。XXX.c中對應函數如下:

1600436044_5f64b74c4bdd42e241f4a.png!small

Request shutdown

每個請求結束,PHP就會自動清理程序,順序調用各個模塊的RSHUTDOWN方法,清除程序運行期間的符號表。典型的RSHUTDOWN方法如:

Module shutdown

所有請求處理完畢后,SAPI也關閉了(即服務器關閉),PHP調用各個模塊的MSHUTDOWN方法釋放內存。

1600436071_5f64b7679f40b331ae559.png!small

RASP預加載主要在Module init 階段實現, 通過在初始化階段預先加載RASP模塊, 替換opcode handler與通過自定義函數替換全局函數表位置。

PHP把中間字節碼稱之為OPCODE,每個OPCODE對應ZEND底層的一個處理函數,ZEND引擎最終執行這個處理函數。

2. Hook Opcode 或 Hook 內部函數

RASP需要監控各個敏感函數的調用,在PHP中比較好的方式便是 Hook Opcode 和 Hook內部函數。

(1) 實現Hook Opcode 功能只需要改變 Hook Opcode 對應的處理函數即可,而 zend 預先就提供了一個現成的接口:zend_set_user_opcode_handler, 如:

1600436090_5f64b77ac3dee29f00878.png!small

替換 Opcode handler 后便可以自定義函數調用前后的操作, 如獲取參數、阻斷攻擊等, 還可以通過 ZEND_USER_OPCODE_DISPATCH 跳回至原來的Opcode執行,雖然PHP調用函數的方式多種多樣, 但從Opcode角度分析, 主要還是分為以下幾類, 以php7為例:

1600436104_5f64b788a1191079087f8.png!small

(2) 另一種實現Hook函數調用的方式就是Hook內部函數, Opcode最終還是會通過CG(function_table)獲取所調用函數的handler執行, 那么我們通過修改CG(function_table)表對應函數的handler指向, 便可以指向我們實現的函數,在完成相應操作后繼續調用原來的函數實現hook。

1600436116_5f64b7941565f8cc9424b.png!small

兩種方式皆可實現Hook函數,有各自的優點。第一種,適合工程化,只需要對幾種Opcode類型進行hook,后續Hook的敏感函數可以自行添加;第二種則是需要對敏感函數進行逐一替換,比較繁瑣,但優點是替換發生在函數表內,故通過越過Opcode進行函數執行的手法也無法繞過檢測,更加可靠。

3. 參數獲取與分析

在完成對敏感函數調用行為的監控后,通過ZEND_CALL_NUM_ARGS和ZEND_CALL_ARG,我們可以獲取到函數的參數個數和內容,便可根據函數的參數制定相應的策略。如文件類可以關注是否讀取了敏感文件, 數據庫操作類是否語法結構發生了變化等等。

二、 RASP 安全應用場景介紹

1. 基于規則的漏洞攻擊檢測

通過RASP實時采集Web應用的高風險行為,具體實現為hook漏洞相關的函數,如檢測SQL注入(劫持mysqli_query等)、命令注入(system/exec等)、文件上傳漏洞(move_uploaded_file等)、xss漏洞(echo/print等);拿到函數數據后對參數進行規則匹配判斷是否存在漏洞攻擊。舉兩個例子:


(1)文件上傳漏洞,以move_uploaded_file為例,函數說明:move_uploaded_file ( string?filename,stringdestination ) : bool,第一個參數為上傳文件,如果上傳了一個動態php腳本后綴文件即判斷存在上傳漏洞。


【ip xxx 安全漏洞告警】
TRASP 發現ip xxx存在上傳漏洞,漏洞細節如下:
漏洞文件: /data/webroot/xxx/x.php(第201行)
上傳的PHP動態腳本: /data/webroot/xxx/1.php


(2)SQL注入,可以發現下圖正常的sql和惡意的注入sql有區別,比如使用了union select,可以基于此做安全策略;

1600436129_5f64b7a14d894adbdc0a2.png!small

傳統規則可能存在誤報,也可以對sql語句做語義解析判斷是否存在sql注入攻擊,非本文重點不再過多介紹。

2. 基于污點追蹤的漏洞檢測

通過追蹤外部可控制的輸入變量(如GET,_POST,REQUEST,REQUEST,_COOKIE等)是否未經安全處理進入危險函數執行,危險函數包括各種可能導致漏洞的函數,如命令注入相關的system/exec,xss相關的echo/print。污點追蹤原理借用了php變量結構體預留的一個標記位,業界知名的相關系統有鳥哥開發的Taint擴展,詳情可參考:https://www.laruence.com/2012/02/14/2544.html,本文不再做過多介紹。

3. IAST掃描聯動

先簡要介紹下IAST,IAST中文名是交互式應用安全測試,相較于傳統的DAST和SAST掃描方式,漏洞檢出率更高&誤報率更低。IAST目前常見的實現方式有兩種,一類是基于代理或網關等形式抓取業務CGI流量后做安全測試掃描,一類是在業務web容器插樁獲取業務代碼執行細節結合DAST掃描用例判斷是否存在漏洞,比如DAST發起一個帶有test_from_dongxi字符串的SQL注入測試請求,web容器內插樁劫持數據庫相關函數,發現sql語句中有test_from_dongxi的字符串,從而聯動發現安全漏洞;RASP可以用于插樁獲取代碼執行流程,相較于傳統漏洞檢測方法可以直接定位到有漏洞的代碼文件和具體代碼行號,業務修復起來更加便捷。

1600436152_5f64b7b876502a29e5987.png!small

4. Webshell檢測

Webshell文件是一個特殊的cgi文件,有文件操作、命令執行等管理功能,可以基于rasp采集的數據在云端做檢測;檢測方法包括 規則匹配(適用于一句話木馬和混淆webshell有明顯特征的樣本)、行為統計分析(適用于大馬);此外,RASP結合污點追蹤也是一種檢測方法,通過標記非信任的數據源,監測整個數據鏈路,此前寫過一篇文章,詳情可參考:https://security.tencent.com/index.php/blog/msg/152,本文不再做過多介紹。

三、RASP 對抗淺析

在上文中,介紹了PHP RASP的安全應用場景和實現原理,寫了很多RASP的優點,但俗話講的好:沒有絕對安全的系統,接下來分享一下RASP存在的不足。先看一下RASP在LINUX系統中的層級:

1600436169_5f64b7c9c22ba4919f194.png!small

PHP RASP作為php解釋器的擴展,運行在php解釋器層面,也就是說在與PHP RASP同級或者在其層級之下的操作,它的監控基本上是失效的,這包括與PHP RASP同一級的其他擴展,PHP解釋器之外的進程,以及通過glibc的操作,這很關鍵。

既然分析繞過手法,那就需要一個繞過的標準,由于命令風險很高,同時更加普遍,因此選擇命令作為突破口:

通過PHP腳本任意執行命令,讓RASP?無法監控到數據或者無法捕獲到正確數據

接下來從9個方面來闡述繞過方法,文中部分知識都是公開的,只是用在了新的場景。

1. 函數監控不全

php手冊中的函數太多了,總有你想不到的,多翻翻PHP手冊,比如rasp hook了以下常用的命令執行函數

1600436186_5f64b7dab30e1ab4f9d83.png!small

利用Windows中COM組件繞過:

1600436199_5f64b7e770583f92d4cdf.png!small

2.函數參數混淆

RASP檢測基于函數和參數做安全策略,可以對參數做變形繞過檢測,舉個例子: system 函數,用來執行命令,很多業務文件也用,比如運維管理后臺。RASP不能只根據函數做報警,會帶來大量誤報,需要結合參數來做策略,system函數底層原理是執行 sh -c "函數參數",因此我們可以通過命令混淆的方式,成功將RASP動態檢測轉化為對函數參數的靜態檢測,這樣操作空間就會變得很大。示例如下:

1600436209_5f64b7f14e8463b13714c.png!small

其實在存在命令注入漏洞的場景中,使用混淆的方式是有很大的機會繞過RASP的監控。

3. loader型函數

什么叫loader型函數呢? 簡單來說函數是正常的,但是通過改變參數來實現惡意行為,函數參數相當于payload。

比如 mail() 函數的第五個additional_parameters參數可用于設置命令行選項傳遞給配置為發送郵件時使用的程序。

mail 函數的底層原理是調用sendmail程序,當系統使用Exim來發送郵件時,sendmail 的 -be 參數支持運行擴展模式,可以 對指定字符串擴展格式進行解析。

默認情況下 sendmail時不支持 -be參數的,如何測試主機上的sendmail是否支持-be擴展呢? 使用sendmail執行whoami,如果成功則沒有問題:

1600436218_5f64b7fad68fab920cfec.png!small

借用github中使用mail 實現命令執行的開源代碼:

1600436231_5f64b80736190b2629a6f.png!small

除了mail函數,還有imap_open 函數在ssh建立連接可利用\t代替空格進行-o ProxyCommand參數命令拼接,從而調用系統shell執行命令。示例代碼如下:

1600436242_5f64b8124290640235b86.png!small

4. LD_PRELOAD

LD_PRELOAD 是Linux中比較特殊的環境變量,它允許用戶指定程序運行前優先加載的動態鏈接庫。在php中,可使用putenv()函數設置LD_PRELOAD環境變量來加載指定的so文件,so文件中包含自定義函數進行劫持從而達到執行惡意命令的目的。

mail() 、 error_log()、ImageMagick() 是常用于劫持的觸發函數,原因是在運行的時候能夠啟動子進程,這樣才能重新加載我們所設置的環境變量,從而劫持子進程所調用的庫函數。

以mail函數為例:mail函數在運行時,會啟動子進程來調用系統的sendmail,sendmail引用了getegid() 函數。

那么我們可以通過重寫 getegid() 函數編譯為so文件,代碼內部執行了whoami:

1600436253_5f64b81d2c59ed003e610.png!small

在利用過程中,通過設置LD_PRELOAD環境變量引入自定義的so庫。由于真正的惡意代碼運行在php之外的進程,自然避過了RASP監控。

1600436264_5f64b8286e6bc257b43cb.png!small

5. htaccess和mod_cgi

在apache的WEB環境中,我們經常會使用.htaccess這個文件來確定某個目錄下的URL重寫規則,如果.htaccess文件被攻擊者修改的話,攻擊者就可以利用apache的mod_cgi模塊,直接繞過PHP來執行系統命令。需要滿足四個條件:

  1. apache環境
  2. mod_cgi為啟用狀態
  3. 允許.htaccess文件,即在httpd.conf中,AllowOverride選項為All,而不是none
  4. 有權限寫.htaccess文件

舉個例子:

.htaccess內容:

1600436276_5f64b834e974add52da4c.png!small

shell.tt

1600436286_5f64b83e9836718407452.png!small

6. PHP-FPM

PHP-FPM是一個fastcgi協議解析器,默認監聽在9000端口。php-fpm由于未授權訪問的設計缺陷,它沒有相應的訪問驗證,因此 可以自己構造fastcgi協議,與php-fpm進行通信,讓它幫我們干一些"壞事",比如動態加載上傳的惡意php擴展。


FastCGI協議由多個record組成,和HTTP協議類似,也有header和body ,但是和HTTP頭不同,record的頭固定8個字節,body是由頭中的contentLength指定,其結構如下:

1600436296_5f64b848423b9f1b88b5c.png!small

在傳入的FastCGI協議數據包中,設置 type=4,就可以給php-fpm傳遞環境參數,指揮它工作。

通過FastCGI協議告訴php-fpm去加載一個我們自定義的擴展,這涉及到php-fpm的兩個環境變量,PHP_VALUE和?PHP_ADMIN_VALUE。這兩個環境變量就是用來設置PHP配置項的,PHP_VALUE可以設置模式為PHP_INI_USERPHP_INI_ALL的選項,PHP_ADMIN_VALUE可以設置所有選項。我們只要發送如下類似的請求就可以實現擴展的自動加載。

1600436308_5f64b85470c0a244ce214.png!small

推薦幾個項目,可以方便大家更好的操作:

7. C接口

FFI(Foreign Function Interface)是 PHP7.4 新加入的功能,即外部函數接口,允許從共享庫中調用C代碼,導致風險點擴大。調用glibc中的system:

1600436322_5f64b86285d72cae381b3.png!small

8. 已知漏洞

php有一些已知的釋放重引用漏洞,比如 GC UAF、Json Serializer UAF 、Backtrace UAF等,具體的exp位于https://github.com/mm0r1/exploits/

通過第一部分對 RASP(PHP)原理的講解,我們知道PHP函數的底層調用都要通過CG(function_table)獲取所調用函數的handler。無論 RASP 是hook opcode 還是 hook function,本質上都沒有從內存中刪除所調用的函數,只是改變了走向,指向了我們自定義的函數。正因如此,我們可以通過上述漏洞,找到內存中對應的函數地址,將其封裝為閉包實現調用,從而完成繞過 。以 system函數為例,繞過原理簡單總結如下圖所示:

v2-756aabc37a5e956d59af6a3ad5f01a17_1440w.jpg

對于 正常的php 文件 system("whoami")而言,由于php rasp 將function_table 函數指向從原來的zif_system 內置函數 改為 自定義的fake_system監控函數,導致命令執行在RASP的控制之下。而通過上述漏洞的方式,可以在內存中直接找到 zif_system函數地址,找到地址后,通過偽造閉包對象,將對象中的函數handler指向該地址,實現對 zif_system函數的調用,從而繞過RASP監控。

9. GOT 表劫持

在linux系統中,procfs 文件系統是個特殊的存在,對應的是 /proc目錄,php 可以通過/proc 目錄讀寫自己所在進程的內存,將非敏感函數地址替換成glibc 中的system地址,從而執行命令,其涉及的技術叫做 GOT表劫持。

通過正常函數實現敏感行為繞過 RASP ,舉個例子,如果能將open函數地址換成system地址,那么便可以將fopen打開文件的命令,最終變成glibc調用system執行命令。

適用條件:

  1. 內核版本>=2.98
  2. 基于www權限的php-fpm/php-cgi work進程必須有權限讀寫 /proc/self/目錄。
  3. open_basedir=off(或者能繞過open_basedir讀寫 /lib/ 和/proc/)

針對適用條件的第2點簡要說明一下:

  • apache+php 由于 apache調用setuid設置www權限工作進程,/proc/self/目錄屬于root用戶,導致沒有權限讀寫。
  • nginx+php,對于低版本的php -fpm www權限工作進程, /proc/self/目錄屬于www用戶可以讀寫。經不完全測試,php<5.6 版本是可以使用GOT表劫持。

下面簡單描述一下劫持GOT表的步驟,以system替換open函數為例:

  1. 讀取/proc/self/maps 找到php與glibc在內存中的基地址
  2. 解析/proc/self/exe 找到php文件中[email protected]的偏移,解析libc.so找到system函數的偏移地址
  3. 解析 /proc/self/mem 定位 [email protected] 對應[email protected]的地址,以及libc.so中system 函數的內存地址
  4. 將system 函數的內存地址 寫入到 [email protected]
  5. 主動調用fopen("/bin/whoami") ,即相當于調用 system("/bin/whoami")

不在文中放exp源碼了,具體源碼在前文提到的git倉庫中,大家可以根據實際環境進行調試修改,并不通用。

四、總結

單純就RASP本身而言,RASP的優點在于能嵌入在應用程序內部,應用代碼無感知,更了解應用程序上下文,方便定位漏洞信息,更少的誤報和漏報,對各種繞過手法具有更強的防護能力;但缺點在于PHP RASP會對服務器的性能造成影響,推動部署落地相對困難。不過隨著DevSecOps理念的推廣,未來借助于云、容器等成熟的大規?;A設施和技術,通過優化完全有可能提供更優雅更易于接受和使用的部署方案,能夠帶來更快更精準更細致入微的安全檢查及防護能力。關于DevSecOps理念與思考,大家可以參考我們團隊之前的文章:?“安全需要每個工程師的參與”-DevSecOps理念及思考。

雖然依然有一些對抗手段,但是RASP 在Web安全領域依然是現階段強有力的存在。但是安全沒有銀彈,不存在一勞永逸的系統和辦法,在漏洞/入侵檢測上我們需要掃描器,WAF,IDS,EDR等系統的配合共建防御體系,縱深防御才是長久之道,并且需要持續研究在對抗中不斷提升和發展。

參考文獻:

https://www.cnblogs.com/zw1sh/p/12632126.html
https://zhuanlan.zhihu.com/p/75114351?from_voters_page=true
https://www.cnblogs.com/tr1ple/p/11213732.html
http://www.219667.live/articles/others-articles/232329.html
https://x-c3ll.github.io/posts/UAF-PHP-disable_functions/

作者:騰訊安全平臺部數據安全團隊 qiye & baz

本文作者:, 轉載請注明來自FreeBuf.COM

# 系統安全 # 數據安全
被以下專輯收錄,發現更多精彩內容
+ 收入我的專輯
評論 按時間排序

登錄/注冊后在FreeBuf發布內容哦

相關推薦
  • 0 文章數
  • 0 評論數
  • 0 關注者
登錄 / 注冊后在FreeBuf發布內容哦
收入專輯
777766香港开奖结果 小说 黑龙江省十一选五走势图播放 福彩排列7的玩法 中国银行股票行情 极速11选5投注技巧 排5走势图连线专业版 山西体彩11选五走势 炒股是什么意思解释 宁夏体彩11选五走势图手机版 宁夏11选5怎么玩 上海11选5