diff --git a/honeygrove/log.py b/honeygrove/log.py index ffa8e6a..ff851fe 100644 --- a/honeygrove/log.py +++ b/honeygrove/log.py @@ -187,20 +187,22 @@ def login(service: str, ip: str, port: int, successful: bool, user: str, secret: _log_alert(message) -def request(service: str, ip: str, port: int, req: str, user: str = None, request_type: str = None): +def request(service: str, remote_ip: str, remote_port: int, local_ip: str, local_port: int, req: str, user: str = None, request_type: str = None): """ Log function to be called when a request is received :param service: the concerning service - :param ip: attacker's IP-Address - :param port: attackers port + :param remote_ip: attacker's IP-Address + :param remote_port: attackers port + :param local_ip: local IP that was accessed + :param local_port: local port that was accessed :param req: the received request :param user: the user whose session invoked the alert :param request_type: for HTTP if the request is a GET or a POST request """ timestamp = format_time(get_time()) - coordinates = get_coordinates(ip) + coordinates = get_coordinates(remote_ip) ecs_event = {'category': 'warning', 'action': 'request'} ecs_hg_request = {'service': service, 'original': req} @@ -214,9 +216,8 @@ def request(service: str, ip: str, port: int, req: str, user: str = None, reques values = {'@timestamp': timestamp, 'service': ECS_SERVICE, 'event': ecs_event, - # XXX: we don't know the source port currently.. - 'source': get_ecs_address_dict(ip), - 'destination': get_ecs_address_dict(Config.general.address, port), + 'source': get_ecs_address_dict(remote_ip, remote_port), + 'destination': get_ecs_address_dict(local_ip, local_port), 'honeygrove': ecs_hg} # Append geo coordinates of source, if available @@ -232,25 +233,27 @@ def request(service: str, ip: str, port: int, req: str, user: str = None, reques lat = '{:.4f}'.format(coordinates[0]) lon = '{:.4f}'.format(coordinates[1]) - message = ('{} [REQUEST] {}, {}:{}, Lat: {}, Lon: {}, {}, {}, {}' - '').format(timestamp, service, ip, port, lat, lon, req, user, request_type) + message = ('{} [REQUEST] {}, {}:{}->{}:{}, Lat: {}, Lon: {}, {}, {}, {}' + '').format(timestamp, service, remote_ip, remote_port, local_ip, local_port, lat, lon, req, user, request_type) _log_alert(message) -def response(service: str, ip: str, port: int, resp: str, user: str = None, status_code=None): +def response(service: str, remote_ip: str, remote_port: int, local_ip: str, local_port: int, resp: str, user: str = None, status_code=None): """ Log function to be called when sending a response :param service: the concerning service - :param ip: attacker's IP-Address - :param port: attackers port + :param remote_ip: attacker's IP-Address + :param remote_port: attackers port + :param local_ip: local IP that was accessed + :param local_port: local port that was accessed :param resp: the response sent :param user: the user whose session invoked the alert :param status_code: the status code sent """ timestamp = format_time(get_time()) - coordinates = get_coordinates(ip) + coordinates = get_coordinates(remote_ip) ecs_event = {'category': 'warning', 'action': 'response'} ecs_hg_request = {'service': service, 'original': resp} @@ -264,8 +267,8 @@ def response(service: str, ip: str, port: int, resp: str, user: str = None, stat values = {'@timestamp': timestamp, 'service': ECS_SERVICE, 'event': ecs_event, - 'source': get_ecs_address_dict(Config.general.address), - 'destination': get_ecs_address_dict(ip, port), + 'source': get_ecs_address_dict(local_ip, local_port), + 'destination': get_ecs_address_dict(remote_ip, remote_port), 'honeygrove': ecs_hg} # Append geo coordinates of source, if available @@ -281,8 +284,8 @@ def response(service: str, ip: str, port: int, resp: str, user: str = None, stat lat = '{:.4f}'.format(coordinates[0]) lon = '{:.4f}'.format(coordinates[1]) - message = ('{} [RESPONSE] {}, {}:{}, Lat: {}, Lon: {}, {}, {}, {}' - '').format(timestamp, service, ip, port, lat, lon, resp, user, status_code) + message = ('{} [RESPONSE] {}, {}:{}->{}:{}, Lat: {}, Lon: {}, {}, {}, {}' + '').format(timestamp, service, local_ip, local_port, remote_ip, remote_port, lat, lon, resp, user, status_code) _log_alert(message) diff --git a/honeygrove/services/HTTPService.py b/honeygrove/services/HTTPService.py index 6b1afa6..b131911 100644 --- a/honeygrove/services/HTTPService.py +++ b/honeygrove/services/HTTPService.py @@ -76,7 +76,6 @@ class HTTPProtocol(Protocol): def __init__(self): self.state = None - self.peerOfAttacker = "" self.page = "" self.path = Config.http.resource_folder self.attackingSite = "" @@ -87,12 +86,13 @@ def __init__(self): def connectionMade(self): # Add connection to dictionary - self.factory.clients[self] = ("<" + str(self.transport.getPeer().host) + ":" - + str(self.transport.getPeer().port) + ">") - self.peerOfAttacker = self.transport.getPeer().host + peer = self.transport.getPeer() + self.factory.clients[self] = ("<" + str(peer.host) + ":" + str(peer.port) + ">") def dataReceived(self, data): + local = self.transport.getHost() + remote = self.transport.getPeer() data = data.decode('utf-8') self.requestType = data.split(' ', 1)[0] @@ -128,7 +128,7 @@ def dataReceived(self, data): elif self.requestType == "GET" and self.page in HTTPService.supportedSites: - log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "GET") + log.request("HTTP", remote.host, remote.port, local.host, local.port, self.page, "", "GET") message = HTTPService.okStatus + "\n" for k in HTTPService.responseHeadersOkStatus.keys(): @@ -139,7 +139,7 @@ def dataReceived(self, data): self.transport.write(message.encode('UTF-8')) if self.page in HTTPService.supportedSites: - log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "200 OK") + log.response("HTTP", remote.host, remote.port, local.host, local.port, self.page, "", "200 OK") self.transport.loseConnection() @@ -159,14 +159,15 @@ def dataReceived(self, data): else: password_string = data[password_index:data.find("&")] - log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, login_string, "POST") + log.request("HTTP", remote.host, remote.port, local.host, local.port, self.page, "", "POST") result = HTTPService.htdb.requestAvatarId(HTTPAvatar(login_string, password_string)) if isinstance(result, Deferred): if isinstance(result.result, failure.Failure): # Failure result.addErrback(self.errorBack) - log.response("HTTP", self.peerOfAttacker, HTTPService.port, "", login_string, "403 FORBIDDEN") - log.login("HTTP", self.peerOfAttacker, HTTPService.port, False, login_string, password_string, - str(HTTPService.htdb.getActual(login_string, password_string))) + log.response("HTTP", remote.host, remote.port, local.host, local.port, self.page, login_string, "403 FORBIDDEN") + # FIXME: Add remote port and local host + log.login("HTTP", remote.host, local.port, False, login_string, password_string, + str(HTTPService.htdb.try_get_tokens(login_string, password_string))) else: # Success message = HTTPService.okStatus + "\n" for k in HTTPService.responseHeadersOkStatus.keys(): @@ -177,9 +178,10 @@ def dataReceived(self, data): self.transport.write(message.encode('UTF-8')) self.page = "wp-admin_content.html" - log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, login_string, "200 OK") - log.login("HTTP", self.peerOfAttacker, HTTPService.port, True, login_string, password_string, - str(HTTPService.htdb.getActual(login_string, password_string))) + log.response("HTTP", remote.host, remote.port, local.host, local.port, self.page, login_string, "200 OK") + # FIXME: Add remote port and local host + log.login("HTTP", remote.host, local.port, True, login_string, password_string, + str(HTTPService.htdb.try_get_tokens(login_string, password_string))) self.transport.loseConnection() else: message = HTTPService.notFoundStatus + "\n" @@ -190,9 +192,9 @@ def dataReceived(self, data): message = message + "\n" + file.read() self.transport.write(message.encode('UTF-8')) - log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "GET") + log.request("HTTP", remote.host, remote.port, local.host, local.port, self.page, "", "GET") self.page = "404_login.html" - log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "404 Not Found") + log.response("HTTP", remote.host, remote.port, local.host, local.port, self.page, login_string, "404 NOT FOUND") self.transport.loseConnection() def connectionLost(self, reason): diff --git a/honeygrove/services/IMAPService.py b/honeygrove/services/IMAPService.py index d592ceb..186c815 100644 --- a/honeygrove/services/IMAPService.py +++ b/honeygrove/services/IMAPService.py @@ -203,6 +203,9 @@ def timeoutConnection(self): def dataReceived(self, rawData): self.resetTimeout() + local = self.transport.getHost() + remote = self.transport.getPeer() + # problem: at least Thunderbird pushes sometimes two commands so quickly they are received by twisted as one line # solution: put received data in buffer and fetch single lines from there @@ -228,7 +231,7 @@ def dataReceived(self, rawData): self.dataBuffer = "" if (not self.state["appendCleanUp"] and not self.state["appendData"]): - log.request(self.name, self.peerOfAttacker, Config.imap.port, line, self.username) + log.request(self.name, remote.host, remote.port, local.host, local.ip, line, self.username) # ignore one (maybe optional) empty line after append command if(self.state["appendCleanUp"]): if (line != ""): @@ -248,7 +251,7 @@ def dataReceived(self, rawData): mail = self.appendBuffer self.saveEmail(self.appendMailbox, self.appendFlaglist, mail) response = self.appendTag + " OK APPEND completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") self.transport.write(response.encode("UTF-8")) else: # wait for another part of the mail self.appendBuffer += self.dataBuffer @@ -256,11 +259,11 @@ def dataReceived(self, rawData): self.dataBuffer = "" elif(len(line) > self.maxCommandLength): response = "* BAD Command line too long\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (too long)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (too long)") self.transport.write(response.encode("UTF-8")) elif(len(line) == 0): response = "* BAD Empty command line\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (too short)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (too short)") self.transport.write(response.encode("UTF-8")) elif(re.match("^[A-Za-z\d]+ .+$", line, re.IGNORECASE)): # provides tag value for following answers in all cases @@ -269,23 +272,23 @@ def dataReceived(self, rawData): # "command-any" (Valid in all states) if(re.match("^"+tag+" CAPABILITY$", line, re.IGNORECASE)): response = "* CAPABILITY IMAP4rev1 LOGIN LOGOUT NOOP LIST LSUB UID SELECT\r\n"+tag+" OK CAPABILITY completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" LOGOUT$", line, re.IGNORECASE)): self.state["connected"] = False response = "* BYE IMAP4rev1 Server logging out\r\n"+tag+" OK LOGOUT completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") self.transport.write(response.encode("UTF-8")) # close connection self.transport.loseConnection() elif(re.match("^"+tag+" NOOP$", line, re.IGNORECASE)): response = tag+" OK NOOP completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" ((CAPABILITY)|(LOGOUT)|(NOOP)) .*$", line, re.IGNORECASE)): # unified error message for several commands response = "* BAD Command argument error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") self.transport.write(response.encode("UTF-8")) # "command-nonauth" (Valid only when in Not Authenticated state) @@ -297,26 +300,26 @@ def dataReceived(self, rawData): self.password = self.stripPadding(arguments.group("password")) if (True): - log.login(self.name, self.peerOfAttacker, Config.imap.port, True, self.username, self.password, "") + log.login(self.name, remote.host, local.port, True, self.username, self.password, "") self.setTimeout(self.timeoutPostAuth) self.stateRFC = IMAPState.Auth response = tag+" OK LOGIN completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: - log.login(self.name, self.peerOfAttacker, Config.imap.port, False, self.username, self.password, "") + log.login(self.name, remote.host, local.port, False, self.username, self.password, "") response = tag+" NO Invalid credentials\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "NO (credentials") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "NO (credentials") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" LOGIN .*$", line, re.IGNORECASE)): if (self.stateRFC == IMAPState.NotAuth): response = "* BAD Command argument error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence") self.transport.write(response.encode("UTF-8")) # TODO: implement AUTHENTICATE command (provides SASL auth (GSSAPI etc.)) @@ -338,10 +341,10 @@ def dataReceived(self, rawData): if (mailboxName in self.mailboxes): response += "* LIST (\\HasNoChildren) \".\" \""+mailboxName+"\"\r\n" response += tag+" OK LIST Completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" LSUB (?P\S+) (?P\S+)$", line, re.IGNORECASE)): @@ -360,10 +363,10 @@ def dataReceived(self, rawData): if (mailboxName in self.mailboxes): response += "* LSUB (\\HasNoChildren) \".\" \""+mailboxName+"\"\r\n" response += tag+" OK LSUB Completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" SELECT (?P\S+)$", line, re.IGNORECASE)): @@ -374,13 +377,13 @@ def dataReceived(self, rawData): self.stateRFC = IMAPState.Selected self.selectedMailbox = mailbox response = "* "+str(self.mailboxes[mailbox])+" EXISTS\r\n* 0 RECENT\r\n"+tag+" OK SELECT completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" NO Mailbox not found\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "NO (mailbox not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "NO (mailbox not found)") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" STATUS (?P\S+) \((?P\S+( \S+)*)\)$", line, re.IGNORECASE)): @@ -410,13 +413,13 @@ def dataReceived(self, rawData): response = "* STATUS "+mailbox+" ("+statusatt+")\r\n" response += tag + " OK STATUS completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = "* NO STATUS failure: no status for that name\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "NO (mailbox not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "NO (mailbox not found)") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" APPEND (?P\S+) \((?P\S+( \S+)*)?\)(?P .+)? \{(?P\d+)\}$", line, re.IGNORECASE)): @@ -439,21 +442,21 @@ def dataReceived(self, rawData): self.transport.write(response.encode("UTF-8")) else: response = "* NO APPEND error: can't append to that mailbox, error in flags or date/time or message text\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "NO (storage limitation)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "NO (storage limitation)") self.transport.write(response.encode("UTF-8")) else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" (LIST|LSUB|SELECT|STATUS|APPEND) .*$", line, re.IGNORECASE)): # unified error message for several commands if (self.stateRFC == IMAPState.Auth or self.stateRFC == IMAPState.Selected): response = "* BAD Command argument error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) # "command-select" (Valid only when in Selected state) @@ -462,19 +465,19 @@ def dataReceived(self, rawData): # TODO: delete accordingly flagged mails self.stateRFC = IMAPState.Auth response = tag+" OK CLOSE completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+"CLOSE .*$", line, re.IGNORECASE)): if (self.stateRFC == IMAPState.Selected): response = "* BAD Command argument error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" UID FETCH (?P\S+) (?P.+)$", line, re.IGNORECASE)): @@ -513,34 +516,34 @@ def dataReceived(self, rawData): response += "\r\n)\r\n" c += 1 response += tag+" OK FETCH complete\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) elif(re.match("^"+tag+" UID FETCH .+$", line, re.IGNORECASE)): response = "* BAD Command argument error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") self.transport.write(response.encode("UTF-8")) # temporary workaround to avoid the client to throw an error after uploading the mail elif(re.match("^"+tag+" UID SEARCH *$", line, re.IGNORECASE)): if (self.stateRFC == IMAPState.Selected): response = "* SEARCH\r\n"+tag+" OK SEARCH completed\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "OK") else: response = tag+" BAD Command received in invalid state.\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (sequence)") self.transport.write(response.encode("UTF-8")) else: response = "* BAD Command unknown\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (command)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (command)") self.transport.write(response.encode("UTF-8")) else: response = "* BAD Syntax error\r\n" - log.response(self.name, self.peerOfAttacker, Config.imap.port, "", self.username, "BAD (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "BAD (syntax)") self.transport.write(response.encode("UTF-8")) diff --git a/honeygrove/services/ListenService.py b/honeygrove/services/ListenService.py index 63251bd..8ebb2c6 100644 --- a/honeygrove/services/ListenService.py +++ b/honeygrove/services/ListenService.py @@ -99,4 +99,7 @@ def dataReceived(self, data): Called when the attacker sends data. :param data: The received data """ - log.request(Config.listenServiceName, self.transport.getPeer().host, self.transport.getHost().port, data.decode()) + + local = self.transport.getHost() + remote = self.transport.getPeer() + log.request(Config.listenServiceName, remote.host, remote.port, local.host, local.port, data.decode()) diff --git a/honeygrove/services/POP3Service.py b/honeygrove/services/POP3Service.py index 5d9abce..a136256 100644 --- a/honeygrove/services/POP3Service.py +++ b/honeygrove/services/POP3Service.py @@ -103,6 +103,9 @@ def timeoutConnection(self): def dataReceived(self, rawData): self.resetTimeout() + local = self.transport.getHost() + remote = self.transport.getPeer() + # TODO: Verifizieren, dass möglichst alle 503-Fälle ("Bad sequence of commands") abgedeckt sind if(rawData.startswith(b'\xff') or rawData.startswith(b'\x04')): # ignore Ctrl+C/D/Z etc. @@ -119,7 +122,7 @@ def dataReceived(self, rawData): line = data[:data.find("\r\n")] # restrict maximum input lenght (doesn't affect mail transmission) line = line[:4094] - log.request(self.name, self.peerOfAttacker, Config.pop3.port, line, self.username) + log.request(self.name, remote.host, remote.port, local.host, local.port, line, self.username) if(re.match("^USER( \S+)?$", line, re.IGNORECASE)): if(re.match("^USER \S+$", line, re.IGNORECASE)): @@ -127,10 +130,10 @@ def dataReceived(self, rawData): self.username = arguments.group("username") self.state["user"] = True response = "+OK Please enter password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR") self.transport.write(response.encode("UTF-8")) elif(re.match("^PASS( .*)?$", line, re.IGNORECASE)): @@ -140,21 +143,21 @@ def dataReceived(self, rawData): self.password = arguments.group("password") # TODO: implement honeytokendb check if (True): - log.login(self.name, self.peerOfAttacker, Config.pop3.port, True, self.username, self.password, "") + log.login(self.name, remote.host, local.port, True, self.username, self.password, "") self.state["auth"] = True self.setTimeout(self.timeoutPostAuth) response = "+OK mailbox locked and ready\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: - log.login(self.name, self.peerOfAttacker, Config.pop3.port, False, self.username, self.password, "") + log.login(self.name, remote.host, local.port, False, self.username, self.password, "") response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") else: response = "-ERR Bad sequence of commands\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (sequence of commands)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (sequence of commands)") else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") # print("POP3Service sent: \""+response+"\"") self.transport.write(response.encode("UTF-8")) @@ -162,13 +165,13 @@ def dataReceived(self, rawData): if(line == "STAT"): if (self.state["auth"]): response = "+OK "+str(self.mailcount)+" "+str(self.mailsize)+"\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") self.transport.write(response.encode("UTF-8")) elif(re.match("^LIST( .*)?$", line, re.IGNORECASE)): @@ -179,24 +182,24 @@ def dataReceived(self, rawData): for i, mail in enumerate(self.emails): response += str(i+1)+" "+str(len(mail[1]))+"\r\n" response += ".\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: # n-th mail requested n = int(re.match("^LIST( (\d+))$", line, re.IGNORECASE).groups()[1]) if (0 <= (n-1) < len(self.emails)): response = "+OK "+str(n)+" "+str(len(self.emails[n-1][1]))+"\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR Email "+str(n)+" not available\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (mail not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (mail not found)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") self.transport.write(response.encode("UTF-8")) elif(re.match("^UIDL( .*)?$", line, re.IGNORECASE)): @@ -207,24 +210,24 @@ def dataReceived(self, rawData): for i, mail in enumerate(self.emails): response += str(i+1)+" "+mail[2]+"\r\n" response += ".\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: # n-th mail requested n = int(re.match("^UIDL( (\d+))$", line).groups()[1]) if (0 <= (n-1) < len(self.emails)): response = "+OK "+str(n)+" "+hashlib.md5(self.emails[n-1][1].encode("UTF-8")).hexdigest()+"\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR Email "+str(n)+" not available\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (mail not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (mail not found)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") self.transport.write(response.encode("UTF-8")) elif(re.match("^RETR( .*)?$", line, re.IGNORECASE)): @@ -234,18 +237,18 @@ def dataReceived(self, rawData): n = int(re.match("^RETR( (\d+))$", line, re.IGNORECASE).groups()[1]) if (0 <= (n-1) < len(self.emails)): response = "+OK "+str(len(self.emails[n-1][1]))+" octets\r\n"+self.emails[n-1][0]+"\r\n"+self.emails[n-1][1]+"\r\n.\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR message "+str(n)+" not available\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (mail not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (mail not found)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") self.transport.write(response.encode("UTF-8")) elif(re.match("^DELE( .*)?$", line, re.IGNORECASE)): @@ -255,18 +258,18 @@ def dataReceived(self, rawData): n = int(re.match("^DELE( (\d+))$", line, re.IGNORECASE).groups()[1]) if (0 <= (n-1) < len(self.emails)): response = "+OK message "+str(n)+" deleted\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") else: response = "-ERR message "+str(n)+" not available\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (mail not found)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (mail not found)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR POP3 Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (credentials)") self.transport.write(response.encode("UTF-8")) else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax)") self.transport.write(response.encode("UTF-8")) elif(re.match("^QUIT( .*)?$", line, re.IGNORECASE)): @@ -274,16 +277,16 @@ def dataReceived(self, rawData): if (line == "QUIT"): self.state["connected"] = False response = "+OK bye\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "+OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "+OK") self.transport.write(response.encode("UTF-8")) # close connection self.transport.loseConnection() else: response = "-ERR Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (syntax") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (syntax") self.transport.write(response.encode("UTF-8")) else: response = "-ERR Unrecognized command \'"+line+"\'\r\n" - log.response(self.name, self.peerOfAttacker, Config.pop3.port, "", self.username, "-ERR (command)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "-ERR (command)") self.transport.write(response.encode("UTF-8")) diff --git a/honeygrove/services/SMTPService.py b/honeygrove/services/SMTPService.py index 09c62fe..95e6f34 100644 --- a/honeygrove/services/SMTPService.py +++ b/honeygrove/services/SMTPService.py @@ -90,6 +90,10 @@ def timeoutConnection(self): def dataReceived(self, rawData): self.resetTimeout() + + local = self.transport.getHost() + remote = self.transport.getPeer() + # TODO: Verifizieren, dass möglichst alle 503-Fälle ("Bad sequence of commands") abgedeckt sind if (rawData.startswith(b'\xff') or rawData.startswith(b'\x04')): # ignore Ctrl+C/D/Z etc. @@ -107,7 +111,7 @@ def dataReceived(self, rawData): # restrict maximum input lenght (doesn't affect mail transmission) line = line[:4094] if not self.state["data"] and not self.state["authLOGIN"] and not self.state["authLOGINuser"]: - log.request(self.name, self.peerOfAttacker, Config.smtp.port, line, self.username) + log.request(self.name, remote.host, remote.port, local.host, local.port, line, self.username) # moved this block to the top: # if self.state["data"] gets verified after commands, a mail body containing these valid commands executes them @@ -118,7 +122,7 @@ def dataReceived(self, rawData): self.state["data"] = False self.state["msg"] = True response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") self.transport.write(response.encode("UTF-8")) elif re.match('^RSET( .*)?$', line, re.IGNORECASE): @@ -130,12 +134,12 @@ def dataReceived(self, rawData): self.username = "" self.password = "" response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") self.transport.write(response.encode("UTF-8")) elif re.match('^NOOP( .*)?$', line, re.IGNORECASE): response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") self.transport.write(response.encode("UTF-8")) elif re.match('^QUIT( .*)?$', line, re.IGNORECASE): @@ -143,13 +147,13 @@ def dataReceived(self, rawData): if (line == "QUIT"): self.state["connected"] = False response = "221 Service closing transmission channel\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "221 OK (closing)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "221 OK (closing)") self.transport.write(response.encode("UTF-8")) # close connection self.transport.loseConnection() else: response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax)") self.transport.write(response.encode("UTF-8")) elif self.state["authLOGIN"]: # doesn't start with anything recognisable @@ -168,40 +172,40 @@ def dataReceived(self, rawData): self.state["authLOGINuser"] = False # TODO: implement honeytokendb check if False: - log.login(self.name, self.peerOfAttacker, Config.smtp.port, True, self.username, self.password, "") + log.login(self.name, remote.host, local.port, True, self.username, self.password, "") self.state["auth"] = True self.setTimeout(self.timeoutPostAuth) response = "235 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "235 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "235 OK") else: - log.login(self.name, self.peerOfAttacker, Config.smtp.port, False, self.username, self.password, "") + log.login(self.name, remote.host, local.port, False, self.username, self.password, "") response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (credentials)") self.transport.write(response.encode("UTF-8")) elif re.match('^HELP( .*)?$', line, re.IGNORECASE): # don't react to arguments (exactly like e.g. smtp.outlook.com) response = "214 This server supports the following commands:\r\n214 HELO EHLO RCPT DATA MAIL QUIT HELP AUTH VRFY RSET NOOP\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "214 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "214 OK") self.transport.write(response.encode("UTF-8")) elif re.match('^(HELO|EHLO)( .*)?$', line, re.IGNORECASE): self.state["hello"] = True if (self.AuthMethods != ""): response = "250 AUTH"+self.AuthMethods+"\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") else: # authentication completed without authentication self.state["auth"] = True self.setTimeout(self.timeoutPostAuth) response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") self.transport.write(response.encode("UTF-8")) elif re.match("^AUTH( .*)?$", line, re.IGNORECASE): if (line == "AUTH"): response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax") else: if self.state["hello"]: if re.match("^AUTH PLAIN \S*$", line, re.IGNORECASE): @@ -216,48 +220,48 @@ def dataReceived(self, rawData): self.state["auth"] = True self.setTimeout(self.timeoutPostAuth) response = "235 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "235 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "235 OK") else: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (credentials)") else: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (unsupported)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (unsupported)") elif line == "AUTH LOGIN": if ("LOGIN" in self.AuthMethods): self.state["authLOGIN"] = True response = "334 VXNlcm5hbWU6\r\n" # "334 Username:" else: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (unsupported)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (unsupported)") elif line == "AUTH CRAM-MD5": # TODO: implement CRAM-MD5 or disable this code path if ("CRAM-MD5" in self.AuthMethods): print("CRAM-MD5 not yet implemented") response = "504 Command parameter not implemented\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "504 (not implemented)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "504 (not implemented)") self.transport.write(response.encode("UTF-8")) self.transport.loseConnection() else: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (unsupported)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (unsupported)") elif line == "AUTH SCRAM-SHA-1": # TODO: implement SCRAM-SHA-1 or disable this code path if "SCRAM-SHA-1" in self.AuthMethods: print("SCRAM-SHA-1 not yet implemented") response = "504 Command parameter not implemented\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "504 (not implemented)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "504 (not implemented)") self.transport.write(response.encode("UTF-8")) self.transport.loseConnection() else: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (unsupported)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (unsupported)") else: response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax)") else: response = "503 Bad sequence of commands\r\n" # "Send hello first" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "503 (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "503 (sequence)") self.transport.write(response.encode("UTF-8")) elif re.match("^MAIL FROM:(.*)$", line, re.IGNORECASE): @@ -267,17 +271,17 @@ def dataReceived(self, rawData): self.state["mailfrom"] = True self.mailFrom = re.match("^MAIL FROM:[ ]?<(.*)>$", line, re.IGNORECASE).groups()[0] # use "<(.*@.*\..*?)>" to check basic adress syntax response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") elif self.state["hello"]: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (credentials)") else: response = "503 Bad sequence of commands\r\n" # "Send hello first" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "503 (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "503 (sequence)") else: # no email adress given etc. response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax)") self.transport.write(response.encode("UTF-8")) elif re.match("^RCPT TO:(.*)$", line, re.IGNORECASE): @@ -287,17 +291,17 @@ def dataReceived(self, rawData): self.state["mailto"] = True self.mailTo = re.match("^RCPT TO:[ ]?<(.*)>$", line, re.IGNORECASE).groups()[0] # use "<(.*@.*\..*?)>" to check basic adress syntax # use "<(.*@.*\..*?)>" to check basic adress syntax response = "250 OK\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "250 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "250 OK") elif self.state["hello"]: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (credentials)") else: response = "503 Bad sequence of commands\r\n" # "Send hello first" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "503 (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "503 (sequence)") else: # no email adress given etc. response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax)") self.transport.write(response.encode("UTF-8")) elif re.match("^DATA( .*)?$", line, re.IGNORECASE): @@ -307,29 +311,29 @@ def dataReceived(self, rawData): response = "354 Start mail input\r\n" elif self.state["auth"]: response = "503 Bad sequence of commands\r\n" # "Send hello first" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "503 (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "503 (sequence)") elif self.state["hello"]: response = "535 SMTP Authentication unsuccessful/Bad username or password\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "535 (credentials)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "535 (credentials)") else: response = "503 Bad sequence of commands\r\n" # "Send hello first" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "503 (sequence)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "503 (sequence)") else: response = "501 Syntax error in parameters or arguments\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "501 (syntax)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "501 (syntax)") self.transport.write(response.encode("UTF-8")) elif re.match("^VRFY( .*)?$", line, re.IGNORECASE): response = "252 Cannot VRFY user\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "252 OK") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "252 OK") self.transport.write(response.encode("UTF-8")) elif re.match("^SIZE( .*)?$", line, re.IGNORECASE): response = "502 Command not implemented\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "502 (not implemented)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "502 (not implemented)") self.transport.write(response.encode("UTF-8")) else: response = "500 Unrecognized command \'"+line+"\'\r\n" - log.response(self.name, self.peerOfAttacker, Config.smtp.port, "", self.username, "500 (command)") + log.response(self.name, remote.host, remote.port, local.host, local.port, "", self.username, "500 (command)") self.transport.write(response.encode("UTF-8")) diff --git a/honeygrove/services/SSHService.py b/honeygrove/services/SSHService.py index 1be27d3..d418e02 100644 --- a/honeygrove/services/SSHService.py +++ b/honeygrove/services/SSHService.py @@ -454,7 +454,8 @@ def openShell(self, transport): ip = transport.session.avatar.conn.transport.transport.client[0] port = transport.session.avatar.conn.transport.transport.server._realPortNumber - log.request("SSH", ip, port, "Request shell", transport.session.avatar.username.decode()) + # FIXME: check which ips and ports belong here + log.request("SSH", ip, port, "", -1, "Request shell", transport.session.avatar.username.decode()) def getPty(self, terminal, windowSize, attrs): """ @@ -475,7 +476,8 @@ def execCommand(self, pp, cmd): """ ip = pp.session.avatar.conn.transport.transport.client[0] port = pp.session.avatar.conn.transport.transport.server._realPortNumber - log.request("SSH", ip, port, "execCommand " + cmd.decode(), pp.session.avatar.username.decode()) + # FIXME: figure out which ips and ports belong here + log.request("SSH", ip, port, "", -1, "execCommand " + cmd.decode(), pp.session.avatar.username.decode()) pp.session.conn.transport.sendDisconnect(7, b"Command Execution is not supported.") def windowChanged(self, *args):