How process can skip from its JOB – A taste of dirty application
August 8, 2011 Leave a comment
I am writing this post while I can’t believe if what I did is normal or not, I will mention what I`ve did then I will pose some questions that really need answer.
Job Object is a very powerful concept in Windows, and it us used to impose limitations on process assigned to it, some of this limitations enhance process security. For more information about jobs refer Jobs post.
An important information you should know about Jobs:
Once a process is part of a job, it cannot be moved to another job and it cannot become jobless (so to speak). Also note that when a process that is part of a job spawns another process, the new process is automatically made part of the parent’s job. However, you can alter this behavior in the following ways
Let’s consider this scenario:
you write a Host application that runs other applications and manages them, this applications may have unknown implementation (you are not its author), and you create these application as a child process (Client process) of your Host process. Imagine that some of these client process are infected by some virus which requires to cross the limitations you imposed by your Job (e.g spawn other children processes, access USER objects outside the process, etc..). To ensure that your client processes run in a safe environment you impose the necessary restrictions.
Imagine if one application (infected one) was written to skip from the Job assigned to it and run as a jobless process with no restrictions! HOW will you control such thing? This is horrible and this is what I could do! I though that doing such thing is not doable as it is very dangerous, but I could do it.
Dirty application code
#include <iostream>
#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include "XWinAssist.h"
using namespace std;
#define HostJobName _T("XHostJob")
#define AppName _T("cmd.exe")
#define AppCount 5
void CreateJoblessSelf()
{
const int cchSize = 128;
DWORD dwSize = cchSize;
TCHAR szProcessName[cchSize];
QueryFullProcessImageName(GetCurrentProcess(), 0, szProcessName, &dwSize);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// Here I create myself again in the same console window
// I specify that I want to create myself and skip the current job
BOOL fCreate = CreateProcess(NULL, szProcessName, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
if(!fCreate)
{
_tprintf_s(_T("Failed to create jobless self\n"));
PrintLastError();
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
void StartSomeProcess()
{
const int iSize = 128;
TCHAR szCommandLine[iSize];
_tcscpy_s(szCommandLine, iSize, AppName);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// Start some cmd.exe prcess, for sure this can be any process you imagine
BOOL fCreate = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if(!fCreate)
{
_tprintf_s(_T("Failed to start some process\n"));
PrintLastError();
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
BOOL bInJob = FALSE;
PROCESS_INFORMATION pi = { 0 };
// find if we are already assigned to a job
IsProcessInJob(GetCurrentProcess(), NULL, &bInJob);
// I will try to skip from the job already assigned to me
if (bInJob)
{
_tprintf_s(_T("\nProcess already in a job\n"));
_tprintf_s(_T("Spawining JOBLESS SELF …\n"));
// instantiating myself but with no restrictions
CreateJoblessSelf();
_tprintf_s(_T("\nRestarting …\n"));
return 0;
}
else
{
// Reaching this line means that I am totally free and have no job restrictions
_tprintf_s(_T("\nMUHAHAHAHA … I am JOBLESS Process (Evil Laugh)\n"));
}
// Spawn some process to mobilize system resources
// this could be some other infectious job
for(int i = 0; i < AppCount; ++i)
{
StartSomeProcess();
}
return(0);
}
Environment:
- Microsoft Win7 Professional
- Visual Studio 2008 Team Suite
Questions and Exclamations
I have some questions in my mind I need answer for, I tried to search online but with no useful information.
- Is there any permission or access rights required to allow a process to spawn other process outside its job? I think there should be some.
- Can this behavior be really dangerous and be used to make havoc in the system?
- Is this considered as a security flaw?