cssp protocol proxy

This commit is contained in:
citronneur
2015-03-05 22:28:33 +01:00
parent 8fb4893b6f
commit 0695825d98
7 changed files with 107 additions and 55 deletions

View File

@@ -183,7 +183,6 @@ class RawLayer(protocol.Protocol, LayerAutomata, IStreamSender):
#len of next packet pass to next state function
self._expectedLen = 0
self._factory = None
self._immediateCallback = None
def setFactory(self, factory):
"""
@@ -242,28 +241,6 @@ class RawLayer(protocol.Protocol, LayerAutomata, IStreamSender):
self._expectedLen = expectedLen
#default callback is recv from LayerAutomata
self.setNextState(callback)
def dataReceivedAll(self, data):
"""
@summary: by pass automata received
@warning: ignore rest in buffer
@param data: {str} received from twisted
"""
self._immediateCallback(Stream(data))
def expectImmediately(self, callback):
"""
@summary: call immediately when available data is received
@param callback: {func} callback called
"""
self.dataReceived = lambda data:self.__class__.dataReceivedAll(self, data)
self._immediateCallback = callback
def restartAutomata(self):
"""
@summary: restart automata
"""
self.dataReceived = lambda data:self.__class__.dataReceived(self, data)
def send(self, message):
"""

View File

@@ -303,9 +303,12 @@ class LicenseManager(object):
"""
#get server information
serverRandom = licenseRequest.serverRandom.value
s = Stream(licenseRequest.serverCertificate.blobData.value)
serverCertificate = gcc.ServerCertificate()
s.readType(serverCertificate)
if self._transport.getGCCServerSettings().SC_SECURITY.serverCertificate._is_readed:
serverCertificate = self._transport.getGCCServerSettings().SC_SECURITY.serverCertificate
else:
s = Stream(licenseRequest.serverCertificate.blobData.value)
serverCertificate = gcc.ServerCertificate()
s.readType(serverCertificate)
#generate crypto values
clientRandom = rsa.random(256)

View File

@@ -24,7 +24,10 @@
from pyasn1.type import namedtype, univ, tag
from pyasn1.codec.der import encoder, decoder
from rdpy.core.type import Stream, String
from rdpy.core.type import Stream
from rdpy.security import x509
from twisted.internet import protocol
from OpenSSL import crypto
class NegoToken(univ.Sequence):
componentType = namedtype.NamedTypes(
@@ -101,7 +104,7 @@ def encodeDERTRequest(negoTypes = [], pubKeyAuth = None):
"""
@summary: create TSRequest from list of Type
@param negoTypes: {list(Type)}
@return: {String}
@return: {str}
"""
negoData = NegoData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))
@@ -121,18 +124,94 @@ def encodeDERTRequest(negoTypes = [], pubKeyAuth = None):
if not pubKeyAuth is None:
request.setComponentByName("pubKeyAuth", univ.OctetString(pubKeyAuth).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)))
return String(encoder.encode(request))
return encoder.encode(request)
def decodeDERTRequest(s):
"""
@summary: Decode the stream as
@param s: ([{Stream}], {str} pubKeyAuth)
@param s: {str}
"""
return decoder.decode(s.getvalue(), asn1Spec=TSRequest())[0]
return decoder.decode(s, asn1Spec=TSRequest())[0]
def getNegoTokens(tRequest):
negoData = tRequest.getComponentByName("negoTokens")
return [Stream(negoData.getComponentByPosition(i).getComponentByPosition(0).asOctets()) for i in range(len(negoData))]
def getPubKeyAuth(tRequest):
return tRequest.getComponentByName("pubKeyAuth").asOctets()
return tRequest.getComponentByName("pubKeyAuth").asOctets()
class CSSP(protocol.Protocol):
"""
@summary: Handle CSSP connection
Proxy class for authentication
"""
def __init__(self, layer, authenticationProtocol):
"""
@param layer: {type.Layer.RawLayer}
@param authenticationProtocol: {sspi.IAuthenticationProtocol}
"""
self._layer = layer
self._authenticationProtocol = authenticationProtocol
def setFactory(self, factory):
"""
@summary: Call by RawLayer Factory
@param param: RawLayerClientFactory or RawLayerFactory
"""
self._layer.setFactory(factory)
def dataReceived(self, data):
"""
@summary: Inherit from twisted.protocol class
main event of received data
@param data: string data receive from twisted
"""
self._layer.dataReceived(data)
def connectionMade(self):
"""
@summary: install proxy
"""
self._layer.transport = self
self._layer.connectionMade()
def write(self, data):
"""
@summary: write data on transport layer
@param data: {str}
"""
self.transport.write(data)
def startTLS(self, sslContext):
"""
@summary: start TLS protocol
@param sslContext: {ssl.ClientContextFactory | ssl.DefaultOpenSSLContextFactory} context use for TLS protocol
"""
self.transport.startTLS(sslContext)
def startNLA(self):
"""
@summary: start NLA authentication
"""
#send negotiate message
self.transport.write(encodeDERTRequest( negoTypes = [ self._authenticationProtocol.getNegotiateMessage() ] ))
#next state is receive a challenge
self.dataReceived = self.recvChallenge
def recvChallenge(self, data):
"""
@summary: second state in cssp automata
@param {str}: all data available on buffer
"""
#get back public key
toto = self.transport.protocol._tlsConnection.get_peer_certificate().get_pubkey()
lolo = crypto.dump_privatekey(crypto.FILETYPE_ASN1, toto)
modulus, exponent = x509.extractRSAKey2(lolo)
import hexdump
print lolo
hexdump.hexdump(lolo)
request = decodeDERTRequest(data)
message, interface = self._authenticationProtocol.getAuthenticateMessage(getNegoTokens(request)[0])
#send authenticate message with public key encoded
import ntlm
self.transport.write(encodeDERTRequest( negoTypes = [ message ], pubKeyAuth = interface.GSS_WrapEx("".join([chr(i) for i in ntlm.pubKeyHex]))))

View File

@@ -683,9 +683,9 @@ if __name__ == "__main__":
ClientChallenge = temp[16:24]
EncryptedRandomSessionKey = authenticate.getEncryptedRandomSession()
domain = "dodo"
user = "uouo"
password = "popo"
domain = "siradel"
user = "speyrefitte"
password = "spe+99@12"
ResponseKeyNT = NTOWFv2(password, user, domain)
ResponseKeyLM = LMOWFv2(password, user, domain)

View File

@@ -29,6 +29,7 @@ import pdu.caps
import rdpy.core.log as log
import tpkt, x224, sec
from t125 import mcs, gcc
from nla import cssp, ntlm
class RDPClientController(pdu.layer.PDUClientListener):
"""
@@ -526,7 +527,8 @@ class ClientFactory(layer.RawLayerClientFactory):
"""
controller = RDPClientController()
self.buildObserver(controller, addr)
return controller.getProtocol()
#Add cssp proxy in case of nla protocol
return cssp.CSSP(controller.getProtocol(), ntlm.NTLMv2("toto", "coco", "lolo"))
def buildObserver(self, controller, addr):
"""

View File

@@ -114,7 +114,6 @@ class TPKT(RawLayer, IFastPathSender):
self._fastPathListener = None
#last secure flag
self._secFlag = 0
self._ntlm = ntlm.NTLMv2("dodo", "uouo", "popo")
def setFastPathListener(self, fastPathListener):
"""
@@ -224,18 +223,4 @@ class TPKT(RawLayer, IFastPathSender):
@summary: use to start NLA (NTLM over SSL) protocol
must be called after startTLS function
"""
#import hexdump
#hexdump.hexdump(self.transport.protocol._tlsConnection.getpeercert())
#send NTLM negotiate message packet
RawLayer.send(self, cssp.encodeDERTRequest( negoTypes = [ self._ntlm.getNegotiateMessage() ] ))
self.expectImmediately(self.readNTLMChallenge)
def readNTLMChallenge(self, data):
"""
@summary: server NTLM challenge
@param data: {Stream}
"""
request = cssp.decodeDERTRequest(data)
message, interface = self._ntlm.getAuthenticateMessage(cssp.getNegoTokens(request)[0])
RawLayer.send(self, cssp.encodeDERTRequest( negoTypes = [ message ], pubKeyAuth = interface.GSS_WrapEx("".join([chr(i) for i in ntlm.pubKeyHex]))))
self.restartAutomata()
self.transport.startNLA()

View File

@@ -150,8 +150,14 @@ def extractRSAKey(certificate):
binaryTuple = certificate.getComponentByName('tbsCertificate').getComponentByName('subjectPublicKeyInfo').getComponentByName('subjectPublicKey')
l = int("".join([str(i) for i in binaryTuple]), 2)
rsaKey = decoder.decode(hex(l)[2:-1].decode('hex'), asn1Spec=RSAPublicKey())[0]
return extractRSAKeyFromASN1(hex(l)[2:-1].decode('hex'))
def extractRSAKeyFromASN1(subjectPublicKey):
rsaKey = decoder.decode(subjectPublicKey, asn1Spec=RSAPublicKey())[0]
return rsaKey.getComponentByName('modulus')._value , rsaKey.getComponentByName('publicExponent')._value
def extractRSAKey2(key):
binaryTuple = decoder.decode(key, asn1Spec=univ.BitString())[0]
l = int("".join([str(i) for i in binaryTuple]), 2)
return extractRSAKeyFromASN1(hex(l)[2:-1].decode('hex'))