0x31 Shellcode
0x31 Shellcode
Content
Intel Architecture
C Arrays
BoF Exploit
Assembler
Remote Exploit
Shellcode
Exploit Mitigations
Function Calls
Slide 2
Shellcode?
Shellcode! Example in one slide
Slide 4
Slide 5
Shellcode
Shellcode is:
Slide 6
Shellcode
Slide 7
Shellcode
Server Software
Evil Exploit
Evil
Slide 8
Shellcode
Slide 9
Shellcode
Slide 10
Shellcode
Shellcode Properties
Should be small
Because we maybe have small buffers in the vulnerable
program
Position Independent
Don’t know where it will be loaded in the vulnerable program
No Null Characters (0x00)
Strcpy etc. will stop copying after Null bytes
Self-Contained
Don’t reference anything outside of shellcode
Slide 11
Shellcode
Recap:
Shellcode is:
A string of bytes
Which can be executed independantly
Slide 12
Syscalls
Syscalls
Slide 14
Syscalls
Syscalls?
Ask the kernel to do something for us
Why syscalls?
Makes it easy to create shellcode
Direct interface to the kernel
Alternative:
Call LIBC code; write()
Problem: Don’t know where write() is located!
Slide 15
Syscalls
To print a message:
“Hi there”
Code:
write(1, “Hi there”, 8);
Slide 16
Syscalls
syscalls(2):
The system call is the fundamental interface
between an application and the Linux kernel.
Slide 17
Syscalls Examples
Process Control
• load
• execute
• end, abort
• create process (for example, fork)
• terminate process
• get/set process attributes
• wait for time, wait event, signal event
• allocate, free memory
File management
• create file, delete file
• open, close
• read, write, reposition
• get/set file attributes
Slide 18
Syscalls Example
Slide 19
Syscalls
Arguments in:
1. EBX
2. ECX
3. EDX
4. …
Slide 20
Syscalls
write (
int fd,
char *msg,
unsigned int len);
write (
1,
&msg,
strlen(msg));
Slide 21
Syscalls
Slide 22
Syscalls
Slide 23
Syscalls: Assembler print
write (
int fd,
char *msg,
unsigned int len);
Slide 24
Syscalls: Assembler print
$ cat print.asm
section .data
msg db 'Hi there',0xa
section .text
global _start
_start:
Recap:
Syscalls are little functions provided by the kernel
Can be called by putting syscall number in eax, and issuing int 80
Arguments are in registers (ebx, ecx, edx)
Slide 27
How is shellcode formed?
section .text
global _start
_start:
Compile it:
$ nasm -f elf print.asm
Link it:
$ ld –m elf_i386 -o print print.o
Execute it:
$ ./print
Hi there
$
Slide 30
How is shellcode formed?
$ objdump -d print
08048080 <_start>:
// print
8048080: b8 04 00 00 00 mov $0x4,%eax
8048085: bb 01 00 00 00 mov $0x1,%ebx
804808a: b9 a4 90 04 08 mov $0x80490a4,%ecx
804808f: ba 09 00 00 00 mov $0x9,%edx
8048094: cd 80 int $0x80
// exit()
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: bb 00 00 00 00 mov $0x0,%ebx
80480a0: cd 80 int $0x80
Slide 31
How is shellcode formed?
$ objdump -d print
08048080 <_start>:
// print
8048080: b8 04 00 00 00 mov $0x4,%eax
8048085: bb 01 00 00 00 mov $0x1,%ebx
804808a: b9 a4 90 04 08 mov $0x80490a4,%ecx
804808f: ba 09 00 00 00 mov $0x9,%edx
8048094: cd 80 int $0x80
// exit()
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: bb 00 00 00 00 mov $0x0,%ebx
80480a0: cd 80 int $0x80
Slide 32
How is shellcode formed?
$ hexdump –C print
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 80 80 04 08 34 00 00 00 |............4...|
00000020 94 01 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |........4. ...(.|
00000030 06 00 03 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 a2 00 00 00 a2 00 00 00 05 00 00 00 |................|
00000050 00 10 00 00 01 00 00 00 a4 00 00 00 a4 90 04 08 |................|
00000060 a4 90 04 08 09 00 00 00 09 00 00 00 06 00 00 00 |................|
00000070 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000080 b8 04 00 00 00 bb 01 00 00 00 b9 a4 90 04 08 ba |................|
00000090 09 00 00 00 cd 80 b8 01 00 00 00 bb 00 00 00 00 |................|
000000a0 cd 80 00 00 48 69 20 74 68 65 72 65 0a 00 2e 73 |....Hi there...s|
000000b0 79 6d 74 61 62 00 2e 73 74 72 74 61 62 00 2e 73 |ymtab..s…
Slide 33
How is shellcode formed?
Compile/Assembler:
The process of converting source code into a series of instructions/bytes
Assembler -> Bytes
Disassemble:
The process of converting a series of instructions/bytes into the equivalent assembler
source code
Bytes -> Assembler
Decompile:
The process of converting instructions/assembler into the original source code
Assembler -> C/C++
Slide 34
How is shellcode formed?
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
Slide 35
How is shellcode formed?
Slide 36
How is shellcode formed?
Recap:
Compiled assembler code produces bytes
These bytes can be executed
Slide 37
Shellcode Fix: Null Bytes
Shellcode Fix: Null Bytes
Slide 39
Shellcode Fix: Null Bytes
Slide 40
Shellcode Fix: Null Bytes
// print
8048080: b8 04 00 00 00 mov $0x4,%eax
8048085: bb 01 00 00 00 mov $0x1,%ebx
804808a: b9 a4 90 04 08 mov $0x80490a4,%ecx
804808f: ba 09 00 00 00 mov $0x9,%edx
8048094: cd 80 int $0x80
// exit()
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: bb 00 00 00 00 mov $0x0,%ebx
80480a0: cd 80 int $0x80
Slide 41
Shellcode Fix: Null Bytes
Examples
Has 0 bytes:
mov $0x04, %eax
Equivalent instructions (without 0 bytes):
xor %eax, %eax
mov $0x04, %al
Slide 42
Shellcode Fix: Null Bytes
// print
8048060: 31 c0 xor %eax,%eax
8048062: 31 db xor %ebx,%ebx
8048064: 31 c9 xor %ecx,%ecx
8048066: 31 d2 xor %edx,%edx
// exit()
804807c: b0 01 mov $0x1,%al
804807e: 31 db xor %ebx,%ebx
8048080: cd 80 int $0x80
Slide 43
Shellcode Fix: Null Bytes
Recap:
Need to remove \x00 bytes
By exchanging instructions with equivalent instructions
Slide 44
Shellcode Fix: Stack Reference
Shellcode Fix: Stack Reference
Problem:
The current shellcode references a string from the data section
In an exploit we can only execute code
not (yet) modify data!
Solution:
Remove dependency on the data section
By storing the same data directly in the code
And move it to the stack
Slide 46
Shellcode Fix: Stack Reference
$ objdump -d print
08048080 <_start>:
// print
8048080: b8 04 00 00 00 mov $0x4,%eax
8048085: bb 01 00 00 00 mov $0x1,%ebx
804808a: b9 a4 90 04 08 mov $0x80490a4,%ecx
804808f: ba 09 00 00 00 mov $0x9,%edx
8048094: cd 80 int $0x80
// exit()
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: bb 00 00 00 00 mov $0x0,%ebx
80480a0: cd 80 int $0x80
Slide 47
Shellcode Fix: Stack Reference
Slide 48
Syscalls: Memory Layout
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
Slide 49
Shellcode Fix: Stack Reference
What do we want?
Have the data in the code section!
Slide 50
Syscalls: Memory Layout
Data
Slide 51
Shellcode Fix: Stack Reference
Translate to ASCII:
; H i _ t h e r e
; 48 69 20 74 68 65 72 65
Slide 52
Shellcode Fix: Stack Reference
; H i _ t h e r e
; 48 69 20 74 68 65 72 65
; 74 20 69 48 65 72 65 68
push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
Slide 53
Shellcode Fix: Stack Reference
<Stuff>
ESP
push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
Slide 54
Shellcode Fix: Stack Reference
<Stuff>
ESP
0x65726568 push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
Slide 55
Shellcode Fix: Stack Reference
<Stuff>
ESP
0x65726568 push 0x65726568
0x74206948 push 0x74206948
mov ecx, esp
int 0x80
Slide 56
Shellcode Fix: Stack Reference
<Stuff>
ESP
0x65726568 push 0x65726568
0x74206948 push 0x74206948
mov ecx, esp
ECX int 0x80
Slide 57
Shellcode Fix: Stack Reference
48 69 20 74 68 65 72 65 <Stuff>
H i _ t h e r e <Stuff>
Recap:
External data reference needs to be removed
Put the data into code
And from the code into the stack
Slide 60
Fixed Shellcode
Shellcode Problems
Now we have:
No null bytes!
No external dependencies!
Slide 62
Memory Layout (Old, with data reference)
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
Slide 63
Memory Layout (New, stack reference)
Stack
“Hi there”
48 69 20 74 68 65 72 65
Data
Slide 64
Convert shellcode
Result:
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\
xb2\x08\x68\x68\x65\x72\x65\x68\x48\x69\x20\x74\x
89\xe1\xcd\x80\xb0\x01\x31\xdb\xcd\x80
Slide 65
Execute shellcode
$ cat shellcodetest.c
#include <stdio.h>
#include <string.h>
Slide 66
Memory Layout (New New)
“Hi there”
48 69 20 74 68 65 72 65
Data
Code
Slide 67
Execute Stuff
Slide 68
Execute Stuff
int execve(
const char *filename,
char *const argv[],
char *const envp[]);
e.g.:
execve(“/bin/bash”, NULL, NULL);
Slide 69
Shell Execute Shellcode
Slide 70
Shellcode! Example in one slide
Slide 71
32 vs 64 bit
32bit vs 64bit
Slide 73
32bit vs 64bit
Syscalls:
Slide 74
Types of shells by shellcode
Types of shellcode
Remote shell
Reverse
Bind
Find
Slide 76
Shellcode
Bind shell:
Port 8080
Server Software
Shellcode Exploit
Port 31337
Slide 77
Shellcode
Reverse shell:
Port 8080
Server Software
Shellcode Exploit
Port 31337
Slide 78
Shellcode
Find shell:
Port 8080
Server Software
Shellcode Exploit
Slide 79
Types of shellcode
Types of shellcode:
Staged
Minimal initial shellcode: Stager
Stager loads stage 1
Stage 1 loads Stage 2
Slide 80
Types of shell / shellcode
Slide 81
Metasploit
Metasploit payloads:
Intel, ARM, MIPS, …
Windows, Linux, FreeBSD, …
32/64 bit
Listen-, connect-back-, execute, add-user, …
Alphanumeric, sticky-bit, anti-IDS, …
Slide 83
Metasploit Shellcode: Payload List
Payloads:
$ msfconsole
msf > use payload/linux/x64/[TAB]
use payload/linux/x64/exec
use payload/linux/x64/shell/bind_tcp
use payload/linux/x64/shell/reverse_tcp
use payload/linux/x64/shell_bind_tcp
use payload/linux/x64/shell_bind_tcp_random_port
use payload/linux/x64/shell_find_port
use payload/linux/x64/shell_reverse_tcp
Slide 84
Metasploit Shellcode: Payload Create
Slide 85
Metasploit Shellcode: Payload Create
Slide 86
Metasploit Shellcode: Payload Encoder
Shellcode encoders:
msf payload(exec) > show encoders
[…]
x86/add_sub manual Add/Sub Encoder
x86/add_sub
x86/alpha_mixed low Alpha2 Alphanumeric Mixedcase Encoder
x86/alpha_upper low Alpha2 Alphanumeric Uppercase Encoder
x86/alpha_mixed
x86/avoid_underscore_tolower manual Avoid underscore/tolower
x86/avoid_utf8_tolower manual Avoid UTF8/tolower
x86/alpha_upper
x86/bloxor manual BloXor - A Metamorphic Block Based XOR Encoder
x86/call4_dword_xor normal Call+4 Dword XOR Encoder
x86/avoid_underscore_tolower
x86/context_cpuid manual CPUID-based Context Keyed Payload Encoder
x86/avoid_utf8_tolower
x86/context_stat
x86/context_time
manual
manual
stat(2)-based Context Keyed Payload Encoder
time(2)-based Context Keyed Payload Encoder
x86/countdown normal Single-byte XOR Countdown Encoder
x86/fnstenv_mov normal Variable-length Fnstenv/mov Dword XOR Encoder
x86/jmp_call_additive normal Jump/Call XOR Additive Feedback Encoder
x86/nonalpha low Non-Alpha Encoder
x86/nonupper low Non-Upper Encoder
x86/opt_sub manual Sub Encoder (optimised)
x86/shikata_ga_nai excellent Polymorphic XOR Additive Feedback Encoder
x86/single_static_bit manual Single Static Bit
x86/unicode_mixed manual Alpha2 Alphanumeric Unicode Mixedcase Encoder
x86/unicode_upper manual Alpha2 Alphanumeric Unicode Uppercase Encoder
Slide 87
Metasploit Shellcode: Payload Encoder
Alphanumeric Shellcode
Slide 88
Metasploit Shellcode
Slide 89
Metasploit Shellcode
Recap:
Metasploit can generate shellcode
Pretty much any form of shellcode
With many useful payloads
Slide 90
References:
References:
Slide 91
Defense: Detect Shellcode
Detect Shellcode
Slide 93