Exploiting – Fuzzing parte 3

Usare Spike

In questo terzo esercizio di fuzzing utilizzeremo sempre con “Vulnserv” una nuova applicazione: “Spike

 Spike è un toolkit che permette attraverso la scrittura di script di effettuare test di vulnerabilità su applicazioni web o standalone attraverso tecniche di buffer overflow.

Al momento la documentazione su Spike e sullo scripting è quasi inesistente per queste ragioni l’esercizio di oggi potrebbe risultare un po’ ostico; il suggerimento per scrivere script customizzati per Spike è quello di fare opera di reverse engineering a partire dagli script forniti con il tool. Per scrivere scripting è richiesta una conoscenza basica di c, di Perl e del protocollo Tcp/ip.

Per poter seguire gli esercizi è necessario approntare due macchine: una macchina Linux da cui effettueremo gli attacchi ed una macchina windows che sarà la macchina target degli attacchi.

Sulla macchina Linux utilizzeremo i seguenti tool:

  • Netcat – disponibile sia su Backtrack, sia su Kali
  • Wireshark –disponibile sia su Backtrack, sia su Kali
  • Un interprete Perl
  • Spike – disponibile sia su Backtrack (consigliato aggiornarlo all’ultima release), sia su Kali, che puo’ essere scaricato all’indirizzo http://www.immunitysec.com/resources-freesoftware.shtml

Sulla macchina Windows utilizzeremo i seguenti tool:

Introduzione a SPIKE

Come introdotto Spike è una serie di API e di tool che permettono la creazione di stress test su diversi protocolli di networking (Tcp/ip, Ftp, http, …).

In Spike sono state codificate una serie di stringhe volte a produrre i più disparati errori nelle applicazioni oggetto di exploiting; una delle caratteristiche più importanti dell’applicativo è che non è necessario da parte dell’utente specificare i valori che queste stringhe devono assumere in quanto questa attività viene svolta direttamente da Spike.

Le stringhe inviate da Spike prendono il numero di “Spikes”: le Spikes sono composte da una serie di moduli chiamati “Blocks”. Un Block e’ una sezione di uno Spike di una determinata lunghezza con predeterminati valori generata dall’applicativo a secondo della customizzazione dello stesso.

Con Spike inoltre vengono fornite tutta una serie di primitive che possono essere utilizzate a seconda dei protocolli che si vogliono testare: nel caso in cui si voglia ad esempio testare il protocollo Tcp/Ip, come nel caso di Vulnserver, ci si potrà appoggiare alla primitiva “generic_send_tcp”; le primitive si trovano nella cartella “src” ed hanno come estensione “.spk

Di seguito un elenco di alcune primitive messe a disposizione dal tool:

  • Apachechunked
  • Generic_send_tcp
  • Generic_send_udp
  • Generic_web_server_fuzz

Ogni primitiva accetterà un determinato set di parametri: la primitiva “generic_send_tcp” ad esempio richiederà un indirizzo IP, una porta, uno script ed alcune variabili; per eseguire il comando si scriverà “./generic_send_tcp <indirizzo ip> <porta> <nome_script.spk> <SKIPVAR> <SKIPSTR>”.

SKIPVAR e SKIPSTR vengono utilizzate per saltare ad una determinata riga dello script contando la prima stringa e la prima variabile a partire da 0: per iniziare la scansione dalla terza stringa dovremo valorizzare SKIPSTR con “2”. Qualora volessimo effettuare una scansione dall’inizio dello script basterà valorizzare sia SKIPVAR, sia SKIPSTR a “0”.

Lo scripting con SPIKE

La prima cosa da farsi per avere una idea di quali primitive sono a disposizione di Spike è quella di aprire con un editor di testo, come ad esempio Bluefish, il file “spike.h” presente nella cartella “/src”; per capire invece come utilizzare i comandi la cosa migliore da farsi è aprire i file con estensione “.spk”.

Vediamo di seguito alcuni dei comandi utilizzabili negli script; importante ricordare che possono essere utilizzati solo i comandi “inizializzati” in spike.h.

Utilizzare le stringhe

Tramite le stringhe si posso aggiungere caratteri ASCII alle Spikes; i comandi più importanti sono:

  • s_string(“stringa”) – stampa nella Spike la stringa indicata tra “”
  • s_string_repeat(“stringa”,numero_ripetizioni) – stampa x volte la stringa indicata tra “”
  • s_string_variable(“stringa”) – inserisce una variabile dopo la stringa; la prima variabile e’ quella indicata nel comando, le successive sono generate

Utilizzare Binary Data

Con il comando “binary” possono essere inseriti valori secondo la codifica binaria:

  • s_binary(“\\x41”) – inserisce il valore corrispondente al valore esadecimale 0x41 (ASCII = A)
  • s_binary_repeat(\\x41,200) – ripete 200 volte il valore esadecimale 0x41 (ASCII = A)

Utilizzare la primitiva block e block_size

Tramite i Blocks e’ possibile definire inizio e fine di un Block all’interno di uno script

  • s_block_start(“block1”) – Indica che in quel punto dello script inizia la sezione denominata block1
  • s_block_end(“block1”) – Indica che in quel punto dello script termina la sezione denominata block1
  • s_blocksize_string(“block1”, dimensione) – aggiunge una stringa della lunghezza di 2 caratteri all’interno della sezione denominata block1
  • s_binary_block_size_byte(“block1”, 1) – aggiunge 1 byte all’interno della sezione denominata block1

Leggere l’output dalla macchina target

Tramite i seguenti comandi è possibile leggere ed interpretare l’output inviato dalla macchina target:

  • s_read_packet() – Legge e stampa a schermo l’output inviato dalla macchina target
  • s_readline() – Legge e stampa a schermo una singola riga inviata dalla macchina target

Uno script di esempio

Vediamo ora un semplicissimo script che tenterà di exploitare uno script php chiamato “testme.php” e valorizzerà la variabile “inputvar” con una stringa che partirà da una determinata lunghezza “data_size”.

Il testo da produrre sarà il seguente:

POST /testme.php HTTP/1.1
Host: testserver.example.com
Content-Length: [data_size]
Connection: close
inputvar=[fuzz_string]

Lo script per produrre tale risultato è il seguente:

s_string(“POST /testme.php HTTP/1.1\r\n”);
s_string(“Host: testserver.example.com\r\n”);
s_string(“Content-Length: “);
s_blocksize_string(“block1”, 5);
s_string(“\r\nConnection: close\r\n\r\n”);
s_block_start(“block1”);
s_string(“inputvar=”);
s_string_variable(“inputval”);
s_block_end(“block1”);

Nel prossimo articolo vedremo come utilizzare Spike per attaccare Vulnserver precedentemente installato sulla macchina target Windows

vediamo come customizzare uno script così da poterlo utilizzare con Vulnserver.

Installiamo quindi come prima cosa le applicazioni sulla macchina target: OllyDBG e Vulnserver (i riferimenti si trovano nell’articolo precedente (http://greyhathacking.wordpress.com/2013/04/06/exploit-fuzzing-3-usare-spike-parte-1/).

Eseguiamo quindi OllyDBG con privilegi di Amministratore e dal debugger lanciamo Vulnserver; per fare questo premiamo F3 (o “File – open”) selezioniamo Vulnserver e in Arguments digitiamo la porta su cui Vulnserver ascolterà le connessioni, ovvero 4444.

Premiamo infine F9 (o “Debug – run”) così da eseguire il programma.

Image

Vale la pena a questo punto di ricordare brevemente come funziona Vulnserver: si tratta di un applicativo scritto ad hoc per effettuare test di verifica di fuzzing o buffer overflow, una volta lanciato il programma questo si mette ad ascoltare su una determinata porta ed accetta una serie di comandi seguiti da stringhe di caratteri.

Per verificarne il funzionamento è sufficiente utilizzare telnet o netcat indicando l’indirizzo ip della macchina target e la porta, nel nostro caso la 4444: nel mio caso <nc 192.168.159.138 4444> oppure <telnet 192.168.159.138 4444>. Basterà a questo punto digitare il comando HELP (tutti i comandi devono essere digitati in maiuscolo) per vedere la lista di comandi che vengono accettati da Vulnserver.

Un comando tipo inviato a Vulnserver sarà: “STATS 1234567890” a cui Vulnserver risponderà con un “STATS VALUE NORMAL”.

Image

Spike, Wireshark e VulnServer

Ora che e’ chiaro il funzionamento di Vulnserver e come interagire con il programma stesso, vediamo come customizzare Spike in modo da tentarne l’exploit.

In primo luogo proviamo un semplice script che non invierà alcun comando particolare ma una stringa di lunghezza sempre maggiore; per fare questo utilizziamo un editor testo e scriviamo i seguenti parametri:

s_readline(); // viene letto l’output inviato da Vulnserver

s_string_variable(“COMMAND”); // invia la stringa a Vulnserver

Salviamo lo script con il nome “vulnserver.spk

Per controllare quali stringhe vengono passate a Vulnserver utilizzeremo Wireshark specificando l’interfaccia di rete su cui effettuare lo sniffing “eth0” e indicando come “Capture Filter” la seguente stringa “host 192.168.159.138 and tcp port 4444” (ovviamente l’ip dovra’ essere sostituito).

Image

Localizziamo con locate “generic_send_tcp” (in kali è disperso in /usr/bin, in Backtrack è sotto /pentest/fuzzers/spike) ed eseguiamo il seguente comando:

/usr/bin/generic_send_tcp 192.168.159.138 4444 vulnserver.spk 0 0

Image

Immediatamente wireshark inizierà a registrare pacchetti sull’interfaccia eth0 e nella shell da cui abbiamo eseguito il comando generic_send_tcp inizieremo a vedere il dettaglio dell’attacco: Spike resterà in attesa dell’output da Vulnserver e quindi invierà la stringa per il buffer overflow (notate nell’output la stringa “Variablesize=” seguita dalla lunghezza della stringa inviata a Vulnserver, questa informazione sarà utile quando riusciremo a crashare l’applicazione). Purtroppo questo attacco non sortirà alcun effetto.

Image

Per poter vedere quale stringa e’ stata inviata a Vulnserver stoppiamo lo sniffing di Wireshark, selezioniamo una riga nel log che abbia un valore di “Lenght” elevato (di almeno un migliaio) clicchiamo sulla riga con il tasto destro e selezioniamo l’opzione “Follow Tcp Stream” si aprirà una finestra contenente i dati relativi ai pacchetti catturati.

Automatizzare l’utilizzo di Spike per Vulnserver

Quello che ora vogliamo fare è scrivere un file script .spk per ogni comando da inviare a Vulnserver, utilizzarli in sequenza e dare comandi aggiuntivi a Spike per ottenere maggiori informazioni sull’attacco in essere; scriveremo quindi una procedura che eseguirà ognuno dei file .spk con il comando generic_send_tcp.

L’applicazione sarà scritta in modo da bloccarsi quando Vulnserver cascherà’.

A questo punto utilizzeremo OllyDBG, wireshark e lo script di automazione di Spike per capire cosa ha provocato il crash di Vulnserver; queste informazioni saranno preziosissime se vorremo scrivere un exploit. Importante ricordare che fino ad ora le attività svolte sono di Vulnerability Assessment e non di exploit vero e proprio.

Creiamo gli script

Iniziamo a creare gli script con un editor di testo: creiamo come prima cosa lo script che inviera’ a Vulnserver il comando “HELP” seguito da una stringa. Cloneremo quindi lo script sostituendo a HELP  via via tutti gli altri comandi gestiti da Vulnserver.

Il primo script si chiamerà 00help.spk e risultera’ il seguente:

printf(“Comando inviato HELP nome script eseguito: 00help.spk”); // stampa a video il comando inviato e il nome dello script

s_readline(); // stampa a video la linea inviata da Vulnserver

s_string(“HELP “); // invia il comando HELP a Vulnserver

s_string_variable(“COMMAND”); // invia la stringa per il tentativo di buffer overflow

Creiamo ora una directory ed al suo interno salviamo lo script; sostituiamo a HELP gli altri comandi di Vulnserver e salviamo gli script con una numerazione progressiva e con il nome del comando: 00help.spk, 01stats.spk, 02rtime.spk, 03ltime.spk

Per comodità potete scaricare tutti gli script dal link – https://mega.co.nz/#!AswS2CAT!VhBiiDCAA4eGevxjMiPkAX_dUK5A0zPX-9eybBMJr5g.

Lo script stamperà quindi come prima cosa a video il nome del comando che invierà ed il nome del file stesso, quindi stamperà a video la stringa ricevuta da Vulnserver; invierà quindi il comando HELP seguito dalla stringa di buffer overflow generata automaticamente da Spike.

Creiamo l’applicazione che eseguirà gli script

Per fare questo utilizzeremo il linguaggio Perl; non essendo la programmazione oggetto di questi tutorial non mi soffermerò sulla sintassi della applicazione.

Di seguito l’applicazione

#!/usr/bin/perl

# Una semplice applicazione per eseguire in sequenza i vari script di Spike

$comando_spike = ‘/usr/bin/generic_send_tcp’;

# Controlla che siano passati tutti I parametri

if ($ARGV[4] eq “”) {

die (“utilizzare $0 Indirizzo macchina target, porta, progressivo file spk , skipvar, skipstr\n\n”);

}

# Indica al programma da quale script file partire

$progressivofile = $ARGV[2];

@files = <*.spk>;

# Per ogni file con estensione *.spk esegue il seguente comando

Foreach $file (@files) {

If (! $progressivofile) {

If (system(“$comando_spike $ARGV[0] $ARGV[1] $file $ARGV[3] $ARGV[4]”) ) {

# segnala dove si e’ interrotto il programma

Print “Il programma si e’ interrotto processando il file $file\n”;

}

} else {

$progressivofile–;

}

}

L’applicazione dovrà essere eseguita nella stessa directory in cui sono stati salvati gli script *.spk e marcata come eseguibile con il comando “chmod +x”.

Eseguendo l’applicazione dovremo specificare l’indirizzo ip della macchina con Vulnserver, la porta, da quale script partire “0 = 00help.spk, 1 = 01stats.spk” e poi le variabili skipvar e skipstr descritte nell’articolo precedente.

Per comodità troverete lo script al link: https://mega.co.nz/#!0sxXhQxB!azMCrFlzyx-sMJjSu9VfP2jFA2RT5ntLrZLfTrjI-Bw

Per lanciare l’applicazione quindi scriveremo: “./vulnserver.pl 192.168.159.138 4444 0 0 0

Debuggare Vulnserver

Se non volete aspettare troppo tempo, lanciate l’applicazione con i seguenti parametri:

./vulnserver.pl 192.168.159.138 4444 8 0 0”; verrà eseguito lo script 08kstet.spk che cascherà’ in pochissimo tempo.

Fermate l’applicazione con CTRL-C e come prima cosa esaminate il debugger che mostrerà un errore eseguendo [41414141] e vedrete anche che il registro EIP punterà a [41414141].

Image

Per vedere esattamente quale stringa è stata inviata a Vulnserver basterà utilizzare Wireshark avendo l’accortezza come prima cosa di ordinare i pacchetti catturati con gli ultimi in cima; dopo questo basterà cercare la stringa “Welcome” così da trovare l’ultima volta che Vulnserver ha risposto correttamente. Il pacchetto subito precedente è quello che avrà causato il crash.

[Si ringrazia http”//http://resources.infosecinstitute.com” per l’ottimo tutorial]

Leave a Reply

Your email address will not be published. Required fields are marked *