diff options
Diffstat (limited to 'src/organize.go')
-rw-r--r-- | src/organize.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/organize.go b/src/organize.go new file mode 100644 index 0000000..025d8c0 --- /dev/null +++ b/src/organize.go | |||
@@ -0,0 +1,124 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
4 | "regexp" | ||
5 | "strconv" | ||
6 | "strings" | ||
7 | |||
8 | "github.com/elastic/go-libaudit/v2" | ||
9 | "github.com/elastic/go-libaudit/v2/auparse" | ||
10 | ) | ||
11 | |||
12 | func orgnaze() { | ||
13 | defer wg.Done() | ||
14 | defer close(cookedChan) | ||
15 | // 接收信息 | ||
16 | var raw interface{} | ||
17 | var ok bool | ||
18 | var rawEvent libaudit.RawAuditMessage | ||
19 | // 事件信息 | ||
20 | var eventId, argc int | ||
21 | var err [6]error | ||
22 | var event, cooked Event | ||
23 | // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的 | ||
24 | eventTable := make(map[int]*Event) | ||
25 | // 要用的正则匹配列表 | ||
26 | syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?ppid=(\d+) pid=(\d+).*?$`) | ||
27 | execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) | ||
28 | argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) | ||
29 | cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) | ||
30 | proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) | ||
31 | eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) | ||
32 | for { | ||
33 | raw, ok = <-rawChan | ||
34 | if !ok { | ||
35 | break | ||
36 | } | ||
37 | rawEvent = raw.(libaudit.RawAuditMessage) | ||
38 | |||
39 | // type Event struct { | ||
40 | // timestamp time.Time | ||
41 | // pid, ppid int | ||
42 | // syscall int | ||
43 | // argc int | ||
44 | // args []string | ||
45 | // cwd string | ||
46 | // } | ||
47 | switch rawEvent.Type { | ||
48 | case auparse.AUDIT_SYSCALL: | ||
49 | if syscallRegex.Match(rawEvent.Data) { | ||
50 | match := syscallRegex.FindSubmatch(rawEvent.Data) | ||
51 | event.timestamp, err[0] = getTimeFromStr(string(match[1])) | ||
52 | eventId, err[1] = strconv.Atoi(string(match[2])) | ||
53 | event.syscall, err[2] = strconv.Atoi(string(match[3])) | ||
54 | event.ppid, err[3] = strconv.Atoi(string(match[4])) | ||
55 | event.pid, err[4] = strconv.Atoi(string(match[5])) | ||
56 | eventTable[eventId] = &Event{ | ||
57 | timestamp: event.timestamp, | ||
58 | syscall: event.syscall, | ||
59 | ppid: event.ppid, | ||
60 | pid: event.pid, | ||
61 | argc: 0, | ||
62 | argv: make([]string, 0), | ||
63 | cwd: "", | ||
64 | } | ||
65 | } | ||
66 | case auparse.AUDIT_EXECVE: | ||
67 | if execveRegex.Match(rawEvent.Data) { | ||
68 | match := execveRegex.FindSubmatch(rawEvent.Data) | ||
69 | eventId, err[0] = strconv.Atoi(string(match[1])) | ||
70 | argc, err[1] = strconv.Atoi(string(match[2])) | ||
71 | if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) { | ||
72 | match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) | ||
73 | for i := 0; i < argc; i++ { | ||
74 | if len(match[i][2]) == 0 { | ||
75 | // 代表着匹配到的是十六进制数 | ||
76 | str := hexToAscii(string(match[i][3])) | ||
77 | eventTable[eventId].argv = append(eventTable[eventId].argv, str) | ||
78 | } else { | ||
79 | eventTable[eventId].argv = append(eventTable[eventId].argv, string(match[i][2])) | ||
80 | } | ||
81 | } | ||
82 | eventTable[eventId].argc = argc | ||
83 | } | ||
84 | } | ||
85 | // case auparse.AUDIT_PATH: | ||
86 | case auparse.AUDIT_CWD: | ||
87 | if cwdRegex.Match(rawEvent.Data) { | ||
88 | match := cwdRegex.FindSubmatch(rawEvent.Data) | ||
89 | eventId, err[0] = strconv.Atoi(string(match[1])) | ||
90 | eventTable[eventId].cwd = string(match[2]) | ||
91 | } | ||
92 | case auparse.AUDIT_PROCTITLE: | ||
93 | if proctitleRegex.Match(rawEvent.Data) { | ||
94 | var cmdline string | ||
95 | var pEvent *Event | ||
96 | match := proctitleRegex.FindSubmatch(rawEvent.Data) | ||
97 | eventId, err[0] = strconv.Atoi(string(match[1])) | ||
98 | pEvent = eventTable[eventId] | ||
99 | if pEvent.argc == 0 { | ||
100 | // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数 | ||
101 | if match[3] == nil { | ||
102 | // PROCTITLE写的是十六进制,转换为字符串 | ||
103 | cmdline = hexToAscii(string(match[4])) | ||
104 | } else { | ||
105 | cmdline = string(match[3]) | ||
106 | } | ||
107 | pEvent.argv = strings.Split(cmdline, " ") | ||
108 | pEvent.argc = len(eventTable[eventId].argv) | ||
109 | } | ||
110 | } | ||
111 | case auparse.AUDIT_EOE: | ||
112 | if eoeRegex.Match(rawEvent.Data) { | ||
113 | match := eoeRegex.FindSubmatch(rawEvent.Data) | ||
114 | eventId, err[0] = strconv.Atoi(string(match[1])) | ||
115 | // ATTENTION: 事件整理完毕,即刻发出,是否合理呢? | ||
116 | cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验 | ||
117 | cookedChan <- cooked | ||
118 | delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地 | ||
119 | } | ||
120 | default: | ||
121 | // ATTENTION: 这里也需要做防护 | ||
122 | } | ||
123 | } | ||
124 | } | ||