From 3efeef969ebc344c993ce0fc46f557c7d8560525 Mon Sep 17 00:00:00 2001 From: We-unite <3205135446@qq.com> Date: Wed, 31 Jul 2024 11:46:01 +0800 Subject: 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. --- src/godo.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) (limited to 'src/godo.go') 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 @@ package main import ( + "bufio" "flag" "fmt" "log" + "netlink" "os" "os/exec" + "strings" + "syscall" "time" "github.com/elastic/go-libaudit/v2" @@ -37,7 +41,8 @@ func main() { auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 auditCmd.Run() - pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} + pidSyscall := []string{"execve"} + // pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} // 设置监听规则 for i := 0; i < len(pidSyscall); i++ { auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) @@ -77,6 +82,10 @@ func coroutine(client *libaudit.AuditClient) { // 各协程至此开始 rawChan = make(chan interface{}) cookedChan = make(chan Event) + + wg.Add(1) + go procWatch() + wg.Add(1) go receive(client) wg.Add(1) @@ -87,3 +96,74 @@ func coroutine(client *libaudit.AuditClient) { wg.Wait() time.Sleep(2 * time.Second) } + +func procWatch() error { + ns, err := netlink.NewNetlinkSocket(syscall.NETLINK_CONNECTOR, 12345) + if err != nil { + fmt.Printf("Error creating socket: %v\n", err) + return err + } + defer ns.Close() + for { + res, err := ns.Receive() + if err != nil { + fmt.Printf("Error recv: %v\n", err) + continue + } + for i := 0; i < len(res); i++ { + procEvent := netlink.ParseProcEvent(res[i].Data) + switch procEvent.What { + case netlink.PROC_EVENT_FORK: + data := procEvent.Data.(netlink.ProcEventFork) + cooked := Event{ + tag: NEWPID, + ppid: int(data.ParentTgid), + pid: int(data.ChildPid), + timestamp: time.Now(), + } + checkProc(&cooked) + if data.ChildPid != data.ChildTgid { + cooked.ppid = int(data.ChildTgid) + cooked.pid = int(data.ChildPid) + } + cookedChan <- cooked + case netlink.PROC_EVENT_EXIT: + data := procEvent.Data.(netlink.ProcEventExit) + cooked := Event{ + tag: PIDEXIT, + timestamp: time.Now(), + pid: int(data.ProcessPid), + exit_code: uint64(data.ExitCode), + exit_signal: int(data.ExitSignal), + } + cookedChan <- cooked + default: + } + } + } +} + +func checkProc(pCooked *Event) { + fileName := fmt.Sprintf("/proc/%d/cmdline", pCooked.pid) + fd, err := os.Open(fileName) + if err != nil { + fmt.Printf("Err opening file %s: %v\n", fileName, err) + return + } + + scanner := bufio.NewScanner(fd) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + line := scanner.Text() + pCooked.argv = append(pCooked.argv, strings.Split(line, "\x00")...) + } + pCooked.argc = len(pCooked.argv) + fd.Close() + + fileName = fmt.Sprintf("/proc/%d/cwd", pCooked.pid) + pCooked.cwd, err = os.Readlink(fileName) + if err != nil { + fmt.Printf("Err readlink %s: %v\n", fileName, err) + pCooked.cwd = "" + } +} -- cgit v1.2.3-70-g09d2