赞
踩
某天,同事编写的软件更新后,居然被微软自家的杀毒软件即 Windows Defender 识别为病毒,引起了我的好奇,到底是什么样的二进制特征,引发了 AV(AntiVirus)杀毒软件的告警?
计算机病毒在二十世纪 90 年代以后出现,随着计算机的普及而被大众所知晓。而如今,安全人员更喜欢”恶意软件“、”威胁“替代,所以杀毒软件,杀的是恶意软件,病毒只是其中的一种。
病毒是一种特定类型的恶意软件,能够感染正常文件。因此,从民众认知的角度上来说,病毒可以广义上替代恶意软件;从安全领域来说,病毒只是恶意软件的子集。 一个恶意软件,是不是病毒,对于普罗大众来说没有绝对正确的对错之分。为了方便,后文也不会区分具体的概念。
很多反病毒软件,包括 Windwos Defender Antivirus,通过扫描文件是否与一组预定属性匹配,检测该文件是否是恶意软件。这样的一组属性,我们称之为签名。
防病毒软件的病毒签名,实际上并没有统一定义。卡巴斯基 Viruses, signatures, disinfection 的一篇博客讲述了从 1980 年开始,签名作为一个概念就没有明确定义。直至今日,病毒签名更像是一个安全领域的基础概念,而非是一个晦涩难懂的词汇。
Malware 签名有多种格式,最常见的是 yara,安全专业人员可以使用的一些流行的恶意软件存储库包括 VirusTotal、Malpedia 和 MalShare,静态分析恶意软件的签名。
威胁是指某一类特定的恶意软件家族,也就是Windows Defender Antivirus (微软反病毒软件)弹框提示,如下所示,就是指 Trojan: MSIL/Cryptor 的恶意软件家族,微软官方有对恶意软件命名规则的解释。
可以简单理解为,一种威胁对应一种恶意软件。
Defender 提供多个 Powershell 命令,用于管理 Defender
PS C:\Users\Q> Get-Command -Module Defender CommandType Name Version Source ----------- ---- ------- ------ Function Add-MpPreference 1.0 Defender Function Get-MpComputerStatus 1.0 Defender Function Get-MpPreference 1.0 Defender Function Get-MpThreat 1.0 Defender Function Get-MpThreatCatalog 1.0 Defender Function Get-MpThreatDetection 1.0 Defender Function Remove-MpPreference 1.0 Defender Function Remove-MpThreat 1.0 Defender Function Set-MpPreference 1.0 Defender Function Start-MpRollback 1.0 Defender Function Start-MpScan 1.0 Defender Function Start-MpWDOScan 1.0 Defender Function Update-MpSignature 1.0 Defender
我们可以通过 Defender 提供的 Get-MpThreatCatalog
命令,查看已定义的威胁列表
恶意软件威胁 ID 和威胁名称也可以通过微软在线网站查阅,在如下 URL 中指定 threadid
或者 name
都可以查到相应的恶意软件家族,但是网站并没有给出具体信息。
https://www.microsoft.com/en-us/wdsi/threats/malware-encyclopedia-description?name=Dialer:Win32/Aconti&threatid=1605
BlackHat USA 2023 年有一篇来自 SafeBreach Labs team 的研究 Defender Pretender: When Windows Defender Updates Become a Security Risk,讲述如何逆向分析 Windows Defender 签名文件的格式。微软的反病毒软件的签名保存在如下四个文件中
mpasbase.vdm
mpasdlta.vdm
mpavbase.vdm
mpavdlta.vdm
SafeBreach 实验室开发的 wd-pretender 可以对微软的病毒签名文件,解压后按照预定格式解析,可以删除某个恶意软件的签名。我们添加了一个打印签名的功能,可以直接导出某个威胁的所有签名。
D:\tmp\wd-pretender>"D:\Program Files\Python11\python.exe" D:\tmp\wd-pretender\wd-pretender.py getsign HackTool:Win64/Mimikatz.A -- Defender-Pretender: v1.0.0 (SafeBreach Labs) -- [+] Getting Signatures Location ... [+] Definitions Path: C:\ProgramData\Microsoft\Windows Defender\Definition Updates\{C59E161E-1458-4CDB-B3EF-770E6C0BD6A5} [+] Loading mpasbase.vdm [+] Loading mpasdlta.vdm [+] Loading mpavbase.vdm [+] Loading mpavdlta.vdm [+] Threats Containing: HackTool:Win64/Mimikatz.A threat => b'HackTool:Win64/Mimikatz.A' threat Id => 2147723337 signature count => 147 b'4bbb6301ffee04acdc86fb300086130001201487095e' b'a40304047ab76ddd390c41b50046110001201a5d81e1' b'2edbff0bde43a84cb29af8d40080030001209a9043cf' b'8fd8010c63011493cc7fbaf71f470b00012091c584be' b'5c9c340da6edb6b1532f3a0d0058120001204e565169'
遗憾的是,我们可以用工具导出 Windows Defender Antivirus 的签名,但是这里的签名仅仅是一个类似于哈希的二进制序列,仅仅有这样一个签名(标签),我们仍然无法将恶意软件归类到某一个威胁。
Windows Defender Antivirus 提供的签名,并不能直接关联到某个二进制特征,SafeBreach 实验室并没有进一步解释 Defender 如何利用这些签名,模糊匹配到特定的规则。好在知名安全研究员 Camille Mougey 先前已分析 Windows Defender’s VDM Format,并介绍这些签名是如何工作的。
一个恶意软件威胁可能会有多个签名,也就是说同一个恶意软件会有多个特征,这也很容易理解,毕竟静态识别恶意软件也可以有多个角度。从 Camille Mougey 统计的签名类型来看,通过字符串来匹配恶意软件,占比很小,因此想直接通过签名包含的字符串直接找到恶意软件,这种最为原始的签名方法,可能比较困难了。
通过上一章节 SafeBreach 实验室的 wd-defender 工具,扫描的结果也可以看到,103(SIGNATURE_TYPE_STATIC)静态类型的签名,占比最大。
[+] Threats Containing: HackTool:Win64/Mimikatz.A
threat => b'HackTool:Win64/Mimikatz.A'
threat Id => 2147723337
signature count => 148
(b'4bbb6301ffee04acdc86fb300086130001201487095e', 103)
(b'a40304047ab76ddd390c41b50046110001201a5d81e1', 103)
(b'2edbff0bde43a84cb29af8d40080030001209a9043cf', 103)
(b'8fd8010c63011493cc7fbaf71f470b00012091c584be', 103)
当然,Camille Mougey 的研究主要是通过逆向手段告诉我们 Windows Defender Antivirus 文件签名通过一个复杂匹配关系,最终找到恶意软件,至于每种签名与实际规则的对应关系,仍然是模糊的。
在看过 Bypass Windows Defender’s Signature Based Detection 之后,我尝试自己用文章中描述的方法将二进制逐个拆解,最终找到实际触发 Defender 病毒特征匹配的三个字节。
样本来自 mimikatz/Win32 的 mimidrv.sys
,mimikatz 是一个寻找 Windows 系统密码哈希的工具,被 Defender 标记为恶意软件。
步骤一:不停分割目标二进制
def split_binary_file(file_path, new_file,start_pos, length):
with open(new_file, 'wb') as newfile:
with open(file_path, 'rb') as file:
file.seek(start_pos) # 移动到起始位置
data = file.read(length) # 读取指定长度的数据
newfile.write(data)
# 使用示例
file_path = 'd:\\tmp\mimidrv.sys' # 文件路径
start_pos = 0 # 起始位置(字节)
length = 1400 # 要读取的字节长度
binary_data = split_binary_file('d:\\tmp\mimidrv.sys', 'd:\\tmp\mimidrvnew.sys', start_pos, length)
步骤二:使用 Defender 不停判断分割后的二进制有没有触发反病毒软件
"C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType 3 -File D:\tmp\mimidrvnew.sys -Trace -Level 0x20
Scan starting...
Scan finished.
Scanning D:\tmp\mimidrvnew.sys found 1 threats.
Cleaning started...
Cleaning finished.
通过这种方式,最终定位到如下 3 个字节是实际触发病毒引擎的地方
本来想自己将这种寻找病毒特征的方法,工具化,后来发现 DefenderCheck 已经为我们做好了一切。逃避 AV 签名的一种方法是暴力破解它们,寻找实际触发引擎的字节,这就是 DefenderCheck。DefenderCheck 使用 C# 编写,开源仓没有 release 包,需要自己编译,于是找到了一个替代工具,gocheck,有直接编译好的二进制,且该工具使用多线程,解决了 defendercheck 效率较低的问题。
gocheck 找到的字节与我们的推断一致,但是 \x0E\X81\XEE
如何关联到对应的签名,仍然不得而知。DefenderYara 是一个开源项目,从 Windows Defender mpavbase 和 mpasbase 数据库中提取了 yara 规则。目前提取的规则不够完整,只有一部分签名类型,而且无法得知其是如何提取的。
研究病毒特征是一门有趣的学科,也是各种杀毒软件的研究对象。恶意软件想要做免杀,而杀毒软件则要识别更多的病毒特征。我们在这里只是初步窥探了 Microsoft Defender Antivirus 的签名数据库,以及实际触发杀毒软件的字节特征,这样可以避免正常的软件被误杀。如果你是一名黑客,则更有可能想要为自己制作的恶意软件或者后门做免杀,躲避杀毒软件的侦察。
experiments/windows-defender/VDM/README.md at master · commial/experiments · GitHub
The difference between signature-based and behavioural detections
Antivirus fundamentals: Viruses, signatures, disinfection | Kaspersky official blog
Reverse, Reveal, Recover: Windows Defender Quarantine Forensics – Fox-IT International blog
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。