主页 > 网络知识 > 突破PHP函数禁用执行Shell代码分析(2)

突破PHP函数禁用执行Shell代码分析(2)

GCC 有个 C 语言扩展修饰符 __attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行 。

01目的:停止环境变量对system(cmdline)函数执行前的打断

02操作:

共享文件C语言中加入以下代码,通过改环境写入进行清空环境变量

extern char** environ ; int i; for (i = 0; environ[i]; ++i) { if (strstr(environ[i], "LD_PRELOAD")) { environ[i][0] = ''; } }

03基础概念

每个程序都有一个环境表,它是一个字符指针数组,其中每个指针包含一个以NULL结尾的C字符串的地址。全局变量environ则包含了该指针数组的地址:externchar **environ;

在调用system(cmdline);会又使得LD_PRELOAD再加载自身,这就陷入无限循环。因此写入,对函数执行的环境变量修改,打断LD_PRELOAD再加载自身,从而顺利执行system(cmdline);

01目的:读取环境变量中的恶意shell指令并执行

02操作:

共享文件C语言中加入以下代码、使用C语言调用的系统函数

const char* cmdline = getenv("EVIL_CMDLINE"); system(cmdline);

03基础概念

读取环境变量函数及系统执行函数

getenv ( string $varname [, bool $local_only = FALSE ] ) : stringint 

system(const char *command);

01目的:生成系统执行的二进制文件,供于被调用

02操作:

编译动态库、通过c语言编写功能函数,再使用GCC执行系统cmd命令

gcc -shared -fPIC -o 1.so 1.c

03基础概念

在 windows 平台和 Linux 平台下都大量存在着库。

库,是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

共享库(动态库)的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。动态通常用.so为后缀

-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

译成 x86 架构需要加上 -m32 选项

01目的:恶意shell指令组合,输出结果和错误信息都记录到指定地方/tmp/xx,从而可以被读取显示结果或错误信息

02操作:

cmd >/tmp/xx 2>&1

03基础概念:

2>&1 的意思就是将标准错误重定向到标准输出。

Linux的文件描述符–标准输入输出说明

stdin,标准输入,默认设备是键盘,文件编号为0。

stdout,标准输出,默认设备是显示器,文件编号为1,也可以重定向到文件。

stderr,标准错误,默认设备是显示器,文件编号为2,也可以重定向到文件。

>&重定向符

01目的:设置环境变量的值,传递恶意shell指令以及指定的动态库加载的优先级最高

02操作:

putenv("EVIL_CMDLINE=" . $evil_cmdline); putenv("LD_PRELOAD=bypass_disablefunc_x64.so");

03基础概念:

putenv ( string $setting ) : bool

添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态。如果环境中没有该服务器环境变量,则会临时存在。

EVIL_CMDLINE在环境变量是不存在,人为生成传递函数用

LD_PRELOAD的作用是为优先加载库设置

一般情况下,库加载顺序为LD_PRELOAD>LD_LIBRARY_PATH> /etc/ld.so.cache>/lib>/usr/lib。

LD_PRELOAD、LD_LIBRARY_PATH都为环境变量、/etc/ld.so.cache、/usr/lib为文件目录;

01目的:触发系统执行编写的二进制文件,执行__attribute__ ((__constructor__)) void preload (void);

02操作:

mail(“”, “”, “”, “”);

03基础概念

mail() 函数允许您从脚本中直接发送电子邮件。

注:php代码中只是为了创建新进程,触发系统对LD_PRELOAD的加载,因__attribute__ ((__constructor__)) 属性的函数会优先main函数先执行,实际在该工程中mail不需要第三方sendmail的支持;

01目的:读取存入/tmp/xx的信息

02操作:

nl2br(file_get_contents($out_path))

03基础概念:

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!