原理

核心函数

CreateRemoteThread:让在其他进程中创建一个线程变成可能

核心思想

HANDLE WINAPI CreateRemoteThread(
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);
HMODULE
WINAPI
LoadLibraryW(
_In_ LPCWSTR lpLibFileName
);

CreateRemoteThread函数的第四个参数是线程函数,我们可以用LoadLibrary的函数地址作为线程函数地址。

CreateRemoteThread函数的第五个参数是线程函数参数。用要加载的dll路径作为线程函数的参数。

相当于用这个线程函数(LoadLibrary)把参数(dll路径)Load到“被注入的进程”里。

设计的巧合才出现了这一注入方式

代码实现

获取pid

OpenProcess这个函数有个参数是pid,获取pid的方式多种多样,我这里使用的是快照

 1 //根据进程名找对应的pid(快照方式)
2 DWORD _getProcessHandle(LPCTSTR lpProcessName)
3 {
4 DWORD dwRet = 0;
5 HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6 if (hSnapShot == INVALID_HANDLE_VALUE)
7 {
8 printf("\n获得进程快照失败,返回的GetLastError():%d", ::GetLastError());
9 return dwRet;
10 }
11
12 PROCESSENTRY32 pe32;
13 pe32.dwSize = sizeof(PROCESSENTRY32);
14 ::Process32First(hSnapShot, &pe32);
15 do
16 {
17 if (!lstrcmp(pe32.szExeFile, lpProcessName))
18 {
19 dwRet = pe32.th32ProcessID;
20 break;
21 }
22 } while (::Process32Next(hSnapShot, &pe32));
23 ::CloseHandle(hSnapShot);
24 return dwRet;
25 }

打开进程

hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, _Pid);

在注入进程里申请空间

pAlloc = ::VirtualAllocEx(hprocess,NULL, _SIZE, MEM_COMMIT,PAGE_READWRITE);

因为我们需要找到那个参数(dll路径),在我本来的进程中,dll路径存放的地方和注入进程中dll路径存放的地方不是同一个地方,我们需要跨进程将dll路径写在注入进程中,下面起线程的时候才能找到存放dll路径的字符串

在申请的空间中写入数据

::WriteProcessMemory(hprocess, pAlloc, psDllFillName, _SIZE, NULL);

获得LoadLibraryW的地址

pThreadFunction = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");

由于Windows引入了基址随机化ASLR安全机制,所以导致每次开机启动时系统DLL加载基址都不一样,有些系统dll(kernel,ntdll)的加载地址,允许每次启动基址可以改变,但是启动之后必须固定,也就是说两个不同进程在相互的虚拟内存中,这样的系统dll地址总是一样的。

创建线程在注入进程中

hThread = ::CreateRemoteThread(hprocess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadFunction, pAlloc,0,NULL);

让这个线程loadlibrary

所有代码

 1 #include <iostream>
2 #include <windows.h>
3 #include <TlHelp32.h>
4 #include "tchar.h"
5
6 //根据进程名找对应的pid(快照方式)
7 DWORD _getProcessHandle(LPCTSTR lpProcessName)
8 {
9 DWORD dwRet = 0;
10 HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
11 if (hSnapShot == INVALID_HANDLE_VALUE)
12 {
13 printf("\n获得进程快照失败,返回的GetLastError():%d", ::GetLastError());
14 return dwRet;
15 }
16
17 PROCESSENTRY32 pe32;
18 pe32.dwSize = sizeof(PROCESSENTRY32);
19 ::Process32First(hSnapShot, &pe32);
20 do
21 {
22 if (!lstrcmp(pe32.szExeFile, lpProcessName))
23 {
24 dwRet = pe32.th32ProcessID;
25 break;
26 }
27 } while (::Process32Next(hSnapShot, &pe32));
28 ::CloseHandle(hSnapShot);
29 return dwRet;
30 }
31
32
33 //打开一个进程并为其创建一个线程
34 DWORD _InjectThread(DWORD _Pid, LPCWSTR psDllFillName)
35 {
36 //打开进程
37 HANDLE hprocess;
38 HANDLE hThread;
39 DWORD _SIZE = 0;
40 LPVOID pAlloc = NULL;
41 DWORD psDllAddr = 0;
42 FARPROC pThreadFunction;
43 hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, _Pid);
44 //在注入进程中写入Loadlibrary名称
45 _SIZE = (_tcslen(psDllFillName) + 1)* sizeof(TCHAR);
46 pAlloc = ::VirtualAllocEx(hprocess,NULL, _SIZE, MEM_COMMIT,PAGE_READWRITE);
47 if (pAlloc == NULL)
48 {
49 printf("VirtualAllocExERROR");
50 return FALSE;
51 }
52 BOOL x = ::WriteProcessMemory(hprocess, pAlloc, psDllFillName, _SIZE, NULL);
53 if (FALSE == x)
54 {
55 printf("WriteProcessMemoryERROR");
56 return FALSE;
57 }
58 //获得Loadlibrary的地址
59 pThreadFunction = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
60 //在另一个进程创建一个线程
61 hThread = ::CreateRemoteThread(hprocess, NULL, 0, (LPTHREAD_START_ROUTINE)pThreadFunction, pAlloc,0,NULL);
62 if (hThread == NULL)
63 {
64 printf("CreateRemoteThreadError");
65 return FALSE;
66 }
67 WaitForSingleObject(hThread,-1);
68 GetExitCodeThread(hThread, &psDllAddr);
69 VirtualFreeEx(hprocess, pAlloc, _SIZE, MEM_DECOMMIT);
70 ::CloseHandle(hprocess);
71 return TRUE;
72 }
73 int main()
74 {
75 DWORD PID = _getProcessHandle(L"Test.exe");
76 _InjectThread(PID,L"MessageBox.dll");
77 }

实际上整个过程就是等效于在注入进程中自己LoadLibrary,只不过我们是在其他进程load这个dll

Dll文件

 1 #include "pch.h"
2
3 BOOL APIENTRY DllMain( HMODULE hModule,
4 DWORD ul_reason_for_call,
5 LPVOID lpReserved
6 )
7 {
8 switch (ul_reason_for_call)
9 {
10 case DLL_PROCESS_ATTACH:
11 MessageBox(NULL, L"sucess!!!", L"注入", MB_OK);
12 case DLL_THREAD_ATTACH:
13 MessageBox(NULL, L"sucess!!!", L"注入", MB_OK);
14 case DLL_THREAD_DETACH:
15 case DLL_PROCESS_DETACH:
16 break;
17 }
18 return TRUE;
19 }

测试

一开始没有这个dll

注入后

说明注入成功

dll远线程注入的更多相关文章

  1. 恶意软件开发——突破SESSION 0 隔离的远线程注入

    一.前言 在Windows XP,Windows Server 2003以及更早的版本中,第一个登录的用户以及Windows的所有服务都运行在Session 0上,这样的做法导致用户使用的应用程序可能 ...

  2. 动态加载dll的实现+远线程注入

    1.在目标进程中申请内存 2.向目标进程内存中写入shellcode(没有特征,编码比较麻烦) 3.创建远线程执行shellcode 之前可以看到shellcode很难编写还要去依赖库,去字符串区等等 ...

  3. VB.NET实现32位、64位远线程运行ASM,注入非托管、托管DLL

    这是一个老话题,远线程函数给我们提供了机会在其他进程中启动一个新线程,所以我们可以做很多事情.但事情远远没有结束,如果我们要做的事情非常复杂,那么将面临编写大量的ASM代码,虽然我们可以用VC之类的工 ...

  4. Dll注入技术之远程线程注入

    DLL注入技术之远线程注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...

  5. 远程线程注入dll,突破session 0

    前言 之前已经提到过,远线程注入和内存写入隐藏模块,今天介绍突破session 0的dll注入 其实今天写这个的主要原因就是看到倾旋大佬有篇文章提到:有些反病毒引擎限制从lsass中dump出缓存,可 ...

  6. 远程线程注入DLL突破session 0 隔离

    远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...

  7. 远程线程注入突破SESSION 0

    远程线程注入突破SESSION 0 SESSION 0 隔离 在Windows XP.Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(Se ...

  8. 安全之路 —— 借助DLL进行远程线程注入实现穿墙与隐藏进程

    简介        大多数后门或病毒要想初步实现隐藏进程,即不被像任务管理器这样典型的RING3级进程管理器找到过于明显的不明进程,其中比较著名的方法就是通过远程线程注入的方法注入将恶意进程的DLL文 ...

  9. 安全之路 —— 无DLL文件实现远程线程注入

    简介         在之前的章节中,笔者曾介绍过有关于远程线程注入的知识,将后门.dll文件注入explorer.exe中实现绕过防火墙反弹后门.但一个.exe文件总要在注入时捎上一个.dll文件着 ...

随机推荐

  1. Axios 取消 Ajax 请求

    Axios 取消 Ajax 请求 Axios XMLHttpRequest https://caniuse.com/?search=XMLHttpRequest https://developer.m ...

  2. website text select notes menu

    website text select notes menu website 文字选择笔记菜单(下划线, 标记, 复制, 分享) 下划线, 标记 https://time.geekbang.org/ ...

  3. 开发Microsoft Teams选项卡应用安全注意事项

    我们都知道,为了方便广大的开发人员快速开发Microsoft Teams选项卡应用,微软提供了一个JS SDK,你可以通过这里 https://docs.microsoft.com/en-us/jav ...

  4. elasticsearch如何设计索引

    本文为博客园作者所写: 一寸HUI,个人博客地址:https://www.cnblogs.com/zsql/ 最近在做es相关的工作,所以记录下自己的一些想法,可能很多方面不会很全面,但是基本都是经过 ...

  5. C++算法代码——奖学金

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1098 题目描述 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学 ...

  6. 手把手教你Centos7 部署 gitlab社区版

    一.前置说明: 操作系统:Centos 7 物理内存:>=2G 本人亲测,如果安装低版本的gitlab,比如我这里所使用的v8.17.0,物理内存1G,swap 2G虚拟内存即可部署.高版本的所 ...

  7. 【死磕JVM】JVM快速入门之前戏篇

    简介 Java是一门可以跨平台的语言,但是Java本身是不可以实现跨平台的,需要JVM实现跨平台.javac编译好后的class文件,在Windows.Linux.Mac等系统上,只要该系统安装对应的 ...

  8. Vue学习笔记-VSCode安装与配置

    一  使用环境: windows 7 64位操作系统 二  VSCode安装与配置  1.下载: https://code.visualstudio.com 直接点击即可. 2. 点击按装程序,默认安 ...

  9. Docker Elasticsearch 集群配置

    一:选用ES原因 公司项目有些mysql的表数据已经超过5百万了,各种业务的查询入库压力已经凸显出来,初步打算将一个月前的数据迁移到ES中,mysql的老数据就物理删除掉. 首先是ES使用起来比较方便 ...

  10. Oracle数据库配置监听程序

    最近在学习Oracle数据库,从安装到配置监听程序基本靠百度... 不得不说百度真的很nice!!! 下面是我的Oracle服务端(PL/SQL Developer)出现的监听程序的问题及我解决的方法 ...