前言在过去的几年中,Linux面临着日益增长的威胁——基于无文件的恶意软件。无文件恶意软件是一种将自身注入正在运行的Linux系统而不在磁盘上留下任何痕迹的恶意软件。现在有很多实现无文件攻击的方法:1.执行二进制文件后从磁盘中删除自身。2.直接将代码注入正在运行的服务器而不写入磁盘(例如,在输入易受攻击的PHP服务器上运行PHP代码)。3、使用ptrace()等系统调用附加到正在运行的进程,将代码插入内存空间执行。4.使用诸如memfd_create()之类的方法在RAM中创建一个可运行的匿名文件。在这篇文章中,我们将讨论如何检测最后一个攻击向量。memfd_create()无文件攻击首先介绍一个Linux系统的底层调用函数memfd_create()。此功能允许您在RAM中创建常驻文件,将文件保存到RAM而不是文件系统本身。调用成功后,就可以引用这个内存驻留文件,就像操作磁盘目录中的文件一样。man中的描述:memfd_create()创建一个匿名文件并返回一个文件描述符。该文件的行为类似于普通文件,可以修改、截断、内存映射等。但是,与普通文件不同的是,它驻留在RAM中并且是易失性的。你可以理解为在Linux主机上不直接调用/bin/ls,而是将ls加载到RAM中,可以调用/ls。与许多系统调用一样,出于性能等原因可以合法使用它,但它也为攻击者提供了机会。更重要的是,如果系统重新启动或关闭,恶意软件会立即被清除,这对于隐藏入侵者的行为很有价值。有很多方法可以使用memfd_create()来发起攻击。它们都有相似的检测模式,所以使用哪一种都没有关系。在本文中,我们使用:InOnlyMemoryELFExecution。我们可以直接通过SSH传输二进制文件,这样就不会将任何内容写入磁盘,也不会生成交互式shell,这大大降低了攻击的检测可能性。攻击通过SSH向目标机器发送bindshell后门并执行。运行后,代码会驻留在目标机器上,并打开一个监听端口等待连接。入侵者可以在远程主机上执行任意命令。可以使用简单的ls和grep命令快速检测针对文章中演示的示例的无文件Linux攻击:ls-alR/proc/*/exe2>/dev/null|grepmemfd:.*(deleted)此命令将遍历/proc目录中所有正在运行的进程,并检查它们是否具有memfd:(deleted)形式的可执行路径。这个条目非常可疑,在无文件攻击中很常见。正常情况下运行这条命令后应该没有回显。如果您看到返回任何结果,您应该立即调查该过程。当然有时会有误报的风险,但对于这种类型的攻击,很少见(如果您有示例,请告诉我们)。执行命令显示如下目录项:lrwxrwxrwx1rootroot0Jul823:37/proc/14667/exe->/memfd:(deleted)在路径中,进程ID(PID)为14667,这就是我们需要焦点对象。如果攻击者使用了完整的方案来隐藏二进制文件,那么下面的策略可能会失败。但是对于常见的攻击,使用这种方法是快速高效的。使用命令行进行攻击取证本例中,bindshell启动后会立即绑定TCP31337端口,进行反向shell操作,开始发送窃取的敏感数据等,我们可以先使用netstat和ps命令进行攻击收集信息。通过netstat命令,我们注意到一个异常的tcp端口,这个端口的进程名也很奇怪:netstat-nalp如上图所示,这个进程的PID是14667,接下来就是使用PS命令查看进程的一些具体信息:ps-auxw在进程列表中,我们看到它的进程名为[kwerker/0:sandfly],这将有助于它隐藏在名称相近的合法进程中。你可以在上面的列表中看到,如果没有用标识符命名,我们真的很难发现白蛉。既然我们已经确定了可疑进程,下一步就是想办法获取有关该进程的具体信息。由于后面的大部分操作都会在/proc目录下进行,所以我们先进入/proc/目录,其中PID就是我们可疑的进程ID。可以通过以下命令进入该目录:cd/proc/14667进程目录列表在进程目录中,我们可以使用ls命令列出文件夹的内容。Linux内核会实时构建目录,并向我们展示很多有价值的信息。ls-al通过简单的ls命令,我们可以知道:1.进程启动时的日期戳。2.当前工作目录(用户最有可能在/root下启动进程)。3.EXE链接指向已删除二进制文件的位置。底线是,在Linux上,除了少数例外,带有已删除标记二进制文件的进程通常是恶意的。而且,进程不仅被删除,还指向了一个非常不寻常的位置:/memfd:这是攻击使用的内存文件描述符。使用Comm和Cmdline参数查找隐藏的Linux进程。/proc目录下的comm和cmdline文件会记录进程的命令名和进程完整的命令行信息,是一个很好的切入点。当启动带有参数的进程时,字符''将用于分隔每个参数。所以当我们使用cat命令查看cmdline文件内容时,只能打印出第一个参数,进程名。所以我们可以使用cat命令查看comm文件,使用strings命令查看cmdline文件。catcommstringscmdlinecomm和cmdline文件显示如下:在Linux中,大多数情况下,文件应显示基本匹配的二进制名称。例如,如果您在像nginx这样的网络服务器上运行它,您将在这两个文件的某处看到nginx名称。但是在这个例子中,comm文件中只有一个数字“3”,这是一种进程伪装的手段。此外,cmdline文件夹的内容很奇怪。这两个文件没有正确记录进程名称。使用进程映射验证二进制名称/proc/[pid]/maps文件显示进程的内存区域映射信息。也可以在这里找到二进制名称,以及在运行时使用的其他库文件。通常,此文件的第一部分包含对正在运行的二进制文件(例如/usr/bin/vi)的引用。但是在文件中我们再次看到对/memfd的奇怪引用:(已删除)。catmaps调查Linux进程环境许多人可能会忽略,在Linux上,当你启动一个进程时,它通常会附加一系列的环境变量。在大多数情况下,用户启动的任何进程都会出现在这里。我们试图通过查看/proc//environ文件夹来获取进程信息。同样,出于格式原因,我们将使用更易于阅读的strings命令。stringsenviron由于我们的恶意软件是通过SSH进入的,即使攻击者设法清理了有关IP地址的日志,在进程启动时仍然会留下痕迹。抓取二进制文件即使磁盘上不存在二进制文件,我们仍然可以很容易地恢复注入的二进制文件。具体的操作细节在恢复已删除的二进制文件一文中已经介绍的很详细,这里只简单介绍一下。cp/proc//exe/destination_dir/filename本例中命令如下:cpexe/tmp/malware.recovered文件恢复到/tmp/malware.recovered。你可以照常分析恶意样本,也可以生成二进制文件的哈希值:sha1sumexesha1sum/tmp/malware.recovered收集到的信息到目前为止,我们收集到了以下信息:1.可疑的可执行文件路径。2.进程使用的端口号。3.进程名称。4.comm和cmdline文件中没有引用相同的命令名称。5.comm文件内容只有一个字符长。6.进程的当前工作目录位于/root下。7.该进程尝试链接到已删除的/memfd位置而不是合法的二进制路径。8.流程图文件显示相同的删除位置。9.恶意软件通过SSH入侵事实上,Linux并没有刻意隐藏任何信息。他们就像屋檐上的守望者,或者就像我们在Sandfly上所说的那样:试图隐藏是入侵的一种特征。
