大家好,又见面了,我是你们的朋友全栈君。
本文是我搜集整理的DLL注入方法,有一些自己实现了,在文末的链接里有源码,其余没有实现的也有git链接或别的源码链接。
参考链接:https://bbs.pediy.com/thread-227075.htm
第一种 CreateRemoteThread远程线程调用 DLL注入是指向某一个特定的进程空间强制插入一个特定的DLL文件映像,值得注意的是这种插入是强制性的插入,从技术层面来看,DLL注入是利用LoadLibrary()加载特定的DLL文件到进程的内存空间。注入的对象是可以是自身,也可以是远程进程。DLL注入技术实现主要分为5个部分,
1.打开进程,获取进程的句柄,
2.是在内存空间开辟一段内存空间
3.是向刚刚开辟的内存中写入需要注入DLL的路径,
4.是利用GetProcessAddree()获取LoadLibrary的地址。
5.是调用远程线程,利用LoadLibrary()去加载DLL。
第二种 RtlCreateUserThread创建用户线程 RtlCreateUserThread是CreateRemoteThread的底层实现,所以使用RtlCreateUserThread的原理是和使用CreateRemoteThread的原理是一样的。唯一的区别是使用CreateRemoteThread写入目标进程的是Dll的路径,而RtlCreateUserThread写入的是一段shellcode。因为直接调用了RtlCreateUserThread创建线程,绕过了win7/vista对这方面的检测所以可以注入到系统进程中(比如winlogon.exe),当然此方法也有缺陷,因为没有和csrss通讯,可能在线程体里面调用某些api函数可能会失败。还有需要注意的是因为RtlCreateUserThread没有经过系统封装所以线程体必须自己调用ExitThread来结束线程。
第三种 APC注入 通过CreateRemoteThread函数创建一个线程就可以使用远程进程中的一个函数。然而,线程创建需要系统开销,所以调用一个现有的线程会更加高效。
Windows的异步过程调用(APC)可以满足这种要求
APC可以让一个线程在它正常的执行路径运行之前执行一些其他的代码。每个线程都有一个附加的APC队列,它们在线程处于可警告的等待状态时被处理。
所以只需要将目标进程的线程的APC队列里面添加APC过程,当然为了提高命中率可以向进程的所有线程中添加APC过程。然后促使线程从休眠中恢复就可以实现APC注入。
第四种 设置进程上下文
核心是通过函数SetContextThread
实现注入,像很多方法比如内存注入,通过傀儡进程注入核心都是这个思想。都是挂起线程,然后往内存中写入shellcode然后,重新设置Context,然后调用SetThreadContext和ResumeThread恢复线程执行。
第五种 反射式注入
反射式dll注入不需要dll文件落地,减少被查杀的风险。首先将需要注入的dll写入进程内存,然后为该dll添加一个导出函数,利用这个导出函数让其自动的装载dll。注射器是将DLL文件写入目标进程内存。反射装载器实现的就是模拟dll装载器装载dll文件的操作。
反射式注入流程如下:
1、读入原始DLL文件至内存缓冲区; 2、解析DLL标头并获取SizeOfImage; 3、为DLL分配新的内存空间,大小为SizeOfImage; 4、将DLL标头和PE节复制到步骤3中分配的内存空间; 5、执行重定位; 6、加载DLL导入的库; 7、解析导入地址表(IAT); 8、调用DLL的DLL_PROCESS_ATTACH;
第六种 输入法注入
切换输入法时候,输入法管理器imm32.dll就会加载IME模块,这样就形成了输入法注入的充要条件。而由于这个Ime文件本质上只是个存放在C:WINDOWSsystem32目录下的特殊的DLL文件,因此我们可以利用这个特性,在Ime文件中使用LoadLibrary()函数待注入的DLL文件。
第七种 全局钩子注入
利用windows的消息机制,可以在事件发送到os之间设置一条钩链,来钩取不同的消息,如以下代码,利用SetwindowsHookEx可以钩取一个键盘消息。并且调用钩子处理函数来处理这个消息,所达到的效果和dll注入是一样的(执行dll内部的代码)
第八种 DLL劫持
DLL劫持原理见链接 https://blog.csdn.net/liuhaidon1992/article/details/103815868
注入实现见文末链接
第九种 注册表注入
REG注入原理是利用在Windows 系统中,当REG以下键值中存在有DLL文件路径时,会跟随EXE文件的启动加载这个DLL文件路径中的DLL文件。当如果遇到有多个DLL文件时,需要用逗号或者空格隔开多个DLL文件的路径。
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersion WindowsAppInit_DLLs中,os就会自动去加载位于该注册表的有效的DLL。所以只需要在注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersion WindowsAppInit_DLLs中添加DLL的绝对路径,并把数值改为1,可以使得所有加载USER32.dll的进程全部加载目标路径的DLL。 利用AppCertDlls注册表,将HKLMSystemCurrentControlSetControlSession ManagerAppCertDlls下写入dll的路径,可以将此注册表项下的DLL加载到调用CreateProcess,CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW和WinExec的每个进程中。值得注意的是win xp-win 10 默认不存在这个注册表项
第十种 挂起线程注入
OpenThread–>SuspendThread–>申请内存–>写入代码–>GetThreadContext–>获取EIP–>修改EIP–>SetThreadContext–>ResumeThread。
第十一种 挂起进程注入
CreateProcess注入方法之一,CREATE_SUSPENDED以挂起的方式打开进程,后面方法与挂起线程注入相似。
第十二种 进程替换技术(进程hollowing)
除了注入之外,我们还可以使用进程替换技术将一个可执行文件写入一个运行的进程内部,这种技术让恶意代码拥有和被替换进程相同的特权,这个技术关键是:需要以挂起状态创建进程,也就是说,这个进程将会被载入内存,但是主线程过去,在外部程序恢复主线程之前,程序不会工作,恢复主线程之后,程序工作。如下代码是进程替换代码的伪代码.该程序通过调用CreateProcess并将进程创建标志设置为CREATE_SUSPENDED(0x00000004)完成。新进程的主线程被创建为挂起状态,直到ResumeThread函数被调用才会运行。接下来,恶意软件需要用恶意的有效载荷来替换合法文件的内容。这可以通过调用ZwUnmapViewOfSection或NtUnmapViewOfSection来取消映射目标进程的内存(这一步的目的在于是重新写入傀儡进程的时候,进程对于这部分待注入的内存还有所有权,为了避免冲突,在重写入进程之前,需要取消进程对内存的映射)。这两个API基本上释放了一个部分指向的所有内存。现在内存被取消映射,加载器执行VirtualAllocEx为恶意软件分配新内存,并使用WriteProcessMemory将每个恶意软件的部分写入目标进程空间。恶意软件调用SetThreadContext将entrypoint指向已编写的新代码段。最后,恶意软件通过调用ResumeThread来恢复挂起的线程。
CreateProcess(…,”目标进程.exe”,CREATE_SUSPENDED);//以挂起状态创建进程
ZwUnmapviewOfSection() //释放内存,解除内存映射
VirtualAllocEx() //为恶意代码分配新空间
writeProcessMenory(header) //写入数据(文件头)
for(i=0;i<NumberOfSection;i )
WriteProcessMenory(section) //写入节区数据
···
ResumeThread() //重新启动主线程
第十三种方法 调试器注入
CreateProcess注入方法之二,DEBUG_ONLY_THIS_PROCESS以调试的方法打开进程,利用CREATE_PROCESS_DEBUG_EVENT,向目标程序中写入我们的ShellCode完成相应功能,并且我们的ShellCode中写入以CC断点,代码执行指令时触发EXCEPTION_DEBUG_EVENT事件,在EXCEPTION_DEBUG_EVENT的处理函数中回到原来的执行流程。
第十四种方法 导入表注入
静态注入的方法。修改PE文件,添加一个新节,修改导入表添加一个新的DLL实现注入。
源码链接: https://pan.baidu.com/s/1VeYcCcGvAOW8oxzclf6d4A 提取码: 9spe
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145314.html原文链接:https://javaforall.cn