diff --git a/examples/ntlmrelayx.py b/examples/ntlmrelayx.py index 66524aa528..be56ef6e24 100644 --- a/examples/ntlmrelayx.py +++ b/examples/ntlmrelayx.py @@ -290,7 +290,7 @@ def stop_servers(threads): # Interface address specification parser.add_argument('-ip','--interface-ip', action='store', metavar='INTERFACE_IP', help='IP address of interface to ' - 'bind SMB and HTTP servers',default='') + 'bind relay servers ("0.0.0.0" or "::" if omitted)',default=argparse.SUPPRESS) serversoptions = parser.add_argument_group() serversoptions.add_argument('--no-smb-server', action='store_true', help='Disables the SMB server') @@ -331,7 +331,7 @@ def stop_servers(threads): 'setting the proxy host to the one supplied.') parser.add_argument('-wa','--wpad-auth-num', action='store', type=int, default=1, help='Prompt for authentication N times for clients without MS16-077 installed ' 'before serving a WPAD file. (default=1)') - parser.add_argument('-6','--ipv6', action='store_true',help='Listen on both IPv6 and IPv4') + parser.add_argument('-6','--ipv6', action='store_true',help='Listen on IPv6') parser.add_argument('--remove-mic', action='store_true',help='Remove MIC (exploit CVE-2019-1040)') parser.add_argument('--serve-image', action='store',help='local path of the image that will we returned to clients') parser.add_argument('-c', action='store', type=str, required=False, metavar = 'COMMAND', help='Command to execute on ' @@ -529,6 +529,9 @@ def stop_servers(threads): socks_thread.start() threads.add(socks_thread) + if 'interface_ip' not in options: + options.interface_ip = '::' if options.ipv6 else '0.0.0.0' + c = start_servers(options, threads) # Log multirelay flag status diff --git a/examples/smbserver.py b/examples/smbserver.py index d3a4278ae1..4b62a97e32 100755 --- a/examples/smbserver.py +++ b/examples/smbserver.py @@ -42,9 +42,10 @@ parser.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes for the Username, format is LMHASH:NTHASH') parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') - parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface') + parser.add_argument('-ip', '--interface-address', action='store', default=argparse.SUPPRESS, help='ip address of listening interface ("0.0.0.0" or "::" if omitted)') parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)') parser.add_argument('-dropssp', action='store_true', default=False, help='Disable NTLM ESS/SSP during negotiation') + parser.add_argument('-6','--ipv6', action='store_true',help='Listen on IPv6') parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)') parser.add_argument('-outputfile', action='store', default=None, help='Output file to log smbserver output messages') @@ -65,7 +66,10 @@ else: comment = options.comment - server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port)) + if 'interface_address' not in options: + options.interface_address = '::' if options.ipv6 else '0.0.0.0' + + server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port), ipv6=options.ipv6) if options.outputfile: logging.info('Switching output to file %s' % options.outputfile) diff --git a/impacket/examples/ntlmrelayx/servers/httprelayserver.py b/impacket/examples/ntlmrelayx/servers/httprelayserver.py index 018d935ff6..376856f651 100644 --- a/impacket/examples/ntlmrelayx/servers/httprelayserver.py +++ b/impacket/examples/ntlmrelayx/servers/httprelayserver.py @@ -33,6 +33,7 @@ from impacket.nt_errors import STATUS_ACCESS_DENIED, STATUS_SUCCESS from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor from impacket.examples.ntlmrelayx.servers.socksserver import activeConnections +from impacket.examples.utils import get_address class HTTPRelayServer(Thread): @@ -40,11 +41,10 @@ class HTTPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def __init__(self, server_address, RequestHandlerClass, config): self.config = config self.daemon_threads = True - if self.config.ipv6: - self.address_family = socket.AF_INET6 + self.address_family, server_address = get_address(server_address[0], server_address[1], self.config.ipv6) # Tracks the number of times authentication was prompted for WPAD per client self.wpad_counters = {} - socketserver.TCPServer.__init__(self,server_address, RequestHandlerClass) + socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass) class HTTPHandler(http.server.SimpleHTTPRequestHandler): def __init__(self,request, client_address, server): diff --git a/impacket/examples/ntlmrelayx/servers/rawrelayserver.py b/impacket/examples/ntlmrelayx/servers/rawrelayserver.py index c92f5958be..9e5a6c3adb 100644 --- a/impacket/examples/ntlmrelayx/servers/rawrelayserver.py +++ b/impacket/examples/ntlmrelayx/servers/rawrelayserver.py @@ -34,6 +34,7 @@ from impacket.nt_errors import STATUS_ACCESS_DENIED, STATUS_SUCCESS from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor from impacket.examples.ntlmrelayx.servers.socksserver import activeConnections +from impacket.examples.utils import get_address class RAWRelayServer(Thread): @@ -43,9 +44,7 @@ class RAWServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def __init__(self, server_address, RequestHandlerClass, config): self.config = config self.daemon_threads = True - #if self.config.ipv6: - # self.address_family = socket.AF_INET6 - + self.address_family, server_address = get_address(server_address[0], server_address[1], self.config.ipv6) socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass) class RAWHandler(socketserver.BaseRequestHandler): diff --git a/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py b/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py index 4a2f554d31..ffe63adcaa 100644 --- a/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py +++ b/impacket/examples/ntlmrelayx/servers/rpcrelayserver.py @@ -28,6 +28,7 @@ from impacket.nt_errors import ERROR_MESSAGES, STATUS_SUCCESS from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor from impacket.examples.ntlmrelayx.servers.socksserver import activeConnections +from impacket.examples.utils import get_address class RPCRelayServer(Thread): @@ -35,8 +36,7 @@ class RPCSocketServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def __init__(self, server_address, RequestHandlerClass, config): self.config = config self.daemon_threads = True - if self.config.ipv6: - self.address_family = socket.AF_INET6 + self.address_family, server_address = get_address(server_address[0], server_address[1], self.config.ipv6) socketserver.TCPServer.allow_reuse_address = True socketserver.TCPServer.__init__(self, server_address, RequestHandlerClass) diff --git a/impacket/examples/ntlmrelayx/servers/smbrelayserver.py b/impacket/examples/ntlmrelayx/servers/smbrelayserver.py index af0f631d51..54cae303ec 100644 --- a/impacket/examples/ntlmrelayx/servers/smbrelayserver.py +++ b/impacket/examples/ntlmrelayx/servers/smbrelayserver.py @@ -106,17 +106,13 @@ def __init__(self,config): smbConfig.set('IPC$','share type','3') smbConfig.set('IPC$','path','') - # Change address_family to IPv6 if this is configured - if self.config.ipv6: - SMBSERVER.address_family = socket.AF_INET6 - # changed to dereference configuration interfaceIp if self.config.listeningPort: smbport = self.config.listeningPort else: smbport = 445 - self.server = SMBSERVER((config.interfaceIp,smbport), config_parser = smbConfig) + self.server = SMBSERVER((config.interfaceIp,smbport), config_parser=smbConfig, ipv6=self.config.ipv6) if not self.config.disableMulti: self.server.setAuthCallback(auth_callback) logging.getLogger('impacket.smbserver').setLevel(logging.CRITICAL) diff --git a/impacket/examples/ntlmrelayx/servers/wcfrelayserver.py b/impacket/examples/ntlmrelayx/servers/wcfrelayserver.py index 383566da8b..db33e54257 100644 --- a/impacket/examples/ntlmrelayx/servers/wcfrelayserver.py +++ b/impacket/examples/ntlmrelayx/servers/wcfrelayserver.py @@ -43,6 +43,7 @@ from impacket.smbserver import outputToJohnFormat, writeJohnOutputToFile from impacket.spnego import SPNEGO_NegTokenInit, ASN1_AID, SPNEGO_NegTokenResp, TypesMech, MechTypes, \ ASN1_SUPPORTED_MECH +from impacket.examples.utils import get_address class WCFRelayServer(Thread): @@ -50,8 +51,7 @@ class WCFServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def __init__(self, server_address, request_handler_class, config): self.config = config self.daemon_threads = True - if self.config.ipv6: - self.address_family = socket.AF_INET6 + self.address_family, server_address = get_address(server_address[0], server_address[1], self.config.ipv6) self.wpad_counters = {} socketserver.TCPServer.__init__(self, server_address, request_handler_class) diff --git a/impacket/examples/utils.py b/impacket/examples/utils.py index e6d47620d9..ac997b495d 100644 --- a/impacket/examples/utils.py +++ b/impacket/examples/utils.py @@ -322,7 +322,9 @@ def parse_identity(credentials, hashes=None, no_pass=False, aesKey=None, k=False def get_address(ip, port, ipv6=False): address = (ip, port) + address_family = socket.AF_INET if ipv6: + address_family = socket.AF_INET6 # scope_id (after %) can be present or not - if not, default: 0 ip_parts = ip.split('%') scope_id = ip_parts[1] if len(ip_parts) == 2 else 0 @@ -333,11 +335,11 @@ def get_address(ip, port, ipv6=False): except ValueError: scope_id = socket.if_nametoindex(scope_id) address = address + (0, scope_id) - return address + return address_family, address import socket def get_connected_socket(ip, port, ipv6=False): s = socket.socket(socket.AF_INET6 if ipv6 else socket.AF_INET) - address = get_address(ip, port, ipv6) + _, address = get_address(ip, port, ipv6) s.connect(address) return s \ No newline at end of file diff --git a/impacket/smbserver.py b/impacket/smbserver.py index fffff70abf..d9bfeb9982 100644 --- a/impacket/smbserver.py +++ b/impacket/smbserver.py @@ -3989,7 +3989,22 @@ def finish(self): class SMBSERVER(socketserver.ThreadingMixIn, socketserver.TCPServer): # class SMBSERVER(socketserver.ForkingMixIn, socketserver.TCPServer): - def __init__(self, server_address, handler_class=SMBSERVERHandler, config_parser=None): + def __init__(self, server_address, handler_class=SMBSERVERHandler, config_parser=None, ipv6=False): + # duplicate of https://github.com/fortra/impacket/blob/082dca34a376d13c70b0df6a1d9048ce98fe9498/impacket/examples/utils.py#L323 + # didn't reuse that same function in order not to make a class from the library depend on one from impacket/examples + if ipv6: + self.address_family = socket.AF_INET6 + # scope_id (after %) can be present or not - if not, default: 0 + ip_parts = server_address[0].split('%') + scope_id = ip_parts[1] if len(ip_parts) == 2 else 0 + # convert scope_id to int (expected by s.connect) + # if exception, assume the interface name and convert to index + try: + scope_id = int(scope_id) + except ValueError: + scope_id = socket.if_nametoindex(scope_id) + server_address = server_address + (0, scope_id) + socketserver.TCPServer.allow_reuse_address = True socketserver.TCPServer.__init__(self, server_address, handler_class) @@ -4880,10 +4895,9 @@ class SimpleSMBServer: :param string configFile: a file with all the servers' configuration. If no file specified, this class will create the basic parameters needed to run. You will need to add your shares manually tho. See addShare() method """ - def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile='', smbserverclass=SMBSERVER): + def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile='', smbserverclass=SMBSERVER, ipv6=False): if configFile != '': - #self.__server = SMBSERVER((listenAddress, listenPort)) - self.__server = smbserverclass((listenAddress, listenPort)) + self.__server = smbserverclass((listenAddress, listenPort), ipv6=ipv6) self.__server.processConfigFile(configFile) self.__smbConfig = None else: @@ -4908,7 +4922,7 @@ def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile='', smbse self.__smbConfig.set('IPC$', 'read only', 'yes') self.__smbConfig.set('IPC$', 'share type', '3') self.__smbConfig.set('IPC$', 'path', '') - self.__server = smbserverclass((listenAddress, listenPort), config_parser=self.__smbConfig) + self.__server = smbserverclass((listenAddress, listenPort), config_parser=self.__smbConfig, ipv6=ipv6) self.__server.processConfigFile() # Now we have to register the MS-SRVS server. This specially important for