aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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}