首页后端开发其他后端知识PHP里面的RASP实现流程是怎么样的?

PHP里面的RASP实现流程是怎么样的?

时间2024-03-25 14:14:03发布访客分类其他后端知识浏览1458
导读:这篇文章给大家介绍了“PHP里面的RASP实现流程是怎么样的?”的相关知识,讲解详细,步骤过程清晰,对大家进一步学习和理解“PHP里面的RASP实现流程是怎么样的?”有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路...
这篇文章给大家介绍了“PHP里面的RASP实现流程是怎么样的?”的相关知识,讲解详细,步骤过程清晰,对大家进一步学习和理解“PHP里面的RASP实现流程是怎么样的?”有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路一起来学习一下吧。


    

一、什么是 RASP

RASP 全称是 Runtime Application self-protection,即运行时应用自我保护,这是一种嵌入到应用程序内部,实时检测来自外部的请求、输入的技术。PHP 的 RASP 是通过 PHP 拓展的形式嵌入到PHP 的解释器中。

RASP(Runtime Application self-protection)是一种在运行时检测攻击并且进行自我保护的一种技术。早在2012年,Gartner就开始关注RASP,惠普、WhiteHat Security等多家国外安全公司陆续推出RASP产品,时至今日,惠普企业的软件部门出售给了Micro Focus,RASP产品Application Defender随之易主。而在国内,去年知道创宇KCon大会兵器谱展示了JavaRASP,前一段时间,百度开源了OpenRASP,去年年底,360的0kee团队开始测试Skywolf,虽然没有看到源码和文档,但它的设计思路或许跟RASP类似。而商业化的RASP产品有OneAPM的OneRASP和青藤云的自适应安全产品。在国内,这两家做商业化RASP产品做得比较早。

二、PHP 拓展简介

PHP 在不同的环境下有不同的工作模式,常见的有:命令行下的单进程模式和 Apache 环境下的多进程或者多线程模式。但不管是哪种模式下,都需要执行以下几个流程:

图1 单进程拓展执行流程

单进程模式下整个 PHP 的生命周期为:

图2 单进程生命周期

多进程模式下的生命周期:

图3 多进程生命周期

多进程下每个进程只执行一次模块初始化和模块关闭,会不断执行请求初始化-处理请求-请求关闭的过程。多线程模式下类似,只是处理请求的是线程。

因此我们可以在模块初始化(MINIT)或者请求初始化(RINIT)阶段 hook,这样每次处理请求的就是我们的业务逻辑函数,可以在我们的业务逻辑函数中对输入、或者请求进行监测,判断出异常后即可上报风险。

三、PHP 的 HOOK 实现

想要了解 hook 的方式,需要先看一下PHP对脚本的处理流程。

PHP 对脚本进行词法分析和语分析后会生成 OPArray,也就是 OPCode 的数组,每个 OPCode 都代表一种不同的操作,名称类似下面这种:

ZEND_ADD:执行两个操作数的算术加法操作;

ZEND_EXIT:退出PHP执行;

Zend VM中则存在一个主分支循环(while(1)死循环),只有当执行的 opcode 的 handler 的返回值是1(ZEND_VM_RETURN())时,这个循环才会结束,所以编译器会为每个 PHP 脚本在最后添加一个 RETURN 的 OPCode。

以 ZEND_ADD 这个 opcode 为例,这个结构体里包含有两个操作数(op1和op2)、handler(函数指针)、result(运算后的结果)。Zend VM 会根据两个操作数的类型,找到对应的handler,在源码中对 ZEND_ADD 这个 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();

}

函数后两个参数分别代表 op1 和 op2 可接受的操作数类型。

处理工具会根据这个函数的定义,对 op1 和 op2 进行类型组合,生成16个处理特定类型的 handler函数。这些 handler 函数命名如下:

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 */ }

......

规律为:static int ZEND_FASTCALL OPCode_SPEC_{ OP1-TYPE} _{ OP2-TYPE} _HANDLER

所以最终执行哪个 handler 是根据需要两个操作数的类型决定的。

所以我们可以替换OPCode的handler,刚好源码中有对应的接口zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)可供使用。

除了 OPCode 外,PHP 还有很多内置函数,比如 sprintf、 system、usort 等等,这些函数是没有OPcode 的,但是这些函数都被保存在了全局函数表里,可以通过 CG(function_table) 获取,这些函数也有对应的handler函数指针,所以我们可以直接备份原先的 handler 后使用 function-> internal_function.handler = new_handler 替换即可。



以上就是关于PHP里面的RASP实现流程是怎么样的?的介绍,本文内容仅供参考,有需要的朋友可以借鉴了解看看,希望对大家学习或工作,想要了解更多欢迎关注网络,小编每天都会为大家更新不同的知识。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: PHP里面的RASP实现流程是怎么样的?
本文地址: https://pptw.com/jishu/652832.html
PHP用PHPMailer实现邮件发送的过程是什么 PHP中三元表达式的用法是什么,怎样写?

游客 回复需填写必要信息