LyShark®

信息安全电子刊物出版品牌

还记得`《驱动开发:内核LoadLibrary实现DLL注入》`中所使用的注入技术吗,我们通过`RtlCreateUserThread`函数调用实现了注入DLL到应用层并执行,本章将继续探索一个简单的问题,如何注入`ShellCode`代码实现反弹Shell,这里需要注意一般情况下`RtlCreateUserThread`需要传入两个最重要的参数,一个是`StartAddress`开始执行的内存块,另一个是`StartParameter`传入内存块的变量列表,而如果将`StartParameter`地址填充为`NULL`则表明不传递任何参数,也就是只在线程中执行`ShellCode`代码,利用这个特点我们就可以在上一篇文章的基础之上简单改进代码即可实现驱动级后门注入的功能。

阅读全文 »

远程线程注入是最常用的一种注入技术,在应用层注入是通过`CreateRemoteThread`这个函数实现的,该函数通过创建线程并调用 `LoadLibrary` 动态载入指定的DLL来实现注入,而在内核层同样存在一个类似的内核函数`RtlCreateUserThread`,但需要注意的是此函数未被公开,`RtlCreateUserThread`其实是对`NtCreateThreadEx`的包装,但最终会调用`ZwCreateThread`来实现注入,`RtlCreateUserThread`是`CreateRemoteThread`的底层实现。

阅读全文 »

在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。

阅读全文 »

本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用`CreateRemoteThread`直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过劫持EIP的方式实现,其实现原理可总结为,挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,并把相关的指令机器码和数据拷贝到里面去,然后直接修改目标进程EIP使其强行跳转到我们拷贝进去的相关机器码位置,执行相关代码后,然后再次跳转回来执行原始指令集。

阅读全文 »

在笔者上篇文章`《驱动开发:内核扫描SSDT挂钩状态》`中简单介绍了如何扫描被挂钩的SSDT函数,并简单介绍了如何解析导出表,本章将继续延申PE导出表的解析,实现一系列灵活的解析如通过传入函数名解析出函数的RVA偏移,ID索引,Index下标等参数,并将其封装为可直接使用的函数,以在后期需要时可以被直接引用,同样为了节约篇幅本章中的`LoadKernelFile()`内存映射函数如需要使用请去前一篇文章中自行摘取。

阅读全文 »

在笔者上一篇文章`《驱动开发:内核实现SSDT挂钩与摘钩》`中介绍了如何对`SSDT`函数进行`Hook`挂钩与摘钩的,本章将继续实现一个新功能,如何`检测SSDT`函数是否挂钩,要实现检测`挂钩状态`有两种方式,第一种方式则是类似于`《驱动开发:摘除InlineHook内核钩子》`文章中所演示的通过读取函数的前16个字节与`原始字节`做对比来判断挂钩状态,另一种方式则是通过对比函数的`当前地址`与`起源地址`进行判断,为了提高检测准确性本章将采用两种方式混合检测。

阅读全文 »

在前面的文章`《驱动开发:内核解析PE结构导出表》`中我们封装了两个函数`KernelMapFile()`函数可用来读取内核文件,`GetAddressFromFunction()`函数可用来在导出表中寻找指定函数的导出地址,本章将以此为基础实现对特定`SSDT`函数的`Hook`挂钩操作,与`《驱动开发:内核层InlineHook挂钩函数》`所使用的挂钩技术基本一致,不同点是前者使用了`CR3`的方式改写内存,而今天所讲的是通过`MDL映射`实现,此外前者挂钩中所取到的地址是通过`GetProcessAddress()`取到的动态地址,而今天所使用的方式是通过读取导出表寻找。

阅读全文 »

本章将继续探索内核中解析PE文件的相关内容,PE文件中FOA与VA,RVA之间的转换也是很重要的,所谓的FOA是文件中的地址,VA则是内存装入后的虚拟地址,RVA是内存基址与当前地址的相对偏移,本章还是需要用到`《驱动开发:内核解析PE结构导出表》`中所封装的`KernelMapFile()`映射函数,在映射后对其PE格式进行相应的解析,并实现转换函数。

阅读全文 »

在笔者上一篇文章《驱动开发:内核解析PE结构导出表》介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中LyShark封装实现了KernelMapFile()内存映射函数,在之后的章节中这个函数会被多次用到,为了减少代码冗余,后期文章只列出重要部分,读者可以自行去前面的文章中寻找特定的片段。

阅读全文 »

在笔者的上一篇文章`《驱动开发:内核特征码扫描PE代码段》`中`LyShark`带大家通过封装好的`LySharkToolsUtilKernelBase`函数实现了动态获取内核模块基址,并通过`ntimage.h`头文件中提供的系列函数解析了指定内核模块的`PE节表`参数,本章将继续延申这个话题,实现对PE文件导出表的解析任务,导出表无法动态获取,解析导出表则必须读入内核模块到内存才可继续解析,所以我们需要分两步走,首先读入内核磁盘文件到内存,然后再通过`ntimage.h`中的系列函数解析即可。

阅读全文 »