因为你安全了,所以你危险了——空指针引用

简介: 1.本文章属于系列文章《因为你安全了,所以你危险了》中的第一篇2.本篇文章的作者是Gcow安全团队复眼小组的晏子霜,未经允许禁止转载3.本篇文章需要你对GDI子系统有一定了解,最好阅读过部分关于Windows显示驱动,打印机驱动,以及调色板这一块的源码.并对DDI函数有一定了解,以及编写Windows Kernel Exploit的能力

因为你安全了,所以你危险了——空指针引用

1.本文章属于系列文章《因为你安全了,所以你危险了》中的第一篇

2.本篇文章的作者是Gcow安全团队复眼小组的晏子霜,未经允许禁止转载

3.本篇文章需要你对GDI子系统有一定了解,最好阅读过部分关于Windows显示驱动,打印机驱动,以及调色板这一块的源码.并对DDI函数有一定了解,以及编写Windows Kernel Exploit的能力

(故对一些不涉及这领域或者刚刚入门这一领域的看官会有点吃力)

4.本篇文章一共1300字,图11张 预计阅读时间9分钟

5.该文章仅逆向ulAnimatePalette函数,但同样的思路在老版本Windows中可挖掘到多个空指针引用漏洞,均为Nday(不过修复也是一次性修复完毕)

0x00 前言

Windows Vista的时候,微软将打印机驱动从内核态移动到了用户态,这样可以解决相当一部分打印机驱动导致的漏洞,因为第三方开发的驱动的安全性有待提高.

这样做好处的显而易见的,减少了许多第三方开发的打印机驱动的漏洞,但是也带来了弊端,通过Hook图形设备驱动接口Or打印机驱动接口,为安全研究员们扩展了一个新的攻击面,这就有些得不偿失了.

因此本系列文章将从简入深的讲解多个由安全性提高转化成安全性”降低”的多个漏洞,其中包含但不限于(空指针引用,内存越界读写)

0x01 图形驱动

创建图形驱动程序必须要创建的函数如下

这些函数是必须要创建的,如果为空,则在内核中创建对象不可能成功.

通过CreateDC 指定名称可以创建一个关于打印机设备的上下文环境,我们阅读源码后发现他会回调打印机DDI函数中的DrvEnablePDEV,并传递了多个重要数据结构,我们可以Hook DrvEnablePDEV函数来修改函数执行过后的结果,当其返回内核时,我们即可控制函数的执行流程了.

不过在早期的Windows 中,安全性并没有现在这么高,很多安全保护都是不存在的,就比如说禁止用户态从0页分配内存,我们就可以利用他来达到本地权限提升的目的.

GreAnimatePalette函数分析

AnimatePalette函数置换指定逻辑调色板中的颜色项,在Win32k中该函数调用了实现函数XEPALOBJ::ulAnimatePalette来实现功能.

但是在早期的Windows7中,该函数存在空指针引用漏洞,利用该漏洞我们可以达到本地权限提升的目的.

我们可以使用用户态包装好的AnimatePalette函数来调用到GreAnimatePalette函数或者从ShaDownSSDT中搜素编号调用NtGdiDoPalette函数都可以执行到XEPALOBJ::ulAnimatePalette.

由于该函数是XEPALOBJ类中的函数,所以存在一个This指针,通常为ecx,此处也是一样,ecx保存着指向PALETTE结构的指针.

该函数首先判断了传入的iStart是否大于颜色项的总个数,如果大于则结束函数

接着判断iStart+ cEntry 是否大于cEntries,如果大于则将cEntry设置为cEntries-iStart.

判断是否为某个DC中的调色板,判断Palette.cRefhpal是否存在,不存在则跳出循环.

判断Palete->GdiInfo.flRaster & RC_PALETTE是否为真,如果为假,则跳出循环.

最后判断 Palete->ptransCurrent是否存在,如果不存在则跳出循环,存在则初始化两个局部变量,一个指向Palete->ptransCurrent,另外一个指向Palete->ptransCurrent->ajVector[iStart].

下面是个循环,大致意思就是从函数的第三个参数(ppalSrc)复制内容到Palette.pFirstColor[iStart]中,并且判断Palete->ptransCurrent是否为真,如果为真则读取Palete->ptransCurrent->ajVector[iStart]处的内容当作偏移,来写入到palSurf.pFirstColor[Palete->ptransCurrent->ajVector[iStart]]中.(写入内容为*ppalSrc)

结束循环后,函数会再次判断Palete->ptransCurrent 是否存在,Palete->GdiInfo.flRaster & RC_PALETTE是否为真以及判断Palete->fs& PDEV_DISABLED是否为假,如果为False,则会从PEDV->apfn[]表中寻找需要的函数函数并跳转执行.

是不是很熟悉PPFNDRV,这个上文是不是回调过DrvEnablePDEV,这里是要回调DrvSetPalette吗?

理论上来说是的,但是实际上来说,上文保存了一个必须创建图形驱动程序必须要创建的函数表,其中并没有DrvSetPalette,因为这个函数是可选的.

  • 问题来了,如果不存在这个函数,但是函数调用了他,会出现什么问题呢?
  • 答对了,空指针引用,在老版本Windows中并没有对函数指针是否正确进行验证,所以如果函数指针指向0,依然会Call过去,这样就造成了一个空指针引用的漏洞,我们只要在0处申请内存,填充代码,在同一进程上下文中即可触发该引用,让操作系统执行我们的代码.


相关文章
|
4月前
|
C++
C++野指针 空指针 危险指针
C++野指针 空指针 危险指针
|
4月前
|
Rust 安全 开发者
Rust的安全特性概览:守护内存安全与空指针的终结者
Rust作为一种系统级编程语言,以其独特的内存安全特性和对空指针的严格管理,为开发者提供了更加稳健和安全的编程环境。本文将对Rust的内存安全机制、空指针处理策略以及其他安全特性进行概览,旨在展示Rust如何帮助开发者构建更加安全和可靠的软件系统。
|
10月前
|
存储 安全 编译器
深入解析Go非类型安全指针:技术全解与最佳实践2
深入解析Go非类型安全指针:技术全解与最佳实践2
223 0
|
10月前
|
存储 Rust 安全
深入解析Go非类型安全指针:技术全解与最佳实践1
深入解析Go非类型安全指针:技术全解与最佳实践
194 0
|
11月前
|
存储 安全 Go
Golang 语言中的非类型安全指针
Golang 语言中的非类型安全指针
34 0
|
存储 编译器 Linux
危险的指针---字符指针和字符数组指针所导致的段错误
危险的指针---字符指针和字符数组指针所导致的段错误
115 0
|
安全 C++
C++指针的内存分配与内存安全
C++指针的内存分配与内存安全
132 0
|
安全
Post/Send Event传递指针的危险性分析(转自CSDN MAOXIAODONG)
        提前概括: Event传递数据时,处理不当极易发生Double Free,或者访问无效指针。而且非常难查,是隐藏的很深的, 主要原因是: BREW有自动释放应用上下文环境下分配的内存的默认行为!!!!         方法1:A创建数据(普通指针),并SendEvent给B:     虽然考虑以后的兼容性,仍然不建议使用。
949 0
|
安全 C++ 数据挖掘
安全编程-c++野指针和内存泄漏
摘要:   尽管C++ 野指针和内存泄漏一直被诟病,但是在实时性很强的应用场合,c++ 仍然是不二之选。游戏服务器开发仍然使用c++ 作为主语言,但是大多结合动态脚本技术,一方面规避了野指针和内存泄露,一方面获得了开发效率和扩展性的红利。
1035 0
|
9天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。