php自定义恶意扩展so编写过程
0x01前言
LD_PRELOAD
是linux的环境变量,可以设置一个指定库的路径,常被用来Passby Disable_functions,本文将从php扩展和php内核的交互来解释php编写自定义扩展的整个过程
0x02前置知识
php的生命周期有五个阶段:
1、模块初始化
此阶段主要注册php和zend引擎的扩展,还有将常量注册到EG(zend_constants),全局变量注册到CG(auto_globals),同时掉用php扩展的PHP_MINT()
2、请求初始化
初始化php脚本的基本执行环境,调用php扩展的PHP_RINT()
3、执行php脚本
将php编译成opcode码,然后再用zend引擎执行
编译过程流程图:
4、请求结束
清理EG(symbol_table),销毁全局变量PG(http_globals),调用析构函数和各种扩展的RSHUTDOWN函数,关闭编译器和执行器,关闭内存管理器
5、模块关闭
清理持久化符号标,调用各扩展的MSHUTDOWN,清理扩展globals,注销扩展提供的函数
php整个扩展的加载就在模块初始化阶段,而整个扩展的加载过程又有以下步骤
使用dlopen()函数来打开so库文件,并返回句柄给dlsym()
dlsym()函数来获取动态库中
get_module()
函数地址调用
get_module()
函数来获取扩展的zend_module_entry
结构zend api版本号检查,看是否是当前php版本下适用的扩展
注册扩展,将扩展添加到
module_registry
中如果扩展有内部函数,将内部函数注册到EG(function_table)中
0x03扩展编写
1、编写config.m4
Config.m4是扩展的编译配置文件,它被include到configure.in文件中,最终被autoconf编译为configure。
以下是一个简单的扩展配置模版:
1 | PHP_ARG_ENABLE(扩展名称, for mytest support, |
下面是我自己实验的config.m4文件:
1 | PHP_ARG_ENABLE(php_knight, Whether to enable the KnightPHP extension, [ --enable-knight-php Enable KnightPHP])//扩展名可以和函数名不同 |
2、编写.h文件
php_knight.h
1 | // 定义模块常量 |
3、编写.c文件
Php_knight.c
1 | //包含php.h文件 |
4、编译
先安装php-dev,而后安装phpize,装好后直接在当前目录执行phpize
phpize主要是操作复杂的autoconf/automake/autoheader/autolocal等系列命令,用于生成configure文件
然后执行./configure --enable-php-knight
提供给configure.in获取配置,生成Makefile
接着就是make
和make install
,在执行完这些命令后,就会在目录下生成一个php_knight.so文件了。
0x04使用恶意扩展
编写php代码
1 |
|
这样通过访问浏览器,就会返回Hello World!
了
0x05 其他方法
还有一个使用很多的方法
Knight.c
1 |
|
然后使用命令gcc knight.c -fPIC -shared -o knight.so
就可以产生so扩展文件了
knight.php
1 |
|
就可以动态加载自己的反弹shell命令了。
此方法相比上面一种方法的局限性就是mail()函数没有被禁用
0x06参考来源
https://blog.csdn.net/hguisu/article/details/7377153