用Capa这个开源工具检查ELF二进制文件的能力

369 阅读7分钟

如果Linux是你的主要工作环境,那么你可能熟悉可执行和可链接格式(ELF),这是Linux上用于可执行文件、库、核心转储等的主要文件格式。我已经写了一些文章,涵盖了理解ELF二进制文件的本地Linux工具,首先是ELF二进制文件是如何建立的,然后是一些关于如何分析ELF二进制文件的一般提示。如果你对ELF和一般的可执行文件不熟悉,我建议先阅读这些文章。

介绍Capa

Capa是Mandiant(一家网络安全公司)的一个开源项目。用该项目自己的话说,Capa检测可执行文件中的能力。虽然Capa的主要目标是未知的、可能是恶意的可执行文件,但本文的例子在日常的Linux实用程序上运行Capa,以了解该工具的工作情况。

鉴于大多数恶意软件是基于Windows的,早期的Capa版本只支持PE文件格式,这是一种主流的Windows可执行文件格式。然而,从v3.0.0开始,已经增加了对ELF文件的支持(感谢Intezer)。

什么是能力?

能力的概念到底是什么意思,特别是在可执行文件的背景下?程序或软件满足某些计算需求或解决某个问题。为了简单起见,我们的需求可以从寻找一个文件、读/写到一个文件、运行一个程序、将一些数据记录到一个日志文件、打开一个网络连接等。然后我们使用我们选择的编程语言,用具体的指令来完成这些任务,并编译程序。然后产生的二进制文件或可执行文件代表用户执行这些任务,所以产生的可执行文件能够执行上述任务。

看一下源代码,很容易确定一个程序做什么或它的意图是什么。然而,一旦程序被编译为可执行文件,源代码就被转换为机器语言,不再是所产生的可执行文件的一部分(除非编译时带有调试信息)。我们仍然可以通过对Linux API(glibc/系统调用)的一些知识的支持,通过查看等效的汇编指令来理解它,然而,这很难。像去编译器这样的工具确实存在,它试图将汇编转换成可能是原始源代码的伪代码。然而,这并不是一对一的匹配,而且这只是一种尽力的尝试。

为什么是另一个工具?

如果我们有多个原生的Linux工具来分析二进制文件,为什么我们还需要另一个?现有的工具可以帮助开发人员排除故障和调试开发过程中可能出现的问题。它们通常是对未知二进制文件进行初步分析的第一步,然而,它们并不足够。

有时需要的不是冗长的反汇编或冗长的伪代码,而只是根据二进制文件的API使用情况,对其功能进行快速总结。通常情况下,恶意的二进制文件和恶意软件采用一些反分析或反转技术,使这种本地工具无能为力。

Capa的主要受众是恶意软件或安全研究人员,他们经常遇到无法获得源代码的未知二进制文件。他们需要识别它是恶意软件还是良性可执行文件。最初的第一步是在进行动态分析之前找出可执行文件的功能。这可以通过一些预定义的规则集与一个流行的框架相匹配来完成(我们在下面探讨)。原生的Linux工具并不是为这种用途设计的。

获取Capa

这里下载一个预建的Capa Linux程序。你必须使用v3.0.0或以上版本。Capa是用Python编程的,但是下载的程序并不是Python解释器可以执行的.py 文件。它是一个ELF可执行文件,可以直接从Linux命令行运行。

$ pwd
/root/CAPA
$
$ wget -q https://github.com/mandiant/capa/releases/download/v3.0.2/capa-v3.0.2-linux.zip
$
$ file capa-v3.0.2-linux.zip
capa-v3.0.2-linux.zip: Zip archive data, at least v2.0 to extract
$
$ unzip capa-v3.0.2-linux.zip
Archive:  capa-v3.0.2-linux.zip
  inflating: capa
$
$ ls -l capa
-rwxr-xr-x. 1 root root 41282976 Sep 28 18:29 capa
$
$ file capa
capa: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=1da3a1d77c7109ce6444919f4a15e7e6c63d02fa, stripped

命令行选项

Capa有多种命令行选项。本文将访问其中的几个,首先是帮助内容。

$ ./capa -h
usage: capa [-h] [--version] [-v] [-vv] [-d] [-q] [--color {auto,always,never}] [-f {auto,pe,elf,sc32,sc64,freeze}]
            [-b {vivisect,smda}] [-r RULES] [-s SIGNATURES] [-t TAG] [-j]
            sample
The FLARE team's open-source tool to identify capabilities in executable files.
<< snip >>
$

使用此命令检查所需版本的Capa(v3及以上)是否正在运行。

$ ./capa --version
capa v3.0.2-0-gead8a83

Capa输出和MITRE ATT&CK框架

Capa的输出可能有点让人不知所措,所以首先在一个简单的工具上运行它,如pwd 。Linux上的pwd 命令会打印出当前工作目录,是一个常用的命令。请注意,pwd 可能是一个为你内置的外壳(没有单独的可执行文件),这取决于你使用的发行版。首先使用which 命令确定其路径,然后向Capa提供完整的路径。下面是一个例子。

$ which pwd
/usr/bin/pwd
$
$ file /usr/bin/pwd
/usr/bin/pwd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ec306ddd72ce7be19dfc1e62328bb89b6b3a6df5, for GNU/Linux 3.2.0, stripped
$
$ ./capa -f elf /usr/bin/pwd
loading : 100%| 633/633 [00:00<00:00, 2409.72 rules/s]
matching: 100%| 76/76 [00:01<00:00, 38.87 functions/s, skipped 0 library functions]
+------------------------+------------------------------------------------------------------------------------+
| md5                    | 8d50bbd7fea04735a70f21cca5063efe                                                   |
| sha1                   | 7d9df581bc3d34c9fb93058be2cdb9a8c04ec061                                           |
| sha256                 | 53205e6ef4e1e7e80745adc09c00f946ae98ccf6f8eb9c4535bd29188f7f1d91                   |
| os                     | linux                                                                              |
| format                 | elf                                                                                |
| arch                   | amd64                                                                              |
| path                   | /usr/bin/pwd                                                                       |
+------------------------+------------------------------------------------------------------------------------+
+------------------------+------------------------------------------------------------------------------------+
| ATT&CK Tactic          | ATT&CK Technique                                                                   |
|------------------------+------------------------------------------------------------------------------------|
| DISCOVERY              | File and Directory Discovery:: T1083                                               |
+------------------------+------------------------------------------------------------------------------------+
+-----------------------------+-------------------------------------------------------------------------------+
| MBC Objective               | MBC Behavior                                                                  |
|-----------------------------+-------------------------------------------------------------------------------|
| FILE SYSTEM                 | Writes File:: [C0052]                                                         |
+-----------------------------+-------------------------------------------------------------------------------+
+------------------------------------------------------+------------------------------------------------------+
| CAPABILITY                                           | NAMESPACE                                            |
|------------------------------------------------------+------------------------------------------------------|
| enumerate files on Linux (2 matches)                 | host-interaction/file-system/files/list              |
| write file on Linux                                  | host-interaction/file-system/write                   |
+------------------------------------------------------+------------------------------------------------------+

使用-f elf 参数运行Capa,告诉它要分析的可执行文件是ELF文件格式的。对于未知的二进制文件,可能需要这个选项;但是,Capa完全有能力自行检测格式并进行分析,所以如果需要,可以跳过这个选项。开始时,您会看到一条加载/匹配信息,因为Capa从后台加载其规则,然后分析可执行文件并与这些规则进行匹配。通过在所有命令中添加-q 选项,可以跳过显示这一内容。

Capa 的输出分为多个部分。第一部分使用md5、sha1或sha256哈希值唯一识别二进制文件,然后是操作系统、文件格式和架构信息。在处理可执行文件时,这些信息往往是至关重要的。在以下章节中,Capa使用ATT&CK战术和技术来匹配能力。

MITRE ATT&CK最好用项目自己的话来描述。

MITRE ATT&CK®是一个全球可访问的、基于真实世界观察的对手战术和技术的知识库。

如果你想了解更多关于ATT&CK的信息,请参考这里的MITRE ATT&CK框架

你可以在下面两节中把Capa的输出与MITRE ATT&CK框架的输出相匹配。在本文中我将跳过这一部分。

最后,在能力部分,你可以看到两个具体的能力列出来。

enumerate files on Linux
write file on Linux

将此与pwd 程序的性质相比较,它需要显示当前目录。在这里,它与第一项能力相匹配(记住Linux中一切事物都是一个文件的概念)。那么第二部分呢,即写文件?我们当然没有把pwd 的输出写入任何文件。然而,记住pwd ,需要把当前的目录位置写到终端;否则如何打印输出?如果你仍然不确定这是如何工作的,请运行以下命令并匹配输出。如果你不熟悉strace 或它的作用,我有一篇文章涉及它,在这里。请关注文章末尾的系统调用,pwd 可执行文件需要将目录路径(字符串)写入1,这代表标准输出。在我们的例子中,这就是终端。

$ strace -f  /usr/bin/pwd
execve("/usr/bin/pwd", ["/usr/bin/pwd"], 0x7ffd7983a238 /* 49 vars */) = 0
brk(NULL)
<< snip >>
write(1, "/root/CAPA\n", 11/root/CAPA
)            = 11
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

在不同的Linux工具上运行Capa

现在你知道了如何运行Capa,我强烈建议你在各种日常的Linux工具上尝试。在选择实用程序时,要尽量多样化。例如,选择与文件系统或存储命令有关的实用程序,如ls,mount,cat,echo 等。接下来,转到网络实用程序,如netstat,ss,telnet 等,在这里你会发现一个可执行文件的网络功能。延伸到更广泛的程序守护程序,如sshd ,以查看与加密有关的能力,然后是systemd,bash, 等等。

需要提醒的是,如果你看到与这些本地实用程序的恶意软件相匹配的规则,不要太惊慌。例如,在分析systemd时,Capa显示匹配的COMMAND AND CONTROL是基于从网络接收数据的能力。这种能力可能被真正的程序用于合法的情况,而恶意软件可能将其用于恶意的目的。

在调试模式下运行

如果您希望看到Capa如何在一个可执行文件中发现所有这些能力,请提供-d 标志,它在屏幕上显示额外的信息,可能有助于了解其内部工作。利用这些数据,在GitHub上的源代码中寻找线索。

$ ./capa -q /usr/sbin/sshd -d

首先要注意的是,Capa将规则保存到一个临时目录,并从那里读取规则。

DEBUG:capa:reading rules from directory /tmp/_MEIKUG6Oj/rules

调试输出显示它从这个目录中加载各种规则。作为一个例子,看看它是如何试图识别一台机器的主机名的。

DEBUG:capa:loaded rule: 'get hostname' with scope: function

有了这些信息,查找规则就很容易了。只需进入rules 目录,然后grep ,查找特定的规则名称,如下面的例子。该规则是在一个.yml文件中说明的。

$ grep -irn "name: get hostname" *
rules/host-interaction/os/hostname/get-hostname.yml:3:    name: get hostname

检查-api 部分,其中列出了各种API。Capa会查找gethostname API的使用情况(在Linux上),你也可以看到那里列出了Windows的对应情况。

$ cat _MEIKUG6Oj/rules/host-interaction/os/hostname/get-hostname.yml
rule:
  meta:
    name: get hostname
    namespace: host-interaction/os/hostname
<< snip >>
  features:
    - or:
      - api: kernel32.GetComputerName
      - api: kernel32.GetComputerNameEx
      - api: GetComputerObjectName
      - api: ws2_32.gethostname
      - api: gethostname

你可以通过man page找到更多关于Linux上这个特定系统调用的信息。

$ man 2 gethostname
GETHOSTNAME(2)                          Linux Programmer's Manual                               GETHOSTNAME(2)
NAME
       gethostname, sethostname - get/set hostname
<< snip >>

粗略的用法

另一个识别Capa正在寻找的API的好方法是使用verbose模式,如下图所示。这个简单的例子显示了opendir,readdir, 和fwrite API的使用情况。

$ ./capa  -q /usr/bin/pwd -vv
enumerate files on Linux (2 matches)
<< snip >>
        api: opendir @ 0x20052E8
        api: readdir @ 0x2005369, 0x200548A
write file on Linux
<< snip >>
    os: linux
    or:
      api: fwrite @ 0x2002CB5

自定义规则

与其他优秀工具一样,Capa允许你通过添加自己的规则来扩展它。如果你注意到,在调试输出中也给出了这个提示。

$ capa --signature ./path/to/signatures/ /path/to/executable

只有特定的规则

您也可以寻找特定的规则,而不是让Capa尝试匹配每一条规则。通过添加-t 标志和确切的规则名称来实现。

$ ./capa -t "create process on Linux" /usr/sbin/sshd -q -j 

显示rules 目录内的 .yml 文件中的规则名称。比如说。

$ grep name rules/host-interaction/process/create/create-process-on-linux.yml
    name: create process on Linux

输出格式

最后,Capa允许使用-j 标志以JSON格式输出。这个标志有助于快速消耗信息,并帮助实现自动化。此示例命令需要安装jq命令

$ ./capa -t "create process on Linux" /usr/sbin/sshd -q -j | jq .

总结

Capa是对ELF可执行文件所急需的工具的一个有价值的补充。我说非常需要是因为我们现在经常看到Linux恶意软件的案例。Linux上的工具必须跟上,以应对这些威胁。你可以玩玩Capa,在各种可执行文件上试试,也可以写自己的规则,并把它们添加到上游,以利于社区的发展。