github.com/Coalfire-Research/Slackor@v0.0.0-20191010164036-aa32a7f9250b/impacket/examples/rdp_check.py (about)

     1  #!/usr/bin/env python
     2  # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
     3  #
     4  # This software is provided under under a slightly modified version
     5  # of the Apache Software License. See the accompanying LICENSE file
     6  # for more information.
     7  #
     8  # Author:
     9  #  Alberto Solino (@agsolino)
    10  #
    11  # Description: [MS-RDPBCGR] and [MS-CREDSSP] partial implementation 
    12  #              just to reach CredSSP auth. This example test whether
    13  #              an account is valid on the target host.
    14  #
    15  # ToDo:
    16  #    [x] Manage to grab the server's SSL key so we can finalize the whole
    17  #        authentication process (check [MS-CSSP] section 3.1.5)
    18  #
    19  
    20  from struct import pack, unpack
    21  
    22  from impacket.examples import logger
    23  from impacket.structure import Structure
    24  from impacket.spnego import GSSAPI, ASN1_SEQUENCE, ASN1_OCTET_STRING, asn1decode, asn1encode
    25  
    26  TDPU_CONNECTION_REQUEST  = 0xe0
    27  TPDU_CONNECTION_CONFIRM  = 0xd0
    28  TDPU_DATA                = 0xf0
    29  TPDU_REJECT              = 0x50
    30  TPDU_DATA_ACK            = 0x60
    31  
    32  # RDP_NEG_REQ constants
    33  TYPE_RDP_NEG_REQ = 1
    34  PROTOCOL_RDP     = 0
    35  PROTOCOL_SSL     = 1
    36  PROTOCOL_HYBRID  = 2
    37  
    38  # RDP_NEG_RSP constants
    39  TYPE_RDP_NEG_RSP = 2
    40  EXTENDED_CLIENT_DATA_SUPPORTED = 1
    41  DYNVC_GFX_PROTOCOL_SUPPORTED   = 2
    42  
    43  # RDP_NEG_FAILURE constants
    44  TYPE_RDP_NEG_FAILURE                  = 3
    45  SSL_REQUIRED_BY_SERVER                = 1
    46  SSL_NOT_ALLOWED_BY_SERVER             = 2
    47  SSL_CERT_NOT_ON_SERVER                = 3
    48  INCONSISTENT_FLAGS                    = 4
    49  HYBRID_REQUIRED_BY_SERVER             = 5
    50  SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 6
    51  
    52  class TPKT(Structure):
    53      commonHdr = (
    54          ('Version','B=3'),
    55          ('Reserved','B=0'),
    56          ('Length','>H=len(TPDU)+4'),
    57          ('_TPDU','_-TPDU','self["Length"]-4'),
    58          ('TPDU',':=""'),
    59      )
    60  
    61  class TPDU(Structure):
    62      commonHdr = (
    63          ('LengthIndicator','B=len(VariablePart)+1'),
    64          ('Code','B=0'),
    65          ('VariablePart',':=""'),
    66      )
    67  
    68      def __init__(self, data = None):
    69          Structure.__init__(self,data)
    70          self['VariablePart']=''
    71  
    72  class CR_TPDU(Structure):
    73      commonHdr = (
    74          ('DST-REF','<H=0'),
    75          ('SRC-REF','<H=0'),
    76          ('CLASS-OPTION','B=0'),
    77          ('Type','B=0'),
    78          ('Flags','B=0'),
    79          ('Length','<H=8'),
    80      )
    81  
    82  class DATA_TPDU(Structure):
    83      commonHdr = (
    84          ('EOT','B=0x80'),
    85          ('UserData',':=""'),
    86      )
    87  
    88      def __init__(self, data = None):
    89          Structure.__init__(self,data)
    90          self['UserData'] =''
    91  
    92  
    93  class RDP_NEG_REQ(CR_TPDU):
    94      structure = (
    95          ('requestedProtocols','<L'),
    96      )
    97      def __init__(self,data=None):
    98          CR_TPDU.__init__(self,data)
    99          if data is None:
   100              self['Type'] = TYPE_RDP_NEG_REQ
   101  
   102  class RDP_NEG_RSP(CR_TPDU):
   103      structure = (
   104          ('selectedProtocols','<L'),
   105      )
   106  
   107  class RDP_NEG_FAILURE(CR_TPDU):
   108      structure = (
   109          ('failureCode','<L'),
   110      )
   111  
   112  class TSPasswordCreds(GSSAPI):
   113  # TSPasswordCreds ::= SEQUENCE {
   114  #         domainName  [0] OCTET STRING,
   115  #         userName    [1] OCTET STRING,
   116  #         password    [2] OCTET STRING
   117  # }
   118     def __init__(self, data=None):
   119         GSSAPI.__init__(self,data)
   120         del self['UUID']
   121    
   122     def getData(self):
   123         ans = pack('B', ASN1_SEQUENCE)
   124         ans += asn1encode( pack('B', 0xa0) +
   125                asn1encode( pack('B', ASN1_OCTET_STRING) + 
   126                asn1encode( self['domainName'].encode('utf-16le'))) +
   127                pack('B', 0xa1) + 
   128                asn1encode( pack('B', ASN1_OCTET_STRING) + 
   129                asn1encode( self['userName'].encode('utf-16le'))) +
   130                pack('B', 0xa2) + 
   131                asn1encode( pack('B', ASN1_OCTET_STRING) + 
   132                asn1encode( self['password'].encode('utf-16le'))) )
   133         return ans 
   134  
   135  class TSCredentials(GSSAPI):
   136  # TSCredentials ::= SEQUENCE {
   137  #        credType    [0] INTEGER,
   138  #        credentials [1] OCTET STRING
   139  # }
   140     def __init__(self, data=None):
   141         GSSAPI.__init__(self,data)
   142         del self['UUID']
   143  
   144     def getData(self):
   145       # Let's pack the credentials field
   146       credentials =  pack('B',0xa1) 
   147       credentials += asn1encode(pack('B',ASN1_OCTET_STRING) +
   148                      asn1encode(self['credentials']))
   149  
   150       ans = pack('B',ASN1_SEQUENCE) 
   151       ans += asn1encode( pack('B', 0xa0) +
   152              asn1encode( pack('B', 0x02) + 
   153              asn1encode( pack('B', self['credType']))) +
   154              credentials)
   155       return ans
   156  
   157  class TSRequest(GSSAPI):
   158  # TSRequest ::= SEQUENCE {
   159  #	version     [0] INTEGER,
   160  #       negoTokens  [1] NegoData OPTIONAL,
   161  #       authInfo    [2] OCTET STRING OPTIONAL,
   162  #	pubKeyAuth  [3] OCTET STRING OPTIONAL,
   163  #}
   164  #
   165  # NegoData ::= SEQUENCE OF SEQUENCE {
   166  #        negoToken [0] OCTET STRING
   167  #}
   168  #
   169  
   170     def __init__(self, data=None):
   171         GSSAPI.__init__(self,data)
   172         del self['UUID']
   173         
   174     def fromString(self, data = None):
   175         next_byte = unpack('B',data[:1])[0]
   176         if next_byte != ASN1_SEQUENCE:
   177             raise Exception('SEQUENCE expected! (%x)' % next_byte)
   178         data = data[1:]
   179         decode_data, total_bytes = asn1decode(data) 
   180  
   181         next_byte = unpack('B',decode_data[:1])[0]
   182         if next_byte !=  0xa0:
   183              raise Exception('0xa0 tag not found %x' % next_byte)
   184         decode_data = decode_data[1:]
   185         next_bytes, total_bytes = asn1decode(decode_data)                
   186         # The INTEGER tag must be here
   187         if unpack('B',next_bytes[0:1])[0] != 0x02:
   188             raise Exception('INTEGER tag not found %r' % next_byte)
   189         next_byte, _ = asn1decode(next_bytes[1:])
   190         self['Version'] = unpack('B',next_byte)[0]
   191         decode_data = decode_data[total_bytes:]
   192         next_byte = unpack('B',decode_data[:1])[0]
   193         if next_byte == 0xa1:
   194             # We found the negoData token
   195             decode_data, total_bytes = asn1decode(decode_data[1:])
   196         
   197             next_byte = unpack('B',decode_data[:1])[0]
   198             if next_byte != ASN1_SEQUENCE:
   199                 raise Exception('ASN1_SEQUENCE tag not found %r' % next_byte)
   200             decode_data, total_bytes = asn1decode(decode_data[1:])
   201  
   202             next_byte = unpack('B',decode_data[:1])[0]
   203             if next_byte != ASN1_SEQUENCE:
   204                 raise Exception('ASN1_SEQUENCE tag not found %r' % next_byte)
   205             decode_data, total_bytes = asn1decode(decode_data[1:])
   206  
   207             next_byte = unpack('B',decode_data[:1])[0]
   208             if next_byte != 0xa0:
   209                 raise Exception('0xa0 tag not found %r' % next_byte)
   210             decode_data, total_bytes = asn1decode(decode_data[1:])
   211     
   212             next_byte = unpack('B',decode_data[:1])[0]
   213             if next_byte != ASN1_OCTET_STRING:
   214                 raise Exception('ASN1_OCTET_STRING tag not found %r' % next_byte)
   215             decode_data2, total_bytes = asn1decode(decode_data[1:])
   216             # the rest should be the data
   217             self['NegoData'] = decode_data2
   218             decode_data = decode_data[total_bytes+1:]
   219  
   220         if next_byte == 0xa2:
   221             # ToDo: Check all this
   222             # We found the authInfo token
   223             decode_data, total_bytes = asn1decode(decode_data[1:])
   224             next_byte = unpack('B',decode_data[:1])[0]
   225             if next_byte != ASN1_OCTET_STRING:
   226                 raise Exception('ASN1_OCTET_STRING tag not found %r' % next_byte)
   227             decode_data2, total_bytes = asn1decode(decode_data[1:])
   228             self['authInfo'] = decode_data2
   229             decode_data = decode_data[total_bytes+1:]
   230  
   231         if next_byte == 0xa3:
   232             # ToDo: Check all this
   233             # We found the pubKeyAuth token
   234             decode_data, total_bytes = asn1decode(decode_data[1:])
   235             next_byte = unpack('B',decode_data[:1])[0]
   236             if next_byte != ASN1_OCTET_STRING:
   237                 raise Exception('ASN1_OCTET_STRING tag not found %r' % next_byte)
   238             decode_data2, total_bytes = asn1decode(decode_data[1:])
   239             self['pubKeyAuth'] = decode_data2
   240  
   241     def getData(self):
   242       # Do we have pubKeyAuth?
   243       if 'pubKeyAuth' in self.fields:
   244           pubKeyAuth = pack('B',0xa3)
   245           pubKeyAuth += asn1encode(pack('B', ASN1_OCTET_STRING) +
   246                         asn1encode(self['pubKeyAuth']))
   247       else:
   248           pubKeyAuth = b''
   249  
   250       if 'authInfo' in self.fields:
   251           authInfo = pack('B',0xa2)
   252           authInfo+= asn1encode(pack('B', ASN1_OCTET_STRING) +
   253                         asn1encode(self['authInfo']))
   254       else: 
   255           authInfo = b''
   256  
   257       if 'NegoData' in self.fields:
   258           negoData = pack('B',0xa1) 
   259           negoData += asn1encode(pack('B', ASN1_SEQUENCE) +
   260                      asn1encode(pack('B', ASN1_SEQUENCE) + 
   261                      asn1encode(pack('B', 0xa0) + 
   262                      asn1encode(pack('B', ASN1_OCTET_STRING) + 
   263                      asn1encode(self['NegoData'])))))
   264       else:
   265           negoData = b''
   266       ans = pack('B', ASN1_SEQUENCE)
   267       ans += asn1encode(pack('B',0xa0) + 
   268              asn1encode(pack('B',0x02) + asn1encode(pack('B',0x02))) +
   269              negoData + authInfo + pubKeyAuth)
   270       
   271       return ans
   272  
   273  if __name__ == '__main__':
   274  
   275      import socket
   276      import argparse
   277      import sys
   278      import logging
   279      from binascii import a2b_hex
   280      from Cryptodome.Cipher import ARC4
   281      from impacket import ntlm, version
   282      try:
   283          from OpenSSL import SSL, crypto
   284      except:
   285          logging.critical("pyOpenSSL is not installed, can't continue")
   286          sys.exit(1)
   287      
   288  
   289      class SPNEGOCipher:
   290          def __init__(self, flags, randomSessionKey):
   291              self.__flags = flags
   292              if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
   293                  self.__clientSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey)
   294                  self.__serverSigningKey = ntlm.SIGNKEY(self.__flags, randomSessionKey,"Server")
   295                  self.__clientSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey)
   296                  self.__serverSealingKey = ntlm.SEALKEY(self.__flags, randomSessionKey,"Server")
   297                  # Preparing the keys handle states
   298                  cipher3 = ARC4.new(self.__clientSealingKey)
   299                  self.__clientSealingHandle = cipher3.encrypt
   300                  cipher4 = ARC4.new(self.__serverSealingKey)
   301                  self.__serverSealingHandle = cipher4.encrypt
   302              else:
   303                  # Same key for everything
   304                  self.__clientSigningKey = randomSessionKey
   305                  self.__serverSigningKey = randomSessionKey
   306                  self.__clientSealingKey = randomSessionKey
   307                  self.__clientSealingKey = randomSessionKey
   308                  cipher = ARC4.new(self.__clientSigningKey)
   309                  self.__clientSealingHandle = cipher.encrypt
   310                  self.__serverSealingHandle = cipher.encrypt
   311              self.__sequence = 0
   312  
   313          def encrypt(self, plain_data):
   314              if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
   315                  # When NTLM2 is on, we sign the whole pdu, but encrypt just
   316                  # the data, not the dcerpc header. Weird..
   317                  sealedMessage, signature =  ntlm.SEAL(self.__flags, 
   318                         self.__clientSigningKey, 
   319                         self.__clientSealingKey,  
   320                         plain_data, 
   321                         plain_data, 
   322                         self.__sequence, 
   323                         self.__clientSealingHandle)
   324              else:
   325                  sealedMessage, signature =  ntlm.SEAL(self.__flags, 
   326                         self.__clientSigningKey, 
   327                         self.__clientSealingKey,  
   328                         plain_data, 
   329                         plain_data, 
   330                         self.__sequence, 
   331                         self.__clientSealingHandle)
   332  
   333              self.__sequence += 1
   334  
   335              return signature, sealedMessage
   336  
   337          def decrypt(self, answer):
   338              if self.__flags & ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY:
   339                  # TODO: FIX THIS, it's not calculating the signature well
   340                  # Since I'm not testing it we don't care... yet
   341                  answer, signature =  ntlm.SEAL(self.__flags, 
   342                          self.__serverSigningKey, 
   343                          self.__serverSealingKey,  
   344                          answer, 
   345                          answer, 
   346                          self.__sequence, 
   347                          self.__serverSealingHandle)
   348              else:
   349                  answer, signature = ntlm.SEAL(self.__flags, 
   350                          self.__serverSigningKey, 
   351                          self.__serverSealingKey, 
   352                          answer, 
   353                          answer, 
   354                          self.__sequence, 
   355                          self.__serverSealingHandle)
   356                  self.__sequence += 1
   357  
   358              return signature, answer
   359  
   360      def check_rdp(host, username, password, domain, hashes = None):
   361  
   362         if hashes is not None:
   363             lmhash, nthash = hashes.split(':')
   364             lmhash = a2b_hex(lmhash)
   365             nthash = a2b_hex(nthash)
   366  
   367         else:
   368             lmhash = ''
   369             nthash = ''
   370  
   371         tpkt = TPKT()
   372         tpdu = TPDU()
   373         rdp_neg = RDP_NEG_REQ()
   374         rdp_neg['Type'] = TYPE_RDP_NEG_REQ
   375         rdp_neg['requestedProtocols'] = PROTOCOL_HYBRID | PROTOCOL_SSL
   376         tpdu['VariablePart'] = rdp_neg.getData()
   377         tpdu['Code'] = TDPU_CONNECTION_REQUEST
   378         tpkt['TPDU'] = tpdu.getData()
   379     
   380         s = socket.socket()
   381         s.connect((host,3389))
   382         s.sendall(tpkt.getData())
   383         pkt = s.recv(8192)
   384         tpkt.fromString(pkt)
   385         tpdu.fromString(tpkt['TPDU'])
   386         cr_tpdu = CR_TPDU(tpdu['VariablePart'])
   387         if cr_tpdu['Type'] == TYPE_RDP_NEG_FAILURE:
   388             rdp_failure = RDP_NEG_FAILURE(tpdu['VariablePart'])
   389             rdp_failure.dump()
   390             logging.error("Server doesn't support PROTOCOL_HYBRID, hence we can't use CredSSP to check credentials")
   391             return
   392         else:
   393             rdp_neg.fromString(tpdu['VariablePart'])
   394  
   395         # Since we were accepted to talk PROTOCOL_HYBRID, below is its implementation
   396  
   397         # 1. The CredSSP client and CredSSP server first complete the TLS handshake, 
   398         # as specified in [RFC2246]. After the handshake is complete, all subsequent 
   399         # CredSSP Protocol messages are encrypted by the TLS channel. 
   400         # The CredSSP Protocol does not extend the TLS wire protocol. As part of the TLS 
   401         # handshake, the CredSSP server does not request the client's X.509 certificate 
   402         # (thus far, the client is anonymous). Also, the CredSSP Protocol does not require 
   403         # the client to have a commonly trusted certification authority root with the 
   404         # CredSSP server. Thus, the CredSSP server MAY use, for example, 
   405         # a self-signed X.509 certificate.
   406  
   407         # Switching to TLS now
   408         ctx = SSL.Context(SSL.TLSv1_2_METHOD)
   409         ctx.set_cipher_list('RC4,AES')
   410         tls = SSL.Connection(ctx,s)
   411         tls.set_connect_state()
   412         tls.do_handshake()
   413  
   414         # If you want to use Python internal ssl, uncomment this and comment 
   415         # the previous lines
   416         #tls = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1, ciphers='RC4')
   417  
   418         # 2. Over the encrypted TLS channel, the SPNEGO handshake between the client 
   419         # and server completes mutual authentication and establishes an encryption key 
   420         # that is used by the SPNEGO confidentiality services, as specified in [RFC4178]. 
   421         # All SPNEGO tokens as well as the underlying encryption algorithms are opaque to 
   422         # the calling application (the CredSSP client and CredSSP server). 
   423         # The wire protocol for SPNEGO is specified in [MS-SPNG].
   424         # The SPNEGO tokens exchanged between the client and the server are encapsulated 
   425         # in the negoTokens field of the TSRequest structure. Both the client and the 
   426         # server use this structure as many times as necessary to complete the SPNEGO 
   427         # exchange.<9>
   428         #
   429         # Note During this phase of the protocol, the OPTIONAL authInfo field is omitted 
   430         # from the TSRequest structure by the client and server; the OPTIONAL pubKeyAuth 
   431         # field is omitted by the client unless the client is sending the last SPNEGO token. 
   432         # If the client is sending the last SPNEGO token, the TSRequest structure MUST have 
   433         # both the negoToken and the pubKeyAuth fields filled in.
   434  
   435         # NTLMSSP stuff
   436         auth = ntlm.getNTLMSSPType1('','',True, use_ntlmv2 = True)
   437  
   438         ts_request = TSRequest()
   439         ts_request['NegoData'] = auth.getData()
   440  
   441         tls.send(ts_request.getData())
   442         buff = tls.recv(4096)
   443         ts_request.fromString(buff)
   444  
   445     
   446         # 3. The client encrypts the public key it received from the server (contained 
   447         # in the X.509 certificate) in the TLS handshake from step 1, by using the 
   448         # confidentiality support of SPNEGO. The public key that is encrypted is the 
   449         # ASN.1-encoded SubjectPublicKey sub-field of SubjectPublicKeyInfo from the X.509 
   450         # certificate, as specified in [RFC3280] section 4.1. The encrypted key is 
   451         # encapsulated in the pubKeyAuth field of the TSRequest structure and is sent over 
   452         # the TLS channel to the server. 
   453         #
   454         # Note During this phase of the protocol, the OPTIONAL authInfo field is omitted 
   455         # from the TSRequest structure; the client MUST send its last SPNEGO token to the 
   456         # server in the negoTokens field (see step 2) along with the encrypted public key 
   457         # in the pubKeyAuth field.
   458  
   459         # Last SPNEGO token calculation
   460         #ntlmChallenge = ntlm.NTLMAuthChallenge(ts_request['NegoData'])
   461         type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, ts_request['NegoData'], username, password, domain, lmhash, nthash, use_ntlmv2 = True)
   462  
   463         # Get server public key
   464         server_cert =  tls.get_peer_certificate()
   465         pkey = server_cert.get_pubkey()
   466         dump = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pkey)
   467  
   468         # Fix up due to PyOpenSSL lack for exporting public keys
   469         dump = dump[7:]
   470         dump = b'\x30'+ asn1encode(dump)
   471  
   472         cipher = SPNEGOCipher(type3['flags'], exportedSessionKey)
   473         signature, cripted_key = cipher.encrypt(dump)
   474         ts_request['NegoData'] = type3.getData()
   475         ts_request['pubKeyAuth'] = signature.getData() + cripted_key
   476  
   477         try:
   478             # Sending the Type 3 NTLM blob
   479             tls.send(ts_request.getData())
   480             # The other end is waiting for the pubKeyAuth field, but looks like it's
   481             # not needed to check whether authentication worked.
   482             # If auth is unsuccessful, it throws an exception with the previous send().
   483             # If auth is successful, the server waits for the pubKeyAuth and doesn't answer 
   484             # anything. So, I'm sending garbage so the server returns an error. 
   485             # Luckily, it's a different error so we can determine whether or not auth worked ;)
   486             buff = tls.recv(1024)
   487         except Exception as err:
   488             if str(err).find("denied") > 0:
   489                 logging.error("Access Denied")
   490             else:
   491                 logging.error(err)
   492             return
   493  
   494         # 4. After the server receives the public key in step 3, it first verifies that 
   495         # it has the same public key that it used as part of the TLS handshake in step 1. 
   496         # The server then adds 1 to the first byte representing the public key (the ASN.1 
   497         # structure corresponding to the SubjectPublicKey field, as described in step 3) 
   498         # and encrypts the binary result by using the SPNEGO encryption services. 
   499         # Due to the addition of 1 to the binary data, and encryption of the data as a binary 
   500         # structure, the resulting value may not be valid ASN.1-encoded values. 
   501         # The encrypted binary data is encapsulated in the pubKeyAuth field of the TSRequest 
   502         # structure and is sent over the encrypted TLS channel to the client. 
   503         # The addition of 1 to the first byte of the public key is performed so that the 
   504         # client-generated pubKeyAuth message cannot be replayed back to the client by an 
   505         # attacker.
   506         #
   507         # Note During this phase of the protocol, the OPTIONAL authInfo and negoTokens 
   508         # fields are omitted from the TSRequest structure.
   509  
   510         ts_request = TSRequest(buff)
   511  
   512         # Now we're decrypting the certificate + 1 sent by the server. Not worth checking ;)
   513         signature, plain_text = cipher.decrypt(ts_request['pubKeyAuth'][16:])
   514  
   515         # 5. After the client successfully verifies server authenticity by performing a 
   516         # binary comparison of the data from step 4 to that of the data representing 
   517         # the public key from the server's X.509 certificate (as specified in [RFC3280], 
   518         # section 4.1), it encrypts the user's credentials (either password or smart card 
   519         # PIN) by using the SPNEGO encryption services. The resulting value is 
   520         # encapsulated in the authInfo field of the TSRequest structure and sent over 
   521         # the encrypted TLS channel to the server.
   522         # The TSCredentials structure within the authInfo field of the TSRequest 
   523         # structure MAY contain either a TSPasswordCreds or a TSSmartCardCreds structure, 
   524         # but MUST NOT contain both.
   525         #
   526         # Note During this phase of the protocol, the OPTIONAL pubKeyAuth and negoTokens 
   527         # fields are omitted from the TSRequest structure.
   528         tsp = TSPasswordCreds()
   529         tsp['domainName'] = domain
   530         tsp['userName']   = username
   531         tsp['password']   = password
   532         tsc = TSCredentials()
   533         tsc['credType'] = 1 # TSPasswordCreds
   534         tsc['credentials'] = tsp.getData()
   535  
   536         signature, cripted_creds = cipher.encrypt(tsc.getData())
   537         ts_request = TSRequest()
   538         ts_request['authInfo'] = signature.getData() + cripted_creds
   539         tls.send(ts_request.getData())
   540         tls.close()
   541         logging.info("Access Granted")
   542  
   543      # Init the example's logger theme
   544      logger.init()
   545      print(version.BANNER)
   546  
   547      parser = argparse.ArgumentParser(add_help = True, description = "Test whether an account is valid on the target "
   548                                                                      "host using the RDP protocol.")
   549  
   550      parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName or address>')
   551  
   552      group = parser.add_argument_group('authentication')
   553  
   554      group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
   555      if len(sys.argv)==1:
   556          parser.print_help()
   557          sys.exit(1)
   558   
   559      options = parser.parse_args()
   560  
   561      import re
   562      domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(options.target).groups('')
   563  
   564      #In case the password contains '@'
   565      if '@' in address:
   566          password = password + '@' + address.rpartition('@')[0]
   567          address = address.rpartition('@')[2]
   568  
   569      if domain is None:
   570          domain = ''
   571  
   572      if password == '' and username != '' and options.hashes is None:
   573          from getpass import getpass
   574          password = getpass("Password:")
   575  
   576      check_rdp(address, username, password, domain, options.hashes)