Normal view

There are new articles available, click to refresh the page.
Before yesterdayNoah Lab

云沙箱流量识别技术剖析

By: 风起
13 July 2022 at 09:02

作者:风起

日期:2022年7月13日

前言

​大家好,我是风起,本次带来的是基于流量的沙箱识别技术。相信大家都知道,沙箱识别是老生常谈的话题了,目前大部分的识别方案都是基于样本侧去完成的,例如常规方式:硬件检查(CPU核心数、输入输出设备、内存)、鼠标移动检查、进程名、系统服务、开机时长等,都不能直观准确的识别出目标进行流量交互的服务器是否是沙箱环境。举个例子,之前看到有师傅使用鼠标移动检查的方式去识别目标是否是沙箱虚拟机环境,那么问题来了,这种方式在钓鱼的场景下我们知道目标是PC客户端有人使用这台电脑,但是对于目标是服务器场景的情况下这种方法就不适用了,运维人员并不会时刻都在每台服务器跟前操作,所以我们需要一种更加优雅的识别方式。

​当然沙箱是快照还原,时间一般都存在问题的并且会进行sleep加速,也就是说这时候在样本恻进行延迟执行操作会被沙箱反调,一但样本被反调了,那么其样本就是所处异常环境下,这时候进行延迟几秒后获取本地时间就能够识别出异常,这当然也是一种很好的反调试手段。但是,上述这些操作都是在样本侧完成的,抛开需要定制化脚本实现功能,出现问题后进行排查等等都会比较麻烦。

本文将深入浅出的讲解基于流量侧对沙箱请求流量进行识别的方法,这种方法也能更易部署且有效识别,从而针对性的反制沙箱分析流量。

TLS JA3指纹

正式讲解流量侧识别云沙箱技术之前,我们先简述一下TLS JA3(S)指纹的基本概念。

​JA3为客户端与服务器之间的加密通信提供了识别度更高的指纹,通过 TLS 指纹来识别恶意客户端和服务器之间的 TLS 协商,从而实现关联恶意客户端的效果。该指纹使用MD5加密易于在任何平台上生成,目前广泛应用于威胁情报,例如在某些沙箱的样本分析报告可以看到以此佐证不同样本之间的关联性。

如果可以掌握 C2 服务器与恶意客户端的JA3(S),即使加密流量且不知道 C2 服务器的 IP 地址或域名,我们仍然可以通过 TLS 指纹来识别恶意客户端和服务器之间的 TLS 协商。相信看到这里大家就能想到,这也正是对付域前置、反向代理、云函数等流量转发隐匿手段的一种措施,通过沙箱执行样本识别与C2之间通信的 TLS 协商并生成JA3(S)指纹,以此应用于威胁情报从而实现辅助溯源的技术手段。

1657001961778

JA3 通过对客户端发送的ClientHello 数据包中的以下字段收集字节的十进制值:

  • SSL 版本
  • 接受的密码
  • 扩展列表
  • 椭圆曲线
  • 椭圆曲线格式

然后它将这些值按顺序连接在一起,使用“,”分隔每个字段,使用“-”分隔每个字段中的每个值。

示例:

771,39578-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,56026-29-23-24,0

MD5编码:9ef1ac1938995d826ebe3b9e13d9f83a

如上示例,最终得到并应用的JA3指纹即 9ef1ac1938995d826ebe3b9e13d9f83a

问题拓展:

之前文章提到的JARM与JA3(S)都是TLS指纹,那么他们的区别是什么呢?

  • JARM指纹是主动扫描并生成指纹的,类似FUZZ的效果
  • JA3(S)是基于客户端与服务端流量交互识别并生成的指纹

基于流量的云沙箱识别

​上面简述了JA3(S)指纹的概念,这里应用到识别沙箱流量也是类似的原理,我们需要一个基础设施可以监控识别 上线主机和C2服务器之间的TLS 协商,从而生成请求主机的JA3指纹,这里我们以RedGuard举例。

image-20220705144302701

通过上图不难看出,RedGuard充当着C2服务器与上线主机流量交互的代理主机,所有的流量都会经由它转发到C2服务器上,那么在这个过程中,我们基于流量侧生成并识别JA3指纹的想法就可以实现了,在不修改后端C2设施源码的基础上,赋予了生成识别JA3指纹的功能。

275170ac767c89ad4c8f30fa5b47c5b

在云沙箱的立场上,通过监控样本与C2服务器之间流量交互生成JA3(S)指纹识别恶意客户端从而进行关联,而我们逆向思考,同样作为C2前置的流量控制设施,我们也可以进行这样的操作获取客户端请求的JA3指纹,通过对不同沙箱环境的调试获取这些JA3指纹形成指纹库从而形成基础拦截策略。

在测试某厂商沙箱环境时发现,其请求交互的出口IP虽然数量不大,但是通过IP识别沙箱并不准确,并且这是很容易改变的特征,但是其在多种不同配置的相同系统环境下JA3指纹是唯一的,效果如上图。

设想在分阶段木马交互的过程中,加载器会首先拉取远程地址的shellcode,那么在流量识别到请求符合JA3指纹库的云沙箱特征时,就会进行拦截后续请求。那么无法获取shellcode不能完成整个加载过程,沙箱自然不能对其完整的分析。如果环境是无阶段的木马,那么沙箱分析同样无法最终上线到C2服务器上,相比大家都有睡一觉起来C2上挂了一大堆超时已久的沙箱记录吧,当然理想状态下我们可以对不同沙箱环境进行识别,这主要也是依赖于指纹库的可靠性。

识别网络空间测绘扫描

在测试的过程中,我发现在指纹库添加GO语言请求库的JA3指纹后监测RedGuard请求流量情况,可以看到,大部分的请求触发了JA3指纹库特征的基础拦截,这里我猜测其测绘产品在该扫描中底层语言是以GO语言实现的大部分扫描任务,通过一条链路,不同底层语言组成的扫描逻辑最终完成了整个扫描任务,这也就解释了部分测绘产品的扫描为什么触发了GO语言请求库的JA3指纹拦截特征。

1657007702279

当然,触发拦截规则的请求都会被重定向到指定URL站点。

后记

​ JA3(S)指纹当然是可以更改的,但是会很大程度提高成本,同样修改基础特征无法对其造成影响,如果准备用劫持的方式去伪造 JA3指纹,并不一定是可行的,OpenSSL 会校验 extension,如果和自己发出的不一致,则会报错:OpenSSL: error:141B30D9:SSL routines:tls_collect_extensions:unsolicited extension

伪造JA3指纹可以看以下两个项目:

通常自主定制化的恶意软件会自己去实现 TLS,这种情况下JA3指纹可以唯一的指向它。但是现在研发一般都会用第三方的库,不管是诸如 Python 的官方模块还是 win 下的组件,如果是这种情况,那么 JA3就会重复,误报率很高。当然应用到我们的流量控制设施其实不需要考虑这些固定组件的问题,因为并不会有正常的封装组件的请求,多数也是上面提到某些语言编写的扫描流量,反而以此对这些语言请求的JA3指纹封装进指纹库也能起到防止扫描的效果。

参考链接:

https://github.com/wikiZ/RedGuard

https://www.tr0y.wang/2020/06/28/ja3/

https://engineering.salesforce.com/tls-fingerprinting-with-ja3-and-ja3s-247362855967/

JARM指纹随机化技术实现

By: 风起
30 June 2022 at 09:17

作者:风起

时间:2022年6月30日

基于JARM指纹的C2识别

​ JARM的工作原理是主动向目标TLS服务器发送10个特殊构造的TLS Client Hello包,以在TLS服务器中提取独特的响应,并捕获TLS Server Hello响应的特定属性,然后以特定的方式对聚合的TLS服务器响应进行散列,产生JARM指纹。

因为Client Hello中的参数不同,最终返回的Server Hello都是不相同的,通过发送特殊构造的Client Hello握手包,以获取与之对应的特殊Server Hello响应,以此作为依据,最终产生TLS Server指纹。

JARM以不同的顺序发送不同的TLS版本、密码和扩展,以收集唯一的响应。

  • 服务器是否支持TLS 1.3协议?
  • 它会用1.2密码协商TLS 1.3吗?
  • 如果我们将密码从弱到强排序,它会选择哪个密码?

这些是JARM本质上要求服务器提取最独特响应的异常问题类型。然后对这10个响应进行哈希处理以产生JARM指纹。

TLS Client Hello请求流量

Wireshark Filter:

ssl.handshake.type == 1
1

TLS Server Hello响应

1

多数情况下JARM指纹都是用以佐证TLS服务并进行标记,从而关联服务。当然,最理想的状态下,我们能够通过JARM指纹唯一的指向目标C2设施,但是实际来讲JARM指纹对于不同服务器部署的C2设施并不是唯一的,有很多因素都会对其扫描的结果造成影响。所以我们并不能作为行为测绘的指纹直接关联到某个C2的服务,仅能起到佐证的效果。

在开发RedGuard的过程中我发现,因为本身来讲RG的作用就是进行前置流量的控制,从而实现后端C2服务的隐匿性,在蓝队对流量交互进行分析的时候,针对RG的JARM指纹扫描结果在多数差异的环境下都是相同的,也就是说,在分析的过程中,这个指纹是可以起到佐证攻击设施的作用,从而破坏我们想要预期达到的隐匿性。

基础设施的更改(例如,IP 地址、托管平台)不会影响JARM签名,这使得常规的方式难以对其进行规避。

影响服务端JARM指纹的因素:

  • 操作系统及版本
  • 使用的库及版本
  • 调用库的顺序
  • 自定义配置
  • ........

也就是说,如果我们想要影响最终针对服务端的JARM指纹扫描结果,我们就要从上面的几个因素入手去做,目前的解决方案共有两种:

一、重播TLS Server Hello响应

二、更改TLS Server配置CipherSuites加密套件

第一种方式也就是在监听特定客户端 Hello 的 TCP 服务器,然后在C2服务器上捕获这些特定的Client Hello(每个请求都有重复的字节,使用这些字节来识别每个特定的Client Hello握手包),稳定的对这10个特殊构造的Client Hello的响应进行重播,从而实现改变真实JARM指纹的效果。

if bytes.Contains(request, [] byte { 
     0x00, 0x8c, 0x1a, 0x1a, 0x00, 0x16, 0x00, 0x33, 0x00, 
     0x67, 0xc0, 0x9e, 0xc0, 0xa2, 0x00, 0x9e, 0x00, 0x39 
     , 0x , 0xc0, 0x9f, 0xc0, 0xa3, 0x00, 0x9f, 0x00, 
     0x45, 0x00, 0xbe, 0x00, 0x88, 0x00, 0xc4, 0x00, 0x9a, 
     ... ... 
}) { 
     fmt.Println("replaying: tls12Forward ") 
     conn.Write([] byte { 
         0x16, 0x03, 0x03, 0x00, 0x5a, 0x02, 0x00, 0x00, 
         0x56, 0x03, 0x03, 0x17, 0xa6, 0xa3, 0x84, 0x80, 
         0x0b, 3,d, 0xbb, 0x 0xe9, 0x3e, 0x92, 0x65, 
         0x9a, 0x68, 0x7d, 0x70, 0xda, 0x00, 0xe9, 0x7c, 
         ... ... 
     }) 
}

在对所有十个不同的请求实施回复后,可以伪造完整的签名。

1

​ 这是一种比较懒惰的办法了,最终的效果确实能够对JARM扫描的结果进行混淆,但是我认为太过单调,需要注意的是ServerHello的原始响应他不能进行任意修改,因为在工具开发中流量的正常交互才是最重要的,任意修改上述一些影响 JARM扫描的因素可能导致无法正常通信的问题出现。也就是说他所重播的这些ServerHello数据包是需要监听某个正常的服务的JARM扫描响应来实现的,并不适合我们应用到工具去实现混淆的效果,我们需要一种简单而又稳定的方法。

当然,这种方式还有一种延伸,就是首先随机获取正常站点的列表进行JARM指纹扫描,从而获取其ServerHello响应然后,直接作为识别到JARM扫描握手包的响应包进行重播,这样是最合理的一种方式。

​ 第二种也就是阿姆斯特丹2021 HITB议题《COMMSEC: JARM Randomizer: Evading JARM Fingerprinting》中提到的一种方式,作者在github上对衍生工具 JARM Randomizer进行了部分开源,通过阅读它的代码不难看出,其实与我最初想到的方式非常相像,最终影响JARM的因素使用的是CipherSuites加密套件(加密算法套件 CipherSuite 由各类基础加密算法组成)**

实现代码:

1

如上图,针对反向代理的TLS Config CipherSuites的设置,我提供了15种不同的加密套件方式,1/2/3....个不同组合的加密套件最终得到的JARM指纹结果都不是相同的(加密套件过多会导致无法正常通信的玄学问题),这里我对这15种加密套件进行随机组合的方式,1-2个随机取值进行组合这些CipherSuites,大概会有几十种不同的随机JARM指纹产生。

最终效果如下:

1

可以看到,最终应用在工具的效果就是在每次启动RG的时候,它的JARM指纹都不是相同的,会自动根据上述的混淆方式产生一个全新的JARM指纹,可以防止空间测绘的扫描,以此关联公网上RG基础设施的部署情况。目前市面上多数测绘平台都会进行集成并默认进行JARM指纹的扫描,可能也是因为其扫描效率快,扫描资源成本低、同时又对C2设施有着一定的佐证指向性的原因吧。

RedGuard是一款C2基础设施前置流量控制设施,可以规避Blue Teams、AVs、EDRs检查。

参考链接:

https://github.com/wikiZ/RedGuard

https://github.com/netskopeoss/jarm_randomizer

https://grimminck.medium.com/spoofing-jarm-signatures-i-am-the-cobalt-strike-server-now-a27bd549fc6b

https://conference.hitb.org/hitbsecconf2021ams/sessions/commsec-jarm-randomizer-evading-jarm-fingerprinting/

❌
❌