81、恶意软件分析(一):静态分析(字符串、导入表、YARA规则)

各位好,欢迎来到《逆向工程实战100例》的第81讲。今天咱们聊聊恶意软件分析的第一步——静态分析。

很多人一听到“恶意软件分析”,就觉得得开个虚拟机、挂上调试器、单步跟踪。其实不然。我个人习惯,拿到一个可疑样本,第一件事绝对不是双击运行,而是先做静态分析。说白了,就是“只看不动手”。

静态分析能帮你快速判断:这玩意儿是不是恶意的?它大概想干什么?有没有已知的家族特征?这些信息,往往在几分钟内就能拿到。

核心原则: 静态分析是安全分析的基石。它安全、快速、无副作用。你不需要运行恶意代码,就能获取大量情报。

1. 字符串分析:恶意软件的“自白书”

字符串,是恶意软件最直接的“自白”。一个程序里硬编码的URL、IP地址、注册表路径、文件名、命令行参数……这些东西,几乎就是恶意行为的说明书。

我常用的工具是 strings 命令(Linux/macOS)或者 bintext(Windows)。

# 提取所有长度大于等于6的ASCII字符串
strings -n 6 sample.exe > strings.txt

# 提取Unicode字符串(很多恶意软件用Unicode隐藏关键信息)
strings -n 6 -e l sample.exe > unicode_strings.txt

拿到字符串列表后,我会重点关注以下几类:

  • 网络相关: http://https://ftp://、IP地址、域名。这些往往是C2(命令与控制)服务器的地址。
  • 文件路径: C:\Windows\%APPDATA%%TEMP%。恶意软件常把自己复制到这些目录。
  • 注册表键: HKEY_LOCAL_MACHINERunRunOnce。这是持久化(开机自启动)的常用手段。
  • API函数名: CreateRemoteThreadWriteProcessMemoryVirtualAllocEx。这些是进程注入的标配。
  • 加密密钥/算法标识: AESRC4base64。恶意软件常用这些来加密通信或自身。
避坑指南: 我曾经遇到一个样本,字符串里全是正常的系统路径和微软签名。差点就放过了。后来仔细一看,它把恶意URL用简单的XOR加密后藏在了资源节里。所以,字符串分析只是第一步,别太依赖它。加密、压缩、编码后的字符串,你是直接看不出来的。

2. 导入表分析:看它“请了哪些外援”

一个PE文件(Windows可执行文件)的导入表(Import Table),记录了它调用了哪些外部DLL和函数。这就像看一个人的朋友圈——他认识谁,大概就能猜出他是什么样的人。

我用 PEviewDependency Walker 来查看导入表。但更高效的是用Python脚本,配合 pefile 库。

import pefile

pe = pefile.PE('sample.exe')

for entry in pe.DIRECTORY_ENTRY_IMPORT:
    print(f"[*] DLL: {entry.dll.decode()}")
    for func in entry.imports:
        if func.name:
            print(f"    -> {func.name.decode()}")
        else:
            print(f"    -> Ordinal: {func.ordinal}")

重点关注以下“危险”API组合:

API函数 所属DLL 常见恶意用途
CreateRemoteThread kernel32.dll 在远程进程中创建线程(进程注入)
WriteProcessMemory kernel32.dll 向远程进程写入数据(代码注入)
VirtualAllocEx kernel32.dll 在远程进程中分配内存
URLDownloadToFile urlmon.dll 从网络下载文件到本地
RegSetValueEx advapi32.dll 修改注册表(持久化)
Socket / Connect / Send ws2_32.dll 网络通信(C2连接)

你想想看,一个普通的计算器程序,会去调用 CreateRemoteThread 吗?不会。所以,一旦导入表里出现这些“敏感”API,就得打起十二分精神。

注意: 高级恶意软件会使用动态加载(LoadLibrary + GetProcAddress)来隐藏导入表。这种情况下,导入表里可能只有这两个函数,真正的恶意API是在运行时才解析的。所以,导入表干净,不代表程序干净

3. YARA规则:自动化“指纹识别”

YARA,说白了就是恶意软件的“指纹识别系统”。你写一个规则,描述某个恶意家族的特征(比如特定的字符串、字节序列、导入表组合),然后让YARA去扫描样本,匹配上了就报警。

我自己的YARA规则库,积累了上千条。每次拿到新样本,第一件事就是跑一遍YARA。

# 一个简单的YARA规则示例
rule Suspicious_Strings_And_Imports
{
    meta:
        description = "检测包含可疑字符串和导入表的样本"
        author = "蓝海资料掘金营"
        date = "2025-01-01"

    strings:
        $s1 = "http://" nocase
        $s2 = "cmd.exe" nocase
        $s3 = "CreateRemoteThread" ascii wide

    condition:
        // 至少匹配两个字符串,并且导入表中包含CreateRemoteThread
        (uint16(0) == 0x5A4D) and // 检查MZ头
        (2 of ($s*)) and
        (pe.imports("kernel32.dll", "CreateRemoteThread"))
}

YARA的威力在于组合。你可以把字符串、导入表、节区特征、甚至文件大小都组合起来。比如:

  • 包含 http:// + 包含 CreateRemoteThread + 文件大小小于1MB → 很可能是下载者(Downloader)。
  • 包含 Mutex 字符串 + 包含 RegSetValueEx + 节区名为 .upx0 → 可能是UPX加壳的恶意软件。
我的经验: 写YARA规则时,别只依赖单一的字符串。比如 http:// 太常见了,误报率极高。我一般会加上 pe.imports 或者 pe.sections 来缩小范围。另外,规则要定期更新,恶意软件也在进化。

4. 知识体系:一张图看懂静态分析

下面这张图,是我自己总结的静态分析核心流程。你可以把它当作一个检查清单。

静态分析核心流程 1. 文件识别 PE/ELF/Mach-O? 2. 字符串分析 URL/IP/路径/API 3. 导入表分析 DLL + API组合 4. YARA规则匹配 自动化指纹识别 5. 综合判断 恶意/可疑/安全? 注意:每一步都可能发现“加壳”或“混淆”,需要动态分析进一步验证

5. 实战:一个完整的静态分析流程

假设你拿到一个名为 update.exe 的样本。我会这么做:

  1. 查壳:Detect It Easy (DiE) 看一眼。如果显示 UPXVMProtect,先脱壳。
  2. 字符串:strings,发现 http://malware.example.com/payload.execmd.exe /c。嗯,有戏。
  3. 导入表:pefile 分析,发现导入了 URLDownloadToFileWinExec。这基本实锤了——它是一个下载者,下载后执行。
  4. YARA: 用我自己的规则库跑一遍,匹配到了 Trojan_Downloader_Generic 这条规则。确认了。

整个过程,不到5分钟。我没运行它,但已经知道它是个下载者,C2地址也拿到了。接下来,我可以把这个IoC(威胁情报指标)提交给威胁情报平台,或者继续做动态分析。

总结: 静态分析是恶意软件分析的第一道防线。字符串、导入表、YARA规则,这三板斧用好了,能解决80%的样本。剩下的20%,才需要上调试器、沙箱、行为分析。记住,先静态,后动态,这是安全分析的基本原则。

好了,这一讲就到这里。希望这些经验对你有帮助。咱们下期见。


公众号:蓝海资料掘金营,微信deep3321