From e342b25a306251cd461501777a01b69d6de9ba45 Mon Sep 17 00:00:00 2001
From: Pavel Valach <pavel.valach@cesnet.cz>
Date: Wed, 19 Apr 2023 14:29:43 +0200
Subject: [PATCH] cowrie: Imported changes from HaaS project

---
 cowrie/wardenfiler.py | 101 +++++++++++++++++++++++++++++-------------
 1 file changed, 70 insertions(+), 31 deletions(-)

diff --git a/cowrie/wardenfiler.py b/cowrie/wardenfiler.py
index 7f21ec8..642ef81 100644
--- a/cowrie/wardenfiler.py
+++ b/cowrie/wardenfiler.py
@@ -161,13 +161,13 @@ class Output(cowrie.core.output.Output):
             entry["dst_ip"] = entry["dst_ip"].lstrip("::ffff:")
 
         # detect IPv4 or IPv6
-        af = "IP4" if not ':' in entry["src_ip"] else "IP6"
+        src_af = "IP4" if not ':' in entry["src_ip"] else "IP6"
 
         # If configured, override destination IP and port
         if entry.get("dst_ip"):
-            if af == "IP4" and self.reported_public_ipv4:
+            if src_af == "IP4" and self.reported_public_ipv4:
                 entry["dst_ip"] = self.reported_public_ipv4
-            elif af == "IP6" and self.reported_public_ipv6:
+            elif src_af == "IP6" and self.reported_public_ipv6:
                 entry["dst_ip"] = self.reported_public_ipv6
 
         if entry.get("dst_port") and self.reported_ssh_port:
@@ -205,14 +205,14 @@ class Output(cowrie.core.output.Output):
                 event["Category"].append("Attempt.Login")
                 event["Note"] = "SSH login attempt"
                 for i, c in self.attackers.items():
-                    src_ip, dst_ip = i.split(',')
-                    af = "IP4" if not ':' in src_ip else "IP6"
+                    a_src_ip, a_dst_ip = i.split(',')
+                    a_af = "IP4" if not ':' in a_src_ip else "IP6"
                     event["ID"] = str(uuid4())
                     event["DetectTime"] = event["WinEndTime"]
                     event["ConnCount"] = c
-                    event["Source"] = [{"Proto": ["tcp", "ssh"], af: [src_ip]}]
-                    event["Target"] = [{"Proto": ["tcp", "ssh"], af: [dst_ip]}]
-                    if (self.anon_mask_4 < 32) and (not ':' in  entry["dst_ip"]) or (self.anon_mask_6 < 128):
+                    event["Source"] = [{"Proto": ["tcp", "ssh"], a_af: [a_src_ip]}]
+                    event["Target"] = [{"Proto": ["tcp", "ssh"], a_af: [a_dst_ip]}]
+                    if (self.anon_mask_4 < 32 and a_af == "IP4") or (self.anon_mask_6 < 128):
                         event["Target"][0]["Anonymised"] = True
                     self.save_event(event)
                 self.attackers = {}
@@ -220,6 +220,12 @@ class Output(cowrie.core.output.Output):
                 self.attackers[aid] = 1
             self.win_start = ws
 
+        elif entry["session"] not in self.sessions:
+            # We do not save sessions
+            # that were created during previous Cowrie runs
+            # and we should not care about them.
+            return()
+
         elif entry["eventid"] == 'cowrie.login.success':
             s = entry["session"]
             if s in self.sessions:
@@ -240,7 +246,7 @@ class Output(cowrie.core.output.Output):
                 mware = None
                 fname = None
                 if "outfile" in entry and os.path.exists(entry["outfile"]):
-                    fp = open(entry["outfile"], "r")
+                    fp = open(entry["outfile"], "rb")
                     mware = fp.read()
                     fp.close()
                     if self.drop_malware:
@@ -253,10 +259,10 @@ class Output(cowrie.core.output.Output):
                     
                     if "url" in entry and entry["url"].startswith(tuple(sch.keys())):
                         url = urlparse(entry["url"])
-                        host = url.hostname
-                        ai = socket.getaddrinfo(host, None)[0]
-                        af = "IP6" if ai[0] == socket.AddressFamily.AF_INET6 else "IP4"
-                        ip = ai[4][0]
+                        url_host = url.hostname
+                        url_ai = socket.getaddrinfo(url_host, None)[0]
+                        url_af = "IP6" if url_ai[0] == socket.AddressFamily.AF_INET6 else "IP4"
+                        url_ip = url_ai[4][0]
                         proto = [ "tcp", url.scheme ]
                         port = url.port or sch[url.scheme]
                         
@@ -265,15 +271,11 @@ class Output(cowrie.core.output.Output):
                             fname = os.path.basename(entry['destfile'])
                             
                     elif not "url" in entry:
-                        # TODO implement the path for other files after discussion
-                        return()
-                        # The remainder of this branch will not execute now
-                        if entry["format"].startswith("Saved redir"):
-                            event["Note"] = "Saved file during honeypot session"
-                            fname = os.path.basename(entry['destfile'])
+                        if "destfile" in entry:
+                            event["Note"] = "Redirected content during honeypot session"
+                            fname = os.path.basename(entry["destfile"])
                         else:
                             event["Note"] = "Stdin contents during honeypot session"
-                        # End of the not executed part
 
                     else:
                         # TODO: Some exotic protocol? Let's not worry with that now
@@ -281,25 +283,27 @@ class Output(cowrie.core.output.Output):
                         
                     event["DetectTime"] = entry["timestamp"]
                     if "url" in entry:
+                        del event["Target"]
                         event["Source"][0] = { "Type": ["Malware"] }
                         event["Source"][0]["URL"] = [entry["url"]]
-                        event["Source"][0][af] = [ip]
+                        event["Source"][0][url_af] = [url_ip]
                         event["Source"][0]["Proto"] = proto
                         event["Source"][0]["Port"] = [port]
-                        if ip != host:
-                            event["Source"][0]["Hostname"] = [host]
+                        if url_ip != url_host:
+                            event["Source"][0]["Hostname"] = [url_host]  
                     else:
-                        # TODO implement later
-                        pass
+                        event["Source"][0] = { "Type": ["Botnet"] }
+                        # the source of the malicious activity is the host, we don't have further details to that
+                        event["Source"][0][src_af] = [entry["src_ip"]]
+                        event["Source"][0]["Port"] = [self.sessions[s]["src_port"]]
 
-                    del event["Target"]
                     event["Attach"] = [{
                         "Type": ["ShellCode"],
-                        "Hash": ["sha1:" + entry["shasum"]],
+                        "Hash": ["sha256:" + entry["shasum"]],
                         "Size": len(mware),
                         "Note": "Some probably malicious code downloaded during honeypot SSH session",
                         "ContentEncoding": "base64",
-                        "Content": b64encode(mware.encode()).decode(),
+                        "Content": b64encode(mware).decode(),
                     }]
                     if fname:
                         event["Attach"][0]["FileName"] = [fname]
@@ -307,6 +311,42 @@ class Output(cowrie.core.output.Output):
                         event["Attach"][0]["ExternalURI"] = [entry["url"]]
                     self.save_event(event)
 
+        elif entry["eventid"] == 'cowrie.session.file_upload':
+            # Upload through SCP or SFTP to the honeypot
+            s = entry["session"]
+            if s in self.sessions:                
+                # deal with the file first (drop even if not reported)
+                mware = None
+                fname = None
+                if "outfile" in entry and os.path.exists(entry["outfile"]):
+                    fp = open(entry["outfile"], "rb")
+                    mware = fp.read()
+                    fp.close()
+                    if self.drop_malware:
+                        os.remove(entry["outfile"])
+                    fname = entry["filename"]
+                    
+                if mware:
+                    event["Category"].append("Malware")
+                    event["Note"] = "Malware download during honeypot session"
+                    event["DetectTime"] = entry["timestamp"]
+                    event["Source"][0] = { "Type": ["Botnet"] }
+                    # the source of the malicious activity is the host, we don't have further details to that
+                    event["Source"][0][src_af] = [entry["src_ip"]]
+                    event["Source"][0]["Port"] = [self.sessions[s]["src_port"]]
+
+                    event["Attach"] = [{
+                        "Type": ["ShellCode"],
+                        "FileName": [fname],
+                        "Hash": ["sha256:" + entry["shasum"]],
+                        "Size": len(mware),
+                        "Note": "Some probably malicious code downloaded during honeypot SSH session",
+                        "ContentEncoding": "base64",
+                        "Content": b64encode(mware).decode(),
+                    }]                    
+                    self.save_event(event)
+            
+
         elif entry["eventid"] == 'cowrie.session.closed':
             s = entry["session"]
             if s in self.sessions and self.sessions[s]["loggedin"]:
@@ -314,9 +354,8 @@ class Output(cowrie.core.output.Output):
                 plain = all(c in string.printable for c in idata)
                 event["Category"].append("Intrusion.UserCompromise")
                 event["Note"] = "SSH successful login" + (" with unauthorized command input" if len(idata) else "")
-                af = "IP4" if not ':' in entry["src_ip"] else "IP6"
-                event["Source"][0][af] = [entry["src_ip"]]
-                event["Target"][0][af] = [self.sessions[s]["dst_ip"]]
+                event["Source"][0][src_af] = [entry["src_ip"]]
+                event["Target"][0][src_af] = [self.sessions[s]["dst_ip"]]
                 event["Source"][0]["Port"] = [self.sessions[s]["src_port"]]
                 dst_port = self.sessions[s]["dst_port"]
                 if dst_port in self.port_xlat:
-- 
GitLab