summaryrefslogtreecommitdiffstats
path: root/src/organize.go
blob: 025d8c062bccb6391d2573b2144e52cd4812e699 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main

import (
	"regexp"
	"strconv"
	"strings"

	"github.com/elastic/go-libaudit/v2"
	"github.com/elastic/go-libaudit/v2/auparse"
)

func orgnaze() {
	defer wg.Done()
	defer close(cookedChan)
	// 接收信息
	var raw interface{}
	var ok bool
	var rawEvent libaudit.RawAuditMessage
	// 事件信息
	var eventId, argc int
	var err [6]error
	var event, cooked Event
	// 为每个事务id存储其信息,事务id在操作系统运行期间是唯一的
	eventTable := make(map[int]*Event)
	// 要用的正则匹配列表
	syscallRegex := regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?ppid=(\d+) pid=(\d+).*?$`)
	execveRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`)
	argsRegex := regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`)
	cwdRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\):  cwd="(.*?)"`)
	proctitleRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`)
	eoeRegex := regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`)
	for {
		raw, ok = <-rawChan
		if !ok {
			break
		}
		rawEvent = raw.(libaudit.RawAuditMessage)

		// type Event struct {
		// 	timestamp time.Time
		// 	pid, ppid int
		// 	syscall   int
		// 	argc      int
		// 	args      []string
		// 	cwd       string
		// }
		switch rawEvent.Type {
		case auparse.AUDIT_SYSCALL:
			if syscallRegex.Match(rawEvent.Data) {
				match := syscallRegex.FindSubmatch(rawEvent.Data)
				event.timestamp, err[0] = getTimeFromStr(string(match[1]))
				eventId, err[1] = strconv.Atoi(string(match[2]))
				event.syscall, err[2] = strconv.Atoi(string(match[3]))
				event.ppid, err[3] = strconv.Atoi(string(match[4]))
				event.pid, err[4] = strconv.Atoi(string(match[5]))
				eventTable[eventId] = &Event{
					timestamp: event.timestamp,
					syscall:   event.syscall,
					ppid:      event.ppid,
					pid:       event.pid,
					argc:      0,
					argv:      make([]string, 0),
					cwd:       "",
				}
			}
		case auparse.AUDIT_EXECVE:
			if execveRegex.Match(rawEvent.Data) {
				match := execveRegex.FindSubmatch(rawEvent.Data)
				eventId, err[0] = strconv.Atoi(string(match[1]))
				argc, err[1] = strconv.Atoi(string(match[2]))
				if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) {
					match := argsRegex.FindAllSubmatch(rawEvent.Data, -1)
					for i := 0; i < argc; i++ {
						if len(match[i][2]) == 0 {
							// 代表着匹配到的是十六进制数
							str := hexToAscii(string(match[i][3]))
							eventTable[eventId].argv = append(eventTable[eventId].argv, str)
						} else {
							eventTable[eventId].argv = append(eventTable[eventId].argv, string(match[i][2]))
						}
					}
					eventTable[eventId].argc = argc
				}
			}
		// case auparse.AUDIT_PATH:
		case auparse.AUDIT_CWD:
			if cwdRegex.Match(rawEvent.Data) {
				match := cwdRegex.FindSubmatch(rawEvent.Data)
				eventId, err[0] = strconv.Atoi(string(match[1]))
				eventTable[eventId].cwd = string(match[2])
			}
		case auparse.AUDIT_PROCTITLE:
			if proctitleRegex.Match(rawEvent.Data) {
				var cmdline string
				var pEvent *Event
				match := proctitleRegex.FindSubmatch(rawEvent.Data)
				eventId, err[0] = strconv.Atoi(string(match[1]))
				pEvent = eventTable[eventId]
				if pEvent.argc == 0 {
					// 只有等于0,才证明没经过EXECVE提取参数,才允许使用PROCTITLE提取参数
					if match[3] == nil {
						// PROCTITLE写的是十六进制,转换为字符串
						cmdline = hexToAscii(string(match[4]))
					} else {
						cmdline = string(match[3])
					}
					pEvent.argv = strings.Split(cmdline, " ")
					pEvent.argc = len(eventTable[eventId].argv)
				}
			}
		case auparse.AUDIT_EOE:
			if eoeRegex.Match(rawEvent.Data) {
				match := eoeRegex.FindSubmatch(rawEvent.Data)
				eventId, err[0] = strconv.Atoi(string(match[1]))
				// ATTENTION: 事件整理完毕,即刻发出,是否合理呢?
				cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验
				cookedChan <- cooked
				delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地
			}
		default:
			// ATTENTION: 这里也需要做防护
		}
	}
}