linux内核态提权漏洞挖掘

             linux内核态和用户态的区别。以IntelCPU为例,根据权限级别,Intel将CPU指令集操作的权限从高到低划分为4级:ring0(通常称为内核状态,cpu可以访问所有内存数据,包括硬盘、网卡、cpu等外设,也可以从一种程序切换到另一种程序)ring1(保留)ring2(保留)ring3(通常称为用户状态,只能访问有限的内存,不允许访问外围设备)内环越多,cpu的权限越高,内环可以随意访问外环资源,外环被禁止。因此,与用户状态的漏洞相比,内核状态的漏洞具有更强的破坏力,获得内核的权限基本相当于控制整个操作系统。

outputo-20220118-100238-185-wcxy.png

构建linux内核分析环境。

如果只是简单的构建内核分析调试环境,一般需要手动下载相应版本的内核并编译,从kernel官网下载。在这里,作者下载了4.19的内核版本,在编译和安装过程中可能会遇到模块丢失的问题。在ubuntu上使用apt安装相应的模块。作者本地手动安装的模块如下:首先,使用makemen生成默认的config文件,这是一个图形配置,可以在kernelhacking选项中使用一些调试选项,更好地分析kernel上的漏洞。然后使用make命令进行编译。当然,这只是一个默认的编译选项。编译linux内核有很多选择。感兴趣的学生可以参考Linuxinsides。默认编译将生成多个文件,包括vmlinux、system.map、bzimage等文件。这里主要关注bzimage文件,因为它是一个可加载的内核镜像文件,x86架构默认生成于arch/x86/boot目录。一般来说,ctf题目会给出三个文件,如相应的内核镜像文件、启动脚本、根文件系统等。通过这三个文件,整个操作系统通过qemu加载,便于后续分析和调试。

接下来需要编译文件系统了,这里使用busybox进行编译,下载好源码后,通过make menuconfig控制编译选项,在build options选择static binary,接下来执行make install可在当前目录生成一个_install目录,保存着编译后的文件,之后通过下面的脚本对系统运行时所需内容进行初始化,需在_install目录下进行


#!/bin/sh

mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin}}

echo """#!/bin/sh

mount -t proc none /proc

mount -t sysfs none /sys

mount -t debugfs none /sys/kernel/debug

mkdir /tmp

mount -t tmpfs none /tmp

mdev -s 

exec /bin/sh""">>init

chmod +x init

接着切换到_install目录并使用压缩指令find . | cpio -o --format=newc > ../rootfs.cpio对_install目录下的所有内容进行打包,这样就可以通过bzImage以及rootfs.cpio两个文件使用qemu将整个内核运行起来。运行命令如下:

qemu-system-x86_64 -kernel ./bzImage -initrd ./rootfs.cpio -s -append "nokaslr"

这样一个简单的linux系统就运行起来了,通过-s 参数可以让gdb通过远程网络连接的方式对内核进行调试,break后gdb中断如下:此时已经可以对任意包含符号的函数下断点了,为了进行初步测试,这里在new_sync_read函数下断点,当有用户输入命令后则会触发,如下:这样一个基础的内核调试分析环境就已经搭建起来了。如何在内核环境中进行提权:

基本概念

用户

对于支持多任务的 Linux 系统来说,用户就是获取资源的凭证,本质上是其所划分权限的归属。

权限

权限用来控制用户对计算机资源(CPU、内存、文件等)的访问。

进程

进程是任何支持多道程序设计的操作系统中的基本概念。通常把进程定义为程序执行时的一个实例。实际上,是进程在帮助我们完成各种任务。用户执行的操作其实是带有用户身份信息的进程执行的操作。

进程权限

既然是进程在为用户执行具体的操作,那么当用户要访问系统的资源时就必须给进程赋予权限。也就是说进程必须携带发起这个进程的用户的身份信息才能够进行合法的操作。

分享: