2024 d3ctf pwn wp
比赛就做了一个签到一个php,补一下另外两道能做的
D3BabyEscape
qemu pwn基础知识
见这个博客👉qemu pwn-基础知识
数据结构关系图,以blizzardctf2017的strng为例:
- TypeInfo:定义类、实例初始化函数
- class_init:初始化父类
- instance_init:初始化子类(对应具体设备)
- realize:初始化实例(使用)
逆向
看启动脚本,设备叫l0dev
1 |
|
滤一下字符串
l0dev可以定位到ldev_info
继而定位到class_init
l0dev_realize可以定位到realize
l0dev_instance_init可以定位到instance_init
剩下的mmio和pmio的read和write函数也可以通过字符串定位
还原的l0dev_state结构体:
- l0dev_mmio_read:读有一个acpi_index的偏移
- l0dev_mmio_write:flag设置后可带acpi_index偏移写
- l0dev_pmio_read:读出数据为0x29A时可递增flag
- l0dev_pmio_write:
- addr为0x40时调用rand_r
- addr为0x80时设置acpi_index
- 其他情况正常写
exp
l0dev_class_init可以看出vendor_id是0x1234,device_id是0x1919
1 |
|
1 |
|
得到PMIO地址
流程:
- mmio_write设置acpi_index
- mmio_read溢出泄漏r_rand
- pmio_write正常写0x29A
- pmio_read读0x29A设置flag
- pmio_write溢出写r_rand为system
- mmio_write调用r_rand命令执行
1 |
|
write_flag_where
可以将flag的某一字节写到libc代码段,输入不合法就退出,合法可以一直改(比赛的时候还看错题了以为只能改一次)
第一次改0x8ca1d+libc_base+3,_IO_vtable_check中取报错字符串的偏移
1
2
3
4
5
6void attribute_hidden
_IO_vtable_check (void)
{
/* …… */
__libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
}第二次改libc_base+0x907a0+5,实际上是__uflow里调用的IO_validate_vtable取__io_vtables地址的部分
1
2
3
4
5
6
7
8
9
10
11static inline const struct _IO_jump_t *
IO_validate_vtable (const struct _IO_jump_t *vtable)
{
uintptr_t ptr = (uintptr_t) vtable;
uintptr_t offset = ptr - (uintptr_t) &__io_vtables;
if (__glibc_unlikely (offset >= IO_VTABLES_LEN))
/* The vtable pointer is not in the expected section. Use the
slow path, which will terminate the process if necessary. */
_IO_vtable_check ();
return vtable;
}
两次改完之后再scanf调用__uflow时会因为vtables偏移不对报错,根据报错字符串的移位可以判断flag字符是什么
懒得搓exp了就这样吧,一直想改exit(因为以为只能改一次)能做出来才怪
2024 d3ctf pwn wp
http://akaieurus.github.io/2024/04/29/2024d3ctf-pwn-wp/