相信大家都知道,沙箱识别是一个比较常见的话题,目前的识别方案大多都是基于样本端。例如,常规方法包括硬件检测(CPU核数、输入输出设备、内存)、鼠标移动检测、进程名称、系统服务、开机时间等,无法直观、准确地识别目标服务器是否为流量交互是一个沙盒环境。比如我看到有高手用鼠标移动检查的方法来识别目标是否是沙盒虚拟机环境。那么问题来了。在钓鱼场景中,虽然我们知道目标是PC客户端,有人使用这台电脑,但是当目标是服务器场景时,这种方法就不适用了。运维人员不会一直在每台服务器前操作,所以我们需要一种更优雅的识别方式。当然,沙盒是快照还原,时机一般是有问题的。并且由于睡眠加速,意味着样本端的延迟执行操作将被沙箱逆转。一旦样本被颠倒,样本就处于异常环境中。这时候延迟几秒就可以得到当地时间,可以识别出异常。这当然也是一种很好的反调试方法。但上述操作均在样例端完成,需要自定义脚本实现功能,出现问题后排查比较麻烦。本文将深入浅出地讲解根据流量侧来识别沙箱请求流量的方法。这种方法也更容易部署和有效识别,从而有针对性地对付沙箱分析流量。1TLSJA3指纹在正式讲解流量侧识别云沙箱技术之前,先简单介绍一下TLSJA3(S)指纹的基本概念。JA3为客户端和服务端的加密通信提供了一个识别度更高的指纹,利用TLS指纹识别恶意客户端和服务端的TLS协商,从而达到关联恶意客户端的效果.该指纹采用MD5加密,易于在任何平台生成,目前广泛应用于威胁情报。比如在一些沙箱的样本分析报告中,可以看到例子来证明不同样本之间的相关性。如果能够掌握C2服务器与恶意客户端之间的JA3(S),即使流量被加密,不知道C2服务器的IP地址或域名,我们仍然可以识别出恶意客户端之间的TLS协商和服务器通过TLS指纹。相信大家看到这里都能想到。这也是应对域名前置、反向代理、云函数等隐藏的流量转发手段的一种措施。通过沙箱进行样本识别与C2通信的TLS协商,生成JA3(S)指纹,应用于威胁情报,实现辅助溯源的技术手段。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,0MD5encoding:9ef1ac1938995d826ebe3b9e13d9f83a如上例最终得到并应用的JA3指纹为:9ef1ac1938995d826ebe3b9e13d9f83a和JA3(S)都是TLS指纹,那么它们之间有什么区别呢?一是主动扫描生成JARM指纹,类似FUZZ的效果;另一种是JA3(S)是根据客户端和服务器流量交互识别生成的指纹。2基于流量的云沙箱识别上面简单介绍了JA3(S)指纹的概念,这里的原理与沙箱流量的识别类似。我们需要一个基础设施,可以监控和识别在线主机与C2服务器之间的TLS协商,从而生成请求主机的JA3指纹。这里我们以RedGuard为例。从上图不难看出,RedGuard作为C2服务器与在线主机之间流量交互的代理主机,所有流量都会通过它转发给C2服务器。在这个过程中,我们根据流量侧生成并识别JA3指纹。它是可以实现的。在不修改后端C2设施源代码的基础上,给出了生成和识别JA3指纹的功能。从云沙箱的角度,通过监控样本与C2服务器的流量交互,生成JA3(S)指纹,识别恶意客户端,进行关联。而我们反过来想,作为C2前面的流控设施,我们也可以进行这样的操作,获取客户端请求的JA3指纹,通过在不同的沙箱环境中调试,获取这些JA3指纹,形成指纹库,从而形成基础拦截策略。在测试某厂商的沙箱环境时,发现虽然请求交互的出口IP数量少,但通过IP来识别沙箱并不准确,这是一个容易改变的特性。JA3指纹在环境下是独一无二的。假设在staged木马交互过程中,loader会先拉取远程地址的shellcode,然后当流量识别请求符合JA3指纹库的云沙箱特性时,拦截后续请求.那么shellcode就获取不到,整个加载过程就无法完成,沙箱自然也分析不全。如果环境是stageless木马,那么最终无法在C2服务器上启动沙箱分析。相信大家都有过一觉醒来,C2上有很多超时很久的沙盒记录的经历。当然,理想情况下,我们可以识别不同的沙箱环境,这主要取决于指纹库的可靠性。3网络空间测扫识别测试过程中,指纹库加入了GO语言请求库的JA3指纹,用于监测RedGuard请求流量。可以看出大部分请求触发了对JA3指纹库特征的基本拦截。这里我猜测在其测绘产品的扫描中,底层语言是GO语言来实现大部分的扫描任务。通过一个链接,由不同底层语言组成的扫描逻辑最终完成了整个扫描任务,这就解释了为什么某些测绘产品的扫描会触发GO语言请求库的JA3指纹拦截功能。当然,触发拦截规则的请求会被重定向到指定的URL站点。4后记JA3(S)指纹当然是可以改的,但是会大大增加成本。同样,修改基本功能也不会影响。如果打算用劫持的方式伪造JA3指纹,可能行不通,OpenSSL会验证扩展名。如果和自己发布的不一致,会报错:OpenSSL:error:141B30D9:SSLroutines:tls_collect_extensions:unsolicitedextensionForgedJA3fingerprints可以在以下两个项目中查看:》https://github.com/CUCyber??/ja3transport""https://github.com/lwthiker/curl-impersonate"通常,自定义恶意软件会自行实现TLS。在这种情况下,JA3指纹可以唯一指向它。但是现在研发一般都是用第三方库,不管是Python之类的官方模块还是win下的组件,如果这样的话,那么JA3就会重复,误报率很高。当然,应用到我们的流控设施上,就不用考虑这些固定组件的问题了,因为封装组件不会有正常的请求,大部分都是扫描上面提到的一些语言写的流量.而是将这些语言要求的JA3指纹封装到指纹库中,也可以防止扫描。
