aboutsummaryrefslogtreecommitdiffstats
path: root/src/organize.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/organize.go79
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 @@
1package main 1package main
2 2
3import ( 3import (
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: 这里也需要做防护