mirror of
https://github.com/The-Art-of-Hacking/h4cker
synced 2024-11-21 18:33:03 +00:00
Create ParseLogs.py
This commit is contained in:
parent
b928c48ba5
commit
da686ceba8
1 changed files with 159 additions and 0 deletions
159
python_ruby_and_bash/parsing_auth_log/ParseLogs.py
Normal file
159
python_ruby_and_bash/parsing_auth_log/ParseLogs.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
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
|
Loading…
Reference in a new issue