Kernel Pwn Struct tty_struct and Struct tty_operations
代码分析
linux 中有一个伪终端设备 /dev/ptmx, 当 open("/dev/ptmx") 时, 会从 kmalloc-1k 中分配一个 tty_struct (0x2b8). 这个结构体关键的一些变量如下:
Docker pull 使用代理
发现自己原来写错了qaq. 当时折腾的脑袋晕了, 记录错了… and 今天一拍脑门发现自己是 sb.
2023 D^3CTF MISC d3craft
第一次给这么大型的比赛出题, 有点慌qaq. 本题仅有 3 支队伍解出, 比预期少一点. 可能是大佬们在看其他更有挑战性的题目, 对游戏不感兴趣吧. 其中来自满分冰美式的师傅以非预期的解法薄纱此题. 下面我会详细分析这题的预期解法, 以及非预期的做法, 欢迎各位对 Minecraft Hack 感兴趣的师傅一起交流!
2023 西湖论剑 Pwn JIT
赛时没出, 复现.
2023 XCTF Final Pwn haslang
一些废话: 比赛时先去看了 V8, 瞄了眼这题没什么想法后又跑去做 misc 了 (逃). 当时以为是什么打解释器的难题就先放了去做 shellgame, 结果啥都没做出来, 喜提零贡献 (逃).
V8 Pwn Basics 1: JSObject
JS 有这几种基本数据类型: Undefined, Null, Boolean, String, Symbol, Number, Object. 数组和函数实际上是 Object. 显然, 最复杂的一种类型就是 对象. 本文主要介绍 Object 在 V8 中的表示.
Object 的本质是一组有序的 属性, 类似于有序字典, 即键值对有序集合. 键可以是非负整数, 也可以是字符串. 键为数字的属性称为 编号属性, 为字符串的称为 命名属性. 比如一个 object = {'x': 5, 1: 6};. 引用这个属性可以用 . 或者 [], 如 object.x, object[1].
每个属性都有一系列 属性特性, 它描述了属性的状态, 比如 object.x 的值, 它是否可写, 可枚举等等.
JSObject
每当创建一个对象时, V8 会在堆上分配一个 JSObject (C++ class), 来表示这个对象:
- Map: 指向 HiddenClass 的指针
- Properties: 指向包含 命名属性 的对象的指针
- Elements: 指向包含 编号属性 的对象的指针
- In-Object Properties: 指向对象初始化时定义的 命名属性 的指针
其中, Map 是用来确定一个 Object 的形状的, Proerties 和 Elements 都是 Object 中的属性. Properties 和 Elements 独立存储, 为两个 FixedArray (V8 定义的 C++ class), 编号属性一般也叫 元素, 他是可以用整数下标来访问的, 一般也就存储在连续的空间中. 而由于动态的原因, 命名属性难以使用固定的下标进行检索. V8 使用 Map Transition 的机制来动态表示命名属性.
Kernel Pwn Heap UAF and Struct cred
UAF overwrite ptr
和用户态一样, 控持程序流的一个最有效的方法就是覆盖函数指针. 在用户态, 我们可能会去覆盖一些 hook 函数指针, 或者是 FILE vtable 的指针. 在内核态也是一样的. 下面会结合例题来介绍一些可以利用的结构体中的函数指针.
例题 CISCN_2017 - babydriver
检查启动脚本和 init, 仅开启 smep, kallsyms 可读, 显示 dmesg. 加载了一个 babydriver.ko 到 /dev/babydev.
检查 ko 的保护, 只开启了 NX. 设备注册了 open, close, read, write, ioctl, open 的时候会 kmalloc 一个 chunk, 指针在全局变量上. ioctl 里可以重新 kmalloc 一个任意大小的 chunk, 覆盖全局变量上的指针. read 和 write 正常读写. close 的时候 kfree, 但是没有将指针置零. 由于指针是在全局变量上, 所以我们打开两次设备, 申请一块我们可以控制大小的空间, 关闭一次设备, 将其释放, 这样没有关闭的那个还可以进行读写操作, 也就是 UAF.
cred
kernel 4.4.72 时, cred 结构体没有专门的一个 kmem_cache (slub allocator) 来分配. struct cred 大小是 0xa8, 会使用 kmalloc-192 这个 kmem_cache 来分配. 而我们知道, cred 中保存了 uid, gid, 等, 如果可以改变这些, 那么就可以成功提权.