Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

force any running process to crash

I would like to crash a running program of my choice (e.g., notepad++, becrypt, word) for software testing purposes.

I know how to BSOD, I know how to cause a program I write to crash, I know how to end process - but how to crash an existing process I do not!

any help?

like image 979
Django Doctor Avatar asked May 21 '12 13:05

Django Doctor


3 Answers

Well, use CreateRemoteThread on a remote process and invoke something [1] that crashes the process reliably. I'm not sure whether CreateRemoteThread guards against null pointers, but you could pass an address in the null page to it and have the remote process execute that.

[1] null pointer or null page access, division by zero, invoking a privileged instruction, int3 ...


Example:

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>

BOOL setCurrentPrivilege(BOOL bEnable, LPCTSTR lpszPrivilege)
{
    HANDLE hToken = 0;
    if(::OpenThreadToken(::GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken)
        || ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        TOKEN_PRIVILEGES tp;
        LUID luid;

        if(!::LookupPrivilegeValue(
            NULL,            // lookup privilege on local system
            lpszPrivilege,   // privilege to lookup 
            &luid ) )        // receives LUID of privilege
        {
            ::CloseHandle(hToken);
            return FALSE; 
        }
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        tp.Privileges[0].Attributes = (bEnable) ?  SE_PRIVILEGE_ENABLED : 0;

        // Enable the privilege or disable all privileges.
        if(!::AdjustTokenPrivileges(
            hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES) NULL,
            (PDWORD) NULL)
            )
        {
            CloseHandle(hToken);
            return FALSE; 
        }
        ::CloseHandle(hToken);
    }
    return TRUE;
}

int killProcess(DWORD processID)
{
    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    if(hProcess)
    {
        if(!setCurrentPrivilege(TRUE, SE_DEBUG_NAME))
        {
            _tprintf(TEXT("Could not enable debug privilege\n"));
        }
        HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)1, NULL, 0, NULL);
        if(hThread)
        {
            ::CloseHandle(hThread);
        }
        else
        {
            _tprintf(TEXT("Error: %d\n"), GetLastError());
            ::CloseHandle(hProcess);
            return 1;
        }
        ::CloseHandle(hProcess);
    }
    return 0;
}

int __cdecl _tmain(int argc, _TCHAR *argv[])
{
    killProcess(3016);
}

Of course you'll want to adjust the PID in the call to killProcess. Compiled with WNET DDK and tested on 2003 Server R2.

The gist here is that we tell the remote process to execute code at address 0x1 ((LPTHREAD_START_ROUTINE)1), which is inside the null page but not a null pointer (in case there are checks against that). The crud around the function, in particular setCurrentPrivilege is used to gain full debug privileges so we can do our evil deed.

like image 169
0xC0000022L Avatar answered Oct 21 '22 12:10

0xC0000022L


You can use DLL injection technique in order to inject your code into another process. Then in your injected code do something simple like abort() or division by zero.

like image 23
Flot2011 Avatar answered Oct 21 '22 10:10

Flot2011


A two steps mechanism is needed:

  1. inject the process to crash (using an injection library, using Detours, using a Hook installation, etc..). What you choose depends on the time and knowledge you have and other preconditions (like credentials, anti-injection protection, size of the foot-print you want to leave..)
  2. perform an invalid operation in the injected process (like int 2Eh, divide by null, etc..)
like image 27
mox Avatar answered Oct 21 '22 11:10

mox