|
#!/usr/bin/env python
|
|
|
|
import sys
|
|
import re
|
|
import shlex
|
|
import pwd
|
|
|
|
|
|
def main ():
|
|
for event in get_events(sys.stdin):
|
|
exec_ = parse_exec(event)
|
|
cwd = parse_cwd(event)
|
|
auid = uid_to_name(parse_auid(event))
|
|
euid = uid_to_name(parse_euid(event))
|
|
event_id = parse_event_id(event)
|
|
|
|
if exec_:
|
|
args_s = ' '.join(exec_['args'])
|
|
if auid != euid:
|
|
print '%s [%s->%s %s] %s' % (event_id, auid, euid, cwd, args_s)
|
|
else:
|
|
print '%s [%s %s] %s' % (event_id, auid, cwd, args_s)
|
|
|
|
|
|
def parse_event_id (event):
|
|
if event:
|
|
return event[0]['id']
|
|
|
|
def uid_to_name (uid):
|
|
if uid:
|
|
uid = int(uid)
|
|
try:
|
|
user = pwd.getpwuid(uid)[0]
|
|
except KeyError:
|
|
user = uid
|
|
else:
|
|
user = uid
|
|
return user
|
|
|
|
|
|
def parse_auid (event):
|
|
for log in event:
|
|
if log['type'] == 'SYSCALL':
|
|
return log['data']['auid']
|
|
|
|
|
|
def parse_euid (event):
|
|
for log in event:
|
|
if log['type'] == 'SYSCALL':
|
|
return log['data']['euid']
|
|
|
|
|
|
def parse_cwd (event):
|
|
for log in event:
|
|
if log['type'] == 'CWD':
|
|
return parse_value(log['data']['cwd'])
|
|
|
|
|
|
def parse_exec (event):
|
|
exec_ = {}
|
|
execve_data = {}
|
|
for log in event:
|
|
if log['type'] == 'EXECVE':
|
|
execve_data.update(log['data'])
|
|
if execve_data:
|
|
exec_['args'] = parse_args(execve_data)
|
|
return exec_
|
|
|
|
|
|
def parse_args (data):
|
|
argc = int(data['argc'])
|
|
args = []
|
|
for i in range(argc):
|
|
key = 'a%i' % i
|
|
try:
|
|
value = data[key]
|
|
except KeyError:
|
|
value = '<unknown>'
|
|
else:
|
|
value = parse_value(value)
|
|
args.append(value)
|
|
return args
|
|
|
|
|
|
def parse_value (value):
|
|
if value.startswith('"') and value.endswith('"'):
|
|
return value[1:-1]
|
|
else:
|
|
value = value.decode('hex')
|
|
if '\n' in value:
|
|
return '<multiline>'
|
|
else:
|
|
return value
|
|
|
|
|
|
def get_events (ausearch):
|
|
event = []
|
|
for match in re.finditer(r'type=([A-Z]+) msg=audit\(([0-9\.:/ ]+)\): +(.*?)(?=\n|$)', ausearch.read()):
|
|
type_, event_id, data, = match.groups()
|
|
entry = {'type': type_, 'id': event_id, 'data': parse_data(data)}
|
|
if event and event_id != event[0]['id']:
|
|
yield event
|
|
event = [entry]
|
|
else:
|
|
event.append(entry)
|
|
if event:
|
|
yield event
|
|
|
|
|
|
def parse_data (data_s):
|
|
data = {}
|
|
key_fragments = []
|
|
for kv in shlex.split(data_s, posix=False):
|
|
try:
|
|
key_fragment, value = kv.split('=', 1)
|
|
except ValueError:
|
|
key_fragments.append(kv)
|
|
key_fragments.append(key_fragment)
|
|
key = ' '.join(key_fragments)
|
|
key_fragments = []
|
|
data[key] = value
|
|
return data
|
|
|
|
|
|
main()
|