Byte CTF 2019 部分 writeup
TOC
源程序下载:byte_ctf_2019.zip。
Mulnote
void __fastcall start_routine(void *a1) |
简单的UAF
漏洞,虽然对程序流进行了混淆,但是并不影响做题。
思路
- 泄露libc信息
- 劫持hook
脚本
#!/usr/bin/python2 |
VIP
void __fastcall edit(unsigned int index) |
该题难点主要是绕过edit
功能。而且在下面的函数中,恰好栈溢出使得我们可以配置沙箱规则。
void __cdecl become_vip() |
溢出了48
个字节,可以配置6条规则,已经足够了。
在open
函数中会调用sys_openat
,我们只要让其返回0,这样就可以直接读取输入流了。沙箱规则如下:
struct sock_filter filter[] = { |
由于关闭了sys_openat
,而且程序设置了子进程会继承沙箱规则,所以不能正常起shell,但是我们可以进行ROP读取flag。
脚本
#!/usr/bin/python2 |
notefive
void __fastcall read_n(char *str, signed int size, char end) |
off by one
漏洞,难点在于其对于size的限制:
void __cdecl New() |
对于我们来说fastbin
还是更好用的,所以先用unsorted bin attack
修改global_max_fast
,使得fastbin可以使用。
New(0, 0x98) |
然后就是修改stdout
结构体,虽然size
被限制为size > 0x8F && size <= 0x400
,但是原有的fastbin attack
依然可以使用,我们可以利用stderr
当中的0xffffffffffffffff
进行偏移来伪造size。
pwndbg> x/16gx 0x7ffff7dd25c0 |
这样我们就有了一个0x00000000000000ff
的size。 具体脚本如下:
delete(4) |
最后就是劫持hook,由于__malloc_hook
前面有stdin
,其内部恰好也有0xffffffffffffffff
,继续进行fastbin attack
,但是其不能修改到__malloc_hook
,但是我们可以fastbin attack
接力,在中途写下一个0xf1
的size,然后继续fastbin attack
,这样就能修改到__malloc_hook
。
delete(4) |
脚本
#!/usr/bin/python2 |
mheap
靶机环境是 glibc-2.27 。
void __fastcall read_n(char *str, signed int length) |
原先从没见过这种类型,原本read_n
读取的字节数是锁死的,但是我们可以read
到那0x1000
内存的边缘,并且让其溢出,由于read
使用的是系统调用,所以程序并不会因为错误内存引用而crash
,最后read
返回标志错误的-1
,当返回-1
之后,v2就会变小,这样我们就可以向上溢出了。
思路
- 利用
read
的边缘操作向上溢出该free_list
的next
指针,使其指向got表
- 劫持got
脚本
#!/usr/bin/python2 |
ezarch
刚开始用heap overlap
来做,但是劫持了stdout
之后就再也不能free了,原因是glibc-2.27
的free会对地址进行对齐检查,所以偏移出来的size没有办法使用了。
看了W&M
的博客之后,才发现模拟的虚拟机,其本身对于ebp处理的就有问题。
v2 = a1->memory_size; |
memory_size
是用户可控的,栈大小是0x1000
,如果设置memory_size
大于0x100
就可以修改vm
的核心配置,比如stack_addr
,将其指向修改指向got表,然后直接修改got表。
由于只有第一次memory_size
可以自行设置,所以free.got
表还没有解析,可以用puts.got
来完成偏移计算。
#!/usr/bin/python2 |