热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【技术分享】用户模式下基于异常和内核控制的线程级钩子技术分析

译者:WisFree预估稿费:200RMB投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿简介在这篇文章中,我们将会跟大家介绍我们在研究过程中所发现的一种新型的钩子(Hook)技术

http://p4.qhimg.com/t010d6febb7e8a70b7e.jpg

译者:WisFree

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


简介

在这篇文章中,我们将会跟大家介绍我们在研究过程中所发现的一种新型的钩子(Hook)技术。

Hook技术可以帮助我们了解并控制操作系统中每一部分软件组件的操作行为,使用了钩子技术的部分软件有:应用程序安全解决方案、系统应用工具、编程软件(例如用于拦截、调试和功能扩展的软件)、以及恶意软件(例如rootkit)等等。

钩子(Hook)是Windows消息处理机制的一个平台,应用程序可以在上面设置子进程/线程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,钩子可以在目标窗口处理函数之前对数据进行处理它,因为钩子机制允许应用程序截获处理window消息或特定事件。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

需要注意的是,本文所要介绍的内容并不涉及提权以及漏洞利用技术。本文所介绍的技术主要用于后渗透场景,即攻击者已经成功获取到目标设备控制权的情况。由于恶意内核代码(rootkit)一般都会尝试在目标系统中实现持久化感染,因此隐藏技术也逐渐开始扮演一种十分重要的角色了。


技术描述

我们给这项技术取名为BoundHook,BoundHook技术可以在用户模式场景中的特殊位置引发异常,然后通过捕捉异常来接管线程的执行。我们可以使用BOUND指令(Intel MPX内存保护扩展的一部分)来实现上述操作,这种指令原本的作用是通过检测指针引用来提升软件的安全性。简而言之,BOUND指令可以检测数组索引的越界情况(可能触发内存崩溃漏洞),如果测试失败则会引起软件中断。(32-bit: nt!KiTrap05, 64-bit: nt!KiBoundFault

你可能会问,为什么不对这两种操作指令进行一下对比呢?因为英特尔的技术人员在设计这种新型指令时故意生成了一个异常,并让操作系统来检查边界测试失败的情况。

http://p8.qhimg.com/t01fd64c890da1e3dc8.png

这种指令的语句如下所示:

BOUND r16, m16&16 – 检测r16(数组索引)是否越界(m16&16指定)

BOUND r32, m32&32 – 检测r32(数组索引)是否越界(m32&32指定)

当边界检查出现错误时,陷阱处理程序(trap handler)将会调用nt!KiHandleBound并执行已注册的边界异常回调程序。

内核模式驱动程序或者运行在内核模式下的shellcode payload可以使用nt!KeRegisterBoundCallback来为边界检测异常注册一个回调程序。需要注意的是,这个函数并不是WDK header“提供”的,而且这里还需要动态加载一个指向该函数的指针。

这种回调程序没有任何的参数,并且会返回一个BOUND_CALLBACK_STATUS(枚举类型),具体如下所示:

http://p4.qhimg.com/t01b211178e5d61d146.jpg

完成了边界异常的注册之后,内核模式代码会得到一个指向用户模式DLL基地址的指针,并计算出需要设置钩子的函数地址。

获取函数地址其实是一件非常简单的事情,而且可以通过多种方式去实现,例如通过解析PE头就可以。需要注意的是,解析一个某个特定进程所加载的图片则需要在进程环境中进行,或者使用特定的API。

当我们的代码计算出了函数地址之后,我们如果可以直接开始向这个地址写入数据就非常好了。但是,由于这部分代码存在于只读/可执行内存之中,我们就没办法做到这一点了。

Windows内存保护的实现主要依赖一下几个因素:

http://p2.qhimg.com/t01f96240896bc6c94e.png

现在我们就有几种选择了。我们可以想办法向这个地址写入数据来触发COW(copy-on-write)保护,或者使用__readcr0()和__writecr0()来修改CR0寄存器。除此之外,我们还可以分配我们的内存描述符列表(MDL)来描述内存页面,并使用按位或(bitwise OR)来调整MDL和MDL_MAPPED_TO_SYSTEM_VA的权限。最后这种方法相对来说更加“隐蔽”一些,因为根据当前PatchGuard实现的设计来看,这种方法是完全不可见的。

首先,我们给大家介绍如何修改CR0寄存器。CR-寄存器的描述如下所示(来源于Intel 64和IA-32软件架构开发人员手册):

”WP写入保护(16位CR0)-当设置时,将阻止高等级进程向只读页面中写入数据;当清空时,将允许高等级进程向只读页面中写入数据。“

下面是CR0寄存器的一个简单的修改样例:

http://p8.qhimg.com/t01f636db54fe72615a.png

如果可以直接向DLL的COW页面写入数据的话,我们就能够对操作系统中每一个使用了这个DLL的进程设置钩子,因为我们已经可以影响cow-origin页面了。

触发边界异常也是比较简单的,比如说,下面的代码将触发一次错误异常:

http://p7.qhimg.com/t01b53d58d9c27e42f0.png

因此,我们负责执行钩子的内核模式代码将能够向目标位置写入一个类似的汇编代码,并成功接管目标线程的执行过程。

比如说,如果我们想要挂钩KERNELBASE!CreateFileW,我们就可以将下面给出的这行操作码注入到该函数的起始位置:

UCHAR opcodes[5]= {0x36, 0x66, 0x62, 0x0C, 0x24};

你可以直接理解为:BOUND CX, DWORD PTR SS : [ESP]。在这种特殊场景下,我们假设CX为0(在真实的使用场景中,我们需要对每一个函数进行测试来决定这个值),而栈顶的值肯定大于0(这只是一个PoC,而并非最终的Exploit)。

现在,当我们将操作码写入进了KERNELBASE!CreateFileW之后,如果用户模式下的线程调用这个函数时,我们内核模式下的回调函数就能够完全接管这个用户模式下的线程了。

如果可以实现的话,那我们的优势就非常大了,比如说:

1.  挂钩的页面仍然是COW,因此反恶意软件解决方案以及研究人员所进行的手动分析将无法发现页面遭到了篡改。

2.  绝大多数反病毒产品不会检测到我们的这种技术,而且这个问题似乎无法解决,因为页面仍然是COW。

3.  用户模式调试器将无法捕捉到这种钩子。普通的内联钩子方法会让已挂钩的程序跳转到其他的用户模式代码,但BoundHook技术可以通过内核边界异常处理器来修改这种执行流程。

4.  绝大多数PatchGuard(PG)保护机制都无法察觉到我们的这种钩子技术。根据目前PG的设计原理,用本文所介绍的MDL方法绕过COW机制是不会被检测到的。对于修改CR0寄存器的方法来说,虽然CR0寄存器是受PG保护的,但PG发现这种修改操作的可能性也非常小,因为修改操作可以在非常短的时间内完成。

PoC-已挂钩的线程调用栈:

http://p9.qhimg.com/t0198abe493b265d724.png

总结

我们知道对于微软而言,BoundHook技术所利用的技术因素并不会被他们认为是一种安全漏洞,因为设备管理员权限已经被攻击者拿到了。在此之前,微软曾从CyberArk(GhostHook技术)那里收到了类似问题的报告,而微软对此的回应如下:

”我们已经对上报的安全问题进行了详细的分析和调查,并且发现这并不是一个真正意义上的安全漏洞,因为这只是一种用于躲避安全检测的技术,但设备此时已经被攻击者入侵了。你们所提交的是一种后渗透技术,而且并不符合我们的漏洞规定,因此我们无法针对该问题发布更新补丁,但我们会在将来的Windows版本中考虑解决这个问题。“

但不管怎么样,我认为我们所设计的这种技术可以给软件安全厂商以及恶意软件开发者提供一种新的思路,也希望微软能够尽快解决这个问题(虽然他们不认为这是一个安全漏洞)。


推荐阅读
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文介绍了编程语言的基本分类,包括机器语言、汇编语言和高级语言的特点及其优缺点。随后详细讲解了Python解释器的安装与配置方法,并探讨了Python变量的定义、使用及内存管理机制。 ... [详细]
  • 雨林木风 GHOST XP SP3 经典珍藏版 YN2014.04
    雨林木风 GHOST XP SP3 经典珍藏版 YN2014.04 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文详细探讨了BCTF竞赛中窃密木马题目的解题策略,重点分析了该题目在漏洞挖掘与利用方面的技巧。 ... [详细]
  • Vulnhub DC3 实战记录与分析
    本文记录了在 Vulnhub DC3 靶机上的渗透测试过程,包括漏洞利用、内核提权等关键步骤,并总结了实战经验和教训。 ... [详细]
  • 2019-2020学年 20174325 叶竞蔚 《网络对抗技术》实验六:Metasploit基础应用
    本实验旨在掌握Metasploit框架的基本应用方法,重点学习三种常见的攻击方式及其实施思路。实验内容包括一次主动攻击(如MS08-067)、一次针对浏览器的攻击(如MS11-050)以及一次针对客户端的攻击(如Adobe漏洞利用)。此外,还包括成功应用一个辅助模块。 ... [详细]
  • 从零开始编译Linux系统:第16章 全新起点
    本章将详细介绍如何从零开始编译一套完整的Linux系统,涵盖关键组件如glibc库的介绍及其重要性。通过本文,读者将了解从源代码构建Linux系统的全过程。 ... [详细]
  • 本文详细介绍了如何在PHP中使用Memcached进行数据缓存,包括服务器连接、数据操作、高级功能等。 ... [详细]
  • selenium通过JS语法操作页面元素
    做过web测试的小伙伴们都知道,web元素现在很多是JS写的,那么既然是JS写的,可以通过JS语言去操作页面,来帮助我们操作一些selenium不能覆盖的功能。问题来了我们能否通过 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • 在iOS开发中,多线程技术的应用非常广泛,能够高效地执行多个调度任务。本文将重点介绍GCD(Grand Central Dispatch)在多线程开发中的应用,包括其函数和队列的实现细节。 ... [详细]
  • 【线段树】  本质是二叉树,每个节点表示一个区间[L,R],设m(R-L+1)2(该处结果向下取整)左孩子区间为[L,m],右孩子区间为[m ... [详细]
author-avatar
马芷靈
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有