恶意软件狩猎新途径:使用.NET元数据分析跟踪恶意软件

2024-04-25 06:44

本文主要是介绍恶意软件狩猎新途径:使用.NET元数据分析跟踪恶意软件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文由Blaze于2024年3月25日发表于其个人博客网站上。

就在不久前,我们意外发现了一个PureCrypter样本,而PureCrypter则是一款适用于各种类型恶意软件(例如Agent Tesla和RedLine)的加载器和混淆处理工具。深入分析之后,我还专门为该样本编写了Yara检测规则,当时我便意识到,我是不是也可以写一些Yara规则来识别.NET开发的恶意软件或.NET程序集。

在这篇文章中,我将跟大家分享如何使用.NET元数据分析、跟踪和分类恶意软件的相关内容。

背景概述

.NET程序集或二进制文件通常包含各种元数据,例如内部程序集名称和GUID,尤其是MVID和TYPELIB:

GUID:也被称为TYPELIB ID,会在创建一个新项目时生成;

MVID:模块版本ID,.NET模块的唯一识别符;

TYPELIB:TYBELIB版本,或类型库编号;

这些特定的识别符可以使用strings命令下列正则表达式来解析:

[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}

我们以PureLogStealer的一个样本为例,基于MVID或Typelib来编写一个Yara规则。VirusTotal上的样本检测信息如下:

对应的Yara规则如下:

rule PureLogStealer_GUID{strings:$mvid = "9066ee39-87f9-4468-9d70-b57c25f29a67" ascii wide fullwordcondition:$mvid}

但现在存在的问题如下:

1、MVID会以二进制值的形式存储,而不是以字符串形式,同时Typelib GUID是以字符串形式存储的,由于我们这里只有MVID,因此该规则无法检测上面给出的这个样本;

2、VirusTotal似乎并没有报告Typelib;

3、使用字符串和正则表达式“手动操作”很麻烦,尤其是在较大的数据集上,而且容易出现假阳性和假阴性问题;

需要注意的是,在IlSpy或dnSpy(Ex)之类工具的帮助下,我们是可以查看到Typelib GUID和MVID的,但并不是所有的工具都会显示所有的数据,比如说:

如果我们使用ildasm来查看到话,会得到如下所示的信息:

针对上述所有的原因,我们要想办法解决,解决方案就是Yara规则结合我所开发的一个新Python工具。

解决方案和工具

在介绍解决方案和我的工具之前,我不得不提一下,多亏了Yara规则一直在进化,并且引入了下列新的模块,我们现在才能够更加有效地检测和捕捉恶意软件样本:

2017:引入.NET模块;【传送门】

2022:引入console模块;【传送门】

这也就意味着,在.NET模块的帮助下,我们现在可以按照下列方式来写Yara规则了:

import "dotnet"rule PureLogStealer_GUID{condition:dotnet.guids[0]== "9066ee39-87f9-4468-9d70-b57c25f29a67"}

检测样本:

Yara规则

现在我们可以利用Yara的强大能力,以及dotnet和console模块来编写一个新的Yara规则,并显示给定.NET样本的全部有用信息,例如程序集名称、Typelib和MVID:

首先,我们需要验证目标二进制代码是否是一个.NET编译文件,如果是,记录下特定的PE或代码信息,然后显示所有相关的.NET信息。上述样本的Yara规则数据(元数据)如下:

这也就意味着,我们现在可以编写下面这样的Yara规则:

import "dotnet"rule PureLogStealer_GUID{condition:dotnet.guids[0]=="9066ee39-87f9-4468-9d70-b57c25f29a67" ordotnet.typelib=="856e9a70-148f-4705-9549-d69a57e669b0"}

Python工具

那么,如果我想要对大规模样本集执行检测,并生成统计数据,然后进行恶意软件家族跟踪和分类的话,该怎么办呢?

为此,我专门开发了一个Python工具,这个工具就可以解决我们的需求问题。它支持输入一个文件、整个样本文件夹或恶意软件代码库,该工具会跳过任意非.NET代码,并报告Typelib、MVID和Typelib ID。

针对单个样本的工具执行结果如下:

该工具的帮助信息如下:

当然了,该工具并不仅限于搜索.NET恶意软件的MVID或Typelib,你也可以使用使用它并结合Yara和Python来提取各种你需要的信息。相关的Yara规则和Python工具(DotNet-MetaData )已经发布在【GitHub】上,有需要的研究人员可以自行访问下载。除此之外,广大研究人员也可以根据自己的需求对工具进行自定义开发和调整,以获取和显示更多的信息。

集群

跟踪威胁行为者的活动,一直以来都是研究人员的常规挑战之一,虽然有的时候会很有趣,但绝大多数都是枯燥乏味的。下面给出的是我遇到的一个恶意软件集群活动示例:

这里涉及到大量的样本集(1300个),主要针对的是SteamStealer。

针对我们的分析目标,我选择了目前四个比较热门的恶意软件(基于.NET或拥有.NET变种版本)进行分析:

RedLine

Agent Tesla

Quasar

Pure*(与PureCrypter, PureLogs等相关)

下载并使用DotNetMetadata分析后,我们会得到如下图所示的结果。

RedLine(56个样本)

RedLine Typelib GUID频率:

RedLine MVID频率:

Agent Tesla(140个样本)

Agent Tesla Typelib GUID频率:

Agent Tesla MVID频率:

Quasar(141个样本)

Quasar Typelib GUID频率:

Quasar MVID频率:

Pure*家族(194个样本)

Pure*  Typelib GUID频率:

Pure* MVID频率:

上述的饼状图能够显示相同Typelib或MVID出现的频率和情况,同时我们也可以利用这些饼状图数据来为每个恶意软件样本集群创建有效的Yara检测规则。

你可能会认为,这些饼状图不会特别有效,因为如果数据集再大一些的话,缩放会比较困难。但是,我们可以通过限制显示的结果数量,来获取更好的结果。上述四个恶意软件家族样本数据集中,总共有531个样本,再次运行可视化处理后,我们将进行下列操作:

1、针对整个样本集执行分析;

2、提取程序集名称;

3、仅列出排名前十的程序集名称;

4、使用柱状图代替饼状图;

结果如下图所示:

排名前三的为:

1、“Client”:Quasar家族;

2、“Product Design 1”:Pure家族;

3、“Sample Design 1”:Pure家族;

“Client”貌似是Quasar恶意软件编译时使用的默认程序集名称,而“Product Design”和“Sample Design”则可能是PureCrypter构建器的默认程序集名称。

接下来,我们就可以根据默认程序集名称为Quasar编写一个Yara规则:

import "dotnet"rule Quasar_AssemblyName{condition:dotnet.assembly.name == "Client"}

我们还可以构建Yara规则来对我们的恶意软件数据集或存储库进行分类:

import "dotnet"import "console"rule DotNet_Malware_Classifier{condition:(dotnet.assembly.name == "Client" and console.log(“Likely Quasar, assembly name: ", dotnet.assembly.name)) or(dotnet.assembly.name == "Product Design 1" and console.log("Likely Pure family, assembly name: ", dotnet.assembly.name)) or(dotnet.assembly.name == "Sample Design 1" and console.log("Likely Pure family, assembly name: ", dotnet.assembly.name))}

针对Pure家族和Quasar合并样本运行新的Yara规则后,分类结果输出如下:

我们可以将基于程序集名称、Typelib、MVID等的Yara规则集组合起来,创建具有更高置信度的规则,并将其用于进一步的恶意软件搜索和分类等操作。

意外收获

既然已经走到了这里,我们再努力一下!现在,我们可以尝试去寻找新的加密器或混淆处理器了。

当我使用工具脚本对500+个样本执行测试时,有一个程序集/代码吸引了我的注意:

针对它写一个简单的Yara规则:

import "dotnet"rule cronos_crypter{strings:$cronos = "Cronos-Crypter" ascii wide nocasecondition:dotnet.is_dotnet and $cronos}

Unpac.me Yara捕捉结果:

由此看来,这个加密器(Cronos-Crypter)似乎并不是很受欢迎。目前为止,只有两个Async RAT样本和两个PovertyStealer样本使用了它。

通过审查Async RAT并改进之前的“分类规则”,我们看到这个加密器至少在两个Async RAT样本上使用过,基于86个样本,我们得到了下列统计数据:

我们得到了下列程序集名称:

AsyncClient

Client(Quasar中也有)

XClient

Output

Loader

Stub

AsyncClient很可能是Async RAT项目的默认名称,针对该样本的Yara规则优化版本如下:

import "dotnet"import "console"rule DotNet_Malware_Classifier{condition:(dotnet.assembly.name == "Client" and console.log("Suspicious assembly name: ", dotnet.assembly.name)) or(dotnet.assembly.name == "Output" and console.log("Suspicious assembly name: ", dotnet.assembly.name)) or(dotnet.assembly.name == "Loader" and console.log("Suspicious assembly name: ", dotnet.assembly.name)) or(dotnet.assembly.name == "Stub" and console.log("Suspicious assembly name: ", dotnet.assembly.name))}

分类器Yara规则结果如下:

总结

在这篇文章中,我们主要介绍了两种用于从.NET恶意软件中提取元数据的技术方法和工具,简而言之,就是通过可靠的方法提取两个唯一GUID(Typelib和MVID)来识别恶意软件。

我们提供的Python脚本可以从大量.NET程序集中提取出所需的数据,广大研究人员可以根据实际情况调整大型集合的Yara规则,并扩展脚本以获取更多有价值的数据。

你可以在下列存储库中找到本文涉及到的工具和Yara规则示例:

GitHub - bartblaze/DotNet-MetaData: Identifies metadata of .NET binary files.

最后,祝大家恶意软件“狩猎”愉快!

参考资料

PureCrypter (Malware Family)

https://twitter.com/James_inthe_box/status/1767548157003743382

https://twitter.com/James_inthe_box

VirusTotal

CyberChef

Release YARA v3.6.0 · VirusTotal/yara · GitHub

Release YARA v4.2.0 · VirusTotal/yara · GitHub

GitHub - bartblaze/DotNet-MetaData: Identifies metadata of .NET binary files.

GitHub - TalosSec/Cronos-Crypter: Cronos Crypter is an simple example of crypter created for educational purposes.

参考链接

https://bartblaze.blogspot.com/2024/03/analyse-hunt-and-classify-malware-using.html

这篇关于恶意软件狩猎新途径:使用.NET元数据分析跟踪恶意软件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/933959

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud