概述&介绍
这是篇综述性论文,出发点是希望能够系统性的描述、分析、理解Linux恶意软件。
作者设计了一个恶意软件分析系统(介绍了其实现),并通过该系统检测了10548个恶意样本,最后的分析结果包括:
- 搜集和分析Linux样本面对的挑战
- 二进制代码的静态分析
- 合适环境的配置
- 不同权限下的运行分析
- 针对Linux的攻击技术
- 反分析技巧
- 加壳
- 多态性
- 逃逸
- 持久驻留
- 恶意软件的常见行为
- 在多种操作系统中运行的能力
- 权限提升
- UPX加壳
- 和一些shell工具交互
- 分析有无root权限的情况下执行同一样本时的恶意软件行为
挑战
目标的多样性 Target Diversity
-
Linux支持多种计算机体系架构
-
不同的加载器和动态链接库(除了glibc外,有的会使用uClibc、musl等)
-
操作系统:难以区分不同版本的Linux、FreeBSD、Android的二进制文件
- ELF标头上包含“OS/ABI”字段原则上指定程序运行所需的操作系统,但实际上Linux和Android的ELF文件都指定了通用的System V
- Linux内核会将“OS/ABI”为“FreeBSD”的文件当作是有效的Linux程序(但是实际上除非是FreeBSD编译的动态链接程序,否则Linux和FreeBSD的系统调用参数不匹配导致程序会奔溃。
——>导致难以编译Linux恶意软件数据集、难以正常运行
静态链接 Static Linking
即所有的库依赖都包含在二进制文件中
逆向分析更加困难,还有上面提到的不同内核差异导致运行奔溃
Analysis Environment
重点是说Linux的恶意代码很多会以root权限运行(尤其时嵌入式设备),这样的话这些恶意代码甚至可以篡改运行它的沙箱,让程序行为的检测和观察更加复杂
缺乏前人的研究
- 如何构建分析管道
- 缺乏全面的数据集等
分析用的基础设施
主要将作者构建的恶意软件分析工具集,他们使用了包括AVClass,IDA pro,redare2,Nucleus以及他们自己设计的工具。总体过程如下图:
数据收集
- used the VirusTotal intelligence API to fetch the reports of every ELF file
- 每天下载200个候选样本——>尽量避免之前的问题,选出Linux文件
- 分类:140个取自超过五个AV阳性的样本;60个AV得分再1-5的样本。
文件和元数据
首先是分析文件本身,作者实现了一个自定义ELF格式解析器(用于提取出ELF文件的字段信息)
- 过滤掉与我们分析无关的文件
- 标识异常的文件结构(会阻止现有的工具对其正确处理)
- 提取每个样本的AV标签,输入AVClass以后的恶意软件系列的规范化名称
M. Sebastian, R. Rivera, P. Kotzias, and J. Caballero, “AVclass: A Tool for Massive Malware Labeling,” in RAID, 2016.
静态分析
包含两步
-
二进制逆向
- IDA Pro提取一些代码量度,如函数的数量、大小、圈复杂度(cyclomatic complexity)等等
- 计算了聚合度量(aggregated metrics),如the distribution of opcodes, or a rolling entropy of the different code and data sections. (不太懂这部分
-
判断是否加壳
将之前得到的ELF报文头部提取的信息和代码分析相结合,识别可能加过壳的程序
if packed : unpacked —-> statically analyzed again
如果无法静态脱壳,则在之后进行动态分析处理
动态分析
有两种动态分析类型
-
在instrumented emulator中执行五分钟
共五个沙盒
- KVM沙盒(x86和x86-64)
- QEMU沙盒(ARM 32位小端、MIPS 32位大端和PowerPC 32位)
沙盒嵌套在外部的VM中,会根据架构分配样本
使用SystemTap来实现内核探测(kprobes)和用户探测(uprobes),收集每个系统调用以及其参数和返回值,还有系统调用的指令指针,以及添加的搜集字符串和内存操作函数的附加信息。
以上部分执行结束后会返回一个文件包含系统调用和用户空间函数的完整过程
- —>解析:识别有用的反馈信息
- 缺少的组件(库和加载器)
- 是否需要测试其他用户权限(如果需要,会以root权限执行,并进行差异分析
- 报告异常样本执行时的错误
- 另外,还会监管样本使用时的网络流量情况
-
自定义加壳分析和脱壳尝试
开发了一个基于Unicorn的工具,该工具会模拟多个体系结构上的指令,可以在脱壳过程中导出UPX使用的有限系统调用集,进而实现大部分样本的从自动脱壳。
数据集
10548个ELF文件,覆盖了十多种不同架构
主要还是用AVClass工具进行了家族分类(83%的样本可以有效分类到108个家族)
分析数据集可以得出:
- 僵尸网络(Botnets)在Linux恶意软件中占主要地位(样本的69%,覆盖了25个以上家族)
- 可能原因1:缺乏保护的IoT设备很容易被攻击者获取(通过Shodan或者ZMap都可以很快的定位目标),用来做DDos的肉鸡。
- 可能原因2:这些恶意软件家族中一部分源码是公开的,导致了大量变体
- 其他样本还包括:后门、勒索软件、挖矿木马、银行木马、提权工具、rootkit、蠕虫等等。
Under The Hood(恶意代码使用的技战术分析)
篡改ELF头部
技术 | 样本数 | 占比 |
---|---|---|
Segment header table pointing beyond file data | 1 | 0.01% |
Overlapping ELF header/segment | 2 | 0.02% |
Wrong string table index (e_shstrndx) | 60 | 0.57% |
Section header table pointing beyond file data | 178 | 1.69% |
总计 | 211 | 2.00% |
这211个被篡改ELF头部的文件,都可以用IDA Pro 7正常解析,而readelf、GDB、pyelftools效果都不佳
恶意软件经常会篡改ELF头部以欺骗分析工具,这里分成了两类:导致异常文件(但仍然符合ELF文件规范)的修改和产生无效文件(但是可以正确执行)的修改
-
异常ELF
- 删掉了所有的ELF节信息
- 报告有关可执行文件的错误信息(例如针对不同ABI的程序会在运行时崩溃)
-
无效ELF
具有错误或者损坏的节信息的样本(2%)
持久性
Persistence,即实现在受害主机中的长期驻留,一般在windows里面会通过修改注册表、系统服务之类的方法。而Linux恶意软件需要依赖不同的策略(实际上就是修改类型不同的文件),这里分成了四类
Path | w/o root | w/ root |
---|---|---|
/etc/rc.d/rc.local | - | 1393 |
/etc/rc.conf | - | 1236 |
/etc/init.d/ | - | 210 |
/etc/rcX.d/ | - | 212 |
/etc/rc.local | - | 11 |
systemd service | - | 2 |
˜/.bashrc | 19 | 8 |
˜/.bash_profile | 18 | 8 |
X desktop autostart | 3 | 1 |
/etc/cron.hourly/ | - | 70 |
/etc/crontab | - | 70 |
/etc/cron.daily/ | - | 26 |
crontab utility | 6 | 6 |
File replacement | - | 110 |
File infection | 5 | 26 |
总计有1644个样本使用了该技术,占比21.10%,对于一个样本通常会连续使用多种技术以实现持久化
-
子系统初始化
利用Linux init系统(需要root权限):修改rc脚本;添加自己到etc/init.d里面,然后创建到保存运行级配置的目录的软链接。
-
基于时间的执行
利用corn(Unix系统的基于时间的作业调度程序),恶意代码会修改corn的配置文件,从而在固定的时间间隔执行。
(如果不是root权限,也可以通过利用crontab程序来进行配置cron)
-
文件感染和替换
感染或者替换目标中已经存在的应用程序,让其带动恶意代码执行
-
用户文件更改
如果没有root权限,恶意代码可能会修改用户目录的配置文件
伪装
样本中共有4091(50%)的样本修改了进程名
-
其中11%使用一些常用程序名(例如sshd, telnetd等)
-
基于prctl调用,使得/
proc/<PID>/status
中列出不同进程名(pstree等工具调用) -
修改
/proc/<PID>/cmdline
中的信息(ps会使用)
-
-
其中88%使用空名称、虚构名称或者随机名称
权限
有25%的样本在以普通用户访问时,会产生检索用户身份或者返回EPREM或者EACES的状况。在这些样本中,有89%的样本在以root用户执行时会显示出不同的行为。
出现的不同行为 | 样本数量 | 占比 |
---|---|---|
Execute privileged shell command | 579 | 21.96% |
Drop a file into a protected directory | 426 | 16.15% |
Achieve system-wide persistence | 259 | 9.82% |
Tamper with Sandbox | 61 | 2.31% |
Delete a protected file | 47 | 1.78% |
Run ptrace request on another process | 10 | 0.38% |
Delete a protected file | 47 | 1.78% |
Run ptrace request on another process | 10 | 0.38% |
最常见的由执行权限决定的操作是:提权攻击和内核交互
-
提权
在动态分析中,使用内核探针监视内核函数可以探测到恶意软件的提权情况(例如通过监视commit_creds可以检测正在运行的任务何时安装了新的凭据)
结果发现,在沙箱中的最新版Linux系统中,没有发现恶意软件成功提升权限或者在用户态下执行特权操作。
提权利用的最常见的十个漏洞包括:
CVE-2017-7308, CVE-2017-6074, CVE-2017-5123, CVE-2017-1000112,CVE-2016-9793, CVE-2016-8655, CVE-2016-5195(最常用), CVE-2016-0728, CVE-2015-1328, CVE-2014-4699
作者开发了自定义签名去识别利用这些漏洞的提权攻击
-
内核模块
在动态分析中可以检测到样本是否加载 或者卸载内核模块
结果发现,在用root权限重新执行的2637个恶意软件样本中,只有15个成功加载了内核模块,并且没有一个执行卸载过程,且这些样本都使用了
ip_table.ko
加壳和多态性
加壳可以很大程度上阻止静态分析,增大动态分析的难度。
相比于Windows,Linux系统的加壳程序并不多,以UPX为主。
作者使用一种基于文件段熵和静态分析结果的启发式方法来标记可能加壳的样本,同时添加了一组自定义分析例程识别可能的UPX变体,还加了一个通用的多架构解包器用来对这些UPX变体尝试脱壳。
发现,在加壳的380个文件中,只有3个不属于UPX及其变体(这三个使用了Mumblehard Packer)
加壳方式 | 样本数 | 占比 |
---|---|---|
Vanilla UPX | 189 | 1.79% |
Custom UPX Variant | 188 | 1.78% |
- Different Magic | 129 | |
- Modified UPX strings | 55 | |
- Inserted junk bytes | 126 | |
- All of the previous | 16 | |
Mumblehard Packer | 3 | 0.03% |
进程交互
主要是说恶意软件用于与Linux系统中已安装或运行的子进程或其他二进制文件交互的技术。
-
多进程
- 25%样本使用单进程
- 9%会产生一个新进程
- 43%共有三个进程(一般包括初始进程、新进程、管理进程)
- 23%有更多的独立进程
-
shell命令
13%的样本至少执行了一个外部shell命令(主要包括:sh, sed, cp, rm, grep, ps, insmod, chmod, cat, iptables等)
-
进程注入
攻击者会将新代码注入正在运行的进程中,以改变其行为,使样本更难调试,或者为了窃取信息挂钩其他函数。主要有以下三种方法:
- ptrace系统调用:请求
PTRACE_POKETEXT
,PTRACE_POKEDATA
或者PTRACE_POKEUSER
- 对于
/proc/<TARGET_PID>/mem
进行读/写操作后,请求PTRACE_ATTACH
- 使用
process_vm_writev
系统调用
在2010年后,Linux内核不再允许对于非当前进程的子进程使用ptrace,除非用户拥有
CAP_SYS_PTRACE
特权。发现的进程注入实例:
We found a sample performing injection by using the first technique mentioned above. It injects a dynamic library in every active process that uses
libc
(but excludes gnome-session, dbus and pulseaudio). In the injected payload the malware uses thelibc
function__libc_dlopen_mode
to load dynamic objects at runtime. This function is similar to the well-knowndlopen
, which is less preferable because implemented inlibdl
, not already included in thelibc
. After the new code is mapped in memory, the malware issuesptrace
requests to backup the registers values of the victim process, hijack the control flow to execute its malicious behavior, and restore the original execution context. - ptrace系统调用:请求
信息收集
恶意软件会通过收集信息来检测沙箱的存在,或者控制样本的执行,对于一些由C2服务器控制的程序,它们还可能会被发送到远程。
作者讨论了恶意软件为了收集信息会查看文件系统的哪些部分,以及安全人员在检查新的恶意软件时应该探测的相关路径。
-
proc和sysfs文件系统
- proc:有关进程、系统和硬件配置的运行时系统信息
- sysfs:有关内核子系统、硬件设备和内核驱动程序的信息
恶意软件主要收集的信息包括:系统配置、进程信息以及网络配置。
- 网络配置:
- 访问/proc/net/route(系统路由表)以获取活动网络接口及其相关配置的列表
- /proc/net/tcp(有效的tcp套接字)
- /proc/net/dev(发送和接收的数据包)
- /proc/net/arp(检索系统arp表)
- /sys/class/net/(获取传输队列长度)一般用于DDos攻击
- 系统配置:
- 已安装内存的数量、可用CPU内核的数量以及其他CPU特征
- 利用这部分信息可以完成沙箱检测和逃逸
- /proc/cmdline(检索正在运行的内核映像的名称)
- 进程信息:
- 用于防止同一恶意软件的多次执行
-
配置文件
- 主要是/etc/文件夹中的内容
- 包括实现持久驻留时经常需要的配置文件
- 网路相关的配置文件,如etc/resolv.conf(DNS解析器)、etc/hosts(主机和IP地址的映射)
- /etc/passwd、/etc/shadow (检查和注册用户)
隐藏逃逸
有的恶意软件会检测杀毒软件的存在状况,或者检测自己是在真实环境还是分析环境运行,进而达到隐藏自己恶意行为的目的。作者的分类如下:
Type of evasion | Samples | Percentage |
---|---|---|
Sandbox detection | 19 | 0.24% |
Processes enumeration | 259 | 3.32% |
Anti-debugging | 63 | 0.81% |
Anti-execution | 3 | 0.04% |
Stalling code | 0 | - |
-
沙箱检测
作者设计了字符串比较工具,检测到了有许多程序从系统中提取各种信息与字符串(如“VMware”、“QENU“)进行比较来检测沙箱的存在。
有十个样本在root权限执行时,能通过检测
sys_vender
文件来探测到作者所用的分析环境。另外有的样本能够通过比较/proc/1/mountinfo和
/proc/<malware PID>/mountinfo
来检测chroot()和OpenVZ的环境。当应用检测到自己在虚拟环境时,有的会选择简单的退出,而有的会采取删除整个文件系统等恶意行为。
-
进程枚举
在Windows环境下,恶意软件经常会通过验证一组特定进程的存在或者检查系统中存在的伴随进程的真实性来逃避分析。
而在作者的实验中,有259个样本会对
proc/<PID>
目录进行全面扫描,但是似乎并没有样本是为了逃避分析进行这些扫描的,而是为了之前说的检测系统是否已经被感染或者杀死目标进程。 -
反调试
最常见的反调试技术是基于
ptrace
系统调用,因为一个给定进程最多只能链接一个调试器,因此恶意软件通常会使用PTRACE_TRACEME
或PTRACE_ATTACH
标志的ptrace
系统调用,用于检测自己是否连接了另一个调试器。注意,作者在沙箱中使用的跟踪系统是基于内核探测的,因此不会被反调试技术检测或者篡改!
-
反沙箱执行
因为沙箱在分析之前通常会重命名文件,所有属于DnsAmp恶意软件家族分析的样本会将自己的文件名和硬编码字符串进行比较,如果不一致,则拒绝执行
(这部分不知道自己是不是理解正确,感觉也可以放在沙箱检测里面,无所谓了,这个方法也只是一个trick罢了)
-
拖延代码
Windows恶意软件通常会使用延迟执行的技术(假设分析沙箱只会运行每个样本几分钟)
作者分析的Linux恶意软件样本中,64%的二进制文件使用了nanosleep系统调用,其值从小于1秒到大于3小时不等,但是似乎并没有使用这些延迟来延缓执行,而是用来协调子进程或者网络通信。
库
80%以上的样本采用静态链接的方式
主要使用的库包括
- glibc 74.21%
- uclibc 24.24%
- libgcc 9.74%
- libstdc++ 7.12%
- libz 5.24%
作者研究发现,Linux恶意软件只有少部分会混淆他们的代码,以防人工分析,这与逃避Windows恶意软件的复杂性形成鲜明对比(例如实战分析之符号混淆和LD_PRELOAD技术的动态补丁破解)
总结
-
篡改ELF头部
- 产生异常的ELF
- 产生无效的ELF
-
持久性
修改文件系统,包括init system, cron, 或者是篡改良性软件让其启动恶意文件,以上基本都需要root权限,如果无,一般恶意软件会修改用户配置文件。
-
伪装
改名字
-
权限
- 提权(使用最新版全补丁的linux系统时,没有一个恶意软件能够完成提权)
- 内核交互,大多是调用ip_table.io
-
加壳
大部分使用UPX及其变体
-
进程交互
首先说了恶意软件大部分是三个或多个进程的形式
有的恶意软件会执行外部shell命令
为了隐藏或者获取外部应用信息,恶意软件会进行进程注入,主要通过ptrace的方式。
-
信息收集
主要探查proc和sysfs文件系统以及etc/中的配置信息
-
隐藏逃逸
主要是检测自己是否在沙箱,来躲避自己被分析(相比于windows,这些恶意软件的躲避方法比较少)
-
库
大部分使用静态链接库(80%),代码混淆较少
恶意软件家族
即使是属于同一家族的恶意软件样本,通常也会有非常不同的特征
在这里作者用Tsunami家族的样本举了例子
相关工作
对恶意ELF文件的分析
While the hacking community developed—almost two decades ago—interesting techniques to implement malicious ELF files [13], [41]–[44], rootkits [45], [46], and tools to dissect them [47]–[49], none of them has seen vast adoption.
In fact, the security industry has only recently started looking at ELF files—mainly driven by newsworthy cases like the Mirai botnet [50] and Shellshock [51].
Many blog posts and papers were published for the analysis and dissection of specific families [52]–[57], but these investigations were mainly conducted by manual reverse engineering.(手工逆向分析特定家族)
Recent research by Shazhad et al [58] and by Bai et al [59] extracts static features from ELF binaries to train a classifier for malware detection.(静态分类器)
动态分析的情况:解决方案少,支持的平台有限
For example, Limon [60] is an analysis sandbox based on strace (and thus easily detectable), and it only supports the analysis of x86-flavored binaries.
Sysdig [61] and PayloadSecurity [62] are affected by similar issues and they also only work for x86 binaries.
Detux [63], instead, supports four different architectures (i.e., x86, x86-64, ARM, and MIPS). However, it only performs a very basic analysis by running readelf and provides network dumps.
Cuckoo sandbox [64] is another available tool that supports the analysis of Linux samples. However, the Cuckoo project only provides the external orchestration analysis framework, while the preparation of the various sandbox images is left to the user.
Tencent/HaboMalHunter, there is no public report on how the system works and it currently works only for x86 binaries.
针对特定网络的系统研究:
IoTPOT: Analysing the Rise of IoT Compromises
Antonakakis et al., “Understanding the Mirai Botnet,” in Proceedings of the USENIX Security Symposium, 2017.
结论
本文首次对基于Linux的恶意软件进行了全面研究。我们记录了专门为Linux恶意软件定制的第一个分析管道的设计和实现,并讨论了第一个关于Linux恶意软件如何实现其恶意行为的大规模实证研究的结果。
虽然当前Linux恶意软件的复杂性不是很高,但我们已经发现了一些已经采用了从Windows同类软件中借鉴的技术的示例。我们认为,这些见解可以为该领域未来更系统的工作奠定基础,不幸的是,这一领域的重要性必将与日俱增。