void* p3 = malloc(0x400); fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3); fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n"); free(p1); fprintf(stderr, "Trigger the double free vulnerability!\n"); fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n"); fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", malloc(0x40), malloc(0x40)); }
运行结果:
1 2 3 4 5 6 7 8
./fastbin_dup_consolidate Allocated two fastbins: p1=0x555dbdb57260 p2=0x555dbdb572b0 Now free p1! Allocated large bin to trigger malloc_consolidate(): p3=0x555dbdb57300 In malloc_consolidate(), p1 is moved to the unsorted bin. Trigger the double free vulnerability! We can pass the check in malloc() since p1 is not fast top. Now p1 is in unsorted bin and fast bin. So we'will get it twice: 0x555dbdb57260 0x555dbdb57260
v8 = __readfsqword(0x28u); alarm0x3c(); // // puts("Waking Sleepy Holder up ..."); fd = open("/dev/urandom", 0); read(fd, &buf, 4uLL); buf &= 0xFFFu; malloc(buf); // malloc something random to change heap_address every time // sleep(3u); puts("Hey! Do you have any secret?"); puts("I can help you to hold your secrets, and no one will be able to see it :)"); while ( 1 ) { puts("1. Keep secret"); puts("2. Wipe secret"); puts("3. Renew secret"); memset(&s, 0, 4uLL); read(0, &s, 4uLL); v3 = atoi(&s); v6 = v3; switch ( v3 ) { case 2: wipe_secret(); //仅仅把free掉并把该chunk的inuse位标记为0 break; case 3: renew_secret(); //重新改写1或者2的chunk,大小最大还是原来那么大。 break; case 1: keep_serect(); //选择123来使用calloc分别分配大小为40,4000,400000大小的chunk且都只能分配一块,12的chunk可以wipe或者renew,3的chunk分配就再也没法变了。inuse位会被标记为1. break; } } }