aboutsummaryrefslogtreecommitdiff
path: root/cowrieder.py
diff options
context:
space:
mode:
authorAda Isopods <me@bathynomus.xyz>2025-05-16 03:24:45 -0600
committerAda Isopods <me@bathynomus.xyz>2026-10-21 23:04:27 -0600
commitf9b2e6c3a550256b62c156d948f2bfdd288e482f (patch)
treeea13b4b7d98f6c8ac0ce8947f18a23be20f2914e /cowrieder.py
parentc21ad820902c69b1bffa4c6453c0e1a15f07fe8c (diff)
readme update + make that filter by hash thing real
Diffstat (limited to 'cowrieder.py')
-rw-r--r--cowrieder.py26
1 files changed, 19 insertions, 7 deletions
diff --git a/cowrieder.py b/cowrieder.py
index f022d4c..44051af 100644
--- a/cowrieder.py
+++ b/cowrieder.py
@@ -44,6 +44,11 @@ def ppip(addr, spacing = False, ttycolor = False): # Pretty-print an address wit
rs = rs + (" " * (15 - len(addr)))
return rs
+def hashgen(seed, length=16):
+ if(length % 2):
+ raise Warning("Due to strange behaviour on the part of the hexdigest() function, length should be a multiple of 2")
+ return hashlib.shake_256(str(seed).encode("utf-8")).hexdigest(int(length / 2))
+
parser = argparse.ArgumentParser(
description="Script to parse JSON logs from popular SSH honeypot Cowrie and print them in a more readable format"
)
@@ -63,11 +68,12 @@ parser.add_argument('-S', '--sessions', action='store_true', help='Print only th
parser.add_argument('-r', '--redact-ip', action='store_true', help='Redact IP addresses by converting them to 16-character hashes')
parser.add_argument('-i', '--filter-ip', help='Filter data to a specific IP or censored hash thereof')
-#parser.add_argument('-a', '--stats', action='store_true', help='Print aggregated statistics')
-#parser.add_argument('-j', '--json-stats', action='store_true', help='Dump aggregated statistics as JSON')
-#print_stats = args.stats or args.json_stats
+parser.add_argument('-a', '--stats', action='store_true', help='Print aggregated statistics')
+parser.add_argument('-j', '--json-stats', action='store_true', help='Dump aggregated statistics as JSON')
+
args = parser.parse_args()
+print_stats = args.stats or args.json_stats
filepath = args.filepath
@@ -98,7 +104,7 @@ with open(filepath, "r") as logfile:
entry = json.loads(line)
if(
- (not args.filter_ip or entry["src_ip"] == args.filter_ip) # If it's not the IP we're filtering for don't even bother man
+ (not args.filter_ip or entry["src_ip"] == args.filter_ip or hashgen(entry["src_ip"]) == args.filter_ip) # If it's not the IP we're filtering for don't even bother man
):
entries.append(entry)
session_id = entry['session']
@@ -106,7 +112,7 @@ with open(filepath, "r") as logfile:
if(session_id not in sessions):
sessions.update({session_id: [entry]})
if(args.redact_ip):
- session_ips.update({session_id: hashlib.shake_256(entry['src_ip'].encode("utf-8")).hexdigest(8)})
+ session_ips.update({session_id: hashgen(entry['src_ip'])})
else:
session_ips.update({session_id: entry['src_ip']})
else:
@@ -146,7 +152,7 @@ with open(filepath, "r") as logfile:
# Blank Mode logic
-if(args.blank):
+if(blankmode):
newsessions = sessions.copy()
for session_id in sessions:
@@ -228,7 +234,10 @@ else: # Default (low) verbosity: just the good stuff
df = entry["url"]
elif("destfile" in entry):
df = entry["destfile"]
- print(" | Saved file " + df + " to " + entry["outfile"][:40])
+ if(args.verbose):
+ print(" | Saved file " + df + " to " + entry["outfile"])
+ else:
+ print(" | Saved file " + df + " to " + entry["outfile"][:40] + "...")
print(" X Disconnected after " + session_durations[session_id] + "s")
else: # Printing logic for successful logins in which no commands were run
@@ -237,3 +246,6 @@ else: # Default (low) verbosity: just the good stuff
if(entry["eventid"] == "cowrie.login.failed" or entry["eventid"] == "cowrie.login.success"):
cred_combos.append((entry["username"], entry["password"]))
print(timestamp + " > " + ppip(ip, True, True) + " > " + ccgen("GREEN") + "Login ping" + ccgen() + ": " + str(cred_combos))
+
+if(args.stats):
+ print("Aggregate statistics") \ No newline at end of file