I'm trying to learn how to create shellcode. I've followed several tutorials online and I still can't get it to work. I start by writing clean assembly x86 code to spawn a shell, extract the opcode, and place it into a C file.
This is the assembly code:
;nasm -f elf64 test.nasm; ld test.o -o test
section .text
global _start
_start:
xor rax, rax
push rax
mov rax, 0x68732f6e69622f2f
push rax
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
xor rax, rax
mov al, 0x3b ; execve()
syscall
The objdump of the object file:
$ objdump -D -M intel test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: 48 31 c0 xor rax,rax
3: 50 push rax
4: 48 b8 2f 2f 62 69 6e movabs rax,0x68732f6e69622f2f
b: 2f 73 68
e: 50 push rax
f: 48 89 e7 mov rdi,rsp
12: 48 31 f6 xor rsi,rsi
15: 48 31 d2 xor rdx,rdx
18: 48 31 c0 xor rax,rax
1b: b0 3b mov al,0x3b
1d: 0f 05 syscall
And the C file with extracted opcode:
#include <stdio.h>
#include <string.h>
unsigned char code[] =
"\x48\x31\xc0\x50\x48\xb8\x2f\x2f"
"\x62\x69\x6e\x2f\x73\x68\x50\x48"
"\x89\xe7\x48\x31\xf6\x48\x31\xd2"
"\x48\x31\xc0\xb0\x3b\x0f\x0";
void main() {
printf(" shell length: %d\n", (int)strlen(code));
int (*ret) () = (int(*) ()) code;
ret();
}
//gcc -fno-stack-protector -z execstack test.c -o test2
After compiling and executing, I get a segmentation fault:
./test2
shell length: 30
zsh: segmentation fault ./test2
How do I get this to work? Every tutorial implies the shellcode just works at this point. Now I'm wondering if it's a hardware/software issue. I'm running this on a Kali VM on VirtualBox:
NASM version is 2.16.01. GCC version is 12.2.0.