def try_password(options, password, output=None, k=0): p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN, version=options.router_version) p.adm_command = 2 p.adm_password = password p = str(SAPNI() / p) import fau_timer fau_timer.init() fau_timer.send_request(options.remote_host, options.remote_port, p, len(p)) fau_timer.calculate_time() cpuSpeed = fau_timer.get_speed() cpuTicks = fau_timer.get_cpu_ticks() time = fau_timer.get_time() if options.verbose: print("Request time: CPU Speed: %s Hz CPU Ticks: %s Time: %s nanosec" % (cpuSpeed, cpuTicks, time)) # Write the time to the output file if output: output.write("%i,%s,%s\n" % (k, password, time)) return time
def test_saprouter_route_dissection(self): """Test dissection of a SAP Router route request.""" # Build the Route request packet router_string = [SAPRouterRouteHop(hostname="1.2.3.4", port=1234), SAPRouterRouteHop(hostname="4.3.2.1", port=4321, password="******")] router_string_lens = list(map(len, list(map(str, router_string)))) p = SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=len(router_string), route_talk_mode=1, route_rest_nodes=1, route_length=sum(router_string_lens), route_offset=router_string_lens[0], route_string=router_string) pkt = Ether()/IP()/TCP(sport=3299, dport=9999)/SAPNI()/p packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), len(p)) self.assertIn('saprouter', packet) self.assert_fields(p, packet["saprouter"], self.route_mapping) self.assertEqual("Route password found", packet['saprouter']._ws_expert_message)
def get_router_version(connection): r = connection.sr( SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=40, opcode=1)) if router_is_control(r) and r.opcode == 2: return r.version else: return None
def test_saprouter_dissection(self): """Test dissection of a basic SAP Router packet. """ pkt = Ether() / IP() / TCP(dport=3299) / SAPNI() / SAPRouter() packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), 24) self.assertIn('saprouter', packet)
def handle_data(self): if self.routed: self.request.send(self.packet) return self.packet.decode_payload_as(SAPRouter) route_request = self.packet[SAPRouter] if router_is_route(route_request): if route_request.route_string[1].hostname == "10.0.0.1" and \ route_request.route_string[1].port == "3200": self.routed = True self.request.send(SAPRouter(type=SAPRouter.SAPROUTER_PONG)) else: self.request.send(SAPRouter(type=SAPRouter.SAPROUTER_ERROR, return_code=-94)) else: self.request.send(SAPRouter(type=SAPRouter.SAPROUTER_ERROR))
def route(self, server): print "[*] Routing to %s:%d !" % (self.options.target_host, self.options.target_port) # Build the Route request packet router_string = [SAPRouterRouteHop(hostname=self.options.remote_host, port=self.options.remote_port), SAPRouterRouteHop(hostname=self.options.target_host, port=self.options.target_port, password=self.options.target_pass)] router_string_lens = map(len, map(str, router_string)) p = SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=len(router_string), route_talk_mode=1, route_rest_nodes=1, route_length=sum(router_string_lens), route_offset=router_string_lens[0], route_string=router_string) if self.options.verbose: p.show2() # Send the request and grab the response response = server.sr(p) if SAPRouter in response: response = response[SAPRouter] if router_is_pong(response): print "[*] Route request accepted !" self.routed = True elif router_is_error(response) and response.return_code == -94: print "[*] Route request not accepted !" print response.err_text_value raise RouteException("Route request not accepted") else: print "[*] Router send error" print response.err_text_value raise Exception("Router error: %s", response.err_text_value) else: print "[*] Wrong response received !" raise Exception("Wrong response received")
def try_password(options, password, output=None, k=0): p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN, version=options.router_version) p.adm_command = 2 p.adm_password = password p = str(SAPNI() / p) fau_timer.init() fau_timer.send_request(options.remote_host, options.remote_port, p, len(p)) fau_timer.calculate_time() cpu_peed = fau_timer.get_speed() cpu_ticks = fau_timer.get_cpu_ticks() time = fau_timer.get_time() if options.verbose: print("Request time: CPU Speed: %s Hz CPU Ticks: %s Time: %s nanosec" % (cpu_peed, cpu_ticks, time)) # Write the time to the output file if output: output.write("%i,%s,%s\n" % (k, password, time)) return time
def test_saprouter_admin_peer_trace_dissection(self): """Test dissection of a SAP Router admin set/clear peer trace.""" for command in [10, 11]: # Build the Admin packet p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN, version=2, adm_command=command, adm_address_mask="0.0.0.0") pkt = Ether()/IP()/TCP(sport=3299, dport=9999)/SAPNI()/p packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), len(p)) self.assertIn('saprouter', packet) self.assert_fields(p, packet["saprouter"], self.admin_mapping)
def test_saprouter_admin_info_request_dissection(self): """Test dissection of a SAP Router admin info request.""" # Build the Admin packet p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN, version=2, adm_command=2, adm_password="******") pkt = Ether()/IP()/TCP(sport=3299, dport=9999)/SAPNI()/p packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), len(p)) self.assertIn('saprouter', packet) self.assert_fields(p, packet["saprouter"], self.admin_mapping) self.assertEqual("Info password found", packet['saprouter']._ws_expert_message)
def test_saprouter_admin_cancel_trace_route_dissection(self): """Test dissection of a SAP Router admin cancel route and trace route request.""" for command in [6, 12, 13]: # Build the Admin packet p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN, version=2, adm_command=command, adm_client_count=2, adm_client_ids=[1,2]) pkt = Ether()/IP()/TCP(sport=3299, dport=9999)/SAPNI()/p packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), len(p)) self.assertIn('saprouter', packet) self.assert_fields(p, packet["saprouter"], self.admin_mapping)
def handle_control(self, pkt): """Handles control messages""" opcode_str = router_control_opcodes[pkt.opcode] if pkt.opcode in router_control_opcodes else "unknown" self.logger.debug("Handling control message, opcode %d (%s)", pkt.opcode, opcode_str) # Version request if pkt.opcode == 1: self.logger.debug("Received version request (client version %d)", pkt.version) self.server.clients[self.client_address].ni_version = pkt.version self.request.send(SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=self.router_version, opcode=2, return_code=-13)) else: self.logger.debug("Unhandled opcode %d (%s)", pkt.opcode, opcode_str) return self.return_error(return_code=-13, error="invalid client version", detail="NiBufIProcMsg: unknown opcode 3 received")
def test_saprouter_control_dissection(self): """Test dissection of a SAP Router control.""" # Build the Control packet p = SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=2, opcode=1, return_code=-99, control_text_length=8, control_text_value="SOMEDATA") pkt = Ether()/IP()/TCP(sport=3299, dport=9999)/SAPNI()/p packet = self.get_capture(pkt)[0] self.assertIn('sapni', packet) self.assertEqual(int(packet['sapni'].length), len(p)) self.assertIn('saprouter', packet) self.assert_fields(p, packet["saprouter"], self.control_mapping)
def return_error(self, **options): """Returns an error response""" self.logger.debug("Returning error code %d (%s)", options.get("return_code"), router_return_codes[options.get("return_code")]) error_text = SAPRouterError(release=str(self.release), version=str(self.router_version), error_time=datetime.now().strftime(SAPRouterError.time_format), location="SAPRouter %d.%d on '%s'" % (self.router_version, self.router_version_patch, self.hostname)) for field in list(options.keys()): setattr(error_text, field, options[field]) error_pkt = SAPRouter(type=SAPRouter.SAPROUTER_ERROR, version=self.router_version, opcode=0, return_code=options.get("return_code"), err_text_value=error_text) self.request.send(error_pkt) self.session.add_event("Returned error", data={"return_code": options.get("return_code"), "error_msg": router_return_codes[options.get("return_code")]}, response=str(error_pkt))
def main(): options = parse_options() if options.verbose: logging.basicConfig(level=logging.DEBUG) response = False p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN) if options.stop: p.adm_command = 5 print "[*] Requesting stop of the remote SAP Router" elif options.soft: p.adm_command = 9 print "[*] Requesting a soft shutdown of the remote SAP Router" response = True elif options.info: p.adm_command = 2 if options.info_password: if len(options.info_password) > 19: print "[*] Password too long, truncated at 19 characters" p.adm_password = options.info_password print "[*] Requesting info using password", p.adm_password else: print "[*] Requesting info" response = True elif options.new_route: p.adm_command = 3 print "[*] Requesting a refresh of the router table" elif options.trace: p.adm_command = 4 print "[*] Requesting a toggle on the trace settings" elif options.cancel: p.adm_command = 6 p.adm_client_ids = map(int, options.cancel.split(",")) print "[*] Requesting a cancel of the route(s) with client id(s) %s" % p.adm_client_ids response = True elif options.dump: p.adm_command = 7 print "[*] Requesting a dump of the buffers" elif options.flush: p.adm_command = 8 print "[*] Requesting a flush of the buffers" elif options.hide: p.adm_command = 14 print "[*] Requesting a hide on the errors to clients" response = True elif options.set_peer: p.adm_command = 10 p.adm_address_mask = options.set_peer print "[*] Request a set peer trace for the address mask %s" % p.adm_address_mask response = True elif options.clear_peer: p.adm_command = 11 p.adm_address_mask = options.clear_peer print "[*] Request a clear peer trace for the address mask %s" % p.adm_address_mask response = True elif options.trace_conn: p.adm_command = 12 p.adm_client_ids = map(int, options.trace_conn.split(",")) print "[*] Requesting a connection trace with client id(s) %s" % p.adm_client_ids response = True else: print "[*] No command specified !" return # Initiate the connection conn = SAPNIStreamSocket.get_nisocket(options.remote_host, options.remote_port) print "[*] Connected to the SAP Router %s:%d" % (options.remote_host, options.remote_port) # Retrieve the router version used by the server if not specified if options.router_version: p.version = options.router_version else: p.version = get_router_version(conn) or p.version print "[*] Using SAP Router version %d" % p.version # Send the router admin request print "[*] Sending Router Admin packet" if options.verbose: p.show2() conn.send(p) # Grab the response if required if response: # Some responses has no SAPRouter's packet format and are raw strings, # we need to get the SAP NI layer first and then check if we could go # down to the SAPRouter layer. response = conn.recv()[SAPNI] if SAPRouter in response and response[SAPRouter].payload: response = response[SAPRouter] # If the response is an error, print and exit if router_is_error(response): print "[*] Error requesting info:" if options.verbose: response.show2() else: print response.err_text_value # Otherwise, print all the packets sent by the SAP Router else: print "[*] Response:" try: while (response): print response.payload response = conn.recv() except: pass
def main(): options = parse_options() if options.verbose: logging.basicConfig(level=logging.DEBUG) response = False p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN) if options.stop: p.adm_command = 5 print("[*] Requesting stop of the remote SAP Router") elif options.soft: p.adm_command = 9 print("[*] Requesting a soft shutdown of the remote SAP Router") response = True elif options.info: p.adm_command = 2 if options.info_password: if len(options.info_password) > 19: print("[*] Password too long, truncated at 19 characters") p.adm_password = options.info_password print("[*] Requesting info using password %s" % p.adm_password) else: print("[*] Requesting info") response = True elif options.new_route: p.adm_command = 3 print("[*] Requesting a refresh of the router table") elif options.trace: p.adm_command = 4 print("[*] Requesting a toggle on the trace settings") elif options.cancel: p.adm_command = 6 p.adm_client_ids = list(map(int, options.cancel.split(","))) print("[*] Requesting a cancel of the route(s) with client id(s) %s" % p.adm_client_ids) response = True elif options.dump: p.adm_command = 7 print("[*] Requesting a dump of the buffers") elif options.flush: p.adm_command = 8 print("[*] Requesting a flush of the buffers") elif options.hide: p.adm_command = 14 print("[*] Requesting a hide on the errors to clients") response = True elif options.set_peer: p.adm_command = 10 p.adm_address_mask = options.set_peer print("[*] Request a set peer trace for the address mask %s" % p.adm_address_mask) response = True elif options.clear_peer: p.adm_command = 11 p.adm_address_mask = options.clear_peer print("[*] Request a clear peer trace for the address mask %s" % p.adm_address_mask) response = True elif options.trace_conn: p.adm_command = 12 p.adm_client_ids = list(map(int, options.trace_conn.split(","))) print("[*] Requesting a connection trace with client id(s) %s" % p.adm_client_ids) response = True else: print("[*] No command specified !") return # Initiate the connection conn = SAPNIStreamSocket.get_nisocket(options.remote_host, options.remote_port) print("[*] Connected to the SAP Router %s:%d" % (options.remote_host, options.remote_port)) # Retrieve the router version used by the server if not specified if options.router_version: p.version = options.router_version else: p.version = get_router_version(conn) or p.version print("[*] Using SAP Router version %d" % p.version) # Send the router admin request print("[*] Sending Router Admin packet") if options.verbose: p.show2() conn.send(p) # Grab the response if required if response: # Some responses has no SAPRouter's packet format and are raw strings, # we need to get the SAP NI layer first and then check if we could go # down to the SAPRouter layer. raw_response = conn.recv()[SAPNI] if SAPRouter in raw_response: router_response = raw_response[SAPRouter] # If the response was null, just return elif raw_response.length == 0: return # If the response is an error, print and exit if router_is_error(router_response): print("[*] Error requesting info:") if options.verbose: router_response.show2() else: print(router_response.err_text_value.error) # Otherwise, print the packets sent by the SAP Router else: print("[*] Response:\n") if options.info: # Decode the first packet as a list of info client raw_response.decode_payload_as(SAPRouterInfoClients) clients = [] clients.append("\t".join( ["ID", "Client", "Partner", "Service", "Connected on"])) clients.append("-" * 60) for client in raw_response.clients: # If the trace flag is set, add a mark flag = "(*)" if client.flag_traced else "(+)" if client.flag_routed else "" fields = [ str(client.id), client.address, "%s%s" % (flag, client.partner) if client.flag_routed else "(no partner)", client.service if client.flag_routed else "", datetime.fromtimestamp(client.connected_on).ctime() ] clients.append("\t".join(fields)) # Decode the second packet as server info raw_response = conn.recv() raw_response.decode_payload_as(SAPRouterInfoServer) print( "SAP Network Interface Router running on port %d (PID = %d)\n" "Started on: %s\n" "Parent process: PID = %d, port = %d\n" % (raw_response.port, raw_response.pid, datetime.fromtimestamp(raw_response.started_on).ctime(), raw_response.ppid, raw_response.pport)) print("\n".join(clients)) print("(*) Connections being traced") # Show the plain packets returned try: raw_response = conn.recv() while raw_response: print(raw_response.payload) raw_response = conn.recv() except error: pass
# The fields used to identify a version being fingerprinted version_info_fields = ["version", "release", "patch_number", "source_id", "update_level", "file_version", "platform", "submitted_by", "comment"] # This is the list of target packets that we use during the fingerprinting. Basically it consist of a dict with the # key being the name of the target packet and the value the construction of it. fingerprint_targets = { # Connect to the SAP Route but not send any packet to trigger a timeout "Timeout": None, # Send a large packet "Network packet too big": Raw("X" * 10025), # Use an invalid opcode "Invalid control opcode": SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=38, opcode=3), # Do not send a route "No route": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE), # Set one entry but do no provide a route "No route one entry": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=1), # Set one entry with an invalid length but do no provide it "No route invalid length": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=2, route_rest_nodes=1, route_length=1, route_offset=3), # Set one entry with an invalid route "Empty route invalid length": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=2, route_rest_nodes=1,
"version", "release", "patch_number", "source_id", "update_level", "file_version", "platform", "submitted_by", "comment" ] # This is the list of target packets that we use during the fingerprinting. Basically it consist of a dict with the # key being the name of the target packet and the value the construction of it. fingerprint_targets = { # Connect to the SAP Route but not send any packet to trigger a timeout "Timeout": None, # Send a large packet "Network packet too big": Raw("X" * 10025), # Use an invalid opcode "Invalid control opcode": SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=38, opcode=3), # Do not send a route "No route": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE), # Set one entry but do no provide a route "No route one entry": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=1), # Set one entry with an invalid length but do no provide it "No route invalid length": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=2, route_rest_nodes=1, route_length=1, route_offset=3), # Set one entry with an invalid route "Empty route invalid length":
def route_request(self, pkt): """Perform a lookup on the route table and routes the packet accordingly if allowed. """ route_string = pkt.route_string[pkt.route_rest_nodes] (action, talk_mode, password) = self.server.route_table.lookup_target(route_string.hostname, int(route_string.port)) if action == RouteTable.ROUTE_DENY: self.logger.debug("Route to %s:%s denied" % (route_string.hostname, route_string.port)) self.return_error(return_code=-94, error="%s: route permission denied (%s to %s, %s)" % (self.hostname, self.server.listener_address, route_string.hostname, route_string.port)) return elif talk_mode != RouteTable.MODE_ANY and talk_mode != pkt.route_talk_mode: self.logger.debug("Talk mode (%d) to %s:%s denied" % (pkt.route_talk_mode, route_string.hostname, route_string.port)) self.return_error(return_code=2) # TODO: Return the proper error return elif action == RouteTable.ROUTE_ALLOW: if password: if password == route_string.password: self.logger.debug("Valid password for route to %s:%s" % (route_string.hostname, route_string.port)) self.session.add_event("Route request allowed, valid password", data={"target_host": route_string.hostname, "target_port": route_string.port, "password": route_string.password}, request=str(pkt)) else: self.logger.debug("Invalid password for route to %s:%s" % (route_string.hostname, route_string.port)) self.session.add_event("Route request allowed, invalid password", data={"target_host": route_string.hostname, "target_port": route_string.port, "password": route_string.password}, request=str(pkt)) self.return_error(return_code=3) # TODO: Return the proper error return else: self.logger.debug("Route request allowed to %s:%s" % (route_string.hostname, route_string.port)) self.session.add_event("Route request allowed", data={"target": route_string.hostname, "port": route_string.port, "password": route_string.password}, request=str(pkt)) # The route is accepted, now look the service for the target address/port # and register it as routed service = self.server.service_manager.find_service_by_address(route_string.hostname, int(route_string.port)) # If the service wasn't found, we should return a timeout message, # meaning that the SAP Router tried to connect to the target service # but it didn't responded if service is None: self.logger.debug("Target service %s:%s not available" % (route_string.hostname, route_string.port)) self.session.add_event("Target service not available", data={"target": route_string.hostname, "port": route_string.port, "password": route_string.password}, request=str(pkt)) else: self.logger.debug("Target service %s:%s found, registering and routing" % (route_string.hostname, route_string.port)) # First cancel the timeout as a valid route was specified self._timeout.cancel() # Register the current client as routed and set the target # address, port and service self.server.clients[self.client_address].routed = True self.server.clients[self.client_address].connected = True self.server.clients[self.client_address].target_service = service self.server.clients[self.client_address].talk_mode = pkt.route_talk_mode self.server.clients[self.client_address].partner = route_string.hostname self.server.clients[self.client_address].service = int(route_string.port) # Send a PONG message to notify the client the route was accepted self.request.send(SAPRouter(type=SAPRouter.SAPROUTER_PONG))
def main(): options = parse_options() if options.verbose: logging.basicConfig(level=logging.DEBUG) response = False p = SAPRouter(type=SAPRouter.SAPROUTER_ADMIN) if options.stop: p.adm_command = 5 print("[*] Requesting stop of the remote SAP Router") elif options.soft: p.adm_command = 9 print("[*] Requesting a soft shutdown of the remote SAP Router") response = True elif options.info: p.adm_command = 2 if options.info_password: if len(options.info_password) > 19: print("[*] Password too long, truncated at 19 characters") p.adm_password = options.info_password print("[*] Requesting info using password %s" % p.adm_password) else: print("[*] Requesting info") response = True elif options.new_route: p.adm_command = 3 print("[*] Requesting a refresh of the router table") elif options.trace: p.adm_command = 4 print("[*] Requesting a toggle on the trace settings") elif options.cancel: p.adm_command = 6 p.adm_client_ids = list(map(int, options.cancel.split(","))) print("[*] Requesting a cancel of the route(s) with client id(s) %s" % p.adm_client_ids) response = True elif options.dump: p.adm_command = 7 print("[*] Requesting a dump of the buffers") elif options.flush: p.adm_command = 8 print("[*] Requesting a flush of the buffers") elif options.hide: p.adm_command = 14 print("[*] Requesting a hide on the errors to clients") response = True elif options.set_peer: p.adm_command = 10 p.adm_address_mask = options.set_peer print("[*] Request a set peer trace for the address mask %s" % p.adm_address_mask) response = True elif options.clear_peer: p.adm_command = 11 p.adm_address_mask = options.clear_peer print("[*] Request a clear peer trace for the address mask %s" % p.adm_address_mask) response = True elif options.trace_conn: p.adm_command = 12 p.adm_client_ids = list(map(int, options.trace_conn.split(","))) print("[*] Requesting a connection trace with client id(s) %s" % p.adm_client_ids) response = True else: print("[*] No command specified !") return # Initiate the connection conn = SAPNIStreamSocket.get_nisocket(options.remote_host, options.remote_port) print("[*] Connected to the SAP Router %s:%d" % (options.remote_host, options.remote_port)) # Retrieve the router version used by the server if not specified if options.router_version: p.version = options.router_version else: p.version = get_router_version(conn) or p.version print("[*] Using SAP Router version %d" % p.version) # Send the router admin request print("[*] Sending Router Admin packet") if options.verbose: p.show2() conn.send(p) # Grab the response if required if response: # Some responses has no SAPRouter's packet format and are raw strings, # we need to get the SAP NI layer first and then check if we could go # down to the SAPRouter layer. raw_response = conn.recv()[SAPNI] if SAPRouter in raw_response: router_response = raw_response[SAPRouter] # If the response was null, just return elif raw_response.length == 0: return # If the response is an error, print and exit if router_is_error(router_response): print("[*] Error requesting info:") if options.verbose: router_response.show2() else: print(router_response.err_text_value.error) # Otherwise, print the packets sent by the SAP Router else: print("[*] Response:\n") if options.info: # Decode the first packet as a list of info client raw_response.decode_payload_as(SAPRouterInfoClients) clients = [] clients.append("\t".join(["ID", "Client", "Partner", "Service", "Connected on"])) clients.append("-" * 60) for client in raw_response.clients: # If the trace flag is set, add a mark flag = "(*)" if client.flag_traced else "(+)" if client.flag_routed else "" fields = [str(client.id), client.address, "%s%s" % (flag, client.partner) if client.flag_routed else "(no partner)", client.service if client.flag_routed else "", datetime.fromtimestamp(client.connected_on).ctime()] clients.append("\t".join(fields)) # Decode the second packet as server info raw_response = conn.recv() raw_response.decode_payload_as(SAPRouterInfoServer) print("SAP Network Interface Router running on port %d (PID = %d)\n" "Started on: %s\n" "Parent process: PID = %d, port = %d\n" % (raw_response.port, raw_response.pid, datetime.fromtimestamp(raw_response.started_on).ctime(), raw_response.ppid, raw_response.pport)) print("\n".join(clients)) print("(*) Connections being traced") # Show the plain packets returned try: raw_response = conn.recv() while raw_response: print(raw_response.payload) raw_response = conn.recv() except error: pass