def test_saproutedstreamsocket(self): """Test SAPRoutedStreamSocket""" self.start_server(SAPRouterServerTestHandler) sock = socket.socket() sock.connect((self.test_address, self.test_port)) route = [ SAPRouterRouteHop(hostname=self.test_address, port=self.test_port), SAPRouterRouteHop(hostname="10.0.0.1", port="3200") ] self.client = SAPRoutedStreamSocket(sock, route=route, router_version=40) packet = self.client.sr(self.test_string) self.assertIn(SAPNI, packet) self.assertEqual(packet[SAPNI].length, len(self.test_string) + 4) self.assertEqual(unpack("!I", packet[SAPNI].payload.load[:4]), (len(self.test_string), )) self.assertEqual(packet[SAPNI].payload.load[4:], self.test_string) self.client.close() self.stop_server()
def route_test(rhost, rport, thost, tport, talk_mode, router_version): logging.info("[*] Routing connections to %s:%s" % (thost, tport)) # Build the route to the target host passing through the SAP Router route = [ SAPRouterRouteHop(hostname=rhost, port=rport), SAPRouterRouteHop(hostname=thost, port=tport) ] # Try to connect to the target host using the routed stream socket try: conn = SAPRoutedStreamSocket.get_nisocket( route=route, talk_mode=talk_mode, router_version=router_version) conn.close() status = 'open' # If an SAPRouteException is raised, the route was denied or an error # occurred with the SAP router except SAPRouteException: status = 'denied' # Another error occurred on the server (e.g. timeout), mark the target as error except Exception: status = 'error' return status
def check_route(self, route_string, route_hops): """Check from string to hops and back again""" hops = SAPRouterRouteHop.from_string(route_string) self.assertListEqual(hops, route_hops) string = SAPRouterRouteHop.from_hops(hops) self.assertEqual(string, route_string)
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 check_route(self, route_string, route_hops): """Check from string to hops and back again""" hops = SAPRouterRouteHop.from_string(route_string) self.assertListEqual(hops, route_hops) string = SAPRouterRouteHop.from_hops(hops) route_string = route_string.replace("/h/", "/H/").replace("/s/", "/S/").replace("/p/", "/P/").replace("/w/", "/W/") self.assertEqual(string, route_string)
def test_saproutedstreamsocket_getnisocket(self): """Test SAPRoutedStreamSocket get nisocket class method""" self.start_server(SAPRouterServerTestHandler) # Test using a complete route route = [ SAPRouterRouteHop(hostname=self.test_address, port=self.test_port), SAPRouterRouteHop(hostname="10.0.0.1", port="3200") ] self.client = SAPRoutedStreamSocket.get_nisocket(route=route, router_version=40) packet = self.client.sr(self.test_string) self.assertIn(SAPNI, packet) self.assertEqual(packet[SAPNI].length, len(self.test_string) + 4) self.assertEqual(unpack("!I", packet[SAPNI].payload.load[:4]), (len(self.test_string), )) self.assertEqual(packet[SAPNI].payload.load[4:], self.test_string) # Test using a route and a target host/port route = [ SAPRouterRouteHop(hostname=self.test_address, port=self.test_port) ] self.client = SAPRoutedStreamSocket.get_nisocket("10.0.0.1", "3200", route=route, router_version=40) packet = self.client.sr(self.test_string) self.assertIn(SAPNI, packet) self.assertEqual(packet[SAPNI].length, len(self.test_string) + 4) self.assertEqual(unpack("!I", packet[SAPNI].payload.load[:4]), (len(self.test_string), )) self.assertEqual(packet[SAPNI].payload.load[4:], self.test_string) # Test using a route string route = "/H/%s/S/%s/H/10.0.0.1/S/3200" % (self.test_address, self.test_port) self.client = SAPRoutedStreamSocket.get_nisocket(route=route, router_version=40) packet = self.client.sr(self.test_string) self.assertIn(SAPNI, packet) self.assertEqual(packet[SAPNI].length, len(self.test_string) + 4) self.assertEqual(unpack("!I", packet[SAPNI].payload.load[:4]), (len(self.test_string), )) self.assertEqual(packet[SAPNI].payload.load[4:], self.test_string) self.client.close() self.stop_server()
def test_saprouter_route_string(self): """Test construction of SAPRouterRouteHop items""" # Two hops with full details self.check_route("/H/host1/S/service1/W/pass1/H/host2/S/service2/W/pass2", [SAPRouterRouteHop(hostname="host1", port="service1", password="******"), SAPRouterRouteHop(hostname="host2", port="service2", password="******")]) # One intermediate hop with service/password self.check_route("/H/host1/H/host2/S/service2/W/pass2/H/host3", [SAPRouterRouteHop(hostname="host1"), SAPRouterRouteHop(hostname="host2", port="service2", password="******"), SAPRouterRouteHop(hostname="host3")]) # Example in SAP Help self.check_route("/H/sap_rout/H/your_rout/W/pass_to_app/H/yourapp/S/sapsrv", [SAPRouterRouteHop(hostname="sap_rout"), SAPRouterRouteHop(hostname="your_rout", password="******"), SAPRouterRouteHop(hostname="yourapp", port="sapsrv")]) # Hostname with FQDN self.check_route("/H/some.valid.domain.com/S/3299", [SAPRouterRouteHop(hostname="some.valid.domain.com", port="3299")]) # Hostname with IP addresses self.check_route("/H/127.0.0.1/S/3299", [SAPRouterRouteHop(hostname="127.0.0.1", port="3299")]) # Lowercase hostname and service self.check_route("/h/127.0.0.1/s/3299/w/Password", [SAPRouterRouteHop(hostname="127.0.0.1", port="3299", password="******")]) # Invalid route strings self.assertListEqual(SAPRouterRouteHop.from_string("/S/service"), []) self.assertListEqual(SAPRouterRouteHop.from_string("/P/password"), [])
def test_saproutedstreamsocket_route_error(self): """Test SAPRoutedStreamSocket throwing of SAPRouteException if a route denied return error is received""" self.start_server(SAPRouterServerTestHandler) sock = socket.socket() sock.connect((self.test_address, self.test_port)) route = [SAPRouterRouteHop(hostname=self.test_address, port=self.test_port), SAPRouterRouteHop(hostname="10.0.0.2", port="3200")] with self.assertRaises(SAPRouteException): self.client = SAPRoutedStreamSocket(sock, route=route, router_version=40) self.stop_server()
def test_saprouter_route_string(self): """Test construction of SAPRouterRouteHop items""" # Two hops with full details self.check_route("/H/host1/S/service1/W/pass1/H/host2/S/service2/W/pass2", [SAPRouterRouteHop(hostname="host1", port="service1", password="******"), SAPRouterRouteHop(hostname="host2", port="service2", password="******")]) # One intermediate hop with service/password self.check_route("/H/host1/H/host2/S/service2/W/pass2/H/host3", [SAPRouterRouteHop(hostname="host1"), SAPRouterRouteHop(hostname="host2", port="service2", password="******"), SAPRouterRouteHop(hostname="host3")]) # Example in SAP Help self.check_route("/H/sap_rout/H/your_rout/W/pass_to_app/H/yourapp/S/sapsrv", [SAPRouterRouteHop(hostname="sap_rout"), SAPRouterRouteHop(hostname="your_rout", password="******"), SAPRouterRouteHop(hostname="yourapp", port="sapsrv")]) # Hostname with FQDN self.check_route("/H/some.valid.domain.com/S/3299", [SAPRouterRouteHop(hostname="some.valid.domain.com", port="3299")]) # Hostname with IP addresses self.check_route("/H/127.0.0.1/S/3299", [SAPRouterRouteHop(hostname="127.0.0.1", port="3299")]) # Invalid route strings self.assertListEqual(SAPRouterRouteHop.from_string("/S/service"), []) self.assertListEqual(SAPRouterRouteHop.from_string("/P/password"), [])
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, route_length=1, route_offset=0, route_string=[SAPRouterRouteHop()]), # Set an empty route with valid length "Empty route valid length": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=2, route_rest_nodes=1, route_length=6, route_offset=3, route_string=[SAPRouterRouteHop(), SAPRouterRouteHop()]), # Set an empty route with a null offset "Empty route null offset": SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=2, route_rest_nodes=1, route_length=6,