首页 » SEO优化 » php对接dll技巧_DLL 注入技能的 N 种姿势

php对接dll技巧_DLL 注入技能的 N 种姿势

访客 2024-12-11 0

扫一扫用手机浏览

文章目录 [+]

本文中我将先容DLL注入的干系知识。
不算太糟的是,DLL注入技能可以被正常软件用来添加/扩展其他程序,调试或逆向工程的功能性;该技能也常被恶意软件以多种办法利用。
这意味着从安全角度来说,理解DLL注入的事情事理是十分必要的。

不久前在为攻击方测试(目的是为了仿照不同类型的攻击行为)开拓定制工具的时候,我编写了这个名为“injectAllTheThings”的小工程的大部分代码。
如果你想看一下利用DLL注入履行的攻击行为的多少示例,请参阅网址:https://attack.mitre.org/wiki/Technique/T1055。
如果你想学习DLL注入的干系知识,你会创造该工程也是有用的。
当你想要查询这类信息/代码时,你会创造网上充斥着垃圾;我的代码可能也属于垃圾。
我并不是程序员,我只是在须要时对代码进行修正。
无论如何,我以一种便于阅读和理解的办法,将多种能在32位和64位环境下生效的DLL注入技能(事实上一共7种不同的技能),整合到了一个单独的Visual Studio工程之中。
有些朋友对这些代码感兴趣,以是它也可能会吸引你。
为了区分,每种技能有其独占的源文件。

php对接dll技巧_DLL 注入技能的 N 种姿势

下图为工具的输出信息,个中显示了所有的选项和实现的技能。

php对接dll技巧_DLL 注入技能的 N 种姿势
(图片来自网络侵删)

网友@SubTee认为,DLL注入是多余的(如下图所示);我方向于赞许TA的不雅观点,然而DLL注入并不仅仅是加载DLL那么大略。

你确实可以利用署名认证的微软二进制文件来加载DLL,但你无法附加到一个特定的进程来干预其内存内容。
为什么大部分渗透测试师实际上不知道DLL注入是什么,或者它是如何事情的?由于Metasploit平台替他们包办的太多了;他们一贯盲目地利用它。
我认为,学习这种“奇特的”内存操作技能的最好地点,实际上是游戏黑客论坛。
如果你正在进行攻击方测试,那么你就必须干这些“脏”活儿,同时研究这些技能;除非你乐意仅仅利用别人随意编写的工具。

大部分韶光,我们利用很繁芜的技能开始一次攻击方测试;如果我们未被创造,则开始降落繁芜度。
基本上这便是我们开始向磁盘投放二进制文件和运用DLL注入技能的韶光点。

本文试图以一种大略而高阶的办法纵览DLL注入技能,同时为GitHub中的项目(网址为:https://github.com/fdiskyou/injectAllTheThings)供应“文档”支持。

简介

DLL注入技能,一样平常来讲是向一个正在运行的进程插入/注入代码的过程。
我们注入的代码以动态链接库(DLL)的形式存在。
DLL文件在运行时将按需加载(类似于UNIX系统中的共享库)。
本工程中,我将仅利用DLL文件,然而实际上,我们可以以其他的多种形式“注入“代码(正如恶意软件中所常见的,任意PE文件,shellcode代码/程序集等)。

同时要记住,你须要得当的权限级别来操控其他进程的内存空间。
但我不会在此谈论保护进程(干系网址:https://www.microsoftpressstore.com/articles/article.aspx?p=2233328&seqNum=2)和权限级别(通过Vista系统先容,干系网址:https://msdn.microsoft.com/en-gb/library/windows/desktop/bb648648(v=vs.85).aspx);这属于完备不同的另一个主题。

再次强调一下,正如我之前所说,DLL注入技能可以被用于合法正当的用场。
比如,反病毒软件和端点安全办理方案利用这些技能来将其软件的代码嵌入/拦截系统中“所有”正在运行的进程,这使得它们可以在其运行过程中监控每一个进程,从而更好地保护我们。
同样存在恶意的用场。
一种常常被用到的通用技能是注入“lsass”进程来获取口令哈希值。
我们之前都这么干过。
很明显,恶意代码同样广泛运用了代码注入技能:不管是运行shellcode代码,运行PE文件,还是在另一个进程的内存空间中加载DLL文件以隐蔽自身,等等。

根本知识

对付每一种技能,我们都将用到微软Windows API,由于它为我们供应了大量的函数来附加和操纵其他进程。
从微软Windows操作系统的第一个版本开始,DLL文件便是其基石。
事实上,微软Windows

API中的所有函数都包含于DLL文件之中。
个中,最主要的是“Kernel32.dll”(包含管理内存,进程和线程干系的函数),“User32.dll”(大部分是用户接口函数),和“GDI32.dll”(绘制图形和显示文本相关的函数)。

你可能会有疑问,为什么会有这些API接口,为什么微软为我们供应如此丰富的函数集来操纵和修正其他进程的内存空间?紧张缘故原由是为了扩展运用程序的功能。
比如,一个公司创建了一款运用程序,并且许可其他公司来扩展或增强这个运用程序;如此,这就有了一个合法正当的用场。
除此之外,DLL文件还用于项目管理,内存保护,资源共享,等等。

下图考试测验解释了险些每一种DLL注入技能的流程。

如上所见,我认为 DLL 注入共四个步骤:

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

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

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

4. 掌握进程运行DLL文件

所有这些步骤是通过调用一系列指定的API函数来完成的。
每种技能须要进行特定的设置和选项配置。
我认为,每种技能都有其优点和缺陷

(1)技能先容

我们有多种办法可以掌握进程运行我们的DLL文件。
最普通的该当是“CreateRemoteThread()”和“NtCreateThreadEx()”函数;然而,不可能仅仅向这些函数通报一个DLL文件作为参数,我们必须供应一个包含实行出发点的内存地址。
为此,我们须要分配内存,利用“LoadLibrary()”加载我们的DLL文件,复制内存,等等。

我称之为“injectAllTheThings”的工程(由于我只是纯挚讨厌“注入器”这个名字,加上GitHub上已经有太多的垃圾“注入器”,而我不想再多一个了)包含7种不同的技能;我并不是个中任何一种技能的原创作者,而是提炼总结了这七种技能(是的,还有更多)。
个中某些已经有很多文档资料描述(像“CreateRemoteThread()”),而另一些则属于未公开API函数(像“NtCreateThreadEx()”)。
以下是所实现的技能的完全列表,个中每种都可以在32位和64位环境下生效。

•CreateRemoteThread()

•NtCreateThreadEx()

•QueueUserAPC

•SetWindowsHookEx()

•RtlCreateUserThread()

•利用SetThreadContext()找到的代码区域

•反射DLL

你可能通过其他的名字理解个中某些技能。
以上并不是包含每一种DLL注入技能的完全列表;正如我所说的,还有更多技能,如果之后我在某个工程中须要对其打仗学习的话我会将它们添加进来。
到目前为止,这便是我在某些工程中所用到的技能列表;个中某些可以稳定利用,某些不可以。
须要把稳的是,不能够稳定利用的那些技能可能是由于我所编写代码的自身问题。

(2)LoadLibrary()

正如MSDN中所述,“LoadLibrary()”函数“被用于向调用进程的地址空间加载指定模块,而该指定模块可能导致其他模块被加载”。
函数原型与参数解释如下所示:

HMODULE WINAPI LoadLibrary(

换言之,该函数只须要一个文件名作为其唯一的参数。
即,我们只须要为我们的DLL文件路径分配内存,将实行出发点设置为“LoadLibrary()”函数的地址,之后将路径的内存地址通报给函数作为参数。

正如你所知道(或不知道)的,最大的问题是“LoadLibrary()”会向程序注册已加载的DLL模块;这意味着这种方法很随意马虎被检测到,但令人惊奇的是很多端点安全办理方案仍检测不出。
不管若何,正如我之前所说,DLL注入也有一些合法正当的用场,因此我们还要把稳的是,如果一个DLL文件已经用“LoadLibrary()”加载过了,则它不会再次实行。
你可以试验一下,但我没有对任何一种技能试过。
当然,利用反射DLL注入技能不会有这方面的问题,由于DLL模块并未被注册。
不同于利用“LoadLibrary()”,反射DLL注入技能将全体DLL文件载入内存,然后通过确定DLL模块的入口点偏移来将其加载;这样可以按照需求更暗藏的对其进行调用。
取证职员仍旧能够在内存中找到你的DLL,但会很困难。
Metasploit平台大量利用了这项技能,而且大部分端点办理方案也还乐意始终利用它。
如果你想查找这方面的技能资料,或者你在攻防游戏中处于防守方,可以参阅以下网址:

https://www.defcon.org/html/defcon-20/dc-20-speakers.html#King

https://github.com/aking1012/dc20

附注一下,如果你正在折腾你的端点安全软件,而它很好地利用了以上所有这些技能,你可能须要利用以下攻防反欺骗引擎来试试(把稳,我只是考试测验轻松的说法,以便你能理解)。
某些反欺骗工具的反Rookit性能要比某些反病毒软件要前辈得多。
reddit网站上有一本书你肯定读过,叫“黑客游戏”,它的作者Nick Cano对其有非常深入的研究;只需理解一下他的事情,你就会理解我所评论辩论的内容。

附加到目标/远程进程

首先,我们须要获取我们想要交互的进程句柄;为此我们调用“OpenProcess()”API函数。
函数原型如下:

HANDLE WINAPI OpenProcess(

如果你读过MSDN中干系的文档,那么你该当知道我们须要要求获取一系列特定的访问权限;访问权限的完全列表参阅网址:https://msdn.microsoft.com/en-gb/library/windows/desktop/ms684880(v=vs.85).aspx。

这些权限随微软Windows操作系统版天职歧而不同;以下调用代码可用于险些每一种技能之中:

HANDLE hProcess = OpenProcess(

在目标/远程进程空间分配内存

我们调用“VirtualAllocEx()”函数为DLL路径分配内存。
正如MSDN中所述,“VirtualAllocEx()”函数“保留,提交或改变指定进程虚拟地址空间中的一块内存区域的状态;函数通过置零来初始化内存。
”函数原型如下:

LPVOID WINAPI VirtualAllocEx(

基本上,我们进行如下的调用操作:

// 打算DLL文件路径名称所需的字节数

或者你可以更聪明一点地调用“GetFullPathName()”API函数;然后,我在全体工程中都没有调用这个API函数,仅仅是出于个人偏好或者是不足聪明。

如果你想要为全体DLL文件分配空间,就必须进行如下操作:

hFile = CreateFileW(pszLibFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

复制DLL文件路径(或者DLL文件)到目标/远程进程的内存空间中

现在,我们须要调用“WriteProcessMemory()”API函数,来将我们的DLL文件路径,或者全体DLL文件,复制到目标/远程进程中。
函数原型如下所示:

BOOL WINAPI WriteProcessMemory(

一样平常的调用代码如下所示:

DWORD n = WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, dwSize, NULL);

如果我们想要像反射DLL注入技能所做的那样复制全体DLL文件,就须要更多的代码,由于在将其复制到目标/远程进程之前我们须要将其读入内存。
详细代码如下所示:

lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength)

正如之前所述,通过利用反射DLL注入技能,以及将DLL文件复制到内存中,进程不会记录该DLL模块。

但这样会有一点繁芜,由于当DLL模块加载到内存中时我们须要获取其入口点;反射DLL工程的“LoadRemoteLibraryR()”函数部分为我们完成了这项事情。
如有须要请参阅源码。

须要把稳的是,我们将注入的DLL文件须要利用适当的包含与选项来进行编译,这样它才能与ReflectiveDLLInjection方法相匹配。
“InjectAllThings”工程中包含了一个名为“rdll_32.dll/rdll_64.dll”的DLL文件,可用于练习。

掌握进程来运行DLL文件

(1)CreateRemoteThread()

可以说,“CreateRemoteThread()”是最传统和最盛行,以及最多文档资料先容的DLL注入技能。

它包括以下几个步骤:

1.利用OpenProcess()函数打开目标进程

2.通过调用GetProAddress()函数找到LoadLibrary()函数的地址

3.通过调用VirtualAllocEx()函数在目标/远程进程地址空间中为DLL文件路径开辟内存空间

4.调用WriteProcessMemory()函数在之前所分配的内存空间中写入DLL文件路径

5.调用CreateRemoteThread()函数创建一个新的线程,新线程以DLL文件路径名称作为参数来调用LoadLibrary()函数

如果你看过MSDN中关于“CreateRemoteThread()”函数的文档,那么你该当知道,我们须要一个指针,“指向将由线程实行的,类型为‘LPTHREAD_START_ROUTINE’的运用程序定义函数,并且该指针代表远程进程中线程的起始地址”。

这意味着要运行我们的DLL文件,我们只须要掌握进程来做就好(译者注:由下文可知,该当是将“LoadLibrary()”函数作为线程的启动函数,来加载待注入的DLL文件)。
很大略。

以下代码即之前所列的全部基本步骤。

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);

完全代码请参阅源文件“t_CreateRemoteThread.cpp”。

(2)NtCreateThreadEx()

另一个选择是利用“NtCreateThreadEx()”函数;这是一个未公开的“ntdll.dll”中的函数,未来可能会消逝或改变。
这种技能比较而言实现更加繁芜,由于我们须要一个构造体(详细如下所示)来向函数通报参数,以及另一个构造体用于从函数吸收数据。

struct NtCreateThreadExBuffer {

网址:http://securityxploded.com/ntcreatethreadex.php处的文章详细先容了该函数调用。
设置部分与“CreateRemoteThread()”非常类似;然而,相较于直接调用“CreateRemoteThread()”函数,我们利用如下代码来调用“NtCreateThreadEx()”。

PTHREAD_START_ROUTINE ntCreateThreadExAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT(\公众ntdll.dll\公众)), \"大众NtCreateThreadEx\"大众);

完全代码请参阅源文件“t_NtCreateThreadEx.cpp”。

(3)QueueUserAPC()

除了之前先容的方法还有一种选择,不用在目标/远程进程中创建一个新的线程,那便是“QueueUserAPC()”函数。

根据MSDN中的文档先容,该函数“向指定线程的APC行列步队中添加一个用户态的异步过程调用(APC)工具”。

函数原型与参数解释如下所示。

DWORD WINAPI QueueUserAPC(

因此,如果不想创建我们自己的线程,我们可以调用“QueueUserAPC()”函数来挟制目标/远程进程中一个已存在的线程;即,调用该函数将在指定线程的APC行列步队中添加一个异步过程调用。

我们可以利用一个真实的APC回调函数,而不该用“LoadLibrary()”。
事实上参数可以是指向我们想要注入的DLL文件名称的指针,详细代码如下所示。

DWORD dwResult = QueueUserAPC((PAPCFUNC)pfnThreadRtn, hThread, (ULONG_PTR)pszLibFileRemote);

如果你想试用这种技能,那么有一点你可能把稳到了,即它与微软Windows操作系统实行APC的办法有关。
没有能够查看APC行列步队的调度器,这意味着只有线程设置成可唤醒模式才能够检讨行列步队。

因此,我们基本上挟制每一个单独的线程,详细代码如下所示。

BOOL bResult = Thread32First(hSnapshot, &threadEntry);

这样做的情由紧张是期望个中一个线程会被设为可唤醒模式。

其余,利用“双脉冲星”(网址:https://countercept.com/our-thinking/doublepulsar-usermode-analysis-generic-reflective-dll-loader/,DOUBLEPULSAR 用户模式剖析:通用反射DLL加载器)工具剖析学习这项技能,是个很好的办法。

完全代码请参阅源文件“t_QueueUserAPC.cpp”。

(4)SetWindowsHookEx()

利用这项技能的紧张事情是,我们须要理解在微软Windows操作系统中挟制的事情事理。
实质上,挟制技能是拦截并干预事宜的一种办法。

正如你所猜想的那样,有很多种不同类型的挟制技能。
最通用的一种可能是WH_KEYBOARD和WH_MOUSE拦截;没错,它们可被用于监控键盘与鼠标的输入。

函数“SetWindowsHookEx()”将一个运用程序定义的拦截例程安装到一个拦截链表中。
函数原型和参数定义如下所示。

HHOOK WINAPI SetWindowsHookEx(

MSDN中有一段很有趣的备注如下:

“SetWindowsHookEx函数可被用于向另一个进程注入DLL文件。
一个32位的DLL文件不能注入一个64位的进程,反之亦然。
如果一个运用程序须要在其他进程中利用挟制技能,那么就哀求一个32(64)位的运用程序调用SetWindowsHookEx函数来将一个32(64)位的DLL文件注入到一个32(64)位的进程中。
32位和64位DLL文件的名称必须不同。

记住以上内容。

以下代码是实现的简要过程。

GetWindowThreadProcessId(targetWnd, &dwProcessId)

我们须要理解的是,每一个发生的事宜都要遍历拦截链表,该链表包含一系列相应事宜的例程。
“SetWindowsHookEx()”函数的设置事情基本上便是如何将我们自己的拦截例程植入拦截链表中。

以上代码用到了待安装的挟制类型(WH_KEYBOARD)例程指针,包含例程的DLL模块句柄,以及挟制所关联的线程标识号。

为了获取例程指针,我们须要首先调用“LoadLibrary()”函数加载DLL文件,然后调用“SetWindowsHookEx()”函数,并等待我们所需的事宜发生(本文中该事宜是指按键);一旦事宜发生我们的DLL就会被实行。

把稳,正如我们在维基解密(网址:https://wikileaks.org/ciav7p1/cms/page_6062133.html)中所看到的,就连联邦调查局的职员也有可能用到“SetWindowsHookEx()”函数。

完全代码请参阅源文件“t_SetWindowsHookEx.cpp”。

(5)RtlCreateUserThread()

“RtlCreateUserThread()”是一个未公开的API函数。
它的设置事情险些和“CreateRemoteThread()”函数相同,相应的也和“NtCreateThreadEx()”函数相同。

实际上,“RtlCreateUserThread()”调用“NtCreateThreadEx()”,这意味着“RtlCreateUserThread()”是“NtCreateThreadEx()”的一个小型封装函数;因此,这个函数并没有新的内容。
然而,我们可能只是纯挚地想利用“RtlCreateUserThread()”而不用“NtCreateThreadEx()”。
哪怕之后发生变动,我们的“RtlCreateUserThread()”仍能正常事情。

正如你所知道的,不同于其他工具,mimikatz工具和Metasploit平台都用到了“RtlCreateUserThread()”。
如果你对此感兴趣,请参阅网址:https://github.com/gentilkiwi/mimikatz/blob/d5676aa66cb3f01afc373b0a2f8fcc1a2822fd27/modules/kull_m_remotelib.c#L59和网址:https://github.com/rapid7/meterpreter/blob/6d43284689240f4261cae44a47f0fb557c1dde27/source/common/arch/win/remote_thread.c。

因此,如果mimikatz工具和Metasploit平台都利用“RtlCreateUserThread()”函数,那么(是的,他们理解自己的处理工具)屈服他们的“建议”,利用“RtlCreateUserThread()”;特殊是你操持做一项比较于大略的“injectAllTheThings”工程来说更负责的项目。

完全代码请参阅源文件“t_RtlCreateUserThread.cpp”。

(6)SetThreadContext()

实际上这是一种非常酷的方法:通过在目标/远程进程等分配一块内存区域,向目标/远程进程注入一段特殊布局的代码,这段代码的用场是加载DLL模块。

以下是32位环境下的代码。

0x68, 0xCC, 0xCC, 0xCC, 0xCC, // push 0xDEADBEEF (为返回地址占位)

对付64位环境,实际上我没有找到任何完全的事情代码,因此我大略写了我自己的代码,如下所示。

0x50, // push rax (保存RAX寄存器)

在我们想目标进程注入这段代码之前,以下占位符须要修正添补:

·返回地址(代码桩实行完毕之后,线程规复应回到的地址)

·DLL路径名称

·LoadLibrary()函数地址

而这也是进行挟制,挂起,注入和规复线程这一系列操作的机遇。

我们须要附加到目标/远程进程,之后当然是在目标/远程进程等分配内存。
把稳,我们须要以读写权限分配内存,以便操作DLL路径名称和用于加载DLL文件的封装代码。
详细代码如下所示。

LPVOID lpDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

之后,我们须要获取一个运行于目标/远程进程之上的线程高下文(即我们将要注入封装代码的目标线程)。

我们调用函数“getThreadID()”来找到线程,你可以在文件“auxiliary.cpp”中找到该函数。

有了线程标识号之后,我们须要设置线程高下文。
详细代码如下所示。

hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, threadID);

然后,我们须要挂起线程来获取其高下文;一个线程的高下文是指其寄存器的状态,我们格外关注的是EIP/RIP寄存器(根据须要也可以称其为IP——instruction pointer,指令指针)。

由于线程已被挂起,以是我们可以改变EIP/RIP寄存器的值,掌握线程在不同的路径上(我们的代码区域)连续实行。
详细代码如下所示。

ctx.ContextFlags = CONTEXT_CONTROL;

因此,我们中断线程,获取高下文,并从高下文中提取EIP/RIP值;保存的旧值用于在注入代码实行完成时规复线程的实行流程。
新的EIP/RIP值设置为我们注入的代码位置。

然后我们用返回地址,DLL路径名称地址和“LoadLibrary”函数地址添补所有的占位符。

线程开始实行的时候,我们的DLL文件将被加载;而当注入代码实行完成时,实行流程将返回县城挂出发点,并从此规复线程的正常实行流程。

如果你想要调试这种技能方法来学习练习,以下是操作流程。
启动你想要注入的运用程序,在此我们以“notepad.exe”为例。
利用“x64dbg”调试工具来运行“injectAllTheThings_64.exe”,如下图所示。

利用以下命令(根据你的实际环境来调度)。

\"大众C:\Users\rui\Documents\Visual Studio 2013\Projects\injectAllTheThings\bin\injectAllTheThings_64.exe\"大众 -t 6 notepad.exe \"大众c:\Users\rui\Documents\Visual Studio 2013\Projects\injectAllTheThings\bin\dllmain_64.dll\"大众

在调用“WriteProcessMemory()”函数处设下断点,如下图所示。

连续运行程序,当运行到断点处时,把稳寄存器RDX中的内存地址,如图所示。
如果你对为什么这里须要关注RDX有疑问,请去查阅x64环境下的调用约定;搞清楚再回来连续学习。

单步步过(快捷键F8)调用“WriteProcessMemory()”函数的过程,开启x64dbg工具的另一个实例,并将其附加到“notepad.exe”进程通过快捷键“Ctrl+g”调到之前复制的地址(即RDX寄存器中的内存地址)处,你将看到我们的代码区域程序集,如下图所示。

很酷吧?现在在Shellcode代码起始处设下断点。
转向“injectAllTheThings”调试进程,并运行程序。
我们的断点被成功断下,如下图所示;现在我们可以步过代码,并剖析这段代码的功能。

当我们调用“LoadLibrary()”函数时,我们的DLL文件成功加载,如下图所示。

太棒了~

我们的Shellcode代码将返回到之前保存的RIP地址处,“notepad.exe”进程将规复实行。

完全代码请参阅源文件“t_suspendInjectResume.cpp”。

(7)反射DLL注入

我将StepheFewer(这项技能的先驱)的代码也整合到了这个“injectAllTheThings”工程中,同时还构建了一个反射DLL文件用于这项技能。
把稳,我们要注入的DLL文件必须利用适当的包含和选项来进行编译,这样它才能与反射DLL注入技能相匹配。

反射DLL注入技能通过将全体DLL文件复制到内存中的办法来生效,因此它避免了向进程注册DLL模块这一行为。
所有的繁琐事情都已完成。
要在DLL模块加载到内存时获取其入口点,我们只须要利用Stephen

Fewer的代码;他的工程中所包含的“LoadRemoteLibrary()”函数为我们完成这项事情。
我们利用“GetReflectLoaderOffset()”函数来确定在我们进程内存中的偏移,然后我们将偏移加上目标/远程进程(即我们写入DLL模块的进程)的内存基址,将该结果作为实行起始点。

太繁芜?好吧,可能有点儿;以下是实现上述过程的4个紧张步骤。

1.将DLL文件头部写入内存

2.将每个区块写入内存(通过解析区块表)

3.检讨输入表,并加载任何引用的DLL文件

4.调用DLLMain函数的入口点

比较于其他方法,这种技能有很好的暗藏性,紧张被用于Metasploit平台。

如果你想要理解更多,请前往官方GitHub库;还想要阅读Stephen http://www.harmonysecurity.com/files/HS-P005_ReflectiveDllInjection.pdf

还可以参阅“MemoryModule”项目的作者Joachim Bauch所写的“从内存中加载DLL文件”,以及一篇好文章“不调用LoadLibrary()函数‘手动’加载32位/64位DLL文件”。

代码

还有一些模糊繁芜的注入方法,因此我未来将对“injectAllTheThings”工程进行更新。
个中某些最有趣的技能包括:

•“双脉冲星”工具所用到的技能

•网友@zerosum0x0所编写的工具,利用SetThreadContext()和NtContinue()实现的反射DLL注入,详细描述拜会网址:https://zerosum0x0.blogspot.co.uk/2017/07/threadcontinue-reflective-injection.html,可用代码详见网址:https://github.com/zerosum0x0/ThreadContinue。

以上我所描述的所有技能,都在一个单独的工程中实现了,我将其放在GitHub库中;个中还包括每种技能所需的DLL文件。
为了便于理解,下表大略先容了所实现的方法和详细用法。

须要解释的是,从安全角度出发,该当坚持利用injectAllTheThings_32.exe注入32位进程,或者injectAllTheThings_64.exe来注入64位进程;只管你也可以利用injectAllTheThings_64.exe来注入32位进程。
而实际上我并没有这样实现,但可能之后我会考试测验一下,详细请参考以下网址:http://blog.rewolf.pl/blog/?p=102。
参考网址中的技能基本上便是Metasploit平台上“smart_migrate”工具所用到的,详见网址:https://github.com/rapid7/meterpreter/blob/5e24206d510a48db284d5f399a6951cd1b4c754b/source/common/arch/win/i386/base_inject.c。

全体工程的代码(包括DLL文件)都在GitHub库中。
代码以32位/64位环境编译,包含或不包含调试信息都可以。

参考

本文由 看雪翻译小组 木无聊偶 编译 转载请注明来自看雪社区

标签:

相关文章