PAWNYABLE kernel stack overflow 笔记
PAWNYABLE 中的第一节 stack overflow 的学习笔记。( 觉得这个教程好细致,而且封面好可爱… 这一节讨论内核的栈溢出,分成了不同防护程度的情况来讨论不同的情况下面,攻击应该如何进行。
基本的思路
在 module_write 里面,copy_from_user 的大小是用户控制,大小没有检查的。可以在这里发生溢出。read 也有这个漏洞,可以读取更多的数据(
网鼎杯 2024 玄武 pwn2 (kernel)
setup 准备工作
void unshare_setup() {
char edit[0x100];
int tmp_fd;
// from lib pthread
unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWNET);
// from lib fcntl
tmp_fd = open("/proc/self/setgroups", O_WRONLY);
write(tmp_fd, "deny", strlen("deny"));
close(tmp_fd);
tmp_fd = open("/proc/self/uid_map", O_WRONLY);
sprintf(edit, "0 %d 1", getuid());
write(tmp_fd, edit, strlen(edit));
tmp_fd = open("/proc/self/gid_map", O_WRONLY);
snprintf(edit, sizeof(edit), "0 %d 1", getgid());
write(tmp_fd, edit, strlen(edit));
close(tmp_fd);
}
这个函数的目的是为当前进程配置新的名字空间,尤其是
mount
、user
和network
名字空间,确保进程在新的名字空间中有隔离的环境。此外,它通过设置 UID 和 GID 映射来确保进程在新的用户名字空间中以 root 用户身份 (UID 0) 运行,但在主机系统中仍保持原有的 UID 和 GID。这种做法通常用于容器技术或者其他需要进程隔离的场景。
L3HCTF 信じてください、先輩!!复现
前情提要
OPTEE 是什么
这题与 OPTEE 有关。可以理解成,这个机器上同时运行有两个 OS:一个是正常的 OS 来处理不需要保密的内容,一个是安全的 OS (OPTEE),涉及保密的内容在这个安全 OS 里面操作。通过 trusted firmware 来启动这两个 OS,相当于这两个 OS 的 bootloader。这两个系统之间的交互通过一些可信应用 trusted application 完成。
DASCTFxGFCTF ezvm&unwind&prese
ezvm
输入第一串字符串,生成新的 check.dll,然后用新的 check.dll 的 check 函数来验证 flag。
这个 vm 的流程大概是:
asisctf 2023 pwn nightjs 复现记录
关于赛题
asisctf2023 nightjs 附件 一道 js 引擎题目,基于 serenityOS 上做的改编。(感觉 serenity 作者很 强迫症 善良得写了很多注释,连一行赋值语句都有注释,读起来超级愉悦)。
偷看了别人的wp来复现。给了 patch 文件之后,查看修改处的函数被什么函数引用,漏洞点就很明了了。攻击流程不难,不记录了。不过第一次见到脚本语言引擎的题目,有一些磕磕绊绊,这里总结一下收获。
js 执行过程
serenity js
(和一般的脚本语言类似的)执行过程大概分为两个阶段:
- parce souce code to bytecode
- run bytecode 。
主要的处理部分在 parse_and_run
中。把源码解析成一个个字节码之后 run 的过程,其实就是找到每个 bytecode 对应的函数执行。
JS::Bytecode::Instruction::execute ()
涉及从 bytecode 找到对应 function 的逻辑(感觉写的好优雅哇)。以 bytecode CALL
来举例,其类型是 Instruction::Type::Call
所对应的函数是 JS::Bytecode::Op::Call::execute_impl()
。
tsctf-j2023 strange_code_runner e_order wp
googlectf2023 gradebook 复现(TOCTOU)
Gradebook 结构
根据函数 sub_2247 开头的部分可以推测出 gradebook 的结构
cpu 3 模式
按照 CPU 功能升级迭代的顺序,CPU 的工作模式有实模式、保护模式、长模式。他们的主要区别是寻址方式和指令权限。下文以 x86_64 为例
实模式
实模式寄存器
每个 16 bit 大小,可以分成 H 和 L 两个。下图的右半边的寄存器。
实模式寻址
-
寻址范围 8086 cpu 的地址总线有 20 位,所以寻址范围 2**20 = 1 MB(后续的 cpu 兼容了实模式的寻址方法)
-
寻址方式 寄存器 16 位,地址有 20 位,为了访问更高的内存引入了段式内存管理——8086CPU将1MB存储空间分成许多逻辑段,每个段最大限长为64KB(但不一定就是64KB)。这样每个存储单元就可以用“段基地址+段内偏移地址”表示段基地址由16位段寄存器值左移4位表达,段内偏移表示相对于某个段起始位置的偏移量。
实模式中断
保护模式
保护模式寻址
段机制 分页机制
逻辑地址———->线性地址————–>物理地址
和实模式直接把段基址放在寄存器当中的做法不一样。保护模式设置了 GDT 段描述符表,寄存器里面存放了段的序号。
保护模式新增了对段落的权限检查,比如读写权限等等:
保护模式的中断同理,也增加了权限检查
长模式
长模式寻址
x 86-64 体系结构在长模式(64 位模式)下不使用分段。其中四个段寄存器:CS、SS、DS 和 ES 强制为 0,限制为 2^64。长模式访存
dasctf2023 june toka garden and bios-mbr os 启动流程
前言
被纯真拉来看题楽。
日常忏悔没有学好操作系统。借着 dasctf 6 toka garden 了解了下操作系统 bios-mbr 的启动流程。
bios-mbr 启动流程
启动(boot)一词来自于一句谚语 “pull oneself up by one’s bootstraps” (“拽着鞋带把自己拉起来”)这当然是不可能的事情。最早的时候,工程师们用它来比喻,计算机启动是一个很矛盾的过程:必须先运行程序,然后计算机才能启动,但是计算机不启动就无法运行程序
必须想尽各种办法,把一小段程序装进内存,然后计算机才能正常运行。所以,工程师们把这个过程叫做"拉鞋带",久而久之就简称为boot了。
计算机通电
计算机通电后,CPU中的执行地址会初始化为BIOS的地址,然后开始加载执行BIOS程序。
BIOS
全称 Basic Input/Output System,用于检查硬件,而跟操作系统关系不大,因此电脑可以适应多种操作系统。BIOS 程序存放在 ROM 中,它的启动地址也是根据标准制定的。
- POST (poser-on self-test)检查硬件,如果有故障会发出 哔 的声音
- 启动设备 会找到第一个设备的第一个扇区内容(MBR)加载到内存,并跳转执行
MBR
参考 启动设备的第一个扇区的内容称为主引导记录(MBR,Master Boot Record),由三个部分组成
- bootloader,主引导程序(446个字节)
- Dpt(Disk Partition table),硬盘分区表(64个字节)
- 扇区结尾标志(55aa)标志当前扇区是否合法,不合法(不是55AA),会跳回BIOS寻找下一个启动设备
BIOS 把主引导程序加载到了内存中的固定位置 0x7c00,这个有 历史遗留原因的。而主引导程序负责把扇区中的操作系统代码加载到内存,然后执行操作系统代码。对于不同的操作系统,这一加载过程可能会有所不同。
bootloader
如果启动过程足够简单,仅仅 MBR 的代码就足以加载 os,那么 MBR 中的代码就可以成为 bootloader。如果启动过程复杂,MBR 会调用一些启动管理器软件来加载 os
os
那就是 os 自己的事情了…吧
MBR 分析
以 dasctf 6 toka garden 为例,用到了一个简单的 bootloader