译者:知道创宇404实验室翻译组
原文链接:Định dạng cơ sở dữ liệu của Windows Defender
Windows Defender (WD) 是一款集成于 Windows 10 和 11 中的恶意软件防护产品。随着时间的推移,WD在与Windows在发展过程中展现出了其在检测和阻止个人计算机不同类型的恶意软件的有效性。在本文中,我们将探讨WD使用的数据库结构(CSDL),以提取其中的数据以更深入了解该CSDL的格式以及其中的一些识别标志类型。
1.Windows Defender数据库文件结构
通常,个人计算机上的WD版本将有4个扩展名为.VDM的CSDL文件和一个负责加载和使用这些CSDL的dll文件。这些文件将存储在%ProgramData%\Microsoft\Windows Defender\Definition Updates[GUID]路径下。主要是:
- mpasbase.vdm:AntiSpyware 模块的数据库
- mpasdlta.vdm:更新到 AntiSpyware 数据库
- mpavbase.vdm:防病毒模块的数据库
- mpavdlta.vdm:更新防病毒数据库
VDM 文件本质上是包含资源(一种特殊类型的 DLL)的 DLL 文件,Microsoft 通过它在不同程序之间来共享数据源。这些DLL不包含任何可执行代码,只包含PE文件的头部和资源中的数据部分。WD 使用的数据库的主要内容位于名为 RT_RCDATA 的资源中。
这个资源是有结构的数据段,其中一部分头部数据包含以下字段:
typedef struct _RMDX_HEADER {
ULONG Signature; //0
ULONG Timestamp; //4
ULONG Unknown1; //8
ULONG Options; //12 (0C)
ULONG Unknown2; //16
ULONG Unknown3; //20
ULONG DataOffset; //24 (18)
ULONG DataSize; //28 (1C)
//incomplete, irrelevant
} RMDX_HEADER, *PRMDX_HEADER;
已知的一些字段在结构中包括:
- Signature:4字节的‘RMDX’;
- Options:包含CSDL的属性,目前提取CSDL仅支持带有压缩属性的vdm文件;
- DataOffset:指向使用zlib压缩的数据部分的偏移量;
- DataSize:压缩数据段的大小。
DataOffset指向的数据包含压缩数据大小及压缩数据的信息的结构。根据这两条信息,我们可以解压VDM中的CSDL,来研究其内部内容。
typedef struct _CDATA_HEADER {
ULONG Length; //0
ULONG Unknown1; //4
union { //8
BYTE Data[1];
ULONG Unknown2;
} u1;
} CDATA_HEADER, *PCDATA_HEADER;
解压后的数据可以作为包含结构化签名元素的数据数组来集成进行读取:
struct {
uint8_t sig_type;
uint8_t size_low;
uint16_t size_high;
uint8_t value[size_low | size_high << 8];
} sig_entry;
sig_type是这个签名元素的数据类型,结合size_low和size_high,可以得到包含签名的数据段的大小,也就是该元素中剩余的数据大小。可以看出,每个签名的大小并不是固定的,需要依靠当前元素的大小来确定下一个元素。新解压的 VDM 数据示例:
第一个签名:
- 签名类型:0x5c
- 大小:0x1e
- 签名数据:大小为 0x1e 的数组(45060000…..24000400)
接下来是第二个签名:
- 签名类型:0x40
- 大小:0x45
- 签名数据:大小为 0x45 的数组(04000103…..fe00000000)
……
签名类型是根据 mpengine.dll 中的函数确定的。该函数接收 sig_type 值进行输入,然后返回与接收到的 sig_type 对应的字符串。
sig_type 字段的数据类型为 uint8,因此值从 0 到 0xff。然而并不是每个值都对应一个签名类型,有些值会被分配“SIGNATURE_TYPE_UNKNOWN”类型。有效的签名类型大约有158种,但大多数数据库并不包含所有这些签名类型,只包含50到100种签名类型。
2.VDM数据库中的一些签名类型
在本节中,我们将探讨某些类型的 sig 如何存储在 VDM 文件中。在读取VDM文件之前,mpengine会通过AutoInitModules::AutoInitModules函数初始化模块。
module_list 变量是一个模块结构数组,包括描述、初始化函数、清理函数和包含标志 0 或 1的 QWORD。
当前版本中,有399个不同的模块,其中159个模块的flag为1,其余模块的flag为0,每个模块的构造函数都可以设置回调进行处理,每种类型的签名都对应。
2.1 SIGNATURE TYPE THREAT BEGIN
Signature类型SIGNATURE_TYPE_THREAT_BEGIN将由threatmgr模块处理。
每个SIGNATURE_TYPE_THREAT_BEGIN元素都包含有关特定威胁的描述。该元素的数据结构如下所示:
struct THREAT_BEGIN
{
char unknow_metadata[0xa];
unsigned __int16 nameSize;
char name[name_size];
// unknow data
}
每个SIGNATURE_TYPE_THREAT_BEGIN之后的签名元素将是此威胁的多个其他类型的签名。当遇到一个具有SIGNATURE_TYPE_THREAT_END形式的签名元素时,其范围将被确定。
如:可以理解VDM文件中的以下数据描述了一个名为MonitoringTool:Win32/ActiveKeylogger 的行为,其中包括2个类型为PEHSTR_EXT的签名。
2.2 SIGNATURE TYPE PEHSTR
Signature类型 PEHSTR 和其他一些类型由 cksig 模块处理。
cksig_init_module 函数将调用 pattsearch_init,然后注册回调(hstr_push、hstr_pushend_common),以在这些签名开始加载后调用此类型签名的函数。
可以将每个PEHSTR元素暂时视为以下结构化数据:
struct string_data
{
WORD reversed0;
char string_size;
char str[1];
} string_data;
typedef struct PEHSTR
{
WORD count_1;
WORD count_2;
WORD count_3;
char reversed_0;
string_data s_data[1];
} PEHSTR, *PPEHSTR;
每个 PEHSTR sig 可以粗略地理解由多个不同的字符串组成,如下所示:
对于只使用PEHSTR模式来识别恶意代码的威胁,我们可以知道windefender的恶意代码的检测标志,将其用于增强检测规则或寻找方法来隐藏这些字符串,来避免在静态签名扫描中被Windows Defender检测到。
还有很多结构比较复杂的标志需要进一步研究,以下是一个从vdm文件(mpengine版本1.1.20200.4,db版本1.387.0.0,然后用WDExtract解压)中提取数据为data.csv格式的脚本,供大家参考参考。
3. 参考链接
- https://github.com/commial/experiments/tree/master/windows-defender/VDM
- https://github.com/hfiref0x/WDExtract
- https://github.com/taviso/loadlibrary
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/3045/