大家好,欢迎来到IT知识分享网。
一 前言
IDS一般指入侵检测系统。 入侵检测系统(intrusion detection system,简称“IDS”)是一种对网络传输进行即时监视,在发现可疑传输时发出警报或者采取主动反应措施的网络安全设备。
HIDS全称是Host-based Intrusion Detection System,即基于主机型入侵检测系统,部署在主机内的,主要是对主机的异常行为进行检测,比如新建文件,创建进程,连接等。
二 eHIDS 介绍和使用
2.1 eHIDS 基本介绍
目前来说eHIDS只算是一个HIDS的雏形,很多功能还没有完成,但是因为我最近对eBPF比较感兴趣,这个是基于eBPF实现的,所以了解下。
官方说明:
eBPF内核技术实现的HIDS . 功能实现:
TCP网络数据捕获
UDP网络数据捕获
uprobe方式的DNS信息捕获
进程数据捕获
uprobe方式实现JAVA的RASP命令执行场景事件捕获
eBPF的go框架实现,针对kprobe\uprobe挂载方式,多类型event进行抽象实现。
开发者只需要实现内核态C文件,用户态go文件,用户态event消息结构体三个文件即可,框架会自动加载执行。
使用者可以按照logger的interface自行实现数据的上报处理,比如上报到ES\kafka等日志中心。 网址: [ehids/ehids-agent: A Linux Host-based Intrusion Detection System based on eBPF. (github.com)](https://github.com/ehids/ehids-agent)
原理:
运行在内核态用C写eBPF代码,llvm编译为eBPF字节码。
用户态使用golang编写,cilium/ebpf纯go类库,做eBPF字节码的内核加载,kprobe/uprobe HOOK对应函数。
用户态使用golang做事件读取、解码、处理。
2.2 实践
git clone https://github.com/ehids/ehids-agent.git cd ehids make ./bin/ehids-agent
编译的时候,会报错,报错原因是go-bindata无法下载,将go.sum的配置更改如下: 需要删除原来的go-bindata的配置,然后添加
github.com/shuLhan/go-bindata v4.0.0+incompatible h1:xD8LkuVZLV5OOn/IEuFdt6EEAW7deWiqgwaaSGhjAJc= github.com/shuLhan/go-bindata v4.0.0+incompatible/go.mod h1:pkcPAATLBDD2+SpAPnX5vEM90F7fcwHCvvLCMXcmw3g=
eBPF的环境安装参考:
[[译]使用eBPF(绕过 TCP/IP)加速云原生应用程序的经验教训 – CFC4N的博客 (cnxct.com)](https://www.cnxct.com/lessons-using-ebpf-accelerating-cloud-native-zh/?f=github#i-3)
运行:
root@ubuntu-lab:/home/miao/ehids-agent-modify# ./bin/ehids 2022/04/17 04:30:25 https://github.com/ehids/ehids-agent 2022/04/17 04:30:25 process pid: 23069 2022/04/17 04:30:25 start to run EBPFProbeProc module 2022/04/17 04:30:25 start to run EBPFProbeUDNS module 2022/04/17 04:30:25 start to run EBPFProbeUJavaRASP module 2022/04/17 04:30:25 start to run EBPFProbeUBash module 2022/04/17 04:30:25 start to run EBPFProbeBPFCall module 2022/04/17 04:30:25 start to run EBPFProbeKTCP module 2022/04/17 04:30:25 start to run EBPFProbeKTCPSec module 2022/04/17 04:30:25 start to run EBPFProbeKUDP module 2022/04/17 04:30:25 HOOK binrayPath:/bin/bash, FunctionName:readline 2022/04/17 04:30:25 target all process. 2022/04/17 04:30:26 process pid: 23069 Xshell2022/04/17 04:54:33 probeName:EBPFProbeProc, probeTpye:kprobe, fork event,childpid:1, childtgid:23737, parentpid:23737, parenttgid:23721, grandparentpid:23720, grandparentgid:21960, cwd_level:0, comm:java, cmdline:javaMain, filepath:java, start_time:, uid:21960, gid:0,uts_ium:0, &{ID:8803 QR:1 Opcode:0 AA:0 TC:0 RD:1 RA:1 Z:0 RCODE:0 QDCOUNT:1 ANCOUNT:1 NSCOUNT:0 ARCOUNT:0} 2022/04/17 04:56:19 probeName:EBPFProbeKUDP, probeTpye:kprobe, PID:0, comm:systemd-resolve, qname:www.baidu.com, qclass:1, qtype:28. qtype:QTypeCNAME, qinfo:[CNAME] :wwwashifencom. 2022/04/17 04:56:19 probeName:EBPFProbeKTCPSec, probeTpye:kprobe, start time:10:31:23, PID:912, UID:103, AF:2, TASK:5systemd-resolv &{ID:39561 QR:1 Opcode:0 AA:0 TC:0 RD:1 RA:1 Z:0 RCODE:0 QDCOUNT:1 ANCOUNT:0 NSCOUNT:0 ARCOUNT:0} 2022/04/17 04:56:19 probeName:EBPFProbeKUDP, probeTpye:kprobe, PID:0, comm:systemd-resolve, qname:www.a.shifen.com, qclass:1, qtype:28. &{ID:55505 QR:1 Opcode:0 AA:0 TC:0 RD:1 RA:1 Z:0 RCODE:0 QDCOUNT:1 ANCOUNT:1 NSCOUNT:0 ARCOUNT:1} 2022/04/17 04:56:19 probeName:EBPFProbeKUDP, probeTpye:kprobe, PID:0, comm:ping, qname:www.baidu.com, qclass:1, qtype:28. qtype:QTypeCNAME, qinfo:[CNAME] :wwwashifen. &{ID:14298 QR:1 Opcode:0 AA:0 TC:0 RD:1 RA:1 Z:0 RCODE:0 QDCOUNT:1 ANCOUNT:3 NSCOUNT:0 ARCOUNT:0} 2022/04/17 04:56:19 probeName:EBPFProbeKUDP, probeTpye:kprobe, PID:0, comm:systemd-resolve, qname:www.baidu.com, qclass:1, qtype:1. qtype:QTypeCNAME, qinfo:[CNAME] :wwwashifen. qtype:QTypeA, qinfo:[A] :14.215.177.38. qtype:QTypeA, qinfo:[A] :14.215.177.39. &{ID:12746 QR:1 Opcode:0 AA:0 TC:0 RD:1 RA:1 Z:0 RCODE:0 QDCOUNT:1 ANCOUNT:3 NSCOUNT:0 ARCOUNT:1} 2022/04/17 04:56:19 probeName:EBPFProbeKUDP, probeTpye:kprobe, PID:0, comm:ping, qname:www.baidu.com, qclass:1, qtype:1. qtype:QTypeCNAME, qinfo:[CNAME] :wwwashifen. qtype:QTypeA, qinfo:[A] :14.215.177.38. qtype:QTypeA, qinfo:[A] :14.215.177.39.
可以看到它加载了几个插件,来实现上述功能,运行时候,捕获进程数据、UDP数据、DNS的信息,以及监控到的java运行程序信息等,并打印,当然可以自己方便扩展。
三 处理流程
3.1 流程处理说明
为了看懂代码,特意学习了下golang,大概对流程有了了解, 启动点是main.go 核心代码,加载各个模块代码,进行初始化和运行:
for k, module := range user.GetModules() { if module.Name() != "EBPFProbeBPFCall" { //continue //模块启用临时开关 } logger.Printf("start to run %s module", k) //初始化 err := module.Init(ctx, logger) if err != nil { panic(err) } // 加载ebpf,挂载到hook点上,开始监听 go func(module user.IModule) { err := module.Run() if err != nil { logger.Fatalf("%v", err) } }(module) }
每个功能以一个模块的形式来运行,module是定义的一组接口,如下
type IModule interface { // Init 初始化 Init(context.Context, *log.Logger) error // Name 获取当前module的名字 Name() string // Run 事件监听感知 Run() error // Start 启动模块 Start() error // Stop 停止模块 Stop() error // Close 关闭退出 Close() error SetChild(module IModule) Decode(*ebpf.Map, []byte) (string, error) Events() []*ebpf.Map DecodeFun(p *ebpf.Map) (IEventStruct, bool) }
在user的目录下的imodule.go代码文件中定义,里面定义了相关方法的基本实现。 然后各个模块把自己注册到全局的map中,go语言比较有意思map的定义比较奇葩,如下:
var modules = make(map[string]IModule)
以string作为key,IModule作为value的map 变量modules,通过开放函数:
func GetModules() map[string]IModule { return modules }
返回。 核心模块的类(结构体)的类图如下:
运行的整体流程
- 将c代码开发的proc_kern.c等ebpf程序,通过LLVM编译成 ebuf的byte code 字节码;
- 利用go-bindata 将字节码文件转成go文件,为assets/ebpf_probe.go;
- main.go 获取模块组信息,运行模块初始化;
- main.go 调用模块的Run方法,Run方法调用IModule接口的start方法,在这里面通过bpfManager加载epbf_probe.go字节码;
- Module.ReadEvent 获取事件的map,判断map类型,按照类型读取map数据(读取之前判断是否结束),读取数据后,通过Decode方法进行解码,Decode 需要获取解码函数,然后根据不同的event进行解码。 6.解码结束后,通过Write方法写到屏幕上,或者写到ES中去。
3.2 扩展
可以看到,整个流程还是比较简单的,扩展:
- 基于bcc开发ebpf程序的c代码,代码运行在内核中的。
- 实现特定事件处理接口,即字节码转成具体的结构体成员。
- 开发go的Module,加载ebpf的字节码,注册等;
总结: 虽然整体来说开发难度一般,ebpf程序本身开发起来可以更简单的,这里面主要用了ebpfManager的开源框架,方便了go语言开发,架构相对比较好一些,其他的也没啥了。
[ehids/ebpfmanager: A golang ebpf libary base on cilium/ebpf and datadog/ebpf. (github.com)](https://github.com/ehids/ebpfmanager)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/108224.html