在上一篇文章《驱动开发:内核中实现Dump进程转储》中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍VAD结构,该结构的全程是Virtual Address Descriptor即虚拟地址描述符,VAD是一个AVL自平衡二叉树,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个VAD节点,由一个MMVAD结构完整描述。
TEB结构一般位于fs:[0]的位置,其声明如下: typedef struct _NT_TEB { NT_TIB Tib; // 00h PVOID EnvironmentPointer; // 1Ch CLIENT_ID Cid; // 20h PVOID ActiveRpcInfo; // 28h PVOID ThreadL
前两次我们分别讲了sysmon的ring3与ring0的实现原理,但是当初使用的版本的是8.X的版本,最新的版本10.X的sysmon功能有所增加,经过分析代码上也有变化。比如增加DNS得功能,这个功能实现也很简单,就是ETW里获取Microsoft-Windows-DNS-Client得数据,但是本篇不讲这个,本续篇主要讲内核里的事件结构。
PEB结构(Process Envirorment Block Structure)其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。
/*************************************************************************************** * * 作者: Fypher [nmn714@163.com] * http://hi.baidu.com/nmn714 * * 时间: 2009/12/29 * * 模块: InjectRing3.c [sys module] * * 平台: Windows XP SP2 * *
微软在x64系统中推出了DSE保护机制,DSE全称(Driver Signature Enforcement),该保护机制的核心就是任何驱动程序或者是第三方驱动如果想要在正常模式下被加载则必须要经过微软的认证,当驱动程序被加载到内存时会验证签名的正确性,如果签名不正常则系统会拒绝运行驱动,这种机制也被称为驱动强制签名,该机制的作用是保护系统免受恶意软件的破坏,是提高系统安全性的一种手段。
InLoadOrderModuleList 成员保存了模块信息,而模块信息的结构为 _LDR_DATA_TABLE_ENTRY。
模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程运行后加载的模块,内核模块指的是内核中特定模块地址,本篇文章将实现一个获取驱动ntoskrnl.exe的基地址以及长度,此功能是驱动开发中尤其是安全软件开发中必不可少的一个功能。
在前面的文章中LyShark一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以监控进程线程创建为例,在Win10系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
在笔者上一篇文章《驱动开发:内核枚举Registry注册表回调》中我们通过特征码定位实现了对注册表回调的枚举,本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回调以及ThreadObCall线程回调,之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用结构体_OB_CALLBACK以及_OBJECT_TYPE所以放在一起来讲解最好不过。
好多开发者一直苦恼于如何在IE浏览器环境下,构建低延迟的RTSP或RTMP播放,对于RTSP流来说,好多公司通常的做法是把RTSP转RTMP,然后分发到RTMP服务器,然后服务器转http-flv出来,浏览器直接播放http-flv流,亦或通过flash控件直接播放RTMP流,还有就是,转hls流出来,缺点是hls流延迟更大。
在上一篇文章《内核中实现Dump进程转储》中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍VAD结构,该结构的全程是Virtual Address Descriptor即虚拟地址描述符,VAD是一个AVL自平衡二叉树,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个VAD节点,由一个MMVAD结构完整描述。
在有的时候.我们会需要对应句柄名字.以及句柄类型的名称. 以及它所对应的的ID. 因为每个系统不一样.所以每次都是不一样的. 有的时候我们就需要借助Pchunter等类似的 Ark工具查看句柄名字. 以及对应的类型.
首先,虽然本文是介绍IE浏览器下OCX控件播放RTSP或RTMP,但这种方式并不推荐,毕竟它只能用于IE浏览器环境下,局限太大,而且随着微软IE浏览器的更新,不确定后续支持情况。当然,话说回来,如果是在特定的使用场景下,只需要某些版本IE浏览器支持,但对延迟和稳定性要求非常高,OCX控件方式也不失为一个好的选择。
在笔者上一篇文章《驱动开发:内核取应用层模块基地址》中简单为大家介绍了如何通过遍历PLIST_ENTRY32链表的方式获取到32位应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数,本章将继续延申这个话题,并依次实现通用版GetUserModuleBaseAddress()取远程进程中指定模块的基址和GetModuleExportAddress()取远程进程中特定模块中的函数地址,此类功能也是各类安全工具中常用的代码片段。
包含的头文件 #include <ntifs.h> #include <ntstrsafe.h> 声明的API函数 NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process); NTKERNELAPI PPEB_EX PsGetProcessPeb(PEPROCESS Process); NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE I
在windows系统下.句柄是很常用的. 骚操作的方法可以通过句柄拷贝方式拷贝到另一个进程让其占用句柄.比如独占文件. 但是有时候比如驱动想删除文件.强删文件的时候就会用到句柄类型. 但是此时一般都是写死的.网上也很少相关资料.这里就介绍一下.怎么通过句柄获取指定句柄类型(任何内核对象 句柄都可以使用) 下面以文件举例
在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用ObSetHandleAttributes函数将特定句柄设置为可关闭状态,然后在调用ZwClose将其文件关闭,强制删除则是通过ObReferenceObjectByHandle在对象上提供相应的权限后直接调用ZwDeleteFile将其删除,虽此类代码较为普遍,但作为揭秘ARK工具来说也必须要将其分析并讲解一下。
在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用ObSetHandleAttributes函数将特定句柄设置为可关闭状态,然后在调用ZwClose将其文件关闭,强制删除则是通过ObReferenceObjectByHandle在对象上提供相应的权限后直接调用ZwDeleteFile将其删除。
内核层与应用层之间的数据交互是必不可少的部分,只有内核中的参数可以传递给用户数据才有意义,一般驱动多数情况下会使用SystemBuf缓冲区进行通信,也可以直接使用网络套接字实现通信,如下将简单介绍通过SystemBuf实现的内核层与应用层通信机制。
许久不写博客,甚至已经有些忘记格式该是如何的,本篇博文用于记录我在学习Windows安全时的一些知识点。
函数很简单.就4个参数. 参数已就是传个类型.代表你要查询什么类型.这个函数很强大.基本什么都是可以查询 参数2: 就是一个缓冲区.这个缓冲区是根据你查询的类型.当查询到数据.就会放到这个缓冲区.所以缓冲区可以接受你指定查询类型的数据.所以你想使用强转为一样的类型即可. 参数3: 缓冲区大小. 参数4: 返回大小
本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
上一篇我们介绍了CreateRemoteThread+LoadLibrary进行注入的技巧。但是这种方法实在是太过格式化,所以几乎所有的安全软件都会监控这种方法。所以HarmanySecurity的Stephen Fewer提出了ReflectiveDLL Injection,也就是反射DLL注入。
其实是python后台程序常用方法: C开发完成底层的功能,python直接把C当做python模块进行调用。
1.全局句柄表中只存储进程和线程对象,把PID/CID当作索引在全局句柄表中查找对应对象结构.
今天翻出一些今年前写的代码。其中一个是09年,我帮一个读研的同学写的一个“无公害恶意”程序。大致要求就是要实现自启动和自我隐藏。我使用的都是些简单的技术,只是实现自我隐藏稍微让我花费了点时间写算法。其实这个算法也很简单,就是大学时候写的从一个单向链表中删除一个元素。(转载请指明出处)
在笔者上一篇文章《内核RIP劫持实现DLL注入》介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过NtCreateThreadEx这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,NtCreateThreadEx函数最终会调用ZwCreateThread,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
在前面的文章《驱动开发:内核解析PE结构导出表》中我们封装了两个函数KernelMapFile()函数可用来读取内核文件,GetAddressFromFunction()函数可用来在导出表中寻找指定函数的导出地址,本章将以此为基础实现对特定SSDT函数的Hook挂钩操作,与《驱动开发:内核层InlineHook挂钩函数》所使用的挂钩技术基本一致,不同点是前者使用了CR3的方式改写内存,而今天所讲的是通过MDL映射实现,此外前者挂钩中所取到的地址是通过GetProcessAddress()取到的动态地址,而今天所使用的方式是通过读取导出表寻找。
反反调试 HandleCount清0 PointCount清0 Name替换 HandleTableEntry清0
本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用CreateRemoteThread直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过劫持EIP的方式实现,其实现原理可总结为,挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,并把相关的指令机器码和数据拷贝到里面去,然后直接修改目标进程EIP使其强行跳转到我们拷贝进去的相关机器码位置,执行相关代码后,然后再次跳转回来执行原始指令集。
在笔者上一篇文章《驱动开发:内核层InlineHook挂钩函数》中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能,此类功能的实现一般可在应用层进行,而驱动层只需要保留一个读写字节的函数即可,将复杂的流程放在应用层实现是一个非常明智的选择,与《驱动开发:内核实现进程反汇编》中所使用的读写驱动基本一致,本篇文章中的驱动只保留两个功能,控制信号IOCTL_GET_CUR_CODE用于读取函数的前16个字节的内存,信号IOCTL_SET_ORI_CODE则用于设置前16个字节的内存。
LyScript插件中提供了三种基本的堆栈操作方法,其中push_stack用于入栈,pop_stack用于出栈,而最有用的是peek_stack函数,该函数可用于检查指定堆栈位置处的内存参数,利用这个特性就可以实现,对堆栈地址的检测,或对堆栈的扫描等。
在驱动层(ring0)里执行应用层(ring3)代码,这是个老生常谈的技术,而且方法也挺多。
文章首发奇安信攻防社区:https://forum.butian.net/share/1361
上一部分已经讨论过,如何搭建开发和测试环境,以及如何初始化CEMAPI,再继续这一部分的讨论之前,我们先要澄清几个概念。第一个是会话(Seesion),相信开发网络应用的朋友都不陌生,为了提高通讯效率降低通讯开销,有时候我们需要再目标与本地之间创建一个通道,在通道创建之初,目标与本地先做一些列的响应和请求确认两边的身份,当通道建立以后,目标与本地之间的通讯过程中就不再涉及两边的身份确认,这通常目标与本地之间的建立的通道,通常被称作会话,也就是Session。在使用Cemapi读取短信之前,应用程序也需要与设备上的信息(邮件)系统之间建立一个Session,用以 确认双方的身份,这是采用Cemapi读取短信的第一步。第二个概念是短消息(邮件)仓库(MsgStore),在WM中,邮件和短消息是属于一个系统的,Session建立了与这个系统之间的连接,然后必须告诉系统,我们的程序是要对邮件功能进行操作,还是要对短信功能进行操作,通过调用相应的函数(后面会介绍),MsgStore会指向我们需要操作的短信或邮件的仓库上。第三个概念是信箱,或者叫文件夹(Folder),当获得了指向一个具体仓库的MsgStore以后,下一步就需要获取具体的信箱(文件夹)了,比如当程序确定了希望对收件箱还是发件箱进行操作以后,Folder将会指向我们想要操作的具体的信箱。
因为我们沙箱注入了一个DLL到了目标进程,并且Hook了一系列NtXX(NtOpenKey)函数,所以我们在注入的代码中是不能使用RegXX(RegOpenKey等)这类函数的。因为RegXX系列函数在底层使用了NtXX系列函数,如果在注入DLL执行Hook后的逻辑中使用了RegXX系列函数,将会导致递归调用的问题,就让程序产生“蛋生鸡,鸡生蛋”这样的“思考”,可是程序不知道停止,最终脑袋用完了就挂了。于是使用Nt函数实现我们曾经习惯使用的RegXX函数是必要的。(转载请指明出处)
当一个进程被保护的时候 比如无法获取其进程句柄权限 (OpenProcess) 或者无法获取内存读写访问权限的时候,则可以使用此方法来进行提权。
二、驱动 2.1.hello world 1.创建项目 2.删除Driver Files里面的helloworld.inf文件 3.右键属性 Inf2Cat->General->Run Inf2Cat 改成否 Driver Settings->General->Traget OS VERSION和Target Platform改成对一个的平台 C/C++ -->常规->警告等级改为3,将警告视为错误改成否 C/C++ -->代码生成-->Spectre Mitigation改为Disabled 4.hell
# "这段代码来自于一个很简单的场景: 在python中调一个程序。给这个程序设置一个timeout 假如一段时间程序还没有返回,就杀掉这个这个新开的进程。" import ctypes import sys TH32CS_SNAPPROCESS = 0x00000002 class PROCESSENTRY32(ctypes.Structure): fields = [("dwSize", ctypes.c_ulong), ("cntUsage", ctypes
领取专属 10元无门槛券
手把手带您无忧上云