$ cat ~ / posts /reverse /lecture12 8.8k Words ~ 31 Mins
cover.png
逆向工程基本原理12

#逆向工程基本原理12

exdoubled Lv5

恶意软件分析概述

恶意软件分析的目标不是简单判断一个程序“好”或“坏”,而是回答更具体的问题:

  • 它属于哪类恶意软件
  • 它如何传播、触发和驻留
  • 它访问了哪些文件、网络、进程和内存资源
  • 它是否包含隐藏、加密、反调试、反虚拟化等对抗技术
  • 它的真实危害、触发条件和可观测证据是什么

恶意软件逆向和普通程序逆向的核心技术相同,仍然依赖文件格式、汇编、反编译、调试和运行时观察。但是恶意软件通常有更强的对抗性:它可能故意隐藏字符串、加壳、检测沙箱、延迟执行,或者只在特定环境中激活恶意逻辑。

一个典型引例是 Stuxnet。它不是单纯破坏 Windows 主机,而是针对西门子工业控制系统设计,通过改变伊朗核设施离心机转速导致设备磨损和故障。它的特点包括:

  • 目标环境非常具体,只在满足特定工业控制条件时触发核心逻辑
  • 使用物理介质、网络蠕虫等多种传播方式
  • 使用伪造数字签名降低被发现的概率
  • 同时利用多个 Windows 0day 漏洞
  • 将网络攻击结果延伸到物理设备损坏

这个例子说明:恶意软件分析不能只停留在“程序调用了哪个危险 API”。还要理解它的传播链、触发条件、运行环境和最终影响。

恶意软件

恶意软件(Malware)是旨在未经授权访问、控制、破坏计算机系统、网络或设备的软件。常见目的包括数据窃取、远程控制、破坏系统功能、加密勒索、投递其他载荷等。

常见传播形态包括:

  • 病毒(Virus):依附在宿主文件中,随宿主运行而传播
  • 蠕虫(Worm):利用漏洞、弱口令或网络连接自动传播
  • 木马(Trojan):伪装成正常程序,诱骗用户下载和运行
  • Drive-by/恶意网站:通过网页、广告、脚本、浏览器漏洞或诱导下载投递恶意代码

这些分类不是互斥的。现实中的恶意软件经常组合多种能力,例如木马可能带有蠕虫式传播模块,蠕虫也可能投递后门或挖矿程序。

病毒

病毒是依附在合法可执行文件、引导区或文档中的恶意代码。它在宿主被执行后运行,并继续感染其他文件。

病毒的典型特征:

  • 是否依赖宿主:是
  • 是否需要用户参与:通常需要,例如用户打开被感染文件
  • 传播方式:被感染的可执行文件、带宏文档、移动存储设备、邮件附件
  • 典型例子:CIH(Chernobyl)病毒

文件感染型病毒常见思路是把恶意逻辑插入宿主可执行文件,并修改入口点,让程序先执行病毒代码,再跳回原始入口继续执行宿主原功能。

以 ELF 文件感染为例,感染过程可以概括为:

  1. 读取宿主 ELF Header、Program Header 和 Section Header。
  2. 找到可以扩展或注入的段,例如 .data 对应的可加载段。
  3. 将病毒代码写入文件中原本数据段之后的位置。
  4. 修改 Program Header 的 fileszmemsz,让加载器把新增病毒代码映射进内存。
  5. 修改段权限,例如把原本 PF_R | PF_W 的数据段改成 PF_R | PF_W | PF_X,使注入代码可执行。
  6. 保存原始 e_entry,再把 ELF Header 中的 e_entry 改为病毒代码入口。
  7. 病毒代码执行完感染逻辑后,跳回原始入口,避免宿主功能异常暴露感染行为。

示意:

1
2
3
4
5
6
7
8
感染前:
e_entry -> 原始程序入口
.data -> 普通数据段,通常 R/W

感染后:
e_entry -> 病毒代码入口
.data -> 原始数据 + 病毒代码,段大小变大,权限可能变成 R/W/X
病毒代码执行完 -> 跳回原始程序入口

分析这类病毒时,要特别关注入口点变化、段大小变化、段权限异常和文件尾部新增数据。

蠕虫

蠕虫是一种可以独立运行、自动寻找攻击目标并自我复制传播的恶意程序。

蠕虫的典型特征:

  • 是否依赖宿主:否
  • 是否需要用户参与:通常不需要
  • 传播方式:扫描网络主机、利用系统漏洞、弱口令、默认口令或暴露服务入侵目标
  • 典型例子:SQL Slammer

蠕虫的关键不在于“诱导用户运行”,而在于自动扩散。例如一个简单 SSH 蠕虫可以按如下流程运行:

1
2
3
4
5
6
遍历 IP 地址
-> 探测 22 端口是否开放
-> 尝试弱口令爆破
-> 登录成功后复制自身
-> 在目标主机启动自身
-> 继续扫描更多目标

这类样本分析时要关注:

  • 是否有 IP 地址生成、端口扫描、连接重试逻辑
  • 是否内置弱口令字典
  • 是否调用 sshtelnetscpwgetcurl 等工具
  • 是否有自复制、自启动和删除痕迹逻辑

木马

木马是伪装成正常软件、工具或文件,诱骗用户安装或运行后实施恶意行为的程序。

木马的典型特征:

  • 是否依赖宿主:通常否,它本身就是独立程序
  • 是否需要用户参与:是
  • 传播方式:伪装安装包、破解工具、钓鱼邮件附件、即时通讯文件分享、假更新提示
  • 典型例子:灰鸽子

木马常见设计是“正常功能 + 隐藏功能”。例如一个伪装成 shell 命令解释器的程序,在大部分输入下正常执行命令,但当收到特定指令或认证字符串时,执行后门逻辑。

分析木马时,不能只运行一次普通功能就认为程序安全。需要搜索隐藏命令、特殊字符串、网络回连、认证逻辑和异常分支。

Drive-by 与恶意网站

Drive-by/恶意网站以网页、脚本、跳转页或虚假站点为载体,通过诱导访问或浏览器环境触发攻击。

典型特征:

  • 不依赖传统宿主文件,但依赖网页、脚本或浏览器环境
  • 通常需要用户点击链接、访问页面或下载页面投递的内容
  • 传播方式包括钓鱼邮件链接、恶意广告跳转、虚假登录页、假更新页面、社交媒体诱导链接
  • 典型例子包括 Angler Exploit Kit

这类攻击中,恶意逻辑可能不在最终下载文件里,而在网页脚本、重定向链、浏览器漏洞利用代码或投递器中。因此分析时要保留 HTTP 请求、响应、跳转链和下载样本之间的关系。

恶意行为分析维度

恶意行为可以从多个维度观察。静态分析和动态分析都围绕这些维度展开。

文件行为

文件行为常用于分析病毒、勒索软件、投递器等样本。

典型行为:

  • 删除或篡改系统文件
  • 感染可执行文件
  • 批量加密用户文件
  • 创建或修改启动项
  • 释放恶意载荷
  • 删除日志、备份或自身落地文件

文件行为的核心问题是:样本读写了哪些路径、这些路径是否敏感、写入内容是否用于持久化或后续执行。

网络行为

网络行为常用于分析蠕虫、间谍软件、僵尸网络、广告软件和远控木马。

典型行为:

  • 连接可疑 IP 或域名
  • 向远端发送敏感数据
  • 从远端下载并执行组件
  • 批量扫描主机、端口或服务
  • 周期性连接 C2(Command and Control)服务器接收指令
  • 使用 DNS、ICMP 等方式建立隐蔽信道

网络行为分析不能只看端口。恶意软件可以使用常见端口伪装协议,也可以在非常见端口上运行自定义协议。更重要的是通信目标、频率、方向、载荷内容和上下文。

进程行为

进程行为常用于分析木马、后门、挖矿程序和 rootkit。

典型行为:

  • 伪装进程名称
  • 创建异常子进程
  • 注入代码到其他进程
  • 通过被删除但仍打开的文件继续运行
  • 使用守护进程或父子进程互相拉起

进程行为的关键是识别“谁创建了谁”“谁控制了谁”“恶意逻辑最终在哪个进程上下文中执行”。

内存行为

内存行为常用于分析加载器、后门、无文件攻击和加壳样本。

典型行为:

  • 在内存中解密或解包恶意代码
  • 创建可执行匿名内存区域
  • 将代码注入正常进程内存
  • 删除落地文件后继续驻留
  • 在内存中暂存通信密钥、配置或加密密钥

内存行为分析的价值在于:磁盘上的样本可能是加密、压缩或伪装过的,而真实载荷只在运行时内存中出现。

其他敏感行为

其他敏感行为包括:

  • 访问账号、口令、浏览器缓存、SSH key 等敏感信息
  • 关闭安全软件
  • 修改系统配置、防火墙规则或 DNS 设置
  • 调用高危系统接口
  • 检测调试器、虚拟机或沙箱

这些行为未必直接造成破坏,但常常是窃密、持久化、规避分析或横向移动的一部分。

恶意软件分析方法

典型分析流程包括静态分析、动态分析和对抗分析。

1
2
3
4
静态分析  ->  初步判断样本类型、能力和可疑位置
动态分析 -> 观察运行时行为,验证静态推测
对抗分析 -> 处理加壳、反调试、反虚拟化和反自动化
综合结论 -> 给出行为链、触发条件、危害和证据

实际工作中三者通常交替进行。静态分析发现可疑字符串和函数后,可以在动态分析中设置断点或观察行为;动态分析发现某个文件或网络行为后,又可以回到反汇编中定位对应代码。

静态分析

静态分析是不执行样本,通过代码、文件结构和静态特征理解其行为的方法。

优点:

  • 使用简单,风险低
  • 可以快速获得样本基本信息
  • 能直接定位字符串、导入函数和代码结构

局限:

  • 难以分析加壳、加密、混淆和自修改代码
  • 难以判断运行时触发条件
  • 无法直接证明恶意行为在真实环境中可触发

反病毒软件与特征库

恶意特征库中收录了大量已知恶意软件的特征。反病毒软件可以快速扫描样本,给出初步判断。

常见做法:

  • 使用本地反病毒软件扫描样本
  • 使用多个检测引擎交叉验证
  • 查询 VirusTotal 等聚合扫描结果

这种方法适合作为第一步,但不能作为最终结论。

原因:

  • 特征库依赖已知样本,遇到新变种可能漏报
  • 加壳、加密、轻微修改可能改变特征
  • 双用途工具可能被误报
  • 检测结果只说明“检测引擎如何判断”,不等于完整行为分析

如果一个样本文件结构完整、反汇编逻辑清晰、VirusTotal 报告为良性,也不能直接断定它无害。可能的解释包括:

  • 样本确实是良性工具
  • 恶意逻辑需要特定参数、配置、时间或网络响应才会触发
  • 它是双用途工具,被攻击者用于恶意场景
  • 样本很新,尚未进入特征库
  • 真正恶意载荷在运行时从网络下载或解密释放

文件哈希与模糊哈希

哈希值可以看作文件指纹。

常见哈希算法:

  • CRC32
  • MD5
  • SHA1
  • SHA256

如果两个文件内容完全相同,它们的哈希值也相同。因此哈希适合用于样本去重、样本库查询和 IOC 记录。

普通哈希的缺点是对微小变化极其敏感。样本只要改动一个字节,整体哈希就会完全不同。为了解决相似样本关联问题,可以使用模糊哈希。

模糊哈希基于分片哈希思想,将文件分块并对每块生成哈希。它对局部变化不那么敏感,可以发现只有少量差异的恶意代码变种。常见工具是 ssdeep

加壳识别

加壳是恶意软件隐藏自身、对抗分析的常见方法。加壳后,磁盘文件中看到的代码可能主要是壳代码,原始恶意逻辑需要运行时解压或解密后才出现。

常见识别方式:

  • 查看区段名和程序头是否异常,例如 UPX0UPX1
  • 观察入口点是否落在壳 stub 中
  • 计算区段熵值,压缩或加密数据通常熵较高
  • 使用 DiE、Exeinfo 等查壳工具
  • 在反汇编中观察导入表是否异常少、字符串是否明显缺失

脱壳方法通常分为两类:

  • 硬脱壳:分析壳算法,写出解压或解密逆算法
  • 动态脱壳:让壳在运行时自行还原程序,再 dump 内存镜像并修复文件

如果样本使用标准 UPX,可以优先尝试:

1
upx -d sample

如果标准脱壳失败,就要回到上节课的思路:运行样本,定位 OEP,dump 内存,修复导入表和入口点。

可读字符串

字符串是静态分析中最便宜也最有用的信息来源之一。

常见命令:

1
2
strings ./target.elf
strings -a ./target.elf | grep -E "http|/proc|/tmp|exec|wget|curl"

字符串可能暴露:

  • URL、域名、IP 地址
  • 文件路径和配置路径
  • 调试输出、错误信息、作者标记
  • 进程名、互斥锁名、服务名
  • 加密算法名、命令字符串、User-Agent
  • 目标平台和动态链接器路径

例如在 Mirai 变体中,字符串可能出现:

1
2
3
4
5
6
7
/lib/ld-linux-armhf.so.3
94.156.227.234
http://94.156.227.233/
/proc/self/exe
/proc/%d/exe
/proc/%u/status
gorilla botnet is on the device...

这些信息可以推测:

  • /lib/ld-linux-armhf.so.3 表明目标可能是 ARM Linux
  • IP 和 URL 可能是 C2 或下载服务器
  • /proc 路径说明样本可能枚举自身、进程或状态信息
  • 特殊文本可能是作者标记、调试信息或僵尸网络家族特征

strings 也有误报。它只是搜索连续可打印字节,不理解文件格式和上下文。有些结果可能只是地址、压缩数据或机器指令碰巧形成的可打印字符。因此字符串只能作为线索,不能直接作为结论。

导入表与 API

导入表/API 是程序声明自己要调用的外部函数列表。通过导入表可以初步判断样本能力。

常见关注点:

  • 网络接口:socketconnectsendrecv
  • 文件操作:openreadwriterenameunlink
  • 命令执行:execvesystempopen
  • 持久化接口:RegSetValueExCreateService
  • 注入接口:VirtualAllocWriteProcessMemoryCreateRemoteThread
  • 调试检测:ptraceIsDebuggerPresentCheckRemoteDebuggerPresent

Linux ELF 样本可以使用:

1
2
readelf -Ws ./target.elf
objdump -T ./target.elf

如果导入表中出现 socketconnectsendrecv,说明样本具备网络连接和数据收发能力。如果同时出现 execvesystem,则可能具备执行系统命令或启动其他程序的能力。

导入表适合作为字符串分析和反汇编之间的过渡步骤。确定可疑 API 后,可以在 Ghidra 或 IDA 中查找交叉引用,定位调用点和上游数据来源。

反汇编与反编译

反汇编用于理解恶意代码的基本流程和关键执行逻辑。常见工具包括:

  • Ghidra
  • IDA Pro
  • radare2
  • Snowman

Ghidra 支持 x86、x64、ARM、MIPS 等指令集,也支持 PE、ELF、DEX、JAR 等多种格式。它可以做函数识别、栈变量恢复、反编译和交叉引用分析。

静态反汇编时可以用字符串和导入表作为锚点:

1
2
3
4
5
6
7
8
9
10
可疑字符串 "http://..."
-> 查找交叉引用
-> 定位构造网络请求的函数
-> 跟踪参数来源
-> 查找 connect/send/recv 调用

导入函数 system
-> 查找交叉引用
-> 定位命令字符串构造逻辑
-> 判断命令是否包含用户输入或远程指令

分析报告中不要只写“调用了 system”。更有价值的是写清楚:

  • 命令字符串如何构造
  • 数据来自本地配置、网络响应还是用户输入
  • 是否经过过滤或白名单
  • 哪些条件下会调用该函数
  • 调用后产生什么行为

动态分析

动态分析是实际运行可疑代码,观察和探测其运行时行为的方法。

静态分析很难完全掌握恶意代码行为,原因包括:

  • 恶意逻辑可能被加密或压缩
  • 行为依赖时间、配置、网络响应或命令控制
  • 样本可能只在特定系统、语言、区域、硬件或权限下触发
  • 样本可能使用反调试、反虚拟化、反沙箱技术

动态分析可以补足这些问题,但也有明显风险和成本:

  • 恶意软件可能破坏系统、扫描网络或外传数据
  • 沙箱或虚拟环境可能被逃逸
  • 行为触发路径有限,覆盖率不一定高
  • 环境构建、恢复和观察成本较高

构建动态分析环境

动态分析首先要保证样本不会影响外部环境。隔离环境的作用包括:

  • 限制恶意行为影响范围
  • 快速恢复初始状态
  • 记录网络、文件、进程和内存行为
  • 支持调试、快照和多次试验

常见隔离环境分为三类。

应用沙箱

应用沙箱是在操作系统上运行的应用软件,它通过策略限制其中程序的行为。

常见手段:

  • 拦截系统调用
  • 限制文件访问
  • 限制网络访问
  • 记录程序行为

常见工具包括 Sandboxie、Powershadow、Firejail。

应用沙箱轻量,但隔离强度有限。使用内核漏洞、rootkit 或高级逃逸技术的恶意代码可能突破沙箱限制。

虚拟化系统

虚拟化系统基于系统级虚拟化技术,提供比应用沙箱更强的隔离环境。

常见工具:

  • VMware
  • VirtualBox

虚拟化系统的优势:

  • 可以创建快照并快速回滚
  • 可以配置网络、磁盘、内存等环境
  • 运行效率较高
  • 适合分析常见 Windows 或 Linux 恶意样本

局限:

  • 不适合跨架构样本,例如在 x86 主机上直接运行 ARM 恶意软件
  • 恶意软件可能检测虚拟机特征后隐藏行为
  • 对硬件级执行细节的干预能力有限

硬件模拟器

硬件模拟器可以用软件模拟目标硬件和 CPU 架构。

常见工具:

  • QEMU
  • Bochs
  • Unicorn

优势:

  • 可以跨架构执行,例如在 x86 主机上分析 ARM 二进制
  • 隔离性较强
  • 可以模拟不存在的硬件设备
  • 适合固件、IoT 恶意软件和嵌入式样本

这也和前面固件模拟课程衔接:如果恶意软件运行在路由器、摄像头或其他 IoT 设备中,往往需要先通过 QEMU、chroot、系统级模拟或应用级模拟让目标程序跑起来,再观察其网络和文件行为。课堂转录中提到的固件灰盒模糊测试也依赖类似思路:通过模拟和动态插装获取覆盖率或运行时信息。

动态分析基本流程

一个实用流程如下:

  1. 准备隔离环境,配置快照、网络和日志记录。
  2. 运行前记录系统基线,例如进程、文件、端口、注册表或关键目录状态。
  3. 运行样本,并记录网络、文件、进程和内存行为。
  4. 根据行为结果回到静态分析中定位对应代码。
  5. 对关键函数设置断点,分析触发条件和数据流。
  6. 回滚快照,改变环境条件后重复运行,例如修改时间、网络响应、配置文件或用户交互。

动态分析不是只看“运行后发生了什么”,还要证明“为什么发生”“怎样触发”“是否可重复”。

网络行为分析

网络行为分析的目标是捕获恶意软件中的可疑网络通信行为。

常见工具:

  • Wireshark
  • FakeNet-NG
  • tcpdump
  • BurpSuite

常见恶意网络行为:

  • 使用异常端口和协议通信
  • 向可疑 IP 或域名发送数据
  • 下载可疑外部资源
  • 周期性连接 C2 服务器
  • 进行主机、端口或服务扫描
  • 使用 DNS 或 ICMP 隐蔽通信

端口与协议

常见端口包括:

1
2
3
4
5
6
80/443    HTTP/HTTPS
53 DNS
22 SSH
25/587 SMTP
445 SMB
3389 RDP

异常端口的异常使用比较容易发现,例如样本持续连接外部 4444 端口。但常见端口也可能被异常使用:

  • 非 Web 流量伪装成 80/443 端口通信
  • 大量扫描正常端口
  • 频繁连接固定域名或 IP
  • 数据载荷明显不是对应协议格式

因此不能只看端口号。要结合:

  • 通信目标是否可疑
  • 请求频率是否异常
  • 通信方向是外连还是监听
  • 载荷是否包含敏感数据
  • 是否存在固定心跳、命令下发或下载行为

隐蔽通信

DNS 隧道会把指令或窃取数据编码进 DNS 请求或响应。

可疑特征:

  • 超长子域名
  • 高随机字符
  • 高频请求
  • 异常 TXT 记录
  • 固定可疑域名反复查询

ICMP 隐蔽通信会把数据写入 ping 报文载荷。

可疑特征:

  • 高频 ICMP 请求
  • payload 过大
  • 固定间隔通信
  • 对外持续回显请求

如果在 Wireshark 中看到样本访问外部 IP、使用 UDP 连接、访问非常见端口,并发送看似编码后的数据,就应进一步定位样本中构造该报文的代码位置。

文件行为分析

文件行为分析的目标是观察恶意软件对文件系统的可疑操作。

常见工具:

  • strace
  • auditd
  • inotifywait
  • Process Monitor(Windows)

Linux 下可以用 strace 观察文件系统相关系统调用:

1
2
strace -f -o trace.log ./sample
grep -E "open|openat|read|write|rename|unlink|execve" trace.log

常见恶意文件行为包括:

  • 批量修改或加密文件
  • 创建或修改启动项
  • 删除日志、备份或关键系统文件
  • 伪装成系统文件名
  • 使用双重扩展名
  • 滥用 /tmp 等临时目录
  • 读取 /etc/passwd.bash_history、浏览器缓存等敏感文件

示例行为链:

1
2
3
openat("/tmp/evil_cron", O_WRONLY|O_CREAT)
write(...)
execve("/usr/bin/crontab", ["crontab", "/tmp/evil_cron"], ...)

这可能说明样本试图写入计划任务,实现持久化。

如果看到大量文件被打开、读取、写回,且扩展名或文件头发生变化,就要考虑勒索软件或文件感染型病毒。此时应记录样本修改前后的文件差异,而不是只记录系统调用名。

进程行为分析

进程行为分析的目标是观察恶意软件对进程、线程和执行上下文的操作。

常见工具:

  • ps
  • top
  • lsof
  • strace
  • perf
  • Process Explorer(Windows)

伪装进程名

Linux 程序可以通过 prctl 修改进程名。

可疑现象:

  • 运行文件名与 ps 中显示的进程名不一致
  • 进程伪装成 sshdkworkersystemd 等常见系统进程
  • 进程路径位于临时目录,但进程名看起来像系统服务

可以用 strace 关注:

1
prctl(PR_SET_NAME, ...)

代码或模块注入

恶意进程可能把代码注入到其他进程中,让恶意逻辑在合法进程上下文中运行。

Linux 中一种思路是使用 ptrace

1
2
3
ptrace(PTRACE_ATTACH, target_pid, ...)
修改目标进程内存或寄存器
让目标进程执行恶意代码或 execve

Windows 中常见组合是:

1
2
3
VirtualAllocEx
WriteProcessMemory
CreateRemoteThread

这类行为的关键不是单个 API,而是组合语义:申请远程内存、写入代码、改变执行流。

删除后继续运行

恶意载荷运行后可能删除磁盘文件,减少被杀毒软件或取证镜像发现的概率。但如果进程仍然持有该文件描述符,文件内容可能还存在于内存或文件系统引用中。

可以使用:

1
lsof | grep deleted

如果发现某个进程仍打开已删除文件,就需要进一步 dump 进程内存或复制对应文件描述符内容。

内存行为分析

内存行为分析的目标是观察恶意软件的可疑内存使用行为和内存中的可疑数据。

常见工具:

  • Volatility
  • GDB/gcore
  • /proc/<pid>/maps
  • LiME

常见恶意内存行为:

  • 创建可执行匿名内存段
  • 在内存中解密或解包恶意代码
  • 将代码注入其他进程内存
  • 运行后释放隐藏载荷
  • 暂存通信密钥、配置或加密密钥

Linux 中可以先查看内存映射:

1
cat /proc/<pid>/maps

需要关注:

  • 匿名映射是否带有 x 权限
  • 堆或栈是否出现异常可执行权限
  • 是否有已删除文件仍被映射
  • 是否存在可疑共享库或临时目录映射

如果发现可疑进程,可以使用:

1
2
gcore <pid>
strings core.<pid> | grep -E "http|key|token|/tmp|/proc"

内存 dump 常用于提取运行时配置、C2 地址、解密后的 payload 或勒索软件密钥材料。

动态调试恶意行为

动态调试用于跟踪样本执行过程,定位关键恶意逻辑和触发条件。

常见工具:

  • GDB
  • OllyDbg
  • x64dbg
  • WinDbg

调试可以解决动态观察无法回答的问题:

  • 哪个条件控制恶意逻辑是否执行
  • 网络响应如何影响后续行为
  • 加密数据在哪里被解密
  • 反调试检查在哪里发生
  • 命令字符串或文件路径如何构造

常见策略:

  • 对可疑 API 下断点,例如 connectsendopenexecvesystem
  • 对可疑字符串交叉引用附近下断点
  • 在比较指令附近观察触发条件
  • 动态修改寄存器或内存变量,绕过反调试或环境检查
  • 在解密后、执行前 dump 内存

例如样本运行后立刻退出,静态分析发现有调试检测逻辑。可以在检测函数返回后修改返回值,或者 patch 条件跳转,让程序继续执行隐藏逻辑。关键是记录修改前后控制流和行为差异,证明被绕过的是分析对抗逻辑,而不是业务逻辑。

动态行为链推测

如果运行样本并使用 strace 和 Wireshark 得到如下行为:

1
2
3
4
创建临时文件
-> 读取系统配置
-> 建立 UDP 连接
-> 无返回数据即退出

可能的解释包括:

  • 样本在收集主机信息后向 C2 发送上线包
  • 临时文件用于缓存配置、主机指纹或待发送数据
  • UDP 连接可能是轻量心跳、DDoS 控制通道或隐蔽通信
  • 无返回数据即退出说明恶意逻辑可能依赖远端指令
  • 当前分析环境未满足触发条件,例如网络不可达、C2 未响应或样本检测到沙箱

下一步应回到静态分析中定位 UDP 发送数据的构造位置,并尝试使用 FakeNet-NG 或自建服务器模拟远端响应。

对抗分析

恶意代码为了避免自身被分析,常常使用对抗技术。对抗分析就是识别并绕过这些技术。

常见对抗方向:

  • 反调试
  • 反虚拟化
  • 反自动化分析
  • 加壳、混淆、自修改代码
  • 延迟执行和环境触发

加壳和反反编译在高级对抗技术课程中已经介绍过,本节更关注恶意软件分析中常见的运行环境对抗。

反调试技术

反调试技术用于检测并阻止调试器监控样本行为。

常见手段:

  • 检测调试器进程
  • 使用 API 判断是否被调试
  • 干扰异常处理,让断点难以命中
  • 使用代码自修改避开静态断点
  • 检测硬件断点或调试寄存器
  • 使用父进程、时间差、信号行为判断是否被调试

Windows 常见 API:

1
2
3
IsDebuggerPresent
CheckRemoteDebuggerPresent
NtQueryInformationProcess

Linux 常见方式:

1
2
3
4
ptrace(PTRACE_TRACEME, ...)
读取 /proc/self/status 中的 TracerPid
getppid()
readlink("/proc/self/exe", ...)

应对思路:

  • 使用 ScyllaHide 等工具隐藏调试器特征
  • 使用 Frida、GDB 或 LD_PRELOAD 拦截特定 API 并返回虚假结果
  • patch 掉反调试分支
  • 对关键点做快照,检测退出后回滚并定位触发退出的位置
  • 使用动态插桩记录 API 调用,而不是直接附加传统调试器

例如样本读取 /proc/self/status 并检查 TracerPid,可以在对应读取函数或字符串解析后设置断点,观察比较逻辑,再将结果改为 0 或 patch 条件跳转。

反虚拟化技术

反虚拟化技术用于识别样本是否运行在虚拟机、模拟器或沙箱中。如果检测到分析环境,样本可能隐藏恶意逻辑,只执行无害操作。

常见检测方式:

  • 检查 VMware、VirtualBox、QEMU 等特征文件或驱动
  • 检查 PCI、DMI、磁盘、网卡、显示器等虚拟硬件指纹
  • 检查注册表项,例如 HKLM\SOFTWARE\VMware, Inc.
  • 使用特殊指令或特权指令探测虚拟机行为
  • 通过时间差检测指令执行延迟
  • 检查内存大小、CPU 核数、硬盘大小是否过小
  • 检查用户名、主机名、安装软件是否像真实用户环境

应对思路:

  • 修改虚拟机配置,隐藏或重命名明显虚拟硬件标识
  • 删除或屏蔽常见虚拟机文件、注册表和驱动标志
  • 使用 VBoxManage 或 VMware 配置伪装真实硬件信息
  • 模拟鼠标移动、键盘输入、浏览器历史等用户行为
  • 拦截 GetSystemInfocpuid 等检测调用并返回伪造数据
  • 使用真实设备或更高保真的模拟环境复现实验

如果某恶意软件在真实设备上表现为勒索行为,但在虚拟机中只读取文件而不加密,很可能存在反虚拟化或反沙箱逻辑。分析时应比较两个环境中的分支条件,定位它检查了哪些环境特征,再逐步满足或绕过这些检查。

反自动化分析技术

自动化分析系统用于快速处理大量样本,自动执行静态扫描和动态运行。恶意软件会利用自动化分析的时间限制、环境同质性和缺少真实用户行为等特点进行规避。

常见反自动化技术:

  • 检测鼠标移动、键盘输入、窗口切换等真实用户行为
  • 检查系统序列号、用户名、内存大小、硬盘大小、最近文件记录
  • 使用 sleep 或长循环拖延执行时间
  • 只在特定日期、时区、语言或地理位置执行
  • 重复无意义加解密或系统调用,造成日志过载
  • 要求远端 C2 返回特定指令后才执行恶意逻辑

应对思路:

  • 模拟真实用户操作
  • 加速或 patch 时间相关 API
  • 将长 sleep 改短或直接跳过
  • 为样本提供更真实的系统环境和用户痕迹
  • 把反自动化行为本身视为恶意特征记录
  • 对常见检测逻辑做静态扫描,提前识别触发条件

反自动化分析的核心是:不要因为样本在沙箱中表现无害就停止分析。无害行为可能只是环境检测失败后的伪装路径。

恶意软件分析报告

一个有效的恶意软件分析报告应尽量形成可验证的证据链。

建议记录:

  • 样本基本信息:文件名、大小、格式、架构、哈希、模糊哈希
  • 静态特征:字符串、导入表、壳信息、可疑函数
  • 动态环境:操作系统、网络配置、工具版本、是否隔离、是否快照
  • 网络行为:域名、IP、端口、协议、请求内容、响应内容
  • 文件行为:创建、修改、删除、加密、释放的文件路径
  • 进程行为:父子进程、注入、伪装、持久化方式
  • 内存行为:可执行匿名内存、解密载荷、运行时配置
  • 对抗技术:反调试、反虚拟化、反自动化、加壳或混淆
  • 触发条件:时间、参数、网络响应、系统环境、用户行为
  • 危害判断:窃密、远控、勒索、传播、破坏、投递其他载荷
  • 残余不确定性:未触发路径、无法访问的 C2、未完成脱壳部分

简化模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sample:
hash: ...
format: ELF 32-bit ARM
packer: 未发现明显壳

static:
strings: C2 URL, /proc 路径, wget 命令
imports: socket, connect, send, recv, execve
suspicious function: sub_8049120 构造网络请求

dynamic:
network: UDP 连接到 x.x.x.x:4444
file: 写入 /tmp/.cache_xxx
process: 修改进程名为 kworker

conclusion:
该样本疑似 IoT botnet 变体,具备上线、接收指令和执行命令能力。

报告中的重点不是堆工具截图,而是解释证据之间的关系:静态线索如何对应动态行为,动态行为如何证明恶意功能,哪些条件控制恶意功能触发。

总结

恶意软件分析的基本路径可以概括为:

1
2
3
4
5
6
7
识别样本类型
-> 静态提取特征
-> 构建隔离环境
-> 动态观察行为
-> 调试关键逻辑
-> 处理对抗技术
-> 输出证据链和结论

不同恶意软件类型的分析重点不同:

  • 病毒:关注入口点修改、文件感染、段权限和跳回原程序逻辑
  • 蠕虫:关注扫描、爆破、自复制和自动传播
  • 木马:关注伪装功能、隐藏命令、远控和用户诱导
  • Drive-by:关注网页载体、重定向链、浏览器环境和载荷投递

静态分析适合快速定位线索,动态分析适合验证真实行为,对抗分析用于让隐藏逻辑暴露出来。三者结合,才能从“发现可疑点”走到“证明恶意行为如何发生”。

$ discussion
# Comments
waline