IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP 的 RASP 实现 -> 正文阅读

[PHP知识库]PHP 的 RASP 实现

目录???????

一、什么是 RASP

二、PHP 拓展简介

三、PHP 的 HOOK 实现


一、什么是 RASP

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

二、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知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-02-16 12:50:44  更:2022-02-16 12:51:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 4:58:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计