diff options
author | We-unite <3205135446@qq.com> | 2024-07-29 11:46:02 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-07-29 11:46:02 +0800 |
commit | a345258c3082903702c81c6c830ff1fd35758861 (patch) | |
tree | a8521e954630b299c85adc10182ee3470a982415 | |
parent | ec260a31927ef77295eaa07ba370b58b416f47f5 (diff) | |
download | godo-a345258c3082903702c81c6c830ff1fd35758861.tar.gz godo-a345258c3082903702c81c6c830ff1fd35758861.zip |
Hear file Open and close, especially O_TRUNC
this commit i successfully catch open/close syscall, and insert them
as an independent collection in mongodb otherwise along with pids.
and now I've record those open flag "O_TRUNC" as written.
-rw-r--r-- | src/deal.go | 101 | ||||
-rw-r--r-- | src/global.go | 1 | ||||
-rw-r--r-- | src/godo.go | 11 | ||||
-rw-r--r-- | src/mongo.go | 12 | ||||
-rw-r--r-- | src/organize.go | 59 |
5 files changed, 133 insertions, 51 deletions
diff --git a/src/deal.go b/src/deal.go index a9861a5..d3b5da0 100644 --- a/src/deal.go +++ b/src/deal.go | |||
@@ -3,6 +3,7 @@ package main | |||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "sync" | 5 | "sync" |
6 | "syscall" | ||
6 | "time" | 7 | "time" |
7 | 8 | ||
8 | "go.mongodb.org/mongo-driver/bson" | 9 | "go.mongodb.org/mongo-driver/bson" |
@@ -11,10 +12,11 @@ import ( | |||
11 | const ( | 12 | const ( |
12 | dbName string = "test" | 13 | dbName string = "test" |
13 | pidColName string = "pids" | 14 | pidColName string = "pids" |
15 | fdColName string = "fds" | ||
14 | ) | 16 | ) |
15 | 17 | ||
16 | var mongoMutex sync.Mutex | 18 | var mongoMutex sync.Mutex |
17 | var pidCol mongoClient | 19 | var pidCol, fdCol mongoClient |
18 | 20 | ||
19 | var docRes []bson.M | 21 | var docRes []bson.M |
20 | var err error | 22 | var err error |
@@ -24,11 +26,29 @@ func deal() { | |||
24 | var cooked Event | 26 | var cooked Event |
25 | var ok bool | 27 | var ok bool |
26 | 28 | ||
27 | if err = initMongo(); err != nil { | 29 | if err = pidCol.init(dbName, pidColName); err != nil { |
28 | fmt.Printf("Error while initing the mongodb: %v\n", err) | 30 | fmt.Printf("Error while initing the mongodb: %v\n", err) |
29 | return | 31 | return |
30 | } | 32 | } |
33 | err = pidCol.InsertOne(bson.M{ | ||
34 | "ppid": 1, | ||
35 | "pid": containerdPid, | ||
36 | "cwd": "/", | ||
37 | "children": []bson.M{}, | ||
38 | }) | ||
39 | if err != nil { | ||
40 | fmt.Printf("Error while initing the mongodb: %v\n", err) | ||
41 | return | ||
42 | } | ||
43 | |||
44 | if err = fdCol.init(dbName, fdColName); err != nil { | ||
45 | fmt.Printf("Error while initing the mongodb: %v\n", err) | ||
46 | return | ||
47 | } | ||
48 | |||
49 | fmt.Printf("Containerd: %d\n", containerdPid) | ||
31 | defer pidCol.Disconnect() | 50 | defer pidCol.Disconnect() |
51 | defer fdCol.Disconnect() | ||
32 | 52 | ||
33 | for { | 53 | for { |
34 | cooked, ok = <-cookedChan | 54 | cooked, ok = <-cookedChan |
@@ -43,6 +63,10 @@ func deal() { | |||
43 | dealExecve(cooked) | 63 | dealExecve(cooked) |
44 | case PIDEXIT: | 64 | case PIDEXIT: |
45 | go deletePid(cooked) | 65 | go deletePid(cooked) |
66 | case FILEOPEN: | ||
67 | fileOpen(cooked) | ||
68 | case FILECLOSE: | ||
69 | fileClose(cooked) | ||
46 | } | 70 | } |
47 | } | 71 | } |
48 | } | 72 | } |
@@ -71,28 +95,6 @@ func deletePid(cooked Event) { | |||
71 | mongoMutex.Unlock() | 95 | mongoMutex.Unlock() |
72 | } | 96 | } |
73 | 97 | ||
74 | func initMongo() error { | ||
75 | var err error | ||
76 | if err = pidCol.Connect(dbName, pidColName); err != nil { | ||
77 | return err | ||
78 | } | ||
79 | if err = pidCol.Drop(); err != nil { | ||
80 | return err | ||
81 | } | ||
82 | |||
83 | err = pidCol.InsertOne(bson.M{ | ||
84 | "ppid": 1, | ||
85 | "pid": containerdPid, | ||
86 | "cwd": "/", | ||
87 | "children": bson.M{}, | ||
88 | }) | ||
89 | if err != nil { | ||
90 | return err | ||
91 | } | ||
92 | fmt.Printf("Containerd: %d\n", containerdPid) | ||
93 | return nil | ||
94 | } | ||
95 | |||
96 | func dealNewPid(cooked Event) { | 98 | func dealNewPid(cooked Event) { |
97 | // 有无父进程在观察中 | 99 | // 有无父进程在观察中 |
98 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | 100 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) |
@@ -181,3 +183,54 @@ func dealExecve(cooked Event) { | |||
181 | } | 183 | } |
182 | mongoMutex.Unlock() | 184 | mongoMutex.Unlock() |
183 | } | 185 | } |
186 | |||
187 | func fileOpen(cooked Event) { | ||
188 | // 查看是否记录了该进程 | ||
189 | res, err := pidCol.Finddoc(bson.M{"pid": cooked.pid}) | ||
190 | if err != nil { | ||
191 | fmt.Printf("Error finding pid %d: %v\n", cooked.pid, err) | ||
192 | } | ||
193 | if len(res) == 0 { | ||
194 | // 没找着,滚 | ||
195 | return | ||
196 | } | ||
197 | |||
198 | // 确有该进程 | ||
199 | // 权限检查过了,不必再查 | ||
200 | fdCol.InsertOne(bson.M{ | ||
201 | "timestamp": cooked.timestamp, | ||
202 | "fileName": cooked.pathName, | ||
203 | "pid": cooked.pid, | ||
204 | "fd": cooked.exit_code, | ||
205 | "flags": cooked.syscallParam, | ||
206 | "written": []bson.M{}, | ||
207 | }) | ||
208 | |||
209 | if cooked.syscallParam[1]&syscall.O_TRUNC != 0 { | ||
210 | fdCol.UpdateOne(bson.M{"pid": cooked.pid, "fd": cooked.exit_code}, bson.M{ | ||
211 | "$push": bson.M{ | ||
212 | "written": cooked.timestamp, | ||
213 | }, | ||
214 | }) | ||
215 | } | ||
216 | } | ||
217 | |||
218 | func fileClose(cooked Event) { | ||
219 | // 直接看文件表有无记录 | ||
220 | res, err := fdCol.Finddoc(bson.M{ | ||
221 | "pid": cooked.pid, | ||
222 | "fd": cooked.syscallParam[0], | ||
223 | "close_timestamp": bson.M{"$exists": false}, | ||
224 | }) | ||
225 | if err != nil { | ||
226 | fmt.Printf("Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err) | ||
227 | } | ||
228 | if len(res) == 0 { | ||
229 | return | ||
230 | } | ||
231 | fdCol.UpdateOne(bson.M{ | ||
232 | "pid": cooked.pid, | ||
233 | "fd": cooked.syscallParam[0], | ||
234 | "close_timestamp": bson.M{"$exists": false}, | ||
235 | }, bson.M{"$set": bson.M{"close_timestamp": cooked.timestamp}}) | ||
236 | } | ||
diff --git a/src/global.go b/src/global.go index 7401dc5..d1c5c0f 100644 --- a/src/global.go +++ b/src/global.go | |||
@@ -13,6 +13,7 @@ const ( | |||
13 | EXECVE | 13 | EXECVE |
14 | FILEOPEN | 14 | FILEOPEN |
15 | FILEWRITE | 15 | FILEWRITE |
16 | FILECLOSE | ||
16 | TYPENUM | 17 | TYPENUM |
17 | ) | 18 | ) |
18 | 19 | ||
diff --git a/src/godo.go b/src/godo.go index 2a00dad..0edcc9f 100644 --- a/src/godo.go +++ b/src/godo.go | |||
@@ -44,12 +44,13 @@ func main() { | |||
44 | auditCmd.Run() | 44 | auditCmd.Run() |
45 | } | 45 | } |
46 | 46 | ||
47 | // // 监听文件的消息 | 47 | // 监听文件的消息 |
48 | fileSyscall := []string{"open", "write", "close"} | ||
48 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} | 49 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} |
49 | // for i := 0; i < len(fileSyscall); i++ { | 50 | for i := 0; i < len(fileSyscall); i++ { |
50 | // auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) | 51 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i]) |
51 | // auditCmd.Run() | 52 | auditCmd.Run() |
52 | // } | 53 | } |
53 | 54 | ||
54 | // 查找pid | 55 | // 查找pid |
55 | containerdPid, err = getPid() | 56 | containerdPid, err = getPid() |
diff --git a/src/mongo.go b/src/mongo.go index d00abd2..54f9533 100644 --- a/src/mongo.go +++ b/src/mongo.go | |||
@@ -15,6 +15,18 @@ type mongoClient struct { | |||
15 | col *mongo.Collection | 15 | col *mongo.Collection |
16 | } | 16 | } |
17 | 17 | ||
18 | func (mc *mongoClient) init(dbName, colName string) error { | ||
19 | var err error | ||
20 | if err = mc.Connect(dbName, colName); err != nil { | ||
21 | return err | ||
22 | } | ||
23 | if err = mc.Drop(); err != nil { | ||
24 | return err | ||
25 | } | ||
26 | |||
27 | return nil | ||
28 | } | ||
29 | |||
18 | func (mc *mongoClient) Connect(dbName, colName string) error { | 30 | func (mc *mongoClient) Connect(dbName, colName string) error { |
19 | var err error | 31 | var err error |
20 | mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) | 32 | mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) |
diff --git a/src/organize.go b/src/organize.go index 2489961..1b064c1 100644 --- a/src/organize.go +++ b/src/organize.go | |||
@@ -95,7 +95,7 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) { | |||
95 | } | 95 | } |
96 | argsMatch := argsRegex.FindAllSubmatch(rawEvent.Data, -1) | 96 | argsMatch := argsRegex.FindAllSubmatch(rawEvent.Data, -1) |
97 | for i := 0; i < 4; i++ { | 97 | for i := 0; i < 4; i++ { |
98 | a[i], errs[0] = strconv.ParseUint(string(argsMatch[i][2]), 16, 64) | 98 | a[i], errs[0] = strconv.ParseUint(string(argsMatch[i][3]), 16, 64) |
99 | } | 99 | } |
100 | 100 | ||
101 | switch syscallTable[event.syscall] { | 101 | switch syscallTable[event.syscall] { |
@@ -117,25 +117,6 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) { | |||
117 | cwd: "", | 117 | cwd: "", |
118 | }) | 118 | }) |
119 | } | 119 | } |
120 | case "open": | ||
121 | // 检查打开的权限 | ||
122 | if a[1]&(syscall.O_APPEND|syscall.O_WRONLY|syscall.O_RDWR|syscall.O_TRUNC) == 0 { | ||
123 | break | ||
124 | } | ||
125 | // TRUNC应该被直接标记为改变,而不是打开 | ||
126 | eventTable.Store(eventId, &Event{ | ||
127 | tag: FILEOPEN, | ||
128 | timestamp: event.timestamp, | ||
129 | syscall: event.syscall, | ||
130 | exit_code: uint64(exit), | ||
131 | ppid: event.ppid, | ||
132 | pid: event.pid, | ||
133 | argc: 0, | ||
134 | argv: make([]string, 0), | ||
135 | cwd: "", | ||
136 | syscallParam: a, | ||
137 | pathName: "", | ||
138 | }) | ||
139 | case "execve": | 120 | case "execve": |
140 | eventTable.Store(eventId, &Event{ | 121 | eventTable.Store(eventId, &Event{ |
141 | tag: EXECVE, | 122 | tag: EXECVE, |
@@ -160,6 +141,40 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) { | |||
160 | argv: make([]string, 0), | 141 | argv: make([]string, 0), |
161 | cwd: "", | 142 | cwd: "", |
162 | }) | 143 | }) |
144 | case "open": | ||
145 | // 检查打开的权限 | ||
146 | if a[1]&(syscall.O_APPEND|syscall.O_WRONLY|syscall.O_RDWR|syscall.O_TRUNC) == 0 { | ||
147 | break | ||
148 | } | ||
149 | // TRUNC应该被直接标记为改变,而不是打开 | ||
150 | eventTable.Store(eventId, &Event{ | ||
151 | tag: FILEOPEN, | ||
152 | timestamp: event.timestamp, | ||
153 | syscall: event.syscall, | ||
154 | exit_code: uint64(exit), | ||
155 | ppid: event.ppid, | ||
156 | pid: event.pid, | ||
157 | argc: 0, | ||
158 | argv: make([]string, 0), | ||
159 | cwd: "", | ||
160 | syscallParam: a, | ||
161 | pathName: "", | ||
162 | }) | ||
163 | case "close": | ||
164 | // 文件关闭 | ||
165 | eventTable.Store(eventId, &Event{ | ||
166 | tag: FILECLOSE, | ||
167 | timestamp: event.timestamp, | ||
168 | syscall: event.syscall, | ||
169 | exit_code: uint64(exit), | ||
170 | ppid: event.ppid, | ||
171 | pid: event.pid, | ||
172 | argc: 0, | ||
173 | argv: make([]string, 0), | ||
174 | cwd: "", | ||
175 | syscallParam: a, | ||
176 | // pathName: "", | ||
177 | }) | ||
163 | } | 178 | } |
164 | } | 179 | } |
165 | 180 | ||
@@ -244,7 +259,7 @@ func eoe(rawEvent libaudit.RawAuditMessage) { | |||
244 | } | 259 | } |
245 | cooked := *(tmp.(*Event)) | 260 | cooked := *(tmp.(*Event)) |
246 | cookedChan <- cooked | 261 | cookedChan <- cooked |
247 | fmt.Printf("Send: %10d\t%v\t%7d\t%7d\n", eventId, cooked.tag, cooked.ppid, cooked.pid) | 262 | // fmt.Printf("Send: %10d\t%v\t%7d\t%7d\n", eventId, cooked.tag, cooked.ppid, cooked.pid) |
248 | eventTable.Delete(eventId) // 死人别占地 | 263 | eventTable.Delete(eventId) // 死人别占地 |
249 | } | 264 | } |
250 | 265 | ||
@@ -267,7 +282,7 @@ func path(rawEvent libaudit.RawAuditMessage) { | |||
267 | return | 282 | return |
268 | } | 283 | } |
269 | 284 | ||
270 | if pEvent.pathName == "" { | 285 | if name[0] == '/' { |
271 | pEvent.pathName = name | 286 | pEvent.pathName = name |
272 | } else { | 287 | } else { |
273 | pEvent.pathName += "/" + name | 288 | pEvent.pathName += "/" + name |