I am a newbie in writing assembler code / shellcodes. My shellcode should generate shell via syscall execve with an argument array. When I run the compiled shellcode it seems to work, I get my username printed on the command line and all arguments are correct, analyzed with the strace tool.
But when I run my shellcode with my shellcode tester, It doesn't passed the correct arguments to the execve function and i can't spawn a shell.
Thats my 64bit shellcode:
section .text
global _start
_start:
;execve
; - rax = syscall number (59, 0x3b)
; - rdi = const char *filename
; - rsi = const char *const *argv
; - rdx = const char *const *envp
xor rax, rax
xor rdx, rdx
; //bin/sh
push rdx
mov rbx, 0x68732f6e69622f2f
push rbx
mov rdi, rsp
; -c
push rdx
sub rsp, 2
mov word [rsp], 0x632d
lea rsi, [rsp]
; whoami
push rdx
sub rsp, 6
mov word [rsp], 0x6877
mov dword [rsp+2], 0x696d616f
lea rcx, [rsp]
push rdx
push rcx
push rsi
push rdi
mov rsi, rsp
push 0x3b
pop rax
syscall
;exit
; - rax = syscall number (60, 0x3c)
; - rdi = int error_code
push 0x3c
pop rax
shl rdi, 0x1
neg rdi
syscall
Thats my shellcodetester:
# include <stdio.h>
# include <string.h>
# include <unistd.h>
# include <sys/mman.h>
# define EXEC_MEM ((void *) 0x80000000)
int main() {
const unsigned char shellcode[] = "\x48\x89\xe5\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x52\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x53\x48\x89\xe7\x52\x48\x83\xec\x02\x66\xc7\x04\x24\x2d\x63\x48\x8d\x34\x24\x52\x48\x83\xec\x06\x66\xc7\x04\x24\x77\x68\xc7\x44\x24\x02\x6f\x61\x69\x48\x8d\x0c\x24\x52\x51\x56\x57\x48\x8d\x34\x24\x6a\x3b\x58\x0f\x05\x6a\x3c\x58\x48\xd1\xe7\x48\xf7\xdf\x0f\x05";
mmap(EXEC_MEM, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
memcpy(EXEC_MEM, (void *)shellcode, strlen(shellcode)+1);
(*(int (*)())EXEC_MEM)();
return 0;
}
Compile shellcode:
nasm -f elf64 -o './shell-64Bit.o' './shell-64Bit.asm' && ld -m elf_x86_64 -o './shell-64Bit' './shell-64Bit.o'
Compile shellcodetester:
gcc -no-pie -fno-stack-protector -z execstack './shellcodetester.c' -o './shellcodetester'
Dump shellcode:
objdump -d './shell-64Bit'|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
I debug with gdb the compiled shellcodetester and analyzed main function with disas main, and set a breakpoint at the last call instruction in the main function, then i stepped over the shellcode instruction with si.
I realized that my data gets popped off the stack and the registers have wrong values for unkown reason.
That worked for me!