IO_FILE 结构
IO_FILE 结构FILE 介绍FILE 在 Linux 系统的标准 IO 库中是用于描述文件的结构,称为文件流。 FILE 结构在程序执行 fopen 等函数时会进行创建,并分配在堆中。我们常定义一个指向 FILE 结构的指针来接收这个返回值。
FILE 结构定义在 libio.h 中,如下所示
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */#define _IO_file_flags _flags /* The following pointers correspond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ ...
House Of 系列简介
House Of 系列简介House Of SpiritHouse Of Spirit 是一种 fastbin attack ,通过利用 free 函数来释放一个 fake chunk,将地址 free 到堆的 bin 链中,然后实现对栈地址的读写实现WAA
保护检查
fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理
fake chunk 地址需要对齐, MALLOC_ALIGN_MASK
fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐
fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem
fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况
主要是:当前chunk的size(chunk->size),和下一个chunk的size(nextchunk->size)
利用条件
可以控制 free 的 ...
House of Orange
House of Orange前言House Of Orange 核心就是通过漏洞利用获得 free 的效果
这种操作的原理简单来说是当前堆的 top chunk 尺寸不足以满足申请分配的大小的时候,原来的 top chunk 会被释放并被置入 unsorted bin 中,通过这一点可以在没有 free 函数情况下获取到 unsorted bins
后续可以配合 unsorted bin attack 和 FSOP 获取 shell
利用条件
有堆溢出,可以修改 top chunk size
可以申请较大的空间
没有释放模块(看见程序没有 free,realloc等函数时,优先考虑打House Of Orange)
伪造的 top chunk size 的要求 :
0x0fe1、0x1fe1、0x2fe1、0x3fe
利用姿势
通过堆溢出修改 top chunk size为“0x0fe1”
申请“0x2000”的空间
版本影响
libc-2.23:可用打通
libc-2.24:增加了 vtable check,但仍然可以绕过
libc-2.27:完全失效
实战pwn450 ...
FSOP
FSOP介绍FSOP 是 File Stream Oriented Programming 的缩写,根据前面对 FILE 的介绍得知进程内所有的_IO_FILE 结构会使用_chain 域相互连接形成一个链表,这个链表的头部由_IO_list_all 维护。
进程中打开的所有文件结构体使用一个单链表来进行管理,即通过_IO_list_all进行管理,在fopen的分析中,我们知道了fopen是通过_IO_link_in函数将新打开的结构体链接进入_IO_list_all的,相关的代码如下:
1234fp->file._flags |= _IO_LINKED;...fp->file._chain = (_IO_FILE *) _IO_list_all;_IO_list_all = fp;
从代码中也可以看出来链表是通过FILE结构体的_chain字段来进行链接的。形成的链表如下图所示:
看到链表的操作,应该就大致猜到了FSOP的主要原理了。即通过伪造_IO_list_all中的节点来实现对FILE链表的控制以实现利用目的。通常来说一般是直接利用任意写的漏洞修改_IO_lis ...
编译内核驱动
编译内核驱动编译驱动这里我们来尝试编译一个驱动模块。驱动代码如下
123456789101112131415#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>MODULE_LICENSE("Dual BSD/GPL");static int ko_test_init(void) { printk("This is a test ko!\n"); return 0;}static void ko_test_exit(void) { printk("Bye Bye~\n");}module_init(ko_test_init);module_exit(ko_test_exit);
Makefile 文件如下
123456789obj-m += ko_test.oKDIR =/home/iromise/dev/kernel/linux-5.4. ...
内核安全基础知识
内核安全基础知识本节我们介绍 Linux kernel pwn 所需要的基础知识,你可以看作简易的《操作系统导论》课程。
Operating System Kernel操作系统内核(Operation System Kernel)本质上也是一种软件,可以看作是普通应用程式与硬件之间的一层中间层,其主要作用便是调度系统资源、控制 IO 设备、操作网络与文件系统等,并为上层应用提供便捷、抽象的应用接口。
操作系统内核实际上是我们抽象出来的一个概念,本质上与用户进程一般无二,都是位于物理内存中的代码 + 数据,不同之处在于当 CPU 执行操作系统内核代码时通常运行在高权限,拥有着完全的硬件访问能力,而 CPU 在执行用户态代码时通常运行在低权限环境,只拥有部分 / 缺失硬件访问能力。
这两种不同权限的运行状态实际上是通过硬件来实现的,因此这里我们开始引入新的一个概念——分级保护环。
hierarchical protection domains分级保护域(hierarchical protection domains)又被称作保护环,简称 Rings ,是一种将计算机不同的资源划 ...
内核安全利用
内核安全利用目的在 Linux 内核漏洞利用中,攻击者可能会有以下几个目的
提权,即获取到 root 权限。
泄露敏感信息。
DoS,即使得内核崩溃。
一般而言,攻击者的主要目的是提权。
Privilege Escalation内核提权指的是普通用户可以获取到 root 用户的权限,访问原先受限的资源。这里从两种角度来考虑如何提权
改变自身:通过改变自身进程的权限,使其具有 root 权限。
改变别人:通过影响高权限进程的执行,使其完成我们想要的功能。
https://en.wikipedia.org/wiki/Privilege_escalation
Change Self内核会通过进程的 task_struct 结构体中的 cred 指针来索引 cred 结构体,然后根据 cred 的内容来判断一个进程拥有的权限,如果 cred 结构体成员中的 uid-fsgid 都为 0,那一般就会认为进程具有 root 权限。
12345678910111213141516171819struct cred { atomic_t usage;#ifdef CONF ...
内核学习入门-CISCN2017_babydriver 复现
内核学习入门-CISCN2017_babydriver 复现附件题目附件可在此处下载。
题目给了三个文件,分别是:
boot.sh 启动脚本
bzImage 内核启动文件
rootfs.cpio 根文件系统镜像
尝试执行初始时,直接解压 babydriver.tar 并运行启动脚本:
123456# 解压mkdir babydrivertar -xf babydriver.tar -C babydriver# 启动cd babydriver ./boot.sh
但 KVM 报错,其报错信息如下所示:
12Could not access KVM kernel module: No such file or directoryqemu-system-x86_64: failed to initialize kvm: No such file or directory
使用以下命令查看当前 linux in vmware 支不支持虚拟化,发现输出为空,即不支持。
1egrep '^flags.*(vmx|svm)' /proc/cpuinfo
检查了一下物理机 ...
内核堆概述
内核堆概述类似于用户态进程中的堆(heap),内核也有着自己的一套动态内存管理机制,为了方便这里我们同样将内核中动态分配的内存称为 “堆”。
Linux kernel 将内存分为 页→区→节点 三级结构,主要有两个内存管理器—— buddy system 与 slab allocator,前者负责以内存页为粒度管理所有可用的物理内存,后者则向前者请求内存页并划分为多个较小的对象(object)以进行细粒度的内存管理。
页→区→节点三级结构这是一张十分经典的 Overview ,自顶向下是
节点(node,对应结构体 pgdata_list)
区(zone,对应结构体 zone,图上展示了三种类型的 zone)
页(page,对应结构体 page)
页(page)Linux kernel 中使用 page 结构体来表示一个物理页框,每个物理页框都有着一个对应的 page 结构体:
区(zone)在 Linux 下将一个节点内不同用途的内存区域划分为不同的 区(zone),对应结构体 struct zone:
节点(node)zone 再向上一层便是节点——Linux 将内存控制 ...
内核下载与编译
内核下载与编译首先,我们需要下载并编译内核。
下载内核我们可以从 https://www.kernel.org 下载想要的内核。根据 https://www.kernel.org/category/releases.html,我们可以知道内核主要有以下几种类别:
Prepatch
Mainline 主线
Stable 稳定的
Longterm 长期
这里我们选择长期支持版。
下面为了方便介绍,我们使用 5.4 版本,内核开发者会一直支持这个版本到 2025 年 12 月份。进一步地,我们选择 5.4 的最新版本 5.4.98(2021 年 2 月记录)。为了加速,我们可以选择就近的源来下载内核,这里使用清华源:https://mirrors.tuna.tsinghua.edu.cn/kernel/。
12curl -O -L https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.4.98.tar.xz &&\unxz linux-5.4.98.tar.xz
验证内核签名为了防止内核被恶意修改,在发布内核时 ...