(置顶)pwncollege部分通关记录

https://dojo.pwn.college/challenges

按照网站要求,这里只提供思路和前两题的exploit。

heap

babyheap1.0~2.1——uaf

1
2
3
4
5
def exploit():
malloc(flag_size)
free()
read_flag()
puts()

babyheap3.0~3.1——uaf2.0

注意tcache是LIFO结构

babyheap4.0&4.1——tcache double free

第一次独立写出堆题,虽然是最简单的那种tcache double free

babyheap5.0&5.1——unsorted bin attack

libc 2.23->libc 2.31

通过耗尽所有的tcache来触发small bin和unsorted bin,进而修改chunk。

babyheap6.0&6.1——tcache poisoning

简单的tcache poisoning

https://wargames.ret2.systems/level/how2heap_tcache_poisoning_2.31

babyheap7.0&7.1——tcache poisoning2.0

由于flag不会变化,secret后半部分,只需将sec_addr+=8,重新运行即可。

babyheap8.0&8.1——brute force

通过先前的方法可以泄露出secret的后12位,前4位可以通过暴力枚举实现。

脚本跑了一节课才跑出来。

kernel

babykernel1.0~6.1——basic definition

参照这篇博客:https://www.cnblogs.com/crybaby/p/14431651.html

kernel shellcode着实有点麻人。

注:如何查看有没有kaslr?

进入kernel后,demsg查看第二行最后有没有nokaslr

babykernel7.0~7.1——struct&debug

需要传入一个类似于这样的结构体:

1
2
3
4
5
struct shellcode{
unsigned long length;
char shellcode[0x1000];
unsigned long* shellcode_addr;
}

注意以下几点:

  • shellcode必须包含ret语句(ret2usr)。
  • shellcode_addr可以通过动调得到,位置固定。

babykernel8.0~8.1——shellcode in shellcode

一句话——在shellcode里写shellcode

第一次进内核来一遍commit_creds(prepare_kernel_cred(0))ret2usr后变成root shell。再进入一次run_cmd /bin/chmod 777 /flag即可修改flag权限。(注意在内核态里起shell没有任何作用)

babykernel9.0~9.1——run_cmd

直接把printk指针改为run_cmd,然后rdi是输入处,写入/bin/chmod 777 /flag即可。

babykernel10.0——kaslr leak

注意kaslr只有在kernel重启之后才会重新随机,所以重新运行程序,原有的kernel函数地址不会变。

与userland的aslr类似,kaslr的低5位都是固定的。写入256字节使得printk的地址被泄露,从而找到run_cmd的地址。

babykernel10.1——partial overwrite

由于该驱动不会打印自己的输入,这里采取重写printk的后3字节,也就是得爆破run_cmd的倒数第六位。

babykernel11.0~12.1——memory scanning

程序将flag加载到内存里,然后删掉了flag文件,因此flag只能在内存里面找。

通过discord的spoiler可以得知应该从0xffff888000000000开始扫内存(即宏phys_to_virt(0)的值,也是源码__PAGE_OFFSET_BASE_L4一行的值),然后dmesg找一下flag即可。

注意以下几点:

  • 如果用这个网站将汇编转成字节码,务必把字节码转成汇编验证一下是否漏掉了指令。
  • 为了减少输出,建议将地址的值与pwn.coll(或类似的64位字符串)比较一下再打印到控制台。
  • python很耗费内存,可能起一遍python,flag那部分的内存就被重新分配了。所以建议把shellcode输出到文件再进行文件流输入。