| Forging HTTP Request |
|
|
|
| Sicurezza |
| Venerdì 27 Febbraio 2009 18:05 |
|
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): Una richiesta simile invierà un POST request (con gli stessi header, allo stesso URL, e con argomento a=b&c=d): (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 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. 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: Questo URL rappresenta un oggetto Flash che esegue il seguente codice ActionScript: 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
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: Risposta del server: 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: SERVER'S RESPONSE: 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: SERVER'S RESPONSE: Il seguente script può essere usato per testare la PROPRIA rete per trovare web servers vulnerabili: 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. |