Linux漏洞挖掘与漏洞分析

       Linux内核最初采用宏内核结构,其基本特点是内核的所有操作都集中在可执行文件中。其优点是模块之间可以直接调用,无需通信,有效提高了内核的运行速度,但缺点是缺乏可扩展性。因此,Linux从2.6版本完善并引入了可装载内核模块(LKMS),可以在内核中加载独立的可执行模块,为扩展内核功能提供了极大的便利。可装载内核模块一般通过以下命令进行操作:装载内核模块的insmod。列出内核模块的lsmod。rmod卸载内核模块。

outputo-20220118-100328-915-jovb.png

在通常的服务器中,大多数服务器都有漏洞的核心模块。在渗透测试中,需要分析该模块并使用有针对性的漏洞。

保护机制

A.KASLR内核空间地址随机化,类似于用户层的ASLR。

b.stackprotector类似于用户层的stackcanary,在内核栈上添加cookie,防止内核栈溢出。

C.SMAP管理模式访问保护,禁止内核层访问用户数据。

d.SMEP管理模式执行保护,内核层禁止执行用户态代码。

E.MMAP_MIN_ADDRMAP函数可以申请的最小地址,空指针类型的漏洞无法使用。

F.KPTI内核页面隔离的主要目的是缓解cpu侧信道攻击和kaslr绕过。

用户与核心之间的交互。

syscall在用户空间与内核空间之间有一个中间层,称为syscall(系统调用,systemcall),是连接用户状态与内核状态的桥梁。这样既提高了内核的安全性,又方便移植,只需要实现同一个接口即可。在Linux系统中,用户空间通过向内核空间发送syscall产生软中断,使程序陷入内核状态并执行相应的操作。

本质上,b.iotcl也是一种系统调用,但它用于直接向驱动设备发送或接收指令和数据。

c.open、read、write可以通过访问文件来操作驱动,因为驱动设备被映射成文件。

漏洞类型

A.UNINITIALIZED/NONVALIDATED/CORUPTEDPOINTERERENCE内核空指针解引用。

b.MEMORYCORUPTION内核栈漏洞,内核堆漏洞。

C.INTEGERISUES(算术)整数溢出,符号转换问题。

d.RACECONDITIONSDOublefetch漏洞。

漏洞样例

这次使用空指针解引用的漏洞进行内核提升。虽然是空指针解引用,但实际上由于linux内核中的MMAP_MIN_ADDR缓解机制,用户层通过MMAP函数申请0地址失败,所以要调用的函数地址改为0x1万,用户层也可以控制这个地址,方便后面的漏洞利用。

首先,使用qemu启动相应的操作系统。在这里,由于默认busybox根文件系统无法通过adduser正常添加其他用户,笔者直接使用ubuntu16base作为根文件系统,并添加test用户,以便查看提权是否成功。启动系统后,通过insmod命令装载有漏洞的核心模块。

poc代码,编译后已提前放入文件系统目录,直接执行。此时可见已成功提权。

分享: