diff options
author | We-unite <3205135446@qq.com> | 2024-08-09 13:56:37 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-12 14:16:51 +0800 |
commit | 3e49a044d22635157916651f0acb5a062397b34b (patch) | |
tree | 254cd9a2605fa003f4579e7c5510e6e2aea19375 /src/organize.go | |
parent | ea32e017e579f168d87732893335c38d539ac2f1 (diff) | |
download | godo-3e49a044d22635157916651f0acb5a062397b34b.tar.gz godo-3e49a044d22635157916651f0acb5a062397b34b.zip |
Add db structure, fix filePath, start filtering
This commit I made several changes:
- Use structure instead of simple bson.M(interface{}). bson.M has
some shortcomings: 1) It makes the database in chaos and hard to
read, but this's not important; 2) Some entrys may has more or
less content than others, which makes it hard to decode and filt.
So I design new data structure to encode and decode. Hopes that
there's no bugs.
- Fix the way to calculate file path. The original method is to add
all the PATH entries together, that's totally wrong! PATH entry
has several types, as it shows in "objtype". I can't find it in
the kernel src code, so what i know is just "PARENT" means the dir
the file is in, while the filename itself has the path, so we
whould ignore all "PARENT"s. When the src code is found, we should
check it again.
- Fix bugs in updating. The update function of mongodb is set to
required to has a '$' such as 'set'/'push', so when we update a
whole doc, we should use replace but not update function. And,
we should never ignore the error infomation it gives us.
Hope that there's no more bugs for this Big Change.
Now its' time to write filter as well as viewer. Best wishes with
NO BUGS!
Diffstat (limited to 'src/organize.go')
-rw-r--r-- | src/organize.go | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/src/organize.go b/src/organize.go deleted file mode 100644 index 293371b..0000000 --- a/src/organize.go +++ /dev/null | |||
@@ -1,291 +0,0 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "os" | ||
6 | "regexp" | ||
7 | "strconv" | ||
8 | "strings" | ||
9 | "sync" | ||
10 | "syscall" | ||
11 | |||
12 | "github.com/elastic/go-libaudit/v2" | ||
13 | "github.com/elastic/go-libaudit/v2/auparse" | ||
14 | ) | ||
15 | |||
16 | // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的 | ||
17 | var eventTable sync.Map | ||
18 | |||
19 | // 事件信息 | ||
20 | var tmp any | ||
21 | var ok bool | ||
22 | var event Event | ||
23 | var pEvent *Event | ||
24 | var eventId, argc int | ||
25 | |||
26 | // var errs [6]error | ||
27 | |||
28 | // 要用的正则匹配列表 | ||
29 | var ( | ||
30 | syscallRegex = regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+)(?:.*?exit=([-+]?\d+))?.*?ppid=(\d+) pid=(\d+).*?subj=(.*?):(.*?):(.*?):(.*?) .*?$`) | ||
31 | execveRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) | ||
32 | argsRegex = regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) | ||
33 | pathRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): item=(\d+) name="(.*?)"`) | ||
34 | cwdRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) | ||
35 | proctitleRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) | ||
36 | eoeRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) | ||
37 | ) | ||
38 | |||
39 | func orgnaze() { | ||
40 | defer wg.Done() | ||
41 | defer close(cookedChan) | ||
42 | // 接收信息 | ||
43 | var raw interface{} | ||
44 | var rawEvent libaudit.RawAuditMessage | ||
45 | |||
46 | for { | ||
47 | raw, ok = <-rawChan | ||
48 | if !ok { | ||
49 | break | ||
50 | } | ||
51 | rawEvent = raw.(libaudit.RawAuditMessage) | ||
52 | // fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) | ||
53 | |||
54 | switch rawEvent.Type { | ||
55 | case auparse.AUDIT_SYSCALL: | ||
56 | syscallRaw(rawEvent) | ||
57 | case auparse.AUDIT_EXECVE: | ||
58 | execve(rawEvent) | ||
59 | case auparse.AUDIT_CWD: | ||
60 | cwd(rawEvent) | ||
61 | case auparse.AUDIT_PATH: | ||
62 | path(rawEvent) | ||
63 | case auparse.AUDIT_PROCTITLE: | ||
64 | proctitle(rawEvent) | ||
65 | case auparse.AUDIT_EOE: | ||
66 | eoe(rawEvent) | ||
67 | default: | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | func syscallRaw(rawEvent libaudit.RawAuditMessage) { | ||
73 | if !syscallRegex.Match(rawEvent.Data) { | ||
74 | return | ||
75 | } | ||
76 | |||
77 | var exit int | ||
78 | var a [4]uint64 | ||
79 | var subj [4]string | ||
80 | // 捕获基础信息 | ||
81 | match := syscallRegex.FindSubmatch(rawEvent.Data) | ||
82 | event.timestamp, _ = getTimeFromStr(string(match[1])) | ||
83 | eventId, _ = strconv.Atoi(string(match[2])) | ||
84 | event.syscall, _ = strconv.Atoi(string(match[3])) | ||
85 | if string(match[4]) == "" { | ||
86 | // exit没捕获到 | ||
87 | exit = 0 | ||
88 | } else { | ||
89 | exit, _ = strconv.Atoi(string(match[4])) | ||
90 | } | ||
91 | event.ppid, _ = strconv.Atoi(string(match[5])) | ||
92 | event.pid, _ = strconv.Atoi(string(match[6])) | ||
93 | |||
94 | // 几个subj,说不定会有用 | ||
95 | for i := 0; i < 4; i++ { | ||
96 | subj[i] = string(match[7+i]) | ||
97 | } | ||
98 | |||
99 | // 捕获参数 | ||
100 | if !argsRegex.Match(rawEvent.Data) { | ||
101 | fmt.Fprintf(os.Stderr, "Error: don't get args in syscall event!\n") | ||
102 | return | ||
103 | } | ||
104 | argsMatch := argsRegex.FindAllSubmatch(rawEvent.Data, -1) | ||
105 | for i := 0; i < 4; i++ { | ||
106 | a[i], _ = strconv.ParseUint(string(argsMatch[i][3]), 16, 64) | ||
107 | } | ||
108 | |||
109 | switch syscallTable[event.syscall] { | ||
110 | case "execve": | ||
111 | eventTable.Store(eventId, &Event{ | ||
112 | tag: EXECVE, | ||
113 | timestamp: event.timestamp, | ||
114 | syscall: event.syscall, | ||
115 | exit_code: a[0], | ||
116 | ppid: event.ppid, | ||
117 | pid: event.pid, | ||
118 | argc: 0, | ||
119 | argv: make([]string, 0), | ||
120 | cwd: "", | ||
121 | }) | ||
122 | case "open": | ||
123 | // 检查打开的权限 | ||
124 | if a[1]&(syscall.O_APPEND|syscall.O_WRONLY|syscall.O_RDWR|syscall.O_TRUNC) == 0 { | ||
125 | break | ||
126 | } | ||
127 | // TRUNC应该被直接标记为改变,而不是打开 | ||
128 | eventTable.Store(eventId, &Event{ | ||
129 | tag: FILEOPEN, | ||
130 | timestamp: event.timestamp, | ||
131 | syscall: event.syscall, | ||
132 | exit_code: uint64(exit), | ||
133 | ppid: event.ppid, | ||
134 | pid: event.pid, | ||
135 | argc: 0, | ||
136 | argv: make([]string, 0), | ||
137 | cwd: "", | ||
138 | syscallParam: a, | ||
139 | srcPath: "", | ||
140 | }) | ||
141 | case "write": | ||
142 | eventTable.Store(eventId, &Event{ | ||
143 | tag: FILEWRITE, | ||
144 | timestamp: event.timestamp, | ||
145 | syscall: event.syscall, | ||
146 | exit_code: uint64(exit), | ||
147 | ppid: event.ppid, | ||
148 | pid: event.pid, | ||
149 | argc: 0, | ||
150 | argv: make([]string, 0), | ||
151 | cwd: "", | ||
152 | syscallParam: a, | ||
153 | }) | ||
154 | case "close": | ||
155 | // 文件关闭 | ||
156 | eventTable.Store(eventId, &Event{ | ||
157 | tag: FILECLOSE, | ||
158 | timestamp: event.timestamp, | ||
159 | syscall: event.syscall, | ||
160 | exit_code: uint64(exit), | ||
161 | ppid: event.ppid, | ||
162 | pid: event.pid, | ||
163 | argc: 0, | ||
164 | argv: make([]string, 0), | ||
165 | cwd: "", | ||
166 | syscallParam: a, | ||
167 | }) | ||
168 | case "pivot_root": | ||
169 | if subj[2] == "container_runtime_t" { | ||
170 | eventTable.Store(eventId, &Event{ | ||
171 | tag: PIVOTROOT, | ||
172 | timestamp: event.timestamp, | ||
173 | syscall: event.syscall, | ||
174 | ppid: event.ppid, | ||
175 | pid: event.pid, | ||
176 | syscallParam: a, | ||
177 | }) | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | func execve(rawEvent libaudit.RawAuditMessage) { | ||
183 | if !execveRegex.Match(rawEvent.Data) { | ||
184 | return | ||
185 | } | ||
186 | |||
187 | match := execveRegex.FindSubmatch(rawEvent.Data) | ||
188 | eventId, _ = strconv.Atoi(string(match[1])) | ||
189 | argc, _ = strconv.Atoi(string(match[2])) | ||
190 | tmp, ok = eventTable.Load(eventId) | ||
191 | if !ok { | ||
192 | return | ||
193 | } | ||
194 | pEvent = tmp.(*Event) | ||
195 | if argsRegex.Match(rawEvent.Data) { | ||
196 | match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) | ||
197 | for i := 0; i < argc; i++ { | ||
198 | if len(match[i][2]) == 0 { | ||
199 | // 代表着匹配到的是十六进制数 | ||
200 | str := hexToAscii(string(match[i][3])) | ||
201 | pEvent.argv = append(pEvent.argv, str) | ||
202 | } else { | ||
203 | pEvent.argv = append(pEvent.argv, string(match[i][2])) | ||
204 | } | ||
205 | } | ||
206 | pEvent.argc = argc | ||
207 | } | ||
208 | } | ||
209 | |||
210 | func cwd(rawEvent libaudit.RawAuditMessage) { | ||
211 | if !cwdRegex.Match(rawEvent.Data) { | ||
212 | return | ||
213 | } | ||
214 | |||
215 | match := cwdRegex.FindSubmatch(rawEvent.Data) | ||
216 | eventId, _ = strconv.Atoi(string(match[1])) | ||
217 | tmp, ok = eventTable.Load(eventId) | ||
218 | if !ok { | ||
219 | return | ||
220 | } | ||
221 | tmp.(*Event).cwd = string(match[2]) | ||
222 | } | ||
223 | |||
224 | func proctitle(rawEvent libaudit.RawAuditMessage) { | ||
225 | if !proctitleRegex.Match(rawEvent.Data) { | ||
226 | return | ||
227 | } | ||
228 | |||
229 | var cmdline string | ||
230 | match := proctitleRegex.FindSubmatch(rawEvent.Data) | ||
231 | eventId, _ = strconv.Atoi(string(match[1])) | ||
232 | tmp, ok = eventTable.Load(eventId) | ||
233 | if !ok { | ||
234 | return | ||
235 | } | ||
236 | pEvent = tmp.(*Event) | ||
237 | if pEvent.argc == 0 { | ||
238 | // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数 | ||
239 | if match[3] == nil { | ||
240 | // PROCTITLE写的是十六进制,转换为字符串 | ||
241 | cmdline = hexToAscii(string(match[4])) | ||
242 | } else { | ||
243 | cmdline = string(match[3]) | ||
244 | } | ||
245 | pEvent.argv = strings.Split(cmdline, " ") | ||
246 | pEvent.argc = len(pEvent.argv) | ||
247 | } | ||
248 | } | ||
249 | |||
250 | func eoe(rawEvent libaudit.RawAuditMessage) { | ||
251 | if !eoeRegex.Match(rawEvent.Data) { | ||
252 | return | ||
253 | } | ||
254 | |||
255 | match := eoeRegex.FindSubmatch(rawEvent.Data) | ||
256 | eventId, _ = strconv.Atoi(string(match[1])) | ||
257 | tmp, ok = eventTable.Load(eventId) | ||
258 | if !ok { | ||
259 | return | ||
260 | } | ||
261 | cooked := *(tmp.(*Event)) | ||
262 | cookedChan <- cooked | ||
263 | eventTable.Delete(eventId) // 死人别占地 | ||
264 | } | ||
265 | |||
266 | func path(rawEvent libaudit.RawAuditMessage) { | ||
267 | if !pathRegex.Match(rawEvent.Data) { | ||
268 | return | ||
269 | } | ||
270 | match := pathRegex.FindSubmatch(rawEvent.Data) | ||
271 | eventId, _ = strconv.Atoi(string(match[1])) | ||
272 | // item, _ := strconv.Atoi(string(match[2])) | ||
273 | name := string(match[3]) | ||
274 | |||
275 | tmp, ok = eventTable.Load(eventId) | ||
276 | if !ok { | ||
277 | return | ||
278 | } | ||
279 | pEvent = tmp.(*Event) | ||
280 | |||
281 | // 先看看是不是文件操作 | ||
282 | if pEvent.tag != FILEOPEN { | ||
283 | return | ||
284 | } | ||
285 | |||
286 | if name[0] == '/' { | ||
287 | pEvent.srcPath = name | ||
288 | } else { | ||
289 | pEvent.srcPath += "/" + name | ||
290 | } | ||
291 | } | ||