首页 / Windows服务器 / Windows x86/ x64 Ring3层注入Dll总结

Windows x86/ x64 Ring3层注入Dll总结

0x01.前言   提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线程、Apc等等,这里我对Ring3层的Dll注入学习做一个总结吧。

0x01.前言

  提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线程、Apc等等,这里我对Ring3层的Dll注入学习做一个总结吧。

  我把注入的方法分成六类,分别是:1.创建新线程、2.设置线程上下背景文,修改寄存器、3.插入Apc队列、4.修改注册表、5.挂钩窗口消息、6.远程手动实现LoadLibrary。

  那么下面就开始学习之旅吧!

0x02.预备工作

  在涉及到注入的程序中,提升程序的权限自然是必不可少的,这里我提供了两个封装的函数,都可以用于提权。第一个是通过权限令牌来调整权限;第二个是通过ntdll.dll的导出的未文档化函数RtlAdjustPrivilege来调整权限。

  紧接着,既然我们要对目标进程注入Dll,那么获得目标进程的Id是不可或缺的吧,因为OpenProcess是肯定会使用的,这里我也提供了两种通过目标进程映像名称获得进程Id的方法。第一种是最常见的使用TlHelp创建系统的进程快照;第二种是借助Psapi枚举系列函数,不过这个方法我实现的有缺憾,32位下不能得到64位进程的Id。

  然后在比如插入Apc队列、挂起线程等等操作中,需要对目标进程的线程操作,所以获得线程Id也有必要,同样的我也提供了两种通过进程Id获得线程Id的方法。第一个仍然是使用TlHelp创建系统的线程快照,把所有的线程存入vector模板里(供Apc注入使用);第二个是利用ZwQuerySystemInformation大法,枚举系统进程信息,这个方法我只返回了一个线程Id,已经够用了。

  嗯,目前为止,预备工作差不多完工,那我们就开始正题吧!

0x03.注入方法一 — 创建新线程

  创建新线程,也就是在目标进程里,创建一个线程为我们服务,而创建线程的方法我找到的有三种:1.CreateRemoteThread;2.NtCreateThreadEx;3.RtlCreateUserThread。

  基本思路是:1.在目标进程内存空间申请内存;2.在刚申请的内存中写入Dll完整路径;3.创建新线程,去执行LoadLibrary,从而完成注入Dll。

  ps:这里直接使用从自己加载的kernel32模块导出表中获得LoadLibrary地址,是因为一般情况下,所有进程加载这类系统库在内存中的地址相同!

  因为只是创线程所使用的函数不一样,所以下面的代码随便放开一个创线程的步骤,屏蔽其他两个,都是可以成功的,这里我放开的是NtCreateThreadEx。

0x04.注入方法二 — 设置线程上下背景文

  设置线程上下背景文的主要目的是让目标进程的某一线程转去执行我们的代码,然后再回来做他该做的事,而我们的代码,就是一串由汇编硬编码组成的ShellCode。

  这串ShellCode做了三件事:1.传入Dll完整路径参数;2.呼叫LoadLibrary函数地址;3.返回原先的Eip或Rip。

  这里我选用的呼叫指令是ff 15 和 ff 25,在32位下为跳转到15(25)指令后面字节码对应地址里面存放的地址,在64位下15(25)指令后面四字节存放的是偏移,该跳转为跳转到换算出来的地址里面存放的地址,这里我把偏移写成0,以便于计算。

  整个注入过程由这些步骤组成:在目标进程申请内存(可执行内存) —> 填充ShellCode需要的地址码 —> 将ShellCode写入申请的内存 —> SuspendThread(挂起线程)—>GetThreadContext(获得线程上下背景文)—> 修改Context的Eip或Rip为ShellCode首地址 —> SetThreadContext(设置刚修改过的Context)—> ResumeThread(恢复线程执行)。

0x05.插入Apc队列

  Ring3层的Apc注入是不太稳定的,我的做法就是暴力的向目标进程的所有线程的UserMode Apc队列(线程有两个Apc队列:Kernel和User)上插入Apc对象,等待他去执行该Apc里注册的函数。而只有当线程处于alterable状态时,才会查看Apc队列是否有需要执行的注册函数。

  ps:正是因为不知道哪个线程会去处理Apc,所以感觉Ring3层Apc注入不如其他方法好使,不过Ring0层Apc注入还是比较稳定的。之前测试xp和win10都成功,win7下注explorer进程总是崩溃,后来意涟胩欤⑾直槔叱痰氖焙虼雍笸氨槔挪迦刖筒换岜览Orz

0x06.修改注册表

  注册表注入算得上是全局Hook了吧,毕竟新创建的进程在加载User32.dll时,都会自动调用LoadLibrary去加载注册表中某个表项键值里写入的Dll路径。

  我们关心的这个注册表项键是:HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindows,我们要设置的键值是AppInit_DLLs = “Dll完整路径”,LoadAppInit_Dlls = 1(让系统使用这个注册表项)

  ps:由于注入的Dll在进程创建的早期,所以在Dll中使用函数要格外小心,因为有的库可能还没加载上。

0x07.挂钩窗口消息

  挂钩窗口消息使用了MS提供的一个API接口SetWindowsHookEx,他的工作原理是给带窗口的目标进程的某个线程的某个消息挂钩上我们Dll导出的函数,一旦消息触发,则导出函数就会被调用。前面学习到的几种方法归根结底是调用了LoadLibrary,而这个方法并没有。

0x08.远程手动实现LoadLibrary

  该方法学习自github上名叫ReflevtiveDllInjection,大体上分为两个部分,exe和dll,下面分别简述。

  exe:作为注入启动程序,在目标进程申请一块儿PAGE_EXECUTE_READWRITE内存,将Dll以文件格式直接写入目标进程内存空间中,然后获得导出函数”LoadDllByOEP”在文件中的偏移,使用CreateRemoteThread直接让目标进程去执行LoadDllByOEP函数。

  Dll:最关键导出 LoadDllByOEP 函数,在该函数里,首先通过目标进程加载模块ntdll.dll的导出表中获得NtFlushInstructionCache函数地址,在Kernel32.dll的导出表中获得LoadLibraryA、GetProcAddress、VirtualAlloc函数地址;然后在进程内存空间里重新申请内存,拷贝自己的PE结构到内存里,接着修正IAT和重定向块,最后调用模块OEP,完成了手动实现LoadLibrary!

  ps:写代码时参考《Windows PE权威指南》,对整个PE结构又有了新的认识。我有for循环强迫症。。这份代码就全贴上了。

0x09.总结

  也许还有我没有学习到的Ring3注入Dll的方法,正所谓,路漫漫其修远兮,吾将上下而求索!

  奉上代码下载地址:https://github.com/YouArekongqi/InjectCollection.git

以上所述是小编给大家介绍的Windows x86/ x64 Ring3层注入Dll总结,希望对大家有所帮助!

本文来自网络,不代表我是攻城狮立场,转载请注明出处:https://www.54gcs.cn/os/windowsserver/12765.html

helwo作者

上一篇
下一篇

为您推荐

发表评论

联系我们

联系我们

在线咨询: QQ交谈

邮箱: web@5vo.cn

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

手机访问
手机扫一扫打开网站

手机扫一扫打开网站

返回顶部
跳至工具栏