64 ELF executable shellcode on a Linux machine
I am creating a training on buffer overflows and stack/heap attacks. I am working on an Ubuntu 12.04 x86_64 machine and want to show some sample buggy programs and the ways you could exploit those vulnerabilities.
I am trying to start with the most basic shellcode I have found so far, the simple exit call, which should exit the program being overflowed.
Hereby the exitcall.asm :
;exitcall.asm
[SECTION .text]
global _start
_start:
xor ebx,ebx ; zero out ebx, same function as mov ebx,0
mov al, 1 ; exit command to kernel
int 0x80
I've got this asm file from other tutorials, written for i386 architectures however. Next thing to do is generate an object file and make it a binary executable:
# nasm -f elf64 exitcall.asm
# ld -o exitcall exitcall.o
# file exitcall
exitcall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
# strace ./exitcall
execve("./exitcall", ["./exitcall"], [/* 73 vars */]) = 0
write(0, NULL, 0 <unfinished ...>
+++ exited with 0 +++
# objdump -d exitcall
exitcall: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: 31 db xor %ebx,%ebx
400082: b0 01 mov $0x1,%al
400084: cd 80 int $0x80
As you can see the binary result executes well (exit 0 verified with strace), somehow giving me the confidence that the asm file is correct as well. So what I am supposed to do now is to create a shellcode character array from it, so I can test is in the following sample shellprogram.c executor. I just took the HEX values from objdump and started reading left to right, top to bottom, resulting in the following test:
char code[] = "x31xdbxb0x01xcdx80";
int main(int argc, char **argv) {
int (*exeshell)();
exeshell = (int (*)()) code;
(int)(*exeshell)();
}
When I compile this file and execute it, I get a segmentation fault , however:
# gcc shellprogram.c -o shellprogram
# file shellprogram
shellprogram: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=765bdf6201099b9784b63a0111dc16c1115118bb, not stripped
# strace ./shellprogram
execve("./shellprogram", ["./shellprogram"], [/* 73 vars */]) = 0
brk(0) = 0x602000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff8000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=134914, ...}) = 0
mmap(NULL, 134914, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fd7000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF211 3 >