def on_request(self, request): self.first_client_chunk_received = True if not self.imap_detected: return request if self.client_starttls_rejected: if not self.vuln_notified: self.log( logging.CRITICAL, "Cleartext traffic after stripped STARTTLS") self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, True, None)) self.connection.vuln_notify( util.vuln.VULN_IMAP_STARTTLS_STRIP) self.vuln_notified = True # Stop analyzing/attacking this connection self.imap_detected = False elif self.client_starttls_pattern.match(request): # Client is attempting STARTTLS -- fake a rejection reply from # server and do not forward STARTTLS to server. self.client_starttls_rejected = True self.log(logging.DEBUG, "Suppressed STARTTLS from client") tag = request[:request.find(" ")] self.connection.client_socket.sendall( tag + " BAD STARTTLS unavailable\r\n") return "" return request
def on_close(self, handler_initiated): super(SelfSignedMITM, self).on_close(handler_initiated) if not self.success: self.log_event( logging.INFO, connection.AttackEvent(self.connection, self.name, False, None))
def on_close(self, handler_initiated): super(ClientHeartbleedHandler, self).on_close(handler_initiated) if not self.success: self.log_event( logging.INFO, connection.AttackEvent(self.connection, self.name, False, None))
def on_http(self, http): host = http.headers.get("host", self.connection.server_addr) self.log(logging.ERROR, "HTTP request %s %s" % (http.command, host + http.path)) self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, True, host + http.path))
def on_report(data): if data is None: return self.log(logging.CRITICAL, "SSLStrip'd URL %s was visited!" % url) self.log_event( logging.CRITICAL, connection.AttackEvent( self.connection, self.name, True, url)) self.connection.vuln_notify(util.vuln.VULN_SSL_STRIP) return False
def on_response(self, response): if not self.success and self.ssl: self.log(logging.CRITICAL, "MITM Success without server cert!") self.log_event( logging.CRITICAL, connection.AttackEvent( self.connection, self.name, True, None)) self.success = True self.connection.vuln_notify(self.vuln) return super(AnonServerMITM, self).on_response(response)
def on_response(self, response): if not self.success and self.ssl: self.log(logging.CRITICAL, "MITM Success! Cert file: %s" % (self.certificate)) self.log_event( logging.CRITICAL, connection.AttackEvent(self.connection, self.name, True, self.certificate)) self.success = True self.connection.vuln_notify(self.vuln) return super(SelfSignedMITM, self).on_response(response)
def on_report(self, data): if data is None: return self.log( logging.CRITICAL, "Client is vulnerable to Android Javascript RCE") self.log_event( logging.ERROR, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.vuln_notify(util.vuln.VULN_ANDROID_JAVASCRIPT_RCE) return False
def on_request(self, request): self.first_client_chunk_received = True if not self.imap_detected: return request if self.client_auth_pattern.match(request): self.log(logging.CRITICAL, "Authentication credentials in cleartext IMAP traffic") self.log_event( logging.ERROR, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.vuln_notify(util.vuln.VULN_CLEARTEXT_AUTH) return request
def on_http(self, http): auth = http.headers.get("Authorization", None) host = http.headers.get("host", self.connection.server_addr) if auth: self.log( logging.CRITICAL, "Authorization header in HTTP request %s %s" % (http.command, host + http.path)) self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, True, host + http.path)) self.connection.vuln_notify(util.vuln.VULN_CLEARTEXT_AUTH)
def on_request(self, request): if not self.ssl or self.bridge: return request try: if self.injected_server: record, size = tls.types.TlsRecord.from_stream(request) message = record.messages[0] if self.injected_server: # OpenSSL after the EarlyCCS fix should send an unexpcted # message error. Some other libraries send a close_notify so # accept that as well. if not (isinstance(message, tls.types.Alert) and ((message.description == 10 and message.level == 2) or message.description == 0)): self.log(logging.CRITICAL, "Client is vulnerable to Early CCS attack!") self.connection.vuln_notify(util.vuln.VULN_EARLY_CCS) self.log_event( logging.CRITICAL, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.close() self.bridge = True else: self.log(logging.DEBUG, "Client not vulnerable to early CCS") self.log_event( logging.INFO, connection.AttackEvent(self.connection, self.name, False, None)) except ValueError: # Failed to parse TLS, this is probably due to a short read of a TLS # record. pass return request
def on_chunk_received(self, data): if not self.first_chunk_checked: self.first_chunk_checked = True self.xmpp_detected = self.is_xmpp_start(data) if self.xmpp_detected: self.log(logging.DEBUG, "XMPP detected") if not self.xmpp_detected: return data # Consider dropping TLS/SSL. However, this will likely destroy # connectivity if STARTTLS stripping does not work. # if data[0] == 0x16: # self.log(logging.INFO, "Dropping TLS/SSL chunk") # return "" if self.starttls_feature_stripped: # Ignore/pass through starttls, proceed, and failure messages if (data == '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>' or data == '<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>' or data == '<failure xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>'): return data if not self.vuln_notified: self.log(logging.CRITICAL, "Cleartext traffic after stripped STARTTLS") self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, True, None)) self.connection.vuln_notify(util.vuln.VULN_XMPP_STARTTLS_STRIP) self.vuln_notified = True if not self.is_stream_features_present(data): return data self.log(logging.DEBUG, "XMPP stream features detected") if not self.is_starttls_feature_present(data): self.log(logging.WARNING, "XMPP STARTTLS feature missing") return data modified_data = self.strip_starttls_feature(data) if data == modified_data: self.log(logging.WARNING, "Failed to strip XMPP STARTTLS") return data self.starttls_feature_stripped = True self.log(logging.INFO, "Stripped XMPP STARTTLS") return modified_data
def on_request(self, request): # parse out request and check for heartbeat try: index = 0 while index < len(request): record, size = tls.types.TlsRecord.from_stream(request[index:]) if record.content_type == 24: self.log(logging.CRITICAL, "Heartbleed response received") self.log_event( logging.CRITICAL, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.vuln_notify( util.vuln.VULN_TLS_CLIENT_HEARTBLEED) self.success = True index += size except: pass return request
def on_chunk_received(self, data): if not self.first_chunk_checked: self.first_chunk_checked = True self.xmpp_detected = self.is_xmpp_start(data) if self.xmpp_detected: self.log(logging.DEBUG, "XMPP detected") if not self.xmpp_detected: return data if "<auth " in data: self.log( logging.CRITICAL, "Authentication credentials in XMPP traffic") self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, True, None)) self.connection.vuln_notify(util.vuln.VULN_CLEARTEXT_AUTH) return data
def on_request(self, request): self.first_client_chunk_received = True if not self.smtp_detected: return request if not self.ehlo_detected: if bool(self.ehlo_pattern.match(request)): self.ehlo_detected = True self.ehlo_response_pending = True self.log(logging.DEBUG, "SMTP EHLO detected") return request if self.ehlo_detected: if request.lower().startswith("starttls"): # Client is attempting STARTTLS -- fake a rejection reply from # server and do not forward STARTTLS to server. self.client_starttls_rejected = True self.log(logging.DEBUG, "Suppressed STARTTLS from client") self.connection.client_socket.sendall( "454 TLS not available due to temporary reason\r\n") return "" elif self.server_starttls_stripped or self.client_starttls_rejected: if not self.vuln_notified: self.log(logging.CRITICAL, "Cleartext traffic after stripped STARTTLS") self.log_event( logging.ERROR, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.vuln_notify( util.vuln.VULN_SMTP_STARTTLS_STRIP) self.vuln_notified = True # Stop analyzing/attacking this connection self.smtp_detected = False return request
def on_request(self, request): self.first_client_chunk_received = True if not self.smtp_detected: return request if not self.ehlo_detected: if bool(self.ehlo_pattern.match(request)): self.ehlo_detected = True self.ehlo_response_pending = True self.log(logging.DEBUG, "SMTP EHLO detected") return request if not self.ehlo_detected: return request if request.lower().startswith("auth "): self.log(logging.CRITICAL, "Authentication credentials in SMTP traffic") self.log_event( logging.ERROR, connection.AttackEvent(self.connection, self.name, True, None)) self.connection.vuln_notify(util.vuln.VULN_CLEARTEXT_AUTH) return request
def log_attack_event(self, data=None, success=True): self.log_event( logging.ERROR, connection.AttackEvent( self.connection, self.name, success, data))