diff options
Diffstat (limited to '')
-rw-r--r-- | src/organize.go | 79 |
1 files changed, 57 insertions, 22 deletions
diff --git a/src/organize.go b/src/organize.go index bb6736a..d963288 100644 --- a/src/organize.go +++ b/src/organize.go | |||
@@ -1,9 +1,11 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | ||
4 | "regexp" | 5 | "regexp" |
5 | "strconv" | 6 | "strconv" |
6 | "strings" | 7 | "strings" |
8 | "sync" | ||
7 | 9 | ||
8 | "github.com/elastic/go-libaudit/v2" | 10 | "github.com/elastic/go-libaudit/v2" |
9 | "github.com/elastic/go-libaudit/v2/auparse" | 11 | "github.com/elastic/go-libaudit/v2/auparse" |
@@ -19,16 +21,20 @@ func orgnaze() { | |||
19 | // 事件信息 | 21 | // 事件信息 |
20 | var eventId, argc int | 22 | var eventId, argc int |
21 | var err [6]error | 23 | var err [6]error |
22 | var event, cooked Event | 24 | var event Event |
25 | var pEvent *Event | ||
26 | var tmp any | ||
23 | // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的 | 27 | // 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的 |
24 | eventTable := make(map[int]*Event) | 28 | var eventTable sync.Map |
29 | |||
25 | // 要用的正则匹配列表 | 30 | // 要用的正则匹配列表 |
26 | syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?(exit=([-+]?\d+).*?)?ppid=(\d+) pid=(\d+).*?$`) | 31 | syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?(exit=([-+]?\d+))? a0=([0-9a-fA-F]+).*?ppid=(\d+) pid=(\d+).*?$`) |
27 | execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) | 32 | execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) |
28 | argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) | 33 | argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) |
29 | cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) | 34 | cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) |
30 | proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) | 35 | proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) |
31 | eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) | 36 | eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) |
37 | |||
32 | for { | 38 | for { |
33 | raw, ok = <-rawChan | 39 | raw, ok = <-rawChan |
34 | if !ok { | 40 | if !ok { |
@@ -44,39 +50,53 @@ func orgnaze() { | |||
44 | eventId, err[1] = strconv.Atoi(string(match[2])) | 50 | eventId, err[1] = strconv.Atoi(string(match[2])) |
45 | event.syscall, err[2] = strconv.Atoi(string(match[3])) | 51 | event.syscall, err[2] = strconv.Atoi(string(match[3])) |
46 | var exit int | 52 | var exit int |
47 | // exit, err[3] = strconv.Atoi(string(match[4])) | 53 | var a0 uint64 |
48 | if string(match[5]) == "" { | 54 | if string(match[5]) == "" { |
49 | // exit没捕获到 | 55 | // exit没捕获到 |
50 | exit = 0 | 56 | exit = 0 |
51 | } else { | 57 | } else { |
52 | exit, err[3] = strconv.Atoi(string(match[5])) | 58 | exit, err[3] = strconv.Atoi(string(match[5])) |
53 | } | 59 | } |
54 | event.ppid, err[4] = strconv.Atoi(string(match[5])) | 60 | if string(match[6]) == "" { |
55 | event.pid, err[5] = strconv.Atoi(string(match[6])) | 61 | a0 = 0 |
62 | } else { | ||
63 | // 系统调用的第一个参数 | ||
64 | // exit和exit_group都是syscall_define1,只有一个参数 | ||
65 | // fork没参数,clone几个参数不重要 | ||
66 | // execve三个参数咱也不关心 | ||
67 | // 所以看第一个就够了 | ||
68 | a0, err[4] = strconv.ParseUint(string(match[6]), 16, 64) | ||
69 | } | ||
70 | event.ppid, err[4] = strconv.Atoi(string(match[7])) | ||
71 | event.pid, err[5] = strconv.Atoi(string(match[8])) | ||
56 | if syscallTable[event.syscall] == "clone" { | 72 | if syscallTable[event.syscall] == "clone" { |
57 | if exit == 0 { | 73 | if exit == 0 || event.pid > exit { |
74 | // exit=0是给新进程的返回,没用 | ||
75 | // pid>exit,证明有问题,抛弃 | ||
58 | break | 76 | break |
59 | } else { | 77 | } else { |
60 | eventTable[eventId] = &Event{ | 78 | eventTable.Store(eventId, &Event{ |
61 | timestamp: event.timestamp, | 79 | timestamp: event.timestamp, |
62 | syscall: event.syscall, | 80 | syscall: event.syscall, |
81 | exit_code: 0, | ||
63 | ppid: event.pid, | 82 | ppid: event.pid, |
64 | pid: exit, | 83 | pid: exit, |
65 | argc: 0, | 84 | argc: 0, |
66 | argv: make([]string, 0), | 85 | argv: make([]string, 0), |
67 | cwd: "", | 86 | cwd: "", |
68 | } | 87 | }) |
69 | } | 88 | } |
70 | } else { | 89 | } else { |
71 | eventTable[eventId] = &Event{ | 90 | eventTable.Store(eventId, &Event{ |
72 | timestamp: event.timestamp, | 91 | timestamp: event.timestamp, |
73 | syscall: event.syscall, | 92 | syscall: event.syscall, |
93 | exit_code: a0, | ||
74 | ppid: event.ppid, | 94 | ppid: event.ppid, |
75 | pid: event.pid, | 95 | pid: event.pid, |
76 | argc: 0, | 96 | argc: 0, |
77 | argv: make([]string, 0), | 97 | argv: make([]string, 0), |
78 | cwd: "", | 98 | cwd: "", |
79 | } | 99 | }) |
80 | } | 100 | } |
81 | } | 101 | } |
82 | case auparse.AUDIT_EXECVE: | 102 | case auparse.AUDIT_EXECVE: |
@@ -84,34 +104,45 @@ func orgnaze() { | |||
84 | match := execveRegex.FindSubmatch(rawEvent.Data) | 104 | match := execveRegex.FindSubmatch(rawEvent.Data) |
85 | eventId, err[0] = strconv.Atoi(string(match[1])) | 105 | eventId, err[0] = strconv.Atoi(string(match[1])) |
86 | argc, err[1] = strconv.Atoi(string(match[2])) | 106 | argc, err[1] = strconv.Atoi(string(match[2])) |
107 | tmp, ok = eventTable.Load(eventId) | ||
108 | if !ok { | ||
109 | break | ||
110 | } | ||
111 | pEvent = tmp.(*Event) | ||
87 | if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) { | 112 | if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) { |
88 | match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) | 113 | match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) |
89 | for i := 0; i < argc; i++ { | 114 | for i := 0; i < argc; i++ { |
90 | if len(match[i][2]) == 0 { | 115 | if len(match[i][2]) == 0 { |
91 | // 代表着匹配到的是十六进制数 | 116 | // 代表着匹配到的是十六进制数 |
92 | str := hexToAscii(string(match[i][3])) | 117 | str := hexToAscii(string(match[i][3])) |
93 | eventTable[eventId].argv = append(eventTable[eventId].argv, str) | 118 | pEvent.argv = append(pEvent.argv, str) |
94 | } else { | 119 | } else { |
95 | eventTable[eventId].argv = append(eventTable[eventId].argv, string(match[i][2])) | 120 | pEvent.argv = append(pEvent.argv, string(match[i][2])) |
96 | } | 121 | } |
97 | } | 122 | } |
98 | eventTable[eventId].argc = argc | 123 | pEvent.argc = argc |
99 | } | 124 | } |
100 | } | 125 | } |
101 | // case auparse.AUDIT_PATH: | ||
102 | case auparse.AUDIT_CWD: | 126 | case auparse.AUDIT_CWD: |
103 | if cwdRegex.Match(rawEvent.Data) { | 127 | if cwdRegex.Match(rawEvent.Data) { |
104 | match := cwdRegex.FindSubmatch(rawEvent.Data) | 128 | match := cwdRegex.FindSubmatch(rawEvent.Data) |
105 | eventId, err[0] = strconv.Atoi(string(match[1])) | 129 | eventId, err[0] = strconv.Atoi(string(match[1])) |
106 | eventTable[eventId].cwd = string(match[2]) | 130 | tmp, ok = eventTable.Load(eventId) |
131 | if !ok { | ||
132 | break | ||
133 | } | ||
134 | tmp.(*Event).cwd = string(match[2]) | ||
107 | } | 135 | } |
108 | case auparse.AUDIT_PROCTITLE: | 136 | case auparse.AUDIT_PROCTITLE: |
109 | if proctitleRegex.Match(rawEvent.Data) { | 137 | if proctitleRegex.Match(rawEvent.Data) { |
110 | var cmdline string | 138 | var cmdline string |
111 | var pEvent *Event | ||
112 | match := proctitleRegex.FindSubmatch(rawEvent.Data) | 139 | match := proctitleRegex.FindSubmatch(rawEvent.Data) |
113 | eventId, err[0] = strconv.Atoi(string(match[1])) | 140 | eventId, err[0] = strconv.Atoi(string(match[1])) |
114 | pEvent = eventTable[eventId] | 141 | tmp, ok = eventTable.Load(eventId) |
142 | if !ok { | ||
143 | break | ||
144 | } | ||
145 | pEvent = tmp.(*Event) | ||
115 | if pEvent.argc == 0 { | 146 | if pEvent.argc == 0 { |
116 | // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数 | 147 | // 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数 |
117 | if match[3] == nil { | 148 | if match[3] == nil { |
@@ -121,17 +152,21 @@ func orgnaze() { | |||
121 | cmdline = string(match[3]) | 152 | cmdline = string(match[3]) |
122 | } | 153 | } |
123 | pEvent.argv = strings.Split(cmdline, " ") | 154 | pEvent.argv = strings.Split(cmdline, " ") |
124 | pEvent.argc = len(eventTable[eventId].argv) | 155 | pEvent.argc = len(pEvent.argv) |
125 | } | 156 | } |
126 | } | 157 | } |
127 | case auparse.AUDIT_EOE: | 158 | case auparse.AUDIT_EOE: |
128 | if eoeRegex.Match(rawEvent.Data) { | 159 | if eoeRegex.Match(rawEvent.Data) { |
129 | match := eoeRegex.FindSubmatch(rawEvent.Data) | 160 | match := eoeRegex.FindSubmatch(rawEvent.Data) |
130 | eventId, err[0] = strconv.Atoi(string(match[1])) | 161 | eventId, err[0] = strconv.Atoi(string(match[1])) |
131 | // ATTENTION: 事件整理完毕,即刻发出,是否合理呢? | 162 | tmp, ok = eventTable.Load(eventId) |
132 | cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验 | 163 | if !ok { |
164 | break | ||
165 | } | ||
166 | cooked := *(tmp.(*Event)) | ||
133 | cookedChan <- cooked | 167 | cookedChan <- cooked |
134 | delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地 | 168 | eventTable.Delete(eventId) // 死人别占地 |
169 | fmt.Printf("%d: %3d %6d %6d\n", eventId, cooked.syscall, cooked.ppid, cooked.pid) | ||
135 | } | 170 | } |
136 | default: | 171 | default: |
137 | // ATTENTION: 这里也需要做防护 | 172 | // ATTENTION: 这里也需要做防护 |