summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-07-29 11:46:02 +0800
committerWe-unite <3205135446@qq.com>2024-07-29 11:46:02 +0800
commita345258c3082903702c81c6c830ff1fd35758861 (patch)
treea8521e954630b299c85adc10182ee3470a982415
parentec260a31927ef77295eaa07ba370b58b416f47f5 (diff)
downloadgodo-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.go101
-rw-r--r--src/global.go1
-rw-r--r--src/godo.go11
-rw-r--r--src/mongo.go12
-rw-r--r--src/organize.go59
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
3import ( 3import (
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 (
11const ( 12const (
12 dbName string = "test" 13 dbName string = "test"
13 pidColName string = "pids" 14 pidColName string = "pids"
15 fdColName string = "fds"
14) 16)
15 17
16var mongoMutex sync.Mutex 18var mongoMutex sync.Mutex
17var pidCol mongoClient 19var pidCol, fdCol mongoClient
18 20
19var docRes []bson.M 21var docRes []bson.M
20var err error 22var 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
74func 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
96func dealNewPid(cooked Event) { 98func 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
187func 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
218func 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
18func (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
18func (mc *mongoClient) Connect(dbName, colName string) error { 30func (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