mirror of
https://github.com/The-Art-of-Hacking/h4cker.git
synced 2024-10-01 01:25:43 -04:00
160 lines
4.6 KiB
Python
160 lines
4.6 KiB
Python
|
import gzip
|
||
|
import re
|
||
|
|
||
|
|
||
|
#
|
||
|
# ParseLogs.py
|
||
|
# Parsing component of Logalyzer. Original: https://github.com/hatRiot/logalyzer
|
||
|
# Converted to python3.6 by @programmerchad
|
||
|
#
|
||
|
|
||
|
# log object
|
||
|
# Stuck into a dictionary by user:Log, where log houses
|
||
|
# logs, fails, successes, logged IPs, and commands used
|
||
|
class Log:
|
||
|
# dump date of first log
|
||
|
def first_date(self):
|
||
|
if len(self.logs) > 0:
|
||
|
date = None
|
||
|
i = 0
|
||
|
# sometimes the first few aren't right, so look
|
||
|
# until we find one
|
||
|
while i < len(self.logs) and date is None:
|
||
|
date = ParseDate(self.logs[i])
|
||
|
i += 1
|
||
|
return date
|
||
|
|
||
|
# dump date of last log
|
||
|
def last_date(self):
|
||
|
if len(self.logs) > 0:
|
||
|
return ParseDate(self.logs[len(self.logs) - 1])
|
||
|
|
||
|
def __init__(self, usr):
|
||
|
self.usr = usr
|
||
|
self.logs = []
|
||
|
self.fail_logs = []
|
||
|
self.succ_logs = []
|
||
|
self.ips = []
|
||
|
self.commands = []
|
||
|
|
||
|
|
||
|
# parse user from various lines
|
||
|
def ParseUsr(line):
|
||
|
usr = None
|
||
|
if "Accepted password" in line:
|
||
|
usr = re.search(r'(\bfor\s)(\w+)', line)
|
||
|
elif "sudo:" in line:
|
||
|
usr = re.search(r'(sudo:\s+)(\w+)', line)
|
||
|
elif "authentication failure" in line:
|
||
|
usr = re.search(r'USER=\w+', line)
|
||
|
elif "for invalid user" in line:
|
||
|
usr = re.search(r'(\buser\s)(\w+)', line)
|
||
|
if usr is not None:
|
||
|
return usr.group(2)
|
||
|
|
||
|
|
||
|
# parse an IP from a line
|
||
|
def ParseIP(line):
|
||
|
ip = re.search(r'(\bfrom\s)(\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b)', line)
|
||
|
if ip is not None:
|
||
|
return ip.group(2)
|
||
|
|
||
|
|
||
|
# parse a date from the line
|
||
|
def ParseDate(line):
|
||
|
date = re.search(r'^[A-Za-z]{3}\s*[0-9]{1,2}\s[0-9]{1,2}:[0-9]{2}:[0-9]{2}', line)
|
||
|
if date is not None:
|
||
|
return date.group(0)
|
||
|
|
||
|
|
||
|
# parse a command from a line
|
||
|
def ParseCmd(line):
|
||
|
# parse command to end of line
|
||
|
cmd = re.search(r'(\bCOMMAND=)(.+?$)', line)
|
||
|
if cmd is not None:
|
||
|
return cmd.group(2)
|
||
|
|
||
|
|
||
|
# begin parsing the passed LOG
|
||
|
def ParseLogs(log):
|
||
|
# initialize the dictionary
|
||
|
logs = {}
|
||
|
|
||
|
# parse the log
|
||
|
f = None
|
||
|
try:
|
||
|
f = gzip.open(log, 'r') if '.gz' in log else open(log, 'r')
|
||
|
log = f.read()
|
||
|
except Exception as e:
|
||
|
print('[-] Error opening \'%s\': %s' % (log, e))
|
||
|
return None
|
||
|
finally:
|
||
|
if f is not None:
|
||
|
f.close()
|
||
|
|
||
|
for line in log.split('\n'):
|
||
|
# match a login
|
||
|
if "Accepted password for" in line:
|
||
|
usr = ParseUsr(line)
|
||
|
|
||
|
# add 'em if they don't exist
|
||
|
if usr not in logs:
|
||
|
logs[usr] = Log(usr)
|
||
|
|
||
|
ip = ParseIP(line)
|
||
|
# set info
|
||
|
if ip not in logs[usr].ips:
|
||
|
logs[usr].ips.append(ip)
|
||
|
logs[usr].succ_logs.append(line.rstrip('\n'))
|
||
|
logs[usr].logs.append(line.rstrip('\n'))
|
||
|
|
||
|
# match a failed login
|
||
|
elif "Failed password for" in line:
|
||
|
# parse user
|
||
|
usr = ParseUsr(line)
|
||
|
|
||
|
if usr not in logs:
|
||
|
logs[usr] = Log(usr)
|
||
|
|
||
|
ip = ParseIP(line)
|
||
|
|
||
|
if ip not in logs[usr].ips:
|
||
|
logs[usr].ips.append(ip)
|
||
|
logs[usr].fail_logs.append(line.rstrip('\n'))
|
||
|
logs[usr].logs.append(line.rstrip('\n'))
|
||
|
|
||
|
# match failed auth
|
||
|
elif ":auth): authentication failure;" in line:
|
||
|
# so there are three flavors of authfail we care about;
|
||
|
# su, sudo, and ssh. Lets parse each.
|
||
|
usr = re.search(r'(\blogname=)(\w+)', line)
|
||
|
if usr is not None:
|
||
|
usr = usr.group(2)
|
||
|
# parse a fail log to ssh
|
||
|
if "(sshd:auth)" in line:
|
||
|
# ssh doesn't have a logname hurr
|
||
|
usr = ParseUsr(line)
|
||
|
if usr not in logs:
|
||
|
logs[usr] = Log(usr)
|
||
|
logs[usr].ips.append(ParseIP(line))
|
||
|
# parse sudo/su fails
|
||
|
else:
|
||
|
if usr not in logs:
|
||
|
logs[usr] = Log(usr)
|
||
|
logs[usr].fail_logs.append(line.rstrip('\n'))
|
||
|
logs[usr].logs.append(line.rstrip('\n'))
|
||
|
# match commands
|
||
|
elif "sudo:" in line:
|
||
|
# parse user
|
||
|
usr = ParseUsr(line)
|
||
|
if usr not in logs:
|
||
|
logs[usr] = Log(usr)
|
||
|
|
||
|
cmd = ParseCmd(line)
|
||
|
# append the command if it isn't there already
|
||
|
if cmd is not None:
|
||
|
if cmd not in logs[usr].commands:
|
||
|
logs[usr].commands.append(cmd)
|
||
|
logs[usr].logs.append(line.rstrip('\n'))
|
||
|
return logs
|