diff options
Diffstat (limited to 'src/organize.go')
-rw-r--r-- | src/organize.go | 291 |
1 files changed, 0 insertions, 291 deletions
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 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
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在操作系统运行期间是唯一的 | ||
17 | var eventTable sync.Map | ||
18 | |||
19 | // 事件信息 | ||
20 | var tmp any | ||
21 | var ok bool | ||
22 | var event Event | ||
23 | var pEvent *Event | ||
24 | var eventId, argc int | ||
25 | |||
26 | // var errs [6]error | ||
27 | |||
28 | // 要用的正则匹配列表 | ||
29 | var ( | ||
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 | |||
39 | func 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 | |||
72 | func 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 | |||
182 | func 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 | |||
210 | func 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 | |||
224 | func 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 | |||
250 | func 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 | |||
266 | func 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 | } | ||