Untitled
Lattuse
plain_text
9 months ago
3.3 kB
19
Indexable
#!/usr/bin/env python3
"""
security_log_analyzer.py
Optional version with visualization (matplotlib)
"""
import re
import os
import sys
from collections import Counter
import argparse
import matplotlib.pyplot as plt
parser = argparse.ArgumentParser(description='Security Log Analyzer with Visualization')
parser.add_argument('--log', default='/var/log/auth.log',
help='Path to auth log (default: /var/log/auth.log)')
args = parser.parse_args()
log_path = args.log
if not os.path.exists(log_path):
if os.path.exists('sample_log.txt'):
print(f"{log_path} not found — using sample_log.txt instead")
log_path = 'sample_log.txt'
else:
print(f"No log file found at {args.log} and no sample_log.txt present.")
sys.exit(1)
ip_re = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')
u1 = re.compile(r'for (?:invalid user )?([^\s:]+)')
u2 = re.compile(r'user=([^\s,;]+)')
ip_counts = Counter()
user_counts = Counter()
with open(log_path, 'r', errors='ignore') as fh:
for line in fh:
if re.search(r'(?i)failed|failure|invalid user|authentication failure|Failed password', line):
ips = ip_re.findall(line)
for ip in ips:
ip_counts[ip] += 1
m = u1.search(line) or u2.search(line)
if m:
user_counts[m.group(1)] += 1
# Save suspicious activity to file
with open('suspicious_activity.txt', 'w') as out:
out.write('IP,attempts\n')
for ip, cnt in ip_counts.most_common():
out.write(f'{ip},{cnt}\n')
print(f"Wrote suspicious_activity.txt ({len(ip_counts)} unique IPs)")
# Check for insecure home directories
insecure = []
if os.path.exists('/etc/passwd'):
with open('/etc/passwd') as pf:
for line in pf:
parts = line.strip().split(':')
if len(parts) < 6:
continue
username, home = parts[0], parts[5]
if not home or not os.path.isdir(home):
continue
try:
mode = os.stat(home).st_mode & 0o777
if mode == 0o777 or (mode & 0o077) == 0o077:
insecure.append((username, home, oct(mode)))
except Exception:
continue
with open('insecure_homes.txt', 'w') as out:
if insecure:
out.write('username:home:mode\n')
for u, h, m in insecure:
out.write(f'{u}:{h}:{m}\n')
print(f"Wrote insecure_homes.txt ({len(insecure)} insecure dirs found)")
else:
out.write('No insecure home directories found\n')
print("No insecure home directories found")
# ---------- Visualization Section ----------
if ip_counts:
# Take top 10 IPs for readability
top_ips = ip_counts.most_common(10)
ips, counts = zip(*top_ips)
plt.figure(figsize=(10, 5))
plt.bar(ips, counts, color='tomato')
plt.title('Top 10 IPs with Failed Login Attempts')
plt.xlabel('IP Address')
plt.ylabel('Number of Failed Attempts')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig('failed_login_stats.png')
print("Saved visualization as failed_login_stats.png")
else:
print("No failed login attempts found — skipping visualization.")
Editor is loading...
Leave a Comment