Shellcode 64
Shellcode 64
Intel Architecture
Buffer Overflow
Memory Layout
C Arrays
BoF Exploit
Assembler
Remote Exploit
Shellcode
Exploit Mitigations
Function Calls
Shellcode is:
evil code
Server Software
Evil
Exploit
Evil
Shellcode Properties
Should be small
Because we maybe have small buffers in the vulnerable
program
Position Independent
program
No Null Characters (0x00)
Strcpy etc. will stop copying after Null bytes
Self-Contained
Recap:
Shellcode is:
A string of bytes
Which can be executed
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()
To print a message:
“Hi there”
Code:
write(1, “Hi there”, 8);
syscalls(2):
The system call is the fundamental interface
between an application and the Linux kernel.
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
Arguments in:
EBX
ECX
EDX
write (
int fd,
char *msg,
unsigned int len);
write (
1,
&msg,
strlen(msg));
© Compass Security Schweiz AG www.csnc.ch Slide 20
Syscalls
And also:
Files
Sockets (Network)
write (
int fd,
char *msg,
unsigned int len);
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
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
$
$ 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
$ 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
$ 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…
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++
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
Recap:
Compiled assembler code produces bytes
These bytes can be executed
// 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
Examples
Has 0 bytes:
mov $0x04, %eax
Equivalent instructions (without 0 bytes):
xor %eax, %eax
mov $0x04, %al
// exit()
804807c: b0 01 mov $0x1,%al
804807e: 31 db xor %ebx,%ebx
8048080: cd 80 int $0x80
Recap:
Need to remove \x00 bytes
By exchanging instructions with equivalent instructions
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
$ 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
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
What do we want?
Have the data in the code section!
Data
Translate to ASCII:
; H i _ t h e r e
; 48 69 20 74 68 65 72 65
; H i _ t h e r e
; 48 69 20 74 68 65 72 65
; 65 72 65 68 74 20 69 48
push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
<Stuff>
ESP
push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
<Stuff>
ESP
0x65726568 push 0x65726568
push 0x74206948
mov ecx, esp
int 0x80
<Stuff>
ESP
0x65726568 push 0x65726568
0x74206948 push 0x74206948
mov ecx, esp
int 0x80
<Stuff>
ESP
0x65726568 push 0x65726568
0x74206948 push 0x74206948
mov ecx, esp
ECX int 0x80
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
Now we have:
No null bytes!
No external dependencies!
Stack
0x80490a4
“Hi there”
Data 48 69 20 74 68 65 72 65
Stack
“Hi there”
48 69 20 74 68 65 72 65
Data
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
© Compass Security Schweiz AG www.csnc.ch Slide 64
Execute shellcode
$ cat shellcodetest.c
#include <stdio.h>
#include <string.h>
“Hi there”
48 69 20 74 68 65 72 65
Data
Code
© Compass Security Schweiz AG www.csnc.ch Slide 66
Execute Stuff
int execve(
const char *filename,
char *const argv[],
char *const envp[]);
e.g.:
execve(“/bin/bash”, NULL, NULL);
Syscalls:
Types of shellcode:
Remote shellcode
Reverse
Bind
Find
Bind shellcode:
Port 8080
Client Software
Shellcode Exploit
Port 31337
Reverse shellcode:
Port 8080
Client Software
Shellcode Exploit
Port 31337
Find shellcode:
Port 8080
Client Software
Shellcode Exploit
Types of shellcode:
Staged
Minimal initial shellcode: Stager
Stager loads stage 1
Stage 1 loads Stage 2
Metasploit payloads:
32/64 bit
Listen-, connect-back-, execute, add-
Alphanumeric, sticky-bit, anti-
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
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
Alphanumeric Shellcode
Recap:
Metasploit can generate shellcode
Pretty much any form of shellcode
References: