代码少不一定是好事,代码多也不一定是坏事。

这道题目的代码可以说是十分简单了,主要就是新开了一条线程,然后在线程里面可以进行批量的malloc操作。
然而malloc操作是的分配空间大小是严格限制好的,除此之外也实在没看出别的问题。
开始寻思着是整形溢出,继而导致缓存区溢出,然而并没有,严格的条件判断致使程序根本没有整形溢出的机会。
看了Write up之后才发现,漏洞真的是就在自己眼皮底下,还不止一次反复怀疑过的,可惜就是没有察觉到。

  1. for ( i = 0LL; ; i += v3 )
  2. {
  3. result = i;
  4. if ( i >= size )
  5. break;
  6. v3 = read(0, (void *)(heap_ptr + i), size);
  7. if ( v3 <= 0 )
  8. {
  9. write(1, "I/O error\n", 0xAuLL);
  10. sub_400AD6(1u);
  11. }
  12. }

这段代码是程序malloc之后唯一往新空间写入内容的地方,如果用户输入和size长度匹配的内容,自然是一点问题都没有。但是如果用户输入小于给定size长度的内容,因为read函数返回值是实际读入的字节数,因此可能造成v3 < size的情况。还是举例来说,size=0x400, 用户输入0x3ff个字节,然后v3=0x3ff,此时程序进入下一个循环。
在下一个循环当中,read的调用情况就变成了read(0, heap_ptr + 0x3ff, 0x400),因此可以溢出到预期空间之外的内存。

vmmap
至于malloc出来空间的位置,简单用上图来说明一下,新线程里面分配的空间并不是分配到heap里面的,而是通过mmap的机制来分配新的内存块。分配的时候首先会消耗掉图中白框部分空闲的内存,当这部分可用的内存都分配完了,程序就会往上找新的空间,比如说2号标记所示的内存。然后1号标记的位置是该线程中的main_arena所在的位置。

main_arena
上图是main_arena的数据结构,对heap攻击利用有一定了解的同学都应该知道,main_arena里面保存了很多malloc有关的数