如何分析Linux恶意软件--Symbiote的案例研究

作者:Sec-Labs | 发布时间:

概括

Symbiote 是一种 Linux 威胁,它挂钩 libc 和 libpcap 函数以隐藏恶意活动。 该恶意软件通过实现名为 hidden_​​proc 和 hidden_​​file 的两个函数来隐藏活动期间使用的进程和文件。 它还可以基于端口列表并通过劫持任何注入的数据包过滤字节码来隐藏网络连接。 该恶意软件的目的是通过挂钩 libc 读取功能从 SSH 和 SCP 进程中窃取凭据。 提取的凭据使用 RC4 加密,存储在系统上的文件中,然后通过 DNS 请求泄露到 C2 服务器。

分析师 @GeeksCyber

技术分析

SHA256:121157e0fcb728eb8a23b55457e89d45d76aa3b7d01d3d49105890a00662c924

这是一个 64 位 ELF 共享对象,似乎是 Symbiote 恶意软件 。 该恶意软件的较新版本具有更多功能,BlackBerry 的分析中对此进行了描述。 该文件未被剥离。

该恶意软件挂钩以下函数:fopen、fopen64、pam_authenticate、pam_set_item、read、readdir、readdir64 和 recvmsg。 我们将提供有关钩子实现的详细信息。

利用dlsym函数获取fopen的地址,然后进程调用原函数(0xFFFFFFFFFFFFFFFF = RTLD_DEFAULT ):

图1

当应用程序试图打开包含所有 TCP 连接的“/proc/net/tcp”文件时,钩子函数的执行流程是不同的:

图 2

ELF 文件通过调用 tmpfile 方法创建一个临时文件,从上述文件中读取第一行,并将其写入新创建的文件中:

图 3

使用 getline 函数逐行读取文件。 在由于失败(包括文件结束条件)而返回 -1 的情况下,进程关闭文件并释放分配给该行的内存区域:

图 4

恶意软件实现了一个名为 gen_proc_net_port 的函数。 此函数的目的是检索应隐藏的端口列表。 上面读取的一行是否包含任何端口,该行不写入临时文件,进程移动到下一行:

图 5

功能实现如下图所示:

图 6

钩子函数返回临时文件对应的文件描述符。 fopen64 函数以类似的方式挂钩。

利用dlsym函数获取pam_authenticate的地址,然后进程调用原函数:

图 7

恶意软件调用 pam_get_item 方法以获取以下信息:0x1 = PAM_SERVICE – 服务名称,0x4 = PAM_RHOST – 请求主机名,0x2 = PAM_USER – 用户名。 还有一个对 getaddrlist 的函数调用,将在接下来的段落中解释:

图 8

基于上面提取的信息,该过程构造以下字符串“pam|<getaddrlist result>|<PAM_SERVICE>|<PAM_RHOST>|<PAM_USER>|<cs:pampassword>”。 使用“/usr/include/linux/usb/usb.h”参数调用名为 saveline 的函数(参见图 9)。 这个特定的功能将在接下来的段落中进行剖析。

图 9

ELF 二进制文件实现了一个名为erasefree 的擦除功能。 它用零覆盖一个区域,然后指向该区域的指针将被释放:

图 10
图 11

利用dlsym函数获取pam_set_item的地址,然后进程调用原函数:

图 12

该过程期望 item_type 值等于 0x6 ( PAM_AUTHTOK ),这是身份验证令牌(通常是密码):

图 13

dlsym 函数用于获取 readdir 的地址,如下图所示:

图 14

该恶意软件实现了一个名为 check_proc 的函数,稍后将对此进行解释。 根据此函数返回的布尔值,进程调用原始的 readdir 方法,然后调用 hidden_​​file 或 hidden_​​proc:

图 15

readdir64 函数以类似的方式挂钩。

利用dlsym函数获取recvmsg的地址,然后进程调用原函数:

图 16

恶意进程需要一个特定的消息结构,即message[8] = 0xc, message[16] != 0,如下图所示:

图 17

ELF 二进制使用 hton 将无符号短整数从主机字节顺序转换为网络字节顺序。 使用 memcpy 方法将消息复制到另一个内存区域:

图 18

在 check_proc 函数中,恶意软件获取目录流文件描述符并计算以下路径“/proc/self/fd/<File descriptor>”:

图 19

上面构造的路径指向使用 readlink 方法读取的符号链接。 该函数返回 1 符号链接是否包含“/proc”,否则返回 0:

图 20

该恶意软件实现了一个名为 check_ssh_scp 的函数。 它通过使用“/proc/self/exe”参数调用 readlink 函数来获取可执行文件的位置:

图 21

此函数的目的是检测 SCP/SSH 可执行文件的存在,如果是,则返回 0:

图 22

Symbiote 在名为 crc32b 的函数中实现了 CRC32b 算法。 该算法可以使用 0xEDB88320 常量来识别:

图 23

有一个名为 create_file 的函数可用于创建文件。 它调用 open 方法(0x441 = O_WRONLY | O_CREAT | O_APPEND ):

图 24

该进程将文件的权限更改为 0x1B6 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ,这意味着所有用户都可以读写但不能执行文件:

图 25

在名为 dns 的函数中,ELF 二进制文件检索当前进程 ID,该 ID 使用 htons 从主机字节顺序转换为网络字节顺序:

图 26

恶意软件调用一个名为 ChangetoDnsNameFormat 的函数,下面将对此进行解释:

图 27

恶意进程创建一个用于与 C2 服务器通信的套接字(0x2 = AF_INET ,0x2 = SOCK_DGRAM ,0x11 = IPPROTO_UDP )。 使用 inet_addr 方法将 C2 服务器地址从点分十进制表示法转换为整数:

图 28

sendto 函数用于向 C2 服务器发送数据:

图 29

名为 ChangetoDnsNameFormat 的函数准备了 DNS 数据泄露请求的结构:

图 30

在名为 getaddrlist 的函数中,ELF 二进制文件使用 getifaddrs 方法提取包含本地计算机网络接口的结构的链表:

图 31

根据上面提取的结构,该过程通过调用 getnameinfo 函数来提取 IP 地址:

图 32

接口 IP 地址使用 strcat 方法连接在一起:

图 33

在 getserver 函数中,恶意二进制文件尝试打开一个名为“/tmp/resolv.conf”的文件:

图 34

该恶意软件正在上述文件中寻找名称服务器。 如果没有名称服务器,则该进程将使用 Google DNS 服务器 (8.8.8.8) 将 DNS 请求作为 UDP 广播发送:

图 35

该过程比较 hidden_​​file 函数中的两个字符串(文件名),如果它们匹配则返回 0:

图 36

The hidden_proc function expects a process ID as an argument. It calls the strspn and strlen functions in order to ensure that the process ID consists of digits only:

图 37

ELF 二进制文件从“/proc/<pid>/status”文件中检索有关进程的信息,如图 38 所示。

图 38

此函数的目的是比较两个进程名称,如果它们匹配则返回 0(参见图 39)。 Symbiote 的目标是隐藏一些与恶意软件相关的进程,例如:certbotx64、certbotx86、javautils、javaserverx64、javaclientex64、javanodex86(BlackBerry 的文章)。

图 39

dlsym 函数用于获取读取方法的地址。 如果 SSH 或 SCP 进程正在调用 libc 读取函数,则将 hook_read 设置为 keylogger,如下所述:

图 40

在 keylogger 函数中,进程调用原始的 read 函数,文件描述符对应 SSH 或 SCP。 它还调用 isatty 方法以确保文件描述符指向终端:

图 41

可执行文件调用名为 log_cmd_line 的函数,然后调用 getaddrlist。 第一个功能将在以下段落中详细介绍:

图 42

恶意软件构造了一个具有以下结构的字符串“<getaddrlist result>|<log_cmd_line result>|pw_5673”。 它使用“/usr/include/linux/usb/usb.h”参数调用 saveline 函数:

图 43

仅对 SSH 或 SCP 进程调用 log_cmd_line 方法。 这些进程之一的命令行从“/proc/self/cmdline”中读取:

图 44

realloc 方法用于释放旧对象并返回指向新对象的指针:

图 45

从 SSH 或 SCP 进程中提取的凭证使用 RC4 算法(密钥 = “suporte42at​​endimento53log”)进行加密。 加密的内容将用于在 sendlines 函数中构造 DNS 请求:

Figure 46

The malicious process creates a file called “/usr/include/linux/usb/usb.h” by calling create_file:

Figure 47

The encrypted credentials are written to the file created above:

图 48

在 sendlines 函数中,恶意软件使用 uname 方法获取有关当前内核的信息。 基于生成的缓冲区,该进程计算一个机器 ID,它由使用 crc32b 生成的 4 个字节组成(存储在 id_6274 中):

Figure 49

The encrypted credentials are hex-encoded and splitted to be exfiltrated via DNS requests to a domain owned by the threat actor. The A DNS request has the following format:

  • <Packet number – starts from 0x2B67 = 11111>.<Machine ID – Crc32b hash>.<Hex-encoded data>.px32.nss.atendimento-estilo[.]com

Finally, the executable calls the dns function that will exfiltrate data:

图 50

RC4算法的实现如下:

Figure 51
图 52

IOC情报

C2域:px32.nss.service-style[.]com

SHA256:121157e0fcb728eb8a23b55457e89d45d76aa3b7d01d3d49105890a00662c924

创建的文件:/usr/include/linux/usb/usb.h

 

原文地址

https://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/

标签:学习笔记