aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/audit.go84
-rw-r--r--src/basefunc.go129
-rw-r--r--src/deal.go265
-rw-r--r--src/global.go49
-rw-r--r--src/go.mod26
-rw-r--r--src/go.sum96
-rw-r--r--src/go.work6
-rw-r--r--src/go.work.sum4
-rw-r--r--src/godo.go164
-rw-r--r--src/mongo.go98
m---------src/netlink0
-rw-r--r--src/organize.go291
-rw-r--r--src/receive.go29
13 files changed, 0 insertions, 1241 deletions
diff --git a/src/audit.go b/src/audit.go
deleted file mode 100644
index ed48691..0000000
--- a/src/audit.go
+++ /dev/null
@@ -1,84 +0,0 @@
1package main
2
3import (
4 "fmt"
5 "io"
6 "log"
7 "os"
8
9 "github.com/elastic/go-libaudit/v2"
10)
11
12func read() error {
13 // Write netlink response to a file for further analysis or for writing
14 // tests cases.
15 var diagWriter io.Writer
16 if *diag != "" {
17 f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o600)
18 if err != nil {
19 return err
20 }
21 defer f.Close()
22 diagWriter = f
23 }
24
25 log.Println("starting netlink client")
26
27 var err error
28 var client *libaudit.AuditClient
29 if *receiveOnly {
30 client, err = libaudit.NewMulticastAuditClient(diagWriter)
31 if err != nil {
32 return fmt.Errorf("failed to create receive-only audit client: %w", err)
33 }
34 defer client.Close()
35 } else {
36 client, err = libaudit.NewAuditClient(diagWriter)
37 if err != nil {
38 return fmt.Errorf("failed to create audit client: %w", err)
39 }
40 defer client.Close()
41
42 status, err := client.GetStatus()
43 if err != nil {
44 return fmt.Errorf("failed to get audit status: %w", err)
45 }
46 log.Printf("received audit status=%+v", status)
47
48 if status.Enabled == 0 {
49 log.Println("enabling auditing in the kernel")
50 if err = client.SetEnabled(true, libaudit.WaitForReply); err != nil {
51 return fmt.Errorf("failed to set enabled=true: %w", err)
52 }
53 }
54
55 if status.RateLimit != uint32(*rate) {
56 log.Printf("setting rate limit in kernel to %v", *rate)
57 if err = client.SetRateLimit(uint32(*rate), libaudit.NoWait); err != nil {
58 return fmt.Errorf("failed to set rate limit to unlimited: %w", err)
59 }
60 }
61
62 if status.BacklogLimit != uint32(*backlog) {
63 log.Printf("setting backlog limit in kernel to %v", *backlog)
64 if err = client.SetBacklogLimit(uint32(*backlog), libaudit.NoWait); err != nil {
65 return fmt.Errorf("failed to set backlog limit: %w", err)
66 }
67 }
68
69 if status.Enabled != 2 && *immutable {
70 log.Printf("setting kernel settings as immutable")
71 if err = client.SetImmutable(libaudit.NoWait); err != nil {
72 return fmt.Errorf("failed to set kernel as immutable: %w", err)
73 }
74 }
75
76 log.Printf("sending message to kernel registering our PID (%v) as the audit daemon", os.Getpid())
77 if err = client.SetPID(libaudit.NoWait); err != nil {
78 return fmt.Errorf("failed to set audit PID: %w", err)
79 }
80 }
81
82 coroutine(client)
83 return nil
84}
diff --git a/src/basefunc.go b/src/basefunc.go
deleted file mode 100644
index 2f39507..0000000
--- a/src/basefunc.go
+++ /dev/null
@@ -1,129 +0,0 @@
1package main
2
3import (
4 "bufio"
5 "fmt"
6 "os"
7 "os/exec"
8 "path/filepath"
9 "strconv"
10 "strings"
11 "time"
12)
13
14func figureOutSyscalls() error {
15 cmd := exec.Command("ausyscall", "--dump")
16 stdout, err := cmd.StdoutPipe()
17 if err != nil {
18 return err
19 }
20
21 if err := cmd.Start(); err != nil {
22 return err
23 }
24
25 scanner := bufio.NewScanner(stdout)
26 for i := 0; scanner.Scan(); i++ {
27 if i == 0 {
28 continue
29 }
30 line := scanner.Text()
31 parts := strings.Split(line, "\t")
32 if len(parts) != 2 {
33 return fmt.Errorf("invalid ausyscall format")
34 }
35 num, err := strconv.Atoi(parts[0])
36 if err != nil {
37 return err
38 }
39 syscallTable[num] = parts[1]
40 }
41
42 if err := scanner.Err(); err != nil {
43 return err
44 }
45 if err := cmd.Wait(); err != nil {
46 return err
47 }
48 return nil
49}
50
51func getPid() (int, error) {
52 // 指定要搜索的关键词
53 keyword := "/usr/bin/containerd"
54
55 // 获取/proc目录下的所有子目录
56 procDir, err := filepath.Glob("/proc/*")
57 if err != nil {
58 return 0, err
59 }
60
61 // 遍历子目录,查找包含关键词的进程
62 for _, dir := range procDir {
63 pid, err := strconv.Atoi(filepath.Base(dir))
64 if err != nil {
65 continue // 跳过非PID的目录
66 }
67
68 // 检查进程是否包含关键词
69 if containsKeyword(pid, keyword) {
70 return pid, nil
71 }
72 }
73 err = fmt.Errorf("Error: no containerd process found.")
74 return 0, err
75}
76
77func containsKeyword(pid int, keyword string) bool {
78 // 构造完整的进程命令路径
79 cmdPath := fmt.Sprintf("/proc/%d/cmdline", pid)
80
81 // 打开文件
82 file, err := os.Open(cmdPath)
83 if err != nil {
84 return false
85 }
86 defer file.Close()
87
88 // 读取文件内容
89 scanner := bufio.NewScanner(file)
90 scanner.Split(bufio.ScanLines)
91 for scanner.Scan() {
92 line := scanner.Text()
93 if strings.Contains(line, keyword) {
94 return true
95 }
96 }
97 return false
98}
99
100func getTimeFromStr(timeStr string) (time.Time, error) {
101 timestampFloat, err := strconv.ParseFloat(timeStr, 64)
102 if err != nil {
103 return time.Unix(0, 0), err
104 }
105 secs := int64(timestampFloat)
106 nsecs := int64((timestampFloat - float64(secs)) * 1e9)
107
108 // 只精确到毫秒就够了
109 t := time.Unix(secs, nsecs).Truncate(time.Millisecond)
110 return t, nil
111}
112
113func hexToAscii(hexString string) string {
114 bytes := []byte{}
115 for i := 0; i < len(hexString); i += 2 {
116 hexPair := hexString[i : i+2]
117 // 将十六进制数转换为十进制数
118 decimal, err := strconv.ParseInt(hexPair, 16, 8)
119 if err != nil {
120 return "Invalid hex string"
121 }
122 char := byte(decimal)
123 bytes = append(bytes, char)
124 }
125
126 asciiString := strings.ReplaceAll(string(bytes), "\000", " ")
127
128 return asciiString
129}
diff --git a/src/deal.go b/src/deal.go
deleted file mode 100644
index e553174..0000000
--- a/src/deal.go
+++ /dev/null
@@ -1,265 +0,0 @@
1package main
2
3import (
4 "fmt"
5 "os"
6 "syscall"
7
8 "go.mongodb.org/mongo-driver/bson"
9)
10
11const (
12 dbName string = "test"
13 pidColName string = "pids"
14 fdColName string = "fds"
15 fileColName string = "files"
16)
17
18// var mongoMutex sync.Mutex
19var pidCol, fdCol, fileCol mongoClient
20
21var docRes []bson.M
22var err error
23
24func deal() {
25 defer wg.Done()
26 var cooked Event
27 var ok bool
28
29 if err = pidCol.init(dbName, pidColName); err != nil {
30 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
31 return
32 }
33 err = pidCol.InsertOne(bson.M{
34 "ppid": 1,
35 "pid": containerdPid,
36 "cwd": "/",
37 "children": []bson.M{},
38 "daemon": true,
39 })
40 if err != nil {
41 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
42 return
43 }
44
45 if err = fdCol.init(dbName, fdColName); err != nil {
46 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
47 return
48 }
49 if err = fileCol.init(dbName, fileColName); err != nil {
50 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
51 }
52
53 fmt.Printf("Containerd: %d\n", containerdPid)
54 defer pidCol.Disconnect()
55 defer fdCol.Disconnect()
56 defer fileCol.Disconnect()
57
58 for {
59 cooked, ok = <-cookedChan
60 if !ok {
61 break
62 }
63
64 switch cooked.tag {
65 case NEWPID:
66 go dealNewPid(cooked)
67 case EXECVE:
68 go dealExecve(cooked)
69 case PIDEXIT:
70 go deletePid(cooked)
71 case FILEOPEN:
72 go fileOpen(cooked)
73 case FILEWRITE:
74 go fileWrite(cooked)
75 case FILECLOSE:
76 go fileClose(cooked)
77 case PIVOTROOT:
78 go pivotRoot(cooked)
79 }
80 }
81}
82
83func deletePid(cooked Event) {
84 // 先从老爹那里销户
85 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
86 "$pull": bson.M{
87 "children": cooked.pid,
88 },
89 })
90
91 // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作
92
93 // 可以去死了
94 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
95 "$set": bson.M{
96 "exit_timestamp": cooked.timestamp,
97 "exit_code": cooked.exit_code,
98 "exit_signal": cooked.exit_signal,
99 },
100 })
101
102 // 理论上这里需要关闭所有文件描述符,但为了处理效率,留给后续流程
103}
104
105func dealNewPid(cooked Event) {
106 // 自身是否已经记录
107 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
108 if err != nil {
109 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err)
110 return
111 }
112
113 if len(docRes) != 0 {
114 // 进程原本就存在,换言之别的消息先到了
115 // 所有先行抵达的消息必须保留execve/children字段
116 // 此处不再更新
117 // 以防把原有信息更没了
118 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
119 "start_timestamp": cooked.timestamp,
120 "ppid": cooked.ppid,
121 "parentTgid": cooked.parentTgid,
122 "pid": cooked.pid,
123 "tgid": cooked.tgid,
124 "cwd": cooked.cwd,
125 // "execve": []bson.M{},
126 "args": cooked.argv,
127 // "children": []bson.M{},
128 })
129 } else {
130 // 这进程本是新修的
131 pidCol.InsertOne(bson.M{
132 "start_timestamp": cooked.timestamp,
133 "ppid": cooked.ppid,
134 "parentTgid": cooked.parentTgid,
135 "pid": cooked.pid,
136 "tgid": cooked.tgid,
137 "cwd": cooked.cwd,
138 "execve": []bson.M{},
139 "args": cooked.argv,
140 "children": []bson.M{},
141 })
142 }
143
144 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
145 "$push": bson.M{
146 "children": cooked.pid,
147 },
148 })
149}
150
151func dealExecve(cooked Event) {
152 // 父进程在不在?不在扔
153 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
154 if err != nil || len(docRes) != 1 {
155 return
156 }
157
158 // 首先检查进程是否存在,如不存在则为之创建
159 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
160 if err != nil {
161 return
162 }
163
164 if len(docRes) == 1 {
165 // 自身已在,直接记录
166 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
167 "$push": bson.M{
168 "execve": bson.M{
169 "timestamp": cooked.timestamp,
170 "execArgs": cooked.argv,
171 },
172 },
173 })
174 } else {
175 // 先fork抵达,插入
176 pidCol.InsertOne(bson.M{
177 "ppid": cooked.ppid,
178 "pid": cooked.pid,
179 "children": []bson.M{},
180 "execve": []bson.M{
181 {
182 "timestamp": cooked.timestamp,
183 "execArgs": cooked.argv,
184 },
185 },
186 })
187 }
188}
189
190func fileOpen(cooked Event) {
191 // 权限检查过了,不必再查
192 fdCol.InsertOne(bson.M{
193 "timestamp": cooked.timestamp,
194 "fileName": cooked.srcPath,
195 "pid": cooked.pid,
196 "fd": cooked.exit_code,
197 "flags": cooked.syscallParam,
198 "written": []bson.M{},
199 })
200
201 if cooked.syscallParam[1]&syscall.O_TRUNC != 0 {
202 fdCol.UpdateOne(bson.M{"pid": cooked.pid, "fd": cooked.exit_code}, bson.M{
203 "$push": bson.M{
204 "written": cooked.timestamp,
205 },
206 })
207 }
208}
209
210func fileClose(cooked Event) {
211 res, err := fdCol.FindOneAndDelete(bson.M{"pid": cooked.pid, "fd": cooked.syscallParam[0]})
212 if err != nil {
213 return
214 }
215 res["close_timestamp"] = cooked.timestamp
216 if err := fileCol.InsertOne(res); err != nil {
217 fmt.Fprintf(os.Stderr, "Err inserting files: %v\n", err)
218 }
219}
220
221func fileWrite(cooked Event) {
222 res, err := fdCol.Finddoc(bson.M{
223 "pid": cooked.pid,
224 "fd": cooked.syscallParam[0],
225 "close_timestamp": bson.M{"$exists": false},
226 })
227 if err != nil {
228 fmt.Fprintf(os.Stderr, "Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err)
229 }
230 if len(res) == 0 {
231 return
232 }
233 fdCol.UpdateOne(bson.M{
234 "pid": cooked.pid,
235 "fd": cooked.syscallParam[0],
236 "close_timestamp": bson.M{"$exists": false},
237 }, bson.M{"$push": bson.M{"written": cooked.timestamp}})
238}
239
240func pivotRoot(cooked Event) {
241 // docker的根目录信息,记录
242 docRes, err := pidCol.Finddoc(bson.M{"pid": cooked.pid})
243 if err != nil {
244 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err)
245 return
246 }
247
248 if len(docRes) == 0 {
249 // fork还没到,等一下
250 pidCol.InsertOne(bson.M{
251 "start_timestamp": cooked.timestamp,
252 "ppid": cooked.ppid,
253 "pid": cooked.pid,
254 "rootfs": "cwd",
255 })
256 } else {
257 // 读取已有的工作目录
258 cwd := docRes[0]["cwd"]
259 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
260 "$set": bson.M{
261 "rootfs": cwd,
262 },
263 })
264 }
265}
diff --git a/src/global.go b/src/global.go
deleted file mode 100644
index 349ba6c..0000000
--- a/src/global.go
+++ /dev/null
@@ -1,49 +0,0 @@
1package main
2
3import (
4 "sync"
5 "time"
6)
7
8type eventType int
9
10const (
11 NEWPID eventType = iota
12 PIDEXIT
13 EXECVE
14 FILEOPEN
15 FILECLOSE
16 FILEWRITE
17 PIVOTROOT
18 TYPENUM
19)
20
21func (et eventType) String() string {
22 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILECLOSE", "FILEWRITE", "PIVOTROOT", "TYPENUM"}
23 if et < NEWPID || et > TYPENUM {
24 return "Unknown"
25 }
26 return names[et]
27}
28
29type Event struct {
30 tag eventType
31 timestamp time.Time
32 pid, tgid int
33 ppid, parentTgid int
34 syscall int
35 syscallParam [4]uint64
36 argc int
37 argv []string
38 cwd string
39 exit_code uint64
40 exit_signal int
41 srcPath string
42 destPath string
43}
44
45var wg sync.WaitGroup // 掌管协程
46var rawChan chan interface{} // 从接收到整理的管道
47var cookedChan chan Event // 整理好的信息的管道
48var syscallTable [500]string //记录一下系统调用
49var containerdPid int
diff --git a/src/go.mod b/src/go.mod
deleted file mode 100644
index ed40331..0000000
--- a/src/go.mod
+++ /dev/null
@@ -1,26 +0,0 @@
1module godo
2
3go 1.21.5
4
5require (
6 github.com/elastic/go-libaudit/v2 v2.5.0
7 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
8 go.mongodb.org/mongo-driver v1.16.0
9)
10
11require (
12 github.com/golang/snappy v0.0.4 // indirect
13 github.com/klauspost/compress v1.13.6 // indirect
14 github.com/montanaflynn/stats v0.7.1 // indirect
15 github.com/xdg-go/pbkdf2 v1.0.0 // indirect
16 github.com/xdg-go/scram v1.1.2 // indirect
17 github.com/xdg-go/stringprep v1.0.4 // indirect
18 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
19 go.uber.org/atomic v1.7.0 // indirect
20 go.uber.org/multierr v1.7.0 // indirect
21 golang.org/x/crypto v0.22.0 // indirect
22 golang.org/x/sync v0.7.0 // indirect
23 golang.org/x/sys v0.19.0 // indirect
24 golang.org/x/text v0.14.0 // indirect
25 gopkg.in/yaml.v3 v3.0.1 // indirect
26)
diff --git a/src/go.sum b/src/go.sum
deleted file mode 100644
index 9164cd3..0000000
--- a/src/go.sum
+++ /dev/null
@@ -1,96 +0,0 @@
1github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4github.com/elastic/go-libaudit/v2 v2.5.0 h1:5OK919QRnGtcjVBz3n/cs5F42im1mPlVTA9TyIn2K54=
5github.com/elastic/go-libaudit/v2 v2.5.0/go.mod h1:AjlnhinP+kKQuUJoXLVrqxBM8uyhQmkzoV6jjsCFP4Q=
6github.com/elastic/go-licenser v0.4.1 h1:1xDURsc8pL5zYT9R29425J3vkHdt4RT5TNEMeRN48x4=
7github.com/elastic/go-licenser v0.4.1/go.mod h1:V56wHMpmdURfibNBggaSBfqgPxyT1Tldns1i87iTEvU=
8github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
9github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
10github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
12github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
13github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
14github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
15github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
16github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
17github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
18github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
19github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
20github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
21github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
22github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
23github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
24github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
25github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
26github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
27github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
28github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
29github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
30github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
31github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
32github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
33github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
34github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
35github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
36go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4=
37go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
38go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
39go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
40go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
41go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
42golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
43golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
44golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
45golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
46golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
47golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
48golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
49golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
50golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
51golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
52golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
53golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
54golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
55golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
56golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
57golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
58golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
59golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
60golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
61golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
62golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
63golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
65golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
66golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
67golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
68golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
69golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
70golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
71golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
72golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
73golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
74golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
75golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
76golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
77golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
78golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
79golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
80golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
81golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
82golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
83golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
84golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
85golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
86golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
87golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
88golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
89golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
90golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
91gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
92gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
93gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
94gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
95gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
96gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/src/go.work b/src/go.work
deleted file mode 100644
index 5b6c957..0000000
--- a/src/go.work
+++ /dev/null
@@ -1,6 +0,0 @@
1go 1.21.5
2
3use (
4 ./netlink
5 ./
6) \ No newline at end of file
diff --git a/src/go.work.sum b/src/go.work.sum
deleted file mode 100644
index 8201e39..0000000
--- a/src/go.work.sum
+++ /dev/null
@@ -1,4 +0,0 @@
1golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
2golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
3golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
4golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
diff --git a/src/godo.go b/src/godo.go
deleted file mode 100644
index a30aa88..0000000
--- a/src/godo.go
+++ /dev/null
@@ -1,164 +0,0 @@
1package main
2
3import (
4 "bufio"
5 "flag"
6 "fmt"
7 "log"
8 "netlink"
9 "os"
10 "os/exec"
11 "strings"
12 "syscall"
13 "time"
14
15 "github.com/elastic/go-libaudit/v2"
16)
17
18var (
19 fs = flag.NewFlagSet("audit", flag.ExitOnError)
20 diag = fs.String("diag", "", "dump raw information from kernel to file")
21 rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)")
22 backlog = fs.Uint("backlog", 8192, "backlog limit")
23 immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)")
24 receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+")
25)
26
27func main() {
28 // 检查用户身份,并添加auditd规则,监听所有syscall
29 if os.Geteuid() != 0 {
30 fmt.Fprintf(os.Stderr, "Err: Please run me as root, %d!\n", os.Getegid())
31 return
32 }
33
34 // 所有的系统调用号与名称的关系
35 err := figureOutSyscalls()
36 if err != nil {
37 fmt.Fprintf(os.Stderr, "Error figuring out syscall numbers: %v\n", err)
38 }
39
40 exec.Command("auditctl", "-D").Run()
41 exec.Command("auditctl", "-b", "1000000000").Run()
42 exec.Command("auditctl", "--reset-lost").Run()
43
44 var auditCmd *exec.Cmd
45
46 pidSyscall := []string{"execve", "pivot_root"}
47 // // 设置监听规则
48 for i := 0; i < len(pidSyscall); i++ {
49 auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i])
50 auditCmd.Run()
51 }
52
53 // 监听文件的消息
54 fileSyscall := []string{"open", "close", "write"}
55 // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"}
56 for i := 0; i < len(fileSyscall); i++ {
57 auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i])
58 auditCmd.Run()
59 }
60
61 // 查找pid
62 containerdPid, err = getPid()
63 if err != nil {
64 fmt.Fprintf(os.Stderr, "Error finding containerd: %v\n", err)
65 return
66 }
67
68 // 开始运行,解析命令行参数后监听
69 if err := fs.Parse(os.Args[1:]); err != nil {
70 log.Fatal(err)
71 }
72
73 if err := read(); err != nil {
74 log.Fatalf("error: %v", err)
75 }
76}
77
78func coroutine(client *libaudit.AuditClient) {
79 // 各协程至此开始
80 rawChan = make(chan interface{}, 65536)
81 cookedChan = make(chan Event, 65536)
82
83 wg.Add(1)
84 go procWatch()
85
86 wg.Add(1)
87 go receive(client)
88 wg.Add(1)
89 go orgnaze()
90 wg.Add(1)
91 go deal()
92
93 wg.Wait()
94 time.Sleep(2 * time.Second)
95}
96
97func procWatch() error {
98 ns, err := netlink.NewNetlinkSocket(syscall.NETLINK_CONNECTOR, 12345)
99 if err != nil {
100 fmt.Fprintf(os.Stderr, "Error creating socket: %v\n", err)
101 return err
102 }
103 defer ns.Close()
104 for {
105 res, err := ns.Receive(20)
106 if err != nil {
107 fmt.Fprintf(os.Stderr, "Error recv: %v\n", err)
108 continue
109 }
110 for i := 0; i < len(res); i++ {
111 procEvent := netlink.ParseProcEvent(res[i].Data)
112 switch procEvent.What {
113 case netlink.PROC_EVENT_FORK:
114 data := procEvent.Data.(netlink.ProcEventFork)
115 cooked := Event{
116 tag: NEWPID,
117 timestamp: time.Now(),
118 pid: int(data.ChildPid),
119 tgid: int(data.ChildTgid),
120 ppid: int(data.ParentPid),
121 parentTgid: int(data.ParentTgid),
122 }
123 checkProc(&cooked)
124 cookedChan <- cooked
125 case netlink.PROC_EVENT_EXIT:
126 data := procEvent.Data.(netlink.ProcEventExit)
127 cooked := Event{
128 tag: PIDEXIT,
129 timestamp: time.Now(),
130 pid: int(data.ProcessPid),
131 exit_code: uint64(data.ExitCode),
132 exit_signal: int(data.ExitSignal),
133 }
134 cookedChan <- cooked
135 default:
136 }
137 }
138 }
139}
140
141func checkProc(pCooked *Event) {
142 fileName := fmt.Sprintf("/proc/%d/task/%d/cmdline", pCooked.tgid, pCooked.pid)
143 fd, err := os.Open(fileName)
144 if err != nil {
145 fmt.Fprintf(os.Stderr, "Err: %v\n", err)
146 return
147 }
148
149 scanner := bufio.NewScanner(fd)
150 scanner.Split(bufio.ScanLines)
151 for scanner.Scan() {
152 line := scanner.Text()
153 pCooked.argv = append(pCooked.argv, strings.Split(line, "\x00")...)
154 }
155 pCooked.argc = len(pCooked.argv)
156 fd.Close()
157
158 fileName = fmt.Sprintf("/proc/%d/task/%d/cwd", pCooked.tgid, pCooked.pid)
159 pCooked.cwd, err = os.Readlink(fileName)
160 if err != nil {
161 fmt.Fprintf(os.Stderr, "Err: %v\n", err)
162 pCooked.cwd = ""
163 }
164}
diff --git a/src/mongo.go b/src/mongo.go
deleted file mode 100644
index 1d9f74f..0000000
--- a/src/mongo.go
+++ /dev/null
@@ -1,98 +0,0 @@
1package main
2
3import (
4 "context"
5 "time"
6
7 "go.mongodb.org/mongo-driver/bson"
8 "go.mongodb.org/mongo-driver/mongo"
9 "go.mongodb.org/mongo-driver/mongo/options"
10)
11
12type mongoClient struct {
13 dbName, colName string
14 client *mongo.Client
15 col *mongo.Collection
16}
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
30func (mc *mongoClient) Connect(dbName, colName string) error {
31 var err error
32 mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
33
34 if err != nil {
35 return err
36 }
37
38 ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
39 err = mc.client.Connect(ctx)
40 if err != nil {
41 return err
42 }
43
44 mc.col = mc.client.Database(dbName).Collection(colName)
45 mc.dbName = dbName
46 mc.colName = colName
47 return nil
48}
49
50func (mc *mongoClient) InsertOne(document interface{}) error {
51 _, err := mc.col.InsertOne(context.Background(), document)
52 return err
53}
54
55func (mc *mongoClient) UpdateOne(filter, update interface{}) error {
56 _, err := mc.col.UpdateOne(context.Background(), filter, update)
57 return err
58}
59
60func (mc *mongoClient) UpdateMany(filter, update interface{}) error {
61 _, err := mc.col.UpdateMany(context.Background(), filter, update)
62 return err
63}
64
65func (mc *mongoClient) Finddoc(filter bson.M) ([]bson.M, error) {
66 cur, err := mc.col.Find(context.Background(), filter)
67 if err != nil {
68 return nil, err
69 }
70
71 var results []bson.M
72 err = cur.All(context.Background(), &results)
73
74 return results, err
75}
76
77func (mc *mongoClient) FindOneAndDelete(filter bson.M) (bson.M, error) {
78 res := mc.col.FindOneAndDelete(context.Background(), filter)
79 var result bson.M
80 err := res.Decode(&result)
81 return result, err
82}
83
84func (mc *mongoClient) Drop() error {
85 return mc.col.Drop(context.Background())
86}
87
88func (mc *mongoClient) Disconnect() error {
89 err := mc.client.Disconnect(context.Background())
90 if err != nil {
91 return err
92 }
93 mc.col = nil
94 mc.client = nil
95 mc.dbName = ""
96 mc.colName = ""
97 return nil
98}
diff --git a/src/netlink b/src/netlink
deleted file mode 160000
Subproject e53c2724725c5991cdd9ea088c26832c5c9fcf0
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}
diff --git a/src/receive.go b/src/receive.go
deleted file mode 100644
index c0dea00..0000000
--- a/src/receive.go
+++ /dev/null
@@ -1,29 +0,0 @@
1package main
2
3import (
4 "fmt"
5
6 "github.com/elastic/go-libaudit/v2"
7 "github.com/elastic/go-libaudit/v2/auparse"
8 "github.com/mohae/deepcopy"
9)
10
11func receive(r *libaudit.AuditClient) error {
12 defer wg.Done()
13 defer close(rawChan)
14 for {
15 rawEvent, err := r.Receive(false)
16 if err != nil {
17 return fmt.Errorf("receive failed: %w", err)
18 }
19
20 // Messages from 1300-2999 are valid audit messages.
21 if rawEvent.Type < auparse.AUDIT_USER_AUTH ||
22 rawEvent.Type > auparse.AUDIT_LAST_USER_MSG2 {
23 continue
24 }
25
26 rawEventMessage := deepcopy.Copy(*rawEvent)
27 rawChan <- rawEventMessage
28 }
29}