aboutsummaryrefslogtreecommitdiffstats
path: root/src/organize.go
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-08-09 13:56:37 +0800
committerWe-unite <3205135446@qq.com>2024-08-12 14:16:51 +0800
commit3e49a044d22635157916651f0acb5a062397b34b (patch)
tree254cd9a2605fa003f4579e7c5510e6e2aea19375 /src/organize.go
parentea32e017e579f168d87732893335c38d539ac2f1 (diff)
downloadgodo-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.go291
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 @@
1package main
2
3import (
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在操作系统运行期间是唯一的
17var eventTable sync.Map
18
19// 事件信息
20var tmp any
21var ok bool
22var event Event
23var pEvent *Event
24var eventId, argc int
25
26// var errs [6]error
27
28// 要用的正则匹配列表
29var (
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
39func 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
72func 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
182func 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
210func 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
224func 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
250func 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
266func 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}