aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md14
-rw-r--r--cowrieder.py26
2 files changed, 26 insertions, 14 deletions
diff --git a/README.md b/README.md
index cd12b27..76c0d22 100644
--- a/README.md
+++ b/README.md
@@ -13,14 +13,14 @@ Options:
-v, --verbose Make the output more verbose (print abridged logs for all logins where commands are run, not just the interesting ones)
-vv, --verboser Make the output even more verbose (print timestamp, event id, and message (if applicable) for all events)
-vvv, --verbosest Make the output even more verboserer (just group the input log by session id and dump it to pretty-printed JSON)
--B, --blank Print nothing whatsoever. Override this with other arguments to filter for only the stuff you care about
--P, --pings | With blank mode active, print "empty pings"
--F, --fails | With blank mode active, print failed logins
--L, --logins | With blank mode active, print "login pings"
--C, --commands | With blank mode active, print "command pings"
--S, --sessions * With blank mode active, print the cool interesting sessions that aren't any of that other stuff.
+-P, --pings Print only "empty pings"
+-F, --fails Print only failed logins
+-L, --logins Print only "login pings"
+-C, --commands Print only "command pings"
+-S, --sessions Print only the cool interesting sessions that aren't any of that other stuff.
+-r, --redact-ip Redact IP addresses by converting them to 16-character hashes
-i, --filter-ip FILTER_IP
- Filter data to a specific IP
+ Filter data to a specific IP or censored hash thereof
```
# Terminology
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