DLL注入技术之远线程注入

DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EXE文件中的API),或以被注入EXE的身份去执行一些操作等等。

    远线程注入原理是利用Windows 系统中CreateRemoteThread()这个API,其中第4个参数是准备运行的线程,我们可以将LoadLibrary()填入其中,这样就可以执行远程进程中的LoadLibrary()函数,进而将我们自己准备的DLL加载到远程进程空间中执行。

    当然除了CreateRemoteThread()和LoadLibrary()这个两个主要的API还是远远不够的,我们还需要以下表格所示的API:

OpenProcess 打开远程进程
VirtualAllocEx 在远程进程中申请空间
WriteProcessMemory 在远程进程中写入数据
WaitForSingleObject 等待信号量
VirtualFreeEx 释放远程进程中申请空间
CloseHandle 关闭句柄

主要代码如下:

  1. int CRemoteThreadInjectDLL::InjectDll(DWORD dwProcessId, PTCHAR szDllName)
  2. {
  3. if (szDllName[0] == NULL)
  4. return -1;
  5. //提高权限相关操作
  6. EnablePrivilege(TRUE);
  7. //1. 打开进程
  8. HANDLE hProcess = ::OpenProcess(  PROCESS_ALL_ACCESS,   //打开进程权限
  9. FALSE,                                              //是否可继承
  10. dwProcessId);                                       //进程ID
  11. if (hProcess == INVALID_HANDLE_VALUE)
  12. return -1;
  13. //2. 在远程进程中申请空间
  14. LPVOID pszDllName = ::VirtualAllocEx(hProcess, //远程进程句柄
  15. NULL,                                  //建议开始地址
  16. 4096,                                  //分配空间大小
  17. MEM_COMMIT,                            //空间初始化全0
  18. PAGE_EXECUTE_READWRITE);               //空间权限
  19. if (NULL == pszDllName)
  20. {
  21. return -1;
  22. }
  23. //3. 向远程进程中写入数据
  24. BOOL bRet = ::WriteProcessMemory( hProcess, pszDllName,
  25. szDllName, MAX_PATH, NULL);
  26. if (NULL == bRet)
  27. {
  28. return -1;
  29. }
  30. //4. 在远程进程中创建远程线程
  31. m_hInjecthread = ::CreateRemoteThread(hProcess,      //远程进程句柄
  32. NULL,                                            //安全属性
  33. 0,                                               //栈大小
  34. (LPTHREAD_START_ROUTINE)LoadLibrary,             //进程处理函数
  35. pszDllName,                                      //传入参数
  36. NULL,                                            //默认创建后的状态
  37. NULL);                                           //线程ID
  38. if (NULL == m_hInjecthread)
  39. {
  40. DWORD dwErr = GetLastError();
  41. return -1;
  42. }
  43. //5. 等待线程结束返回
  44. DWORD dw = WaitForSingleObject(m_hInjecthread, -1);
  45. //6. 获取线程退出码,即LoadLibrary的返回值,即dll的首地址
  46. DWORD dwExitCode;
  47. GetExitCodeThread(m_hInjecthread, &dwExitCode);
  48. m_hMod = (HMODULE)dwExitCode;
  49. //7. 释放空间
  50. BOOL bReturn = VirtualFreeEx(hProcess, pszDllName,
  51. 4096, MEM_DECOMMIT);
  52. if (NULL == bReturn)
  53. {
  54. return -1;
  55. }
  56. CloseHandle(hProcess);
  57. hProcess = NULL;
  58. //恢复权限相关操作
  59. EnablePrivilege(FALSE);
  60. return 0;
  61. }

此外,我们还需要提升进程权限以便于提高注入成功率,所需API如下表所示:

OpenProcessToken 得到令牌句柄
LookupPrivilegeValue 得到权限值
AdjustTokenPrivileges 提升令牌句柄权限
  1. int CRemoteThreadInjectDLL::EnablePrivilege(bool isStart)
  2. {
  3. //1. 得到令牌句柄
  4. HANDLE  hToken = NULL;      //令牌句柄
  5. if (!OpenProcessToken( GetCurrentProcess(),
  6. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_READ,
  7. &hToken))
  8. {
  9. return FALSE;
  10. }
  11. //2. 得到特权值
  12. LUID    luid = {0};         //特权值
  13. if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
  14. {
  15. return FALSE;
  16. }
  17. //3. 提升令牌句柄权限
  18. TOKEN_PRIVILEGES tp = {0};  //令牌新权限
  19. tp.PrivilegeCount = 1;
  20. tp.Privileges[0].Luid = luid;
  21. tp.Privileges[0].Attributes = isStart ? SE_PRIVILEGE_ENABLED : 0;
  22. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
  23. {
  24. return FALSE;
  25. }
  26. //4. 关闭令牌句柄
  27. CloseHandle(hToken);
  28. return 0;
  29. }

当要在指定的进程中加载DLL时,我们就需要过滤指定名称的进程,这时遍历进程ID并进行对比,得到所指定的进程,所需API如表所示:

CreateToolhelp32Snapshot   创建进程快照  
Process32First   第一个进程快照
Process32Next   循环下一个进程快照  
  1. DWORD CRemoteThreadInjectDLL::GetProcessId(PTCHAR pszProcessName)
  2. {
  3. HANDLE hProcess = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  4. if (INVALID_HANDLE_VALUE == hProcess)
  5. {
  6. return 0;
  7. }
  8. DWORD dwProcessId = 0;
  9. PROCESSENTRY32 process32 = {0};
  10. process32.dwSize = sizeof(PROCESSENTRY32);
  11. BOOL bRetProcess = FALSE;
  12. bRetProcess = ::Process32First(hProcess, &process32);
  13. do
  14. {
  15. if (_tcscmp(pszProcessName, process32.szExeFile) == 0)
  16. {
  17. dwProcessId = process32.th32ProcessID;
  18. break;
  19. }
  20. bRetProcess = ::Process32Next(hProcess, &process32);
  21. }while (bRetProcess);
  22. ::CloseHandle(hProcess);
  23. return dwProcessId;
  24. }

远线程注入API使用较多,不易实现。但是可以批量注入和卸载,这样对于需要反复调试的注入就非常的方便。

Dll注入技术之远程线程注入的更多相关文章

  1. 远程线程注入DLL

    远程线程注入 0x00 前言 远程线程注入是一种经典的DLL注入技术.其实就是指一个新进程中另一个进程中创建线程的技术. 0x01 介绍 1.远程线程注入原理 画了一个图大致理解了下远程线程注入dll ...

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

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

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

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

  4. 详细解读:远程线程注入DLL到PC版微信

    一.远程线程注入的原理 1.其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以 ...

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

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

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

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

  7. 远程线程注入方法CreateRemoteThread

    最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是  https://github.com/Ars ...

  8. DLL注入技术之依赖可信进程注入

    DLL注入技术之依赖可信进程注入 依赖可信进程注入原理是利用Windows 系统中Services.exe这个权限较高的进程,首先将a.dll远线程注入到Services.exe中,再利用a.dll将 ...

  9. windows-CODE注入(远程线程注入)

    远程线程注入(先简单说,下面会详细说)今天整理下代码注入(远程线程注入),所谓代码注入,可以简单的理解为是在指定内进程里申请一块内存,然后把我们自己的执行代码和一些变量拷贝进去(通常是以启线程的方式) ...

随机推荐

  1. 阿里云HBase全新发布X-Pack NoSQL数据库再上新台阶

    一.八年双十一,造就国内最大最专业HBase技术团队 阿里巴巴集团早在2010开始研究并把HBase投入生产环境使用,从最初的淘宝历史交易记录,到蚂蚁安全风控数据存储.持续8年的投入,历经8年双十一锻 ...

  2. linux文件目录颜色及特殊权限对应的颜色

    白色:表示普通文件蓝色:表示目录绿色:表示可执行文件红色:表示压缩文件浅蓝色:链接文件红色闪烁:表示链接的文件有问题黄色:表示设备文件灰色:表示其它文件 各种背景颜色的显示和文件的权限有关红色背景:特 ...

  3. xlwings结合dataframe数据的写入

    一.代码 import xlwings as xw import pandas as pd xl_path=r'***' df_path=r'***' df=pd.read_excel(df_path ...

  4. (转)OpenFire源码学习之四:openfire的启动流程

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43413233 openfire启动 ServerStarter 启动流程图: 启动的总入 ...

  5. eclipse中server name选项变灰

    删除workspace中.metadata\.plugins\org.eclipse.core.runtime\.settings目录下 org.eclipse.wst.server.core.pre ...

  6. 堆、栈、方法区、静态代码块---Java

    java 堆.栈.方法区 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基 ...

  7. 20、formAdd,javascript实现动态添加

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. try-with-resources 让java资源关闭代码更简洁

    一.JDK7的资源关闭方式优化 1 try-with-resource语法 在JDK7以前,Java没有自动关闭外部资源的语法特性,直到JDK7中新增了try-with-resource语法,才实现了 ...

  9. FreeBSD_11-系统管理——{Part_9-SVN}

    一.使用 svn / svnlite 代替 freebsd-update 及 portsnap 等常规工具更新系统及 ports 源码 二.安装可信 ca 机构列表 cd /usr/ports/sec ...

  10. shell脚本批量监控主机磁盘信息

    写一个配置文件保存被监控主机SSH连接信息,格式:IP User Port [root@Test ~]# cat host 10.10.10.10 root 22 10.10.10.11 root 2 ...