当前位置: 首页 > Linux

技术分享-Linux入侵检测中的进程创建监控

时间:2023-04-06 06:26:10 Linux

作者简介:张博,网易高级信息安全工程师。0x00Introduction在入侵检测过程中,进程创建监控是必不可少的,因为大多数攻击者的攻击行为都是以进程的形式呈现的,所以及时获取新进程创建的信息可以帮助我们快速定位攻击行为。本文将介绍监控进程创建的一些常用方法,包括其原理、demo、使用条件、优缺点。文笔仓促。如有错误和不足,希望大家批评指正。0x01常用方法目前常用的获取进程创建信息的方法有四种:sopreloadNetlinkConnectorAuditSyscallhook接下来我们将从原理、demo、使用条件、优缺点等方面来了解这四种方法。0x02Sopreload原理首先给大家介绍两个基础知识:1.Linux中大部分的可执行程序都是动态链接的,与进程执行相关的常用函数,如execve,都是在动态链接库libc中实现的。所以。2、Linux提供了so预加载机制,允许定义一个先加载的动态链接库,这样用户就可以在不同的动态链接库中选择性地加载相同的功能。结合以上两点,不难得出结论,我们可以使用sopreload覆盖libc.so中的execve等函数来监控进程的创建。Demo下面来实现一个简单的demo。1.创建一个hook.c文件,内容如下:#define_GNU_SOURCE#include#include#includetypedefssize_t(*execve_func_t)(constchar*filename,char*constargv[],char*constenvp[]);staticexecve_func_told_execve=NULL;intexecve(constchar*filename,char*constargv[],char*constenvp[]){printf("Runninghook\n");printf("程序执行:%s\n",filename);old_execve=dlsym(RTLD_NEXT,"execve");returnold_execve(filename,argv,envp);}这个文件的主要部分是重新定义execve函数,在原来的execve执行之前打印可执行文件的名字。2、生成动态链接库:gcchook.c-fPIC-shared-ohook.so3、将上面生成的动态链接库注册为preload:echo'/path/to/hook.so'>/etc/ld。所以.preload4。退出当前shell,重新登录(下面会解释原因),执行命令可以看到我们写的代码已经执行了:使用条件这种方法没有限制,只需要root权限(用于入侵监控需要程序的root权限,以下方法默认也在root权限下)。优缺点优点轻量级,只修改库函数代码,不与内核交互。缺点对于第四步的使用方法,大家可能会有疑惑:为什么要重新获取shell才能看到效果呢?这是因为在当前shell下执行命令(即执行execve)的实际上是当前的shell可执行程序,比如bash,而bash需要的动态链接库在开始运行的时候就已经确定了,所以我们按照添加预加载不会影响当前的bash,只有添加预加载后创建的进程才会受到预加载的影响。这也导致了该方法的第一个缺点:它只能影响preload之后创建的进程,这就需要尽早安装检测Agent,并尽量在其他应用进程启动之前完成安装。此外,还有以下缺点:无法监控静态链接程序:目前,一些蠕虫和木马为了减少对环境的依赖而使用静态链接,不会加载共享库。在这种情况下,这种监控方法是失败的。容易被攻击者发现和篡改:目前一些蠕虫和木马也会在/etc/ld.so.preload中写入后门,以方便对机器进行持久控制。在这种情况下,这种监控方式也会失效。攻击者可以使用int80h绕过libc直接调用系统调用,这种情况下这种监控方式也会失效。0x03NetlinkConnector原理在介绍NetlinkConnector之前,先了解什么是Netlink。Netlink是一个套接字家族(socketfamily),用于内核和用户态进程与用户态进程之间的IPC通信。我们经常使用的ss命令是通过Netlink与内核通信获取的信息。NetlinkConnector是Netlink的一种,其Netlink协议号为NETLINK_CONNECTOR,其代码位于https://github.com/torvalds/l...,其中connectors.c和cnqueue.c为NetlinkConnector的实现代码,而cnproc.c是一个叫做进程事件连接器的应用实例,通过它我们可以监控进程的创建。系统架构:(图片来源:https://www.slideshare.net/ke...)具体流程:(图片来源:https://4hou.win/wordpress/?p...)图中的ncp就是NetlinkConnectorProcess,也就是我们需要在用户态开发的程序。Demo在Github上开发了一个简单的基于进程事件连接器的进程监控程序:https://github.com/ggrandes-c...,其核心函数有以下三个:nl_connect:与内核建立连接set_proc_ev_listen:订阅流程事件handle_proc_ev:处理流程事件,其执行流程如上图所示。我们通过gccpmon.c-opmon生成一个可执行程序,然后执行程序看效果:获取到pid后,到/proc//目录下获取进程的详细信息。使用条件Kernel支持NetlinkConnectorversion>2.6.14Kernelconfigurationenabled:cat/boot/config-$(uname-r)|egrep'CONFIG_CONNECTOR|CONFIG_PROC_EVENTS'优缺点优点轻量级,可以获取内核提供的用户模式信息。缺点是只能获取pid,详细信息需要到/proc//查看,有时间差,可能造成数据丢失。0x04Audit原理LinuxAudit是Linux内核中用于审计的组件,可以监控系统调用和文件访问。具体结构如下(图片来源:https://slack.engineering/sys...):状态管理进程配置规则(如图中的go-audit,也可以换成常用的auditd),并通过Netlink套接字通知内核。2、内核中的kauditd通过Netlink获取规则并加载。3.当应用程序调用系统调用和从系统调用返回时,会经过kauditd,kauditd会记录这些事件,并通过Netlink发送回用户态进程。4.用户态进程解析事件日志并输出。Demo从上面的架构图可以看出整个框架分为用户态和内核态两部分。内核空间的kauditd是不可变的,用户态的程序是可以定制的。目前最常用的用户态程序是auditd。著名的osquery也与Audit交互,获取底层的流程事件(https://medium.com/palantir/a...)。下面简单介绍一下如何通过auditd监控进程创建。首先安装并启动auditd:aptupdate&&aptinstallauditdsystemctlstartauditd&&systemctlstatusauditdauditd包中包含一个命名线控制程序auditctl,我们可以在命令行中使用它与auditd进行交互,使用如下命令创建一对execve这个系统调用监控:auditctl-aexit,always-Farch=b64-Sexecve然后通过auditd软件包中的ausearch检索auditd产生的日志:ausearch-scexecve|grep/usr/bin/id执行整个过程结果如下:至于其他的使用方式,可以通过manauditd和manauditctl查看。使用条件内核打开auditcat/boot/config-$(uname-r)|grep^CONFIG_AUDIT优缺点优缺点优点组件齐全,使用auditd包中的工具可以满足大部分需求,无需额外开发代码。与NetlinkConnector相比,获取的信息更加全面,而不仅仅是pid。缺点性能消耗随着进程数的增加而增加,需要通过增加白名单等配置来限制其资源占用。0x05Syscallhook上面的NetlinkConnector和Audit是Linux自己提供的监控系统调用的方法。如果我们想要有更大程度的定制化,我们需要通过安装内核模块来挂钩系统调用。原理目前常用的hook方法是通过修改sys_call_table(Linux系统调用表)来实现的。具体原理是系统在执行系统调用时,通过系统调用号在sys_call_table中找到对应的函数进行调用,所以只要将sys_call_table中的execve对应的函数的地址改成该函数的地址即可我们安装的内核模块中的功能。具体实现细节可以参考这篇YSRC文章玉龙HIDS是如何实现进程监控的:https://mp.weixin.qq.com/s/nt...,这里贴一下文章里的图片方便大家对整个过程有一个直观的认识:DemoaboutSyscallhookDemo,在Github上找了很多demo代码,包括御龙HIDS的hook模块,但是这些都不能在我的机器上使用(Ubuntu16.04Kernel4.4.0-151-generic)正常工作,这也暴露了Syscallhook的兼容性问题。最后,我决定使用Sysdig进行演示。Sysdig是一个开源系统监控工具。其核心原理是通过内核模块监控系统调用,将系统调用抽象为事件。用户可以根据这些事件自定义检测规则。Sysdig作为一个比较成熟的产品,兼容性比较好,所以这里用它来做演示,也方便大家自己测试。具体步骤如下:1.通过官方安装脚本安装:curl-shttps://s3.amazonaws.com/download.draios.com/stable/install-sysdig|sudobash2.检查内核模块是否安全:lsmod|grepsysdig3。启动execve的监控:sysdigevt.type=execve最终执行效果如下:关于Sysdig的更多信息,可以访问其wiki获取。此外,Sysdig团队还推出了专用于安全监控的工具Falco,基于Sysdig,Falco抽象出更具可读性的检测规则,支持部署在容器中。同样,如果你有兴趣,可以访问它的wiki了解更多信息。可以使用条件安装内核模块。需要针对不同的Linux发行版和内核版本进行定制。优缺点优点定制化程度高,从系统调用层面获取完整信息。缺点是开发难度大。兼容性差,需要针对不同的发行版和内核版本进行定制和测试。0x06总结本文讲4种监控进程创建的常用方法。这些方法本质上都是监控库函数或者系统调用,各有优缺点。这里我将每一个总结成一句话:Sopreload:HooklibraryFunction,不与内核交互,轻量级但容易被绕过。NetlinkConnector:从内核获取数据,监控系统调用。轻量级,只能直接获取pid。其他信息需要通过读取/proc//来完成。Audit:从内核获取数据,监控系统调用,功能很多,不仅可以监控进程创建,还可以获取比较全面的信息。Syscallhook:从内核获取数据,监控系统调用,最接近实际系统调用,定制化程度高,兼容性差。就我个人而言,纯粹从监控进程创建的角度来说,还是推荐使用NetlinkConnector的方式。这种方式足够轻量,方便定制化开发,同时保证从内核获取数据。如果你想监控包括进程、网络和文件在内的所有方面,审计是一个不错的选择。另外,本文以demo的形式介绍功能,主要是提醒我们吸睛的作用。至于每种方法的稳定性,还没有完全测试过。如果您有这方面的测试数据,请在这里与您分享和讨论。0x07参考https://4hou.win/wordpress/?p...https://tech.meituan.com/2019...https://www.ibm.com/developer...https://linux-audit.com/conf...https://my.oschina.net/macwe/...https://mp.weixin.qq.com/s/nt...https://mp.weixin.qq.com/s?__...https://github.com/draios/sysdighttps://github.com/falcosecur...