diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | src/deal.go | 30 | ||||
-rw-r--r-- | src/global.go | 7 | ||||
-rw-r--r-- | src/go.work | 6 | ||||
-rw-r--r-- | src/go.work.sum | 4 | ||||
-rw-r--r-- | src/godo.go | 82 | ||||
m--------- | src/netlink | 0 | ||||
-rw-r--r-- | src/organize.go | 31 |
9 files changed, 117 insertions, 49 deletions
@@ -1,5 +1,6 @@ | |||
1 | .vscode/* | 1 | .vscode/* |
2 | godo | 2 | */godo |
3 | */hello | ||
3 | 4 | ||
4 | old/* | 5 | old/* |
5 | !old/*.* | 6 | !old/*.* |
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6a63c7b --- /dev/null +++ b/.gitmodules | |||
@@ -0,0 +1,3 @@ | |||
1 | [submodule "src/netlink"] | ||
2 | path = src/netlink | ||
3 | url = https://github.com/We-unite/netlink | ||
diff --git a/src/deal.go b/src/deal.go index 717344c..3119fff 100644 --- a/src/deal.go +++ b/src/deal.go | |||
@@ -98,12 +98,15 @@ func deletePid(cooked Event) { | |||
98 | "$set": bson.M{ | 98 | "$set": bson.M{ |
99 | "exit_timestamp": cooked.timestamp, | 99 | "exit_timestamp": cooked.timestamp, |
100 | "exit_code": cooked.exit_code, | 100 | "exit_code": cooked.exit_code, |
101 | "exit_signal": cooked.exit_signal, | ||
101 | }, | 102 | }, |
102 | }) | 103 | }) |
103 | mongoMutex.Unlock() | 104 | mongoMutex.Unlock() |
105 | fmt.Printf("Exit: %v\t%6d\t%6d\n", cooked.timestamp, cooked.pid, cooked.exit_code) | ||
104 | } | 106 | } |
105 | 107 | ||
106 | func dealNewPid(cooked Event) { | 108 | func dealNewPid(cooked Event) { |
109 | fmt.Printf("Fork: %v\t%6d\t%6d\n", cooked.timestamp, cooked.ppid, cooked.pid) | ||
107 | // 有无父进程在观察中 | 110 | // 有无父进程在观察中 |
108 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | 111 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) |
109 | if err != nil || len(docRes) != 1 { | 112 | if err != nil || len(docRes) != 1 { |
@@ -153,6 +156,7 @@ func dealNewPid(cooked Event) { | |||
153 | } | 156 | } |
154 | 157 | ||
155 | func dealExecve(cooked Event) { | 158 | func dealExecve(cooked Event) { |
159 | fmt.Printf("EXEC: %6d\t%6d\n", cooked.ppid, cooked.pid) | ||
156 | // 父进程在不在?不在扔 | 160 | // 父进程在不在?不在扔 |
157 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | 161 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) |
158 | if err != nil || len(docRes) != 1 { | 162 | if err != nil || len(docRes) != 1 { |
@@ -175,19 +179,19 @@ func dealExecve(cooked Event) { | |||
175 | }, | 179 | }, |
176 | }, | 180 | }, |
177 | }) | 181 | }) |
178 | // } else { | 182 | } else { |
179 | // // 先fork抵达,插入 | 183 | // 先fork抵达,插入 |
180 | // pidCol.InsertOne(bson.M{ | 184 | pidCol.InsertOne(bson.M{ |
181 | // "ppid": cooked.ppid, | 185 | "ppid": cooked.ppid, |
182 | // "pid": cooked.pid, | 186 | "pid": cooked.pid, |
183 | // "children": []bson.M{}, | 187 | "children": []bson.M{}, |
184 | // "execve": []bson.M{ | 188 | "execve": []bson.M{ |
185 | // { | 189 | { |
186 | // "timestamp": cooked.timestamp, | 190 | "timestamp": cooked.timestamp, |
187 | // "execArgs": cooked.argv, | 191 | "execArgs": cooked.argv, |
188 | // }, | 192 | }, |
189 | // }, | 193 | }, |
190 | // }) | 194 | }) |
191 | } | 195 | } |
192 | mongoMutex.Unlock() | 196 | mongoMutex.Unlock() |
193 | } | 197 | } |
diff --git a/src/global.go b/src/global.go index f0f909c..a266b1b 100644 --- a/src/global.go +++ b/src/global.go | |||
@@ -33,12 +33,13 @@ type Event struct { | |||
33 | timestamp time.Time | 33 | timestamp time.Time |
34 | pid, ppid int | 34 | pid, ppid int |
35 | syscall int | 35 | syscall int |
36 | exit_code uint64 | 36 | syscallParam [4]uint64 |
37 | pathName string | ||
37 | argc int | 38 | argc int |
38 | argv []string | 39 | argv []string |
39 | cwd string | 40 | cwd string |
40 | syscallParam [4]uint64 | 41 | exit_code uint64 |
41 | pathName string | 42 | exit_signal int |
42 | } | 43 | } |
43 | 44 | ||
44 | func (event Event) String() string { | 45 | func (event Event) String() string { |
diff --git a/src/go.work b/src/go.work new file mode 100644 index 0000000..5b6c957 --- /dev/null +++ b/src/go.work | |||
@@ -0,0 +1,6 @@ | |||
1 | go 1.21.5 | ||
2 | |||
3 | use ( | ||
4 | ./netlink | ||
5 | ./ | ||
6 | ) \ No newline at end of file | ||
diff --git a/src/go.work.sum b/src/go.work.sum new file mode 100644 index 0000000..8201e39 --- /dev/null +++ b/src/go.work.sum | |||
@@ -0,0 +1,4 @@ | |||
1 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||
2 | golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= | ||
3 | golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= | ||
4 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | ||
diff --git a/src/godo.go b/src/godo.go index 0edcc9f..c332c86 100644 --- a/src/godo.go +++ b/src/godo.go | |||
@@ -1,11 +1,15 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "bufio" | ||
4 | "flag" | 5 | "flag" |
5 | "fmt" | 6 | "fmt" |
6 | "log" | 7 | "log" |
8 | "netlink" | ||
7 | "os" | 9 | "os" |
8 | "os/exec" | 10 | "os/exec" |
11 | "strings" | ||
12 | "syscall" | ||
9 | "time" | 13 | "time" |
10 | 14 | ||
11 | "github.com/elastic/go-libaudit/v2" | 15 | "github.com/elastic/go-libaudit/v2" |
@@ -37,7 +41,8 @@ func main() { | |||
37 | auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 | 41 | auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 |
38 | auditCmd.Run() | 42 | auditCmd.Run() |
39 | 43 | ||
40 | pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | 44 | pidSyscall := []string{"execve"} |
45 | // pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | ||
41 | // 设置监听规则 | 46 | // 设置监听规则 |
42 | for i := 0; i < len(pidSyscall); i++ { | 47 | for i := 0; i < len(pidSyscall); i++ { |
43 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) | 48 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) |
@@ -77,6 +82,10 @@ func coroutine(client *libaudit.AuditClient) { | |||
77 | // 各协程至此开始 | 82 | // 各协程至此开始 |
78 | rawChan = make(chan interface{}) | 83 | rawChan = make(chan interface{}) |
79 | cookedChan = make(chan Event) | 84 | cookedChan = make(chan Event) |
85 | |||
86 | wg.Add(1) | ||
87 | go procWatch() | ||
88 | |||
80 | wg.Add(1) | 89 | wg.Add(1) |
81 | go receive(client) | 90 | go receive(client) |
82 | wg.Add(1) | 91 | wg.Add(1) |
@@ -87,3 +96,74 @@ func coroutine(client *libaudit.AuditClient) { | |||
87 | wg.Wait() | 96 | wg.Wait() |
88 | time.Sleep(2 * time.Second) | 97 | time.Sleep(2 * time.Second) |
89 | } | 98 | } |
99 | |||
100 | func procWatch() error { | ||
101 | ns, err := netlink.NewNetlinkSocket(syscall.NETLINK_CONNECTOR, 12345) | ||
102 | if err != nil { | ||
103 | fmt.Printf("Error creating socket: %v\n", err) | ||
104 | return err | ||
105 | } | ||
106 | defer ns.Close() | ||
107 | for { | ||
108 | res, err := ns.Receive() | ||
109 | if err != nil { | ||
110 | fmt.Printf("Error recv: %v\n", err) | ||
111 | continue | ||
112 | } | ||
113 | for i := 0; i < len(res); i++ { | ||
114 | procEvent := netlink.ParseProcEvent(res[i].Data) | ||
115 | switch procEvent.What { | ||
116 | case netlink.PROC_EVENT_FORK: | ||
117 | data := procEvent.Data.(netlink.ProcEventFork) | ||
118 | cooked := Event{ | ||
119 | tag: NEWPID, | ||
120 | ppid: int(data.ParentTgid), | ||
121 | pid: int(data.ChildPid), | ||
122 | timestamp: time.Now(), | ||
123 | } | ||
124 | checkProc(&cooked) | ||
125 | if data.ChildPid != data.ChildTgid { | ||
126 | cooked.ppid = int(data.ChildTgid) | ||
127 | cooked.pid = int(data.ChildPid) | ||
128 | } | ||
129 | cookedChan <- cooked | ||
130 | case netlink.PROC_EVENT_EXIT: | ||
131 | data := procEvent.Data.(netlink.ProcEventExit) | ||
132 | cooked := Event{ | ||
133 | tag: PIDEXIT, | ||
134 | timestamp: time.Now(), | ||
135 | pid: int(data.ProcessPid), | ||
136 | exit_code: uint64(data.ExitCode), | ||
137 | exit_signal: int(data.ExitSignal), | ||
138 | } | ||
139 | cookedChan <- cooked | ||
140 | default: | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | func checkProc(pCooked *Event) { | ||
147 | fileName := fmt.Sprintf("/proc/%d/cmdline", pCooked.pid) | ||
148 | fd, err := os.Open(fileName) | ||
149 | if err != nil { | ||
150 | fmt.Printf("Err opening file %s: %v\n", fileName, err) | ||
151 | return | ||
152 | } | ||
153 | |||
154 | scanner := bufio.NewScanner(fd) | ||
155 | scanner.Split(bufio.ScanLines) | ||
156 | for scanner.Scan() { | ||
157 | line := scanner.Text() | ||
158 | pCooked.argv = append(pCooked.argv, strings.Split(line, "\x00")...) | ||
159 | } | ||
160 | pCooked.argc = len(pCooked.argv) | ||
161 | fd.Close() | ||
162 | |||
163 | fileName = fmt.Sprintf("/proc/%d/cwd", pCooked.pid) | ||
164 | pCooked.cwd, err = os.Readlink(fileName) | ||
165 | if err != nil { | ||
166 | fmt.Printf("Err readlink %s: %v\n", fileName, err) | ||
167 | pCooked.cwd = "" | ||
168 | } | ||
169 | } | ||
diff --git a/src/netlink b/src/netlink new file mode 160000 | |||
Subproject 10d3ea361f0bcafb9b92054440984d32421aeb7 | |||
diff --git a/src/organize.go b/src/organize.go index d7a1df1..238509f 100644 --- a/src/organize.go +++ b/src/organize.go | |||
@@ -47,7 +47,6 @@ func orgnaze() { | |||
47 | break | 47 | break |
48 | } | 48 | } |
49 | rawEvent = raw.(libaudit.RawAuditMessage) | 49 | rawEvent = raw.(libaudit.RawAuditMessage) |
50 | fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) | ||
51 | 50 | ||
52 | switch rawEvent.Type { | 51 | switch rawEvent.Type { |
53 | case auparse.AUDIT_SYSCALL: | 52 | case auparse.AUDIT_SYSCALL: |
@@ -100,24 +99,6 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) { | |||
100 | } | 99 | } |
101 | 100 | ||
102 | switch syscallTable[event.syscall] { | 101 | switch syscallTable[event.syscall] { |
103 | case "clone": | ||
104 | if exit == 0 || event.pid > exit { | ||
105 | // exit=0是给新进程的返回,没用 | ||
106 | // pid>exit,证明有问题,抛弃 | ||
107 | break | ||
108 | } else { | ||
109 | eventTable.Store(eventId, &Event{ | ||
110 | tag: NEWPID, | ||
111 | timestamp: event.timestamp, | ||
112 | syscall: event.syscall, | ||
113 | exit_code: 0, | ||
114 | ppid: event.pid, | ||
115 | pid: exit, | ||
116 | argc: 0, | ||
117 | argv: make([]string, 0), | ||
118 | cwd: "", | ||
119 | }) | ||
120 | } | ||
121 | case "execve": | 102 | case "execve": |
122 | eventTable.Store(eventId, &Event{ | 103 | eventTable.Store(eventId, &Event{ |
123 | tag: EXECVE, | 104 | tag: EXECVE, |
@@ -130,18 +111,6 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) { | |||
130 | argv: make([]string, 0), | 111 | argv: make([]string, 0), |
131 | cwd: "", | 112 | cwd: "", |
132 | }) | 113 | }) |
133 | case "exit", "exit_group": | ||
134 | eventTable.Store(eventId, &Event{ | ||
135 | tag: PIDEXIT, | ||
136 | timestamp: event.timestamp, | ||
137 | syscall: event.syscall, | ||
138 | exit_code: a[0], | ||
139 | ppid: event.ppid, | ||
140 | pid: event.pid, | ||
141 | argc: 0, | ||
142 | argv: make([]string, 0), | ||
143 | cwd: "", | ||
144 | }) | ||
145 | case "open": | 114 | case "open": |
146 | // 检查打开的权限 | 115 | // 检查打开的权限 |
147 | if a[1]&(syscall.O_APPEND|syscall.O_WRONLY|syscall.O_RDWR|syscall.O_TRUNC) == 0 { | 116 | if a[1]&(syscall.O_APPEND|syscall.O_WRONLY|syscall.O_RDWR|syscall.O_TRUNC) == 0 { |