aboutsummaryrefslogtreecommitdiffstats
path: root/src/godo.go
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-07-31 11:46:01 +0800
committerWe-unite <3205135446@qq.com>2024-08-01 15:10:36 +0800
commit3efeef969ebc344c993ce0fc46f557c7d8560525 (patch)
treef0f917080c64c8def6922c365465f1ee5371c464 /src/godo.go
parentd6c6e13796435f9e1e59fec891aa53680748a2d7 (diff)
downloadgodo-3efeef969ebc344c993ce0fc46f557c7d8560525.tar.gz
godo-3efeef969ebc344c993ce0fc46f557c7d8560525.zip
Use netlink connector to recv pid info, fix exec
For some reasons, kernel-connector can catch exec event, but it doesn't tell me about what the process exec and what're its args. So we should use audit to collect these infomations, and complete in the database. However, there's different delays between connector and audit, although they both use netlink socket, as a result of which, exec may comes before fork. we deal with it the same way. But, there's also exec event lost, may because of the check for ppid in exec event, but it's necessary, and if is deleted, too much irrelavent infomation would flood into database, i've tried. So make it there, just go forward. Besides, what's newly discovered is that pthread_create also use clone syscall, but if pid 1 has a thread 2, the exec info will say that pid 2 execs. So i shouldn't ignore connector msg that childPid ne childTgid. This is my first attempt to use git-submodule function in my own pro- ject, also golang local package. Congratulations! Now, fight to fix about file operations. Hope that there wouldn't be too many fucking bugs.
Diffstat (limited to '')
-rw-r--r--src/godo.go82
1 files changed, 81 insertions, 1 deletions
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 @@
1package main 1package main
2 2
3import ( 3import (
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
100func 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
146func 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}