欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Windows PsSetLoadImageNotifyRoutine的0day漏洞

来源: 作者: 时间:2019-02-24 19:29 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

在研讨windows内核过程当中,咱们存眷了一个很感兴趣的内容,便是PsSetLoadImageNotifyRoutine,像他名字异样便是供给模块加载关照的。
工作是如许的,内核中为加载的PE文件注册了一个回调关照以后,可以或许会收到一个不法的模块名字。
在对这个成绩停止发掘以后,看起来是一个偶尔的成绩实在是由于windows内核自己的代码差错惹起的。
这个缺点存在于从Windows 2000到最新的Windows 10宣布版本的一切版本中。
长处:模块加载关照
假如你是个开辟驱动的安全厂商,你必要晓得体系甚么时刻加载了模块。经由过程Hook来实现,可以或许….然则可以或许会有许多安全和实现的缺点。
微软是这么先容windows2000的PsSetLoadImageNotifyRoutine的。这个机制会在一个PE文件被加载到虚构内存中(不论是内核态照样用户态)关照内核中注册过回调的驱动,。
深刻面前:
上面这几种情况会挪用到会地哦啊关照例程:
加载驱动
启动新过程(过程可执行文件/体系DLL:ntdll.dll(对付Wow64过程会有两种分歧的文件))
静态加载PE镜像-导入表,LoadLibrary,LoadLibraryEx,NtMapViewOfSection

图1:在ntoskrnl.exe中一切对PsSetLoadImageNotifyRoutine的挪用
在挪用已注册的关照回调时,内核供给一些参数来准确标志加载的PE镜像。参数可以或许看上面的回调函数原型界说:
1
2
3
4
5
VOID (*PLOAD_IMAGE_NOTIFY_ROUTINE)(
_In_opt_ PUNICODE_STRING FullImageName, // The image name
_In_ HANDLE ProcessId, // A handle to the process the PE has been loaded to
_In_ PIMAGE_INFO ImageInfo // Information describing the loaded image (base address, size, kernel/user-mode image, etc)
);
独一的前途:
现实上,这是WDK文档化的独一用于监督PE加载到内存的的办法。
别的一种微软保举的办法,是应用文件体系mini-filter回调(IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION)。NtCreateSection为了可以或许辨别section object能否是一个加载的可执行镜像的一部分,会反省能否存在SEC_IMAGE标志。但是,文件体系mini-filter不会接管这个标志,是以不克不及辨别section object能否是加载PE镜像创立的。
缺点:差错的模块参数
独一标志加载的PE文件的参数是FullImageName。
但是,在前面描写的一切场景中,内核应用的别的一种格局的FullImageName。
第一看的时刻,咱们留意到获得过程可执行文件全门路和体系DLL的情况变量(没有卷名)时,其余静态加载的用户态PE供给的门路也没有卷名。
更让人担心的是不仅是门路没有了卷名,有时刻门路完备是畸形的,可以或许指向了一个分歧的或许不存在的文件。
RTFM
和一切研讨职员/开辟职员异样,咱们做的第一件事便是去看文档,包管对这个器械懂得准确了。
依据MSDN的描写,FullImageName表现文件在磁盘的门路,用来标志可执行文件。没有提到可以或许存在不合法或许不存在的门路。
文档中进步了门路可以或许是空:在过程创立时代假如操纵体系无奈获得镜像的完备门路,这个参数可以或许为空。也便是说,假如这个参数不是空的,那末内核就会觉得这是准确的参数而接管。
甚于拼写差错的文档
细心浏览文档是,咱们留意到另外一件事,MSDN中表现的函数原型是差错的。参数Create依据描写完备像是跟这个机制没有关系,在WDK中的函数原型完备没有这个参数。很讥讽的便是,应用MSDN供给的原型会招致栈溢出瓦解。
面纱的上面
nt!PsCallImageNotifyRoutines会挪用已注册回调函数的。它仅仅是将它挪用者传来的UNICODE_STRING指针作为FullImageName参数传给回调函数。在nt!MiMapViewOfImageSection映照一个image的section时,UNICODE_STRING是section表现的FILE_OBJECT的FileName字段。

图2 传给回调的FullImageName现实是FILE_OBJECT的FileName字段
FILE_OBJECT经由过程SECTION->SEGMENT->CONTROL_AREA来获得。这些都是外部未文档的内核布局体。内存治理器在映照文件到内存中的时刻创立了这些布局,只需文件曾经映照了,都邑在外部应用这些布局。

图3 挪用nt!PsCallImageNotifyRoutines以前nt!MiMapViewOfImageSection获得FILE_OBJECT
每个映照的镜像只有一个SEGMENT。意味着异样一个镜像在同一个过程当中或许跨过程间同时存在的多个section会应用同一个SEGMENT和CONTROL_AREA。这就说明了为何FullImagename在同一个PE文件同时加载到分歧过程可以或许作为PE文件的标志了。

图4 文件映照外部布局(简化版)
继承RTFM
为了弄明确FileName是若何设置和治理的,咱们回到文档中,发明MSDN制止应用它。由于这个值只在初始化过程的IRP_MJ_CREATE哀求时是有用的,在文件体系开端处置IRP_MJ_CREATE哀求时不考虑是有用的值,然则在文件体系处置完IPR_MJ_CREATE以后FILE_OBJECT确切在应用它。
很显著,NTFS驱动领有这个UNICODE_STRING(FILE_OBJECT.FileName)的一切权
应用内核调试器调试中,咱们发明ntfs!NtfsUpdateCcbsForLcbMove 是卖力重命名的一个操纵。在看这个函数时咱们揣摸出在IRP_MJ_CREATE哀求中文件体系驱动只是创立了一个FILE_OBJECT.FileName的浅拷贝,而后零丁保护它。这也就意味着只是拷贝了buffer的地点,而没有拷贝内容。

[1] [2]  下一页

在研讨windows内核过程当中,咱们存眷了一个很感兴趣的内容,便是PsSetLoadImageNotifyRoutine,像他名字异样便是供给模块加载关照的。
工作是如许的,内核中为加载的PE文件注册了一个回调关照以后,可以或许会收到一个不法的模块名字。
在对这个成绩停止发掘以后,看起来是一个偶尔的成绩实在是由于windows内核自己的代码差错惹起的。
这个缺点存在于从Windows 2000到最新的Windows 10宣布版本的一切版本中。
长处:模块加载关照
假如你是个开辟驱动的安全厂商,你必要晓得体系甚么时刻加载了模块。经由过程Hook来实现,可以或许….然则可以或许会有许多安全和实现的缺点。
微软是这么先容windows2000的PsSetLoadImageNotifyRoutine的。这个机制会在一个PE文件被加载到虚构内存中(不论是内核态照样用户态)关照内核中注册过回调的驱动,。
深刻面前:
上面这几种情况会挪用到会地哦啊关照例程:
加载驱动
启动新过程(过程可执行文件/体系DLL:ntdll.dll(对付Wow64过程会有两种分歧的文件))
静态加载PE镜像-导入表,LoadLibrary,LoadLibraryEx,NtMapViewOfSection copyright 无奈人生

图1:在ntoskrnl.exe中一切对PsSetLoadImageNotifyRoutine的挪用
在挪用已注册的关照回调时,内核供给一些参数来准确标志加载的PE镜像。参数可以或许看上面的回调函数原型界说:
1
2
3
4
5
VOID (*PLOAD_IMAGE_NOTIFY_ROUTINE)(
_In_opt_ PUNICODE_STRING FullImageName, // The image name
_In_ HANDLE ProcessId, // A handle to the process the PE has been loaded to
_In_ PIMAGE_INFO ImageInfo // Information describing the loaded image (base address, size, kernel/user-mode image, etc)
);
独一的前途:
现实上,这是WDK文档化的独一用于监督PE加载到内存的的办法。
别的一种微软保举的办法,是应用文件体系mini-filter回调(IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION)。NtCreateSection为了可以或许辨别section object能否是一个加载的可执行镜像的一部分,会反省能否存在SEC_IMAGE标志。但是,文件体系mini-filter不会接管这个标志,是以不克不及辨别section object能否是加载PE镜像创立的。 内容来自无奈安全网
缺点:差错的模块参数
独一标志加载的PE文件的参数是FullImageName。
但是,在前面描写的一切场景中,内核应用的别的一种格局的FullImageName。
第一看的时刻,咱们留意到获得过程可执行文件全门路和体系DLL的情况变量(没有卷名)时,其余静态加载的用户态PE供给的门路也没有卷名。
更让人担心的是不仅是门路没有了卷名,有时刻门路完备是畸形的,可以或许指向了一个分歧的或许不存在的文件。
RTFM
和一切研讨职员/开辟职员异样,咱们做的第一件事便是去看文档,包管对这个器械懂得准确了。
依据MSDN的描写,FullImageName表现文件在磁盘的门路,用来标志可执行文件。没有提到可以或许存在不合法或许不存在的门路。
文档中进步了门路可以或许是空:在过程创立时代假如操纵体系无奈获得镜像的完备门路,这个参数可以或许为空。也便是说,假如这个参数不是空的,那末内核就会觉得这是准确的参数而接管。
甚于拼写差错的文档
细心浏览文档是,咱们留意到另外一件事,MSDN中表现的函数原型是差错的。参数Create依据描写完备像是跟这个机制没有关系,在WDK中的函数原型完备没有这个参数。很讥讽的便是,应用MSDN供给的原型会招致栈溢出瓦解。
面纱的上面 内容来自无奈安全网
nt!PsCallImageNotifyRoutines会挪用已注册回调函数的。它仅仅是将它挪用者传来的UNICODE_STRING指针作为FullImageName参数传给回调函数。在nt!MiMapViewOfImageSection映照一个image的section时,UNICODE_STRING是section表现的FILE_OBJECT的FileName字段。

图2 传给回调的FullImageName现实是FILE_OBJECT的FileName字段
FILE_OBJECT经由过程SECTION->SEGMENT->CONTROL_AREA来获得。这些都是外部未文档的内核布局体。内存治理器在映照文件到内存中的时刻创立了这些布局,只需文件曾经映照了,都邑在外部应用这些布局。

图3 挪用nt!PsCallImageNotifyRoutines以前nt!MiMapViewOfImageSection获得FILE_OBJECT
每个映照的镜像只有一个SEGMENT。意味着异样一个镜像在同一个过程当中或许跨过程间同时存在的多个section会应用同一个SEGMENT和CONTROL_AREA。这就说明了为何FullImagename在同一个PE文件同时加载到分歧过程可以或许作为PE文件的标志了。

内容来自无奈安全网



图4 文件映照外部布局(简化版)
继承RTFM
为了弄明确FileName是若何设置和治理的,咱们回到文档中,发明MSDN制止应用它。由于这个值只在初始化过程的IRP_MJ_CREATE哀求时是有用的,在文件体系开端处置IRP_MJ_CREATE哀求时不考虑是有用的值,然则在文件体系处置完IPR_MJ_CREATE以后FILE_OBJECT确切在应用它。
很显著,NTFS驱动领有这个UNICODE_STRING(FILE_OBJECT.FileName)的一切权
应用内核调试器调试中,咱们发明ntfs!NtfsUpdateCcbsForLcbMove 是卖力重命名的一个操纵。在看这个函数时咱们揣摸出在IRP_MJ_CREATE哀求中文件体系驱动只是创立了一个FILE_OBJECT.FileName的浅拷贝,而后零丁保护它。这也就意味着只是拷贝了buffer的地点,而没有拷贝内容。
内容来自无奈安全网

[1] [2]  下一页 本文来自无奈人生安全网

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。