PHP?中的?RASP?實(shí)現(xiàn)流程分析
一、什么是 RASP
RASP 全稱是 Runtime Application self-protection,即運(yùn)行時(shí)應(yīng)用自我保護(hù),這是一種嵌入到應(yīng)用程序內(nèi)部,實(shí)時(shí)檢測(cè)來(lái)自外部的請(qǐng)求、輸入的技術(shù)。PHP 的 RASP 是通過(guò) PHP 拓展的形式嵌入到PHP 的解釋器中。
RASP(Runtime Application self-protection)是一種在運(yùn)行時(shí)檢測(cè)攻擊并且進(jìn)行自我保護(hù)的一種技術(shù)。早在2012年,Gartner就開始關(guān)注RASP,惠普、WhiteHat Security等多家國(guó)外安全公司陸續(xù)推出RASP產(chǎn)品,時(shí)至今日,惠普企業(yè)的軟件部門出售給了Micro Focus,RASP產(chǎn)品Application Defender隨之易主。而在國(guó)內(nèi),去年知道創(chuàng)宇KCon大會(huì)兵器譜展示了JavaRASP,前一段時(shí)間,百度開源了OpenRASP,去年年底,360的0kee團(tuán)隊(duì)開始測(cè)試Skywolf,雖然沒(méi)有看到源碼和文檔,但它的設(shè)計(jì)思路或許跟RASP類似。而商業(yè)化的RASP產(chǎn)品有OneAPM的OneRASP和青藤云的自適應(yīng)安全產(chǎn)品。在國(guó)內(nèi),這兩家做商業(yè)化RASP產(chǎn)品做得比較早。
二、PHP 拓展簡(jiǎn)介
PHP 在不同的環(huán)境下有不同的工作模式,常見的有:命令行下的單進(jìn)程模式和 Apache 環(huán)境下的多進(jìn)程或者多線程模式。但不管是哪種模式下,都需要執(zhí)行以下幾個(gè)流程:

圖1 單進(jìn)程拓展執(zhí)行流程
單進(jìn)程模式下整個(gè) PHP 的生命周期為:

圖2 單進(jìn)程生命周期
多進(jìn)程模式下的生命周期:

圖3 多進(jìn)程生命周期
多進(jìn)程下每個(gè)進(jìn)程只執(zhí)行一次模塊初始化和模塊關(guān)閉,會(huì)不斷執(zhí)行請(qǐng)求初始化-處理請(qǐng)求-請(qǐng)求關(guān)閉的過(guò)程。多線程模式下類似,只是處理請(qǐng)求的是線程。
因此我們可以在模塊初始化(MINIT)或者請(qǐng)求初始化(RINIT)階段 hook,這樣每次處理請(qǐng)求的就是我們的業(yè)務(wù)邏輯函數(shù),可以在我們的業(yè)務(wù)邏輯函數(shù)中對(duì)輸入、或者請(qǐng)求進(jìn)行監(jiān)測(cè),判斷出異常后即可上報(bào)風(fēng)險(xiǎn)。
三、PHP 的 HOOK 實(shí)現(xiàn)
想要了解 hook 的方式,需要先看一下PHP對(duì)腳本的處理流程。
PHP 對(duì)腳本進(jìn)行詞法分析和語(yǔ)分析后會(huì)生成 OPArray,也就是 OPCode 的數(shù)組,每個(gè) OPCode 都代表一種不同的操作,名稱類似下面這種:
ZEND_ADD:執(zhí)行兩個(gè)操作數(shù)的算術(shù)加法操作;
ZEND_EXIT:退出PHP執(zhí)行;
Zend VM中則存在一個(gè)主分支循環(huán)(while(1)死循環(huán)),只有當(dāng)執(zhí)行的 opcode 的 handler 的返回值是1(ZEND_VM_RETURN())時(shí),這個(gè)循環(huán)才會(huì)結(jié)束,所以編譯器會(huì)為每個(gè) PHP 腳本在最后添加一個(gè) RETURN 的 OPCode。
以 ZEND_ADD 這個(gè) opcode 為例,這個(gè)結(jié)構(gòu)體里包含有兩個(gè)操作數(shù)(op1和op2)、handler(函數(shù)指針)、result(運(yùn)算后的結(jié)果)。Zend VM 會(huì)根據(jù)兩個(gè)操作數(shù)的類型,找到對(duì)應(yīng)的handler,在源碼中對(duì) ZEND_ADD 這個(gè) opcode 的 handler 定義如下:
ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}函數(shù)后兩個(gè)參數(shù)分別代表 op1 和 op2 可接受的操作數(shù)類型。
處理工具會(huì)根據(jù)這個(gè)函數(shù)的定義,對(duì) op1 和 op2 進(jìn)行類型組合,生成16個(gè)處理特定類型的 handler函數(shù)。這些 handler 函數(shù)命名如下:
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { /* handler code */ }
......規(guī)律為:static int ZEND_FASTCALL OPCode_SPEC_{OP1-TYPE}_{OP2-TYPE}_HANDLER
所以最終執(zhí)行哪個(gè) handler 是根據(jù)需要兩個(gè)操作數(shù)的類型決定的。
所以我們可以替換OPCode的handler,剛好源碼中有對(duì)應(yīng)的接口zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)可供使用。
除了 OPCode 外,PHP 還有很多內(nèi)置函數(shù),比如 sprintf、 system、usort 等等,這些函數(shù)是沒(méi)有OPcode 的,但是這些函數(shù)都被保存在了全局函數(shù)表里,可以通過(guò) CG(function_table) 獲取,這些函數(shù)也有對(duì)應(yīng)的handler函數(shù)指針,所以我們可以直接備份原先的 handler 后使用 function->internal_function.handler = new_handler 替換即可。
到此這篇關(guān)于PHP 中的 RASP 實(shí)現(xiàn)流程分析的文章就介紹到這了,更多相關(guān)PHP 的 RASP 實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
讓Laravel API永遠(yuǎn)返回JSON格式響應(yīng)的方法示例
這篇文章主要給大家介紹了關(guān)于如何讓Laravel API永遠(yuǎn)返回JSON格式響應(yīng)的相關(guān)資料,需要的朋友可以參考下2018-09-09
CodeIgniter框架提示Disallowed Key Characters的解決辦法
在做項(xiàng)目過(guò)程中,出現(xiàn)提交form表單的時(shí)候,出現(xiàn)了Disallowed Key Characters 的提示2014-04-04
基于PHP+mysql實(shí)現(xiàn)新聞發(fā)布系統(tǒng)的開發(fā)
這篇文章主要介紹了基于PHP+mysql實(shí)現(xiàn)新聞發(fā)布系統(tǒng)的開發(fā),文章通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下 面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
ThinkPHP5.1驗(yàn)證碼功能實(shí)現(xiàn)的示例代碼
這篇文章主要介紹了ThinkPHP5.1驗(yàn)證碼功能實(shí)現(xiàn)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Laravel 將數(shù)據(jù)表的數(shù)據(jù)導(dǎo)出,并生成seeds種子文件的方法
今天小編就為大家分享一篇Laravel 將數(shù)據(jù)表的數(shù)據(jù)導(dǎo)出,并生成seeds種子文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10

