Vai al contenuto
Home » Shellshock capitolo 1. La prova pratica che le code review servono

Shellshock capitolo 1. La prova pratica che le code review servono

Se non sapete cosa sia la vulnerabilità
shellshock, allora
siete rimasti scollegati dalla rete negli ultimi 4, 5 giorni. In alternativa
non vi occupate né di software, né di Information Technology in generale, il
che in alcune circostanze è un bene.

La vulnerabilità che ha preso il nome di
shellshock

è una issue di security che afflige l’interprete dei comandi bash. Scoperta da Stéphane Chazelas il 12 Settembre e
parcheggiata per permettere la scrittura della patch ed il successivo rilascio
degli aggiornamenti da parte delle principali distribuzioni di Linux e Unix (e
sì, anche Mac OS X, ma la Apple sta ancora pensando a The Fappening).

Resa nota il 24 Settembre a questa vulnerabilità è stato assegnato un primo
identificativo CVE-2014-6271 ed un indicatore di severità, il
CVSS, di 10 su 10.

Cos’è una shell?

I sistemi operativi moderni offrono un’interfaccia grafica che permette di
interagire con il nostro computer, che permette di far fare “cose” a questa che
sarebbe solo una calcolatrice con manie di protagonismo. E a volte con un bel
retina display.

Quest’interfaccia, che permette di creare cartelle, di spostare file da una
cartella all’altra, di lanciare i programmi, di svuotare il cestino, deve
appoggiarsi su un “qualcosa” per parlare con il sistema operativo, che è quella
cosa, per farla MOLTO breve, che gestisce per voi l’hardware, i pezzi di
ferro insomma.

Questo qualcosa, questi servizi offerti dal sistema operativo, formano la
shell. La shell, non è altro che un involucro1 che racchiude il kernel.
Quando aprite il terminale, o il prompt di dos per i più smaliziati, aprite
un programma che espone la shell ai vostri comandi, permettendovi di fare le
stesse cose (in maniera molto più potente e parametrizzata) che fate con
l’interfaccia grafica.

Ok, in breve e molto semplificato, questa è la shell. La bash è
una delle tante shell disponibili, ce ne sono molte altre, ma questa è quella
di default all’interno di un sistema Linux. Ognuno è libero di cambiarsela, ma
questa è quella con cui partite.

La shell che uso io è la zsh, ma tanto non preoccupatevi una
bash voi ce l’avete, così come il buco.

Le vulnerabilità

CVE-2014-6271

Tanto per essere chiari, il problema si chiama errore nell’interpretazione
dell’input. Se un utente dichiara una variabile d’ambiente contenente una
funzione opportunamente formattata in modo da accodare dei comandi arbitrari al
corpo della funzione stessa, la shell non solo prende quell’input e lo mette
nella variabile come se fosse del testo, ma esegue anche tutti i comandi che le
sono stati dati.

$ env x='() { :;}; echo vulnerable' bash -c 'echo hello'
vulnerable
hello
$

La scritta vulnerable non dovrebbe apparire. Appare? Ecco, allora dovete
aggiornare la bash, al posto di “echo vulnerable”, potrebbe esserci un meno
rassicurante “rm -rf /” o “echo 0 > /dev/sda”.

E’ importante notare che il comando arbitrario viene eseguito con gli stessi
privilegi dell’utente che sta assegnando alla variabile “x” il payload
d’attacco.

Un utente non privilegiato, in realtà può far ben pochi danni. Può tirarsi la
zappa sui piedi, non può leggere /etc/shadow ad esempio. L’utente root, al
contrario, può, ma voi non siete sempre connessi con l’utente privilegiato
vero?

Vero?2

In realtà, le vulnerabilità non sono una sola ma cinque. Aperto il vaso di
Pandora, non si sa mai quanta porcheria esce vero? Cinque issue diverse di
security, tutte figlie di codice scritto male. Tutte figlie della stessa
porzione di codice scritta male.

Quella di cui abbiamo parlato prima, che viene testata con quel pezzetto di
codice ha preso l’identificativo
CVE-2014-6271.

CVE-2014-7169

Tavis Ormandy, mentre lavorava alla patch per il
CVE-2014-6271,
ha trovato un altro bug nel parser della shell.

Prendete questo pezzo di codice.

env X='() { (a)=>' sh -c "echo date" cat echo

Sintatticamente non è corretta come definizione, infatti se osservate bene le
parentesi graffe non sono neppure bilanciate. La shell da un messaggio
d’errore, tuttavia il parser prende il codice ‘sh -c “echo date”’ ed esegue il
comando date mettendo l’output in un file chiamato echo.

Se provato a lanciare solo il pezzo aggiunto per attaccare la macchina, vedete
che il comporamento è quello atteso, ovvero “date” viene preso come parametro
del comando “echo” e quindi viene stampata la stringa “date” a video.

$ sh -c "echo date"
date
$

Il problema è nel parser della shell che invece interpreta “date” come un
comando da eseguire ed “echo” come nome del file da usare per redirigerne
l’output.

Lanciato sul mio Mac poco fa:

$ env X='() { (a)=>' sh -c "echo date" cat echo
sh: X: line 1: syntax error near unexpected token `='
sh: X: line 1: `'
sh: error importing function definition for `X'
Tue Sep 30 08:17:36 CEST 2014
$

CVE-2014-7186 e CVE-2014-7187

Florian Weimer, un ricercatore RedHat, mentre lavorava
alla patch per il
CVE-2014-6271,
ha trovato non uno, ma due problematiche. Quando la shell si trova a gestire
più dichiarazioni come «EOF o done permette di concatenare nello stack un
comando arbitrario a spazzatura, comando che ovviamente viene eseguito dalla
shell.

Un sistema vulnerabile a CVE-2014-7186, eseguendo questo codice, stamperà
“CVE-2014-7186 vulnerable, redir_stack”

bash -c 'true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF' ||
echo "CVE-2014-7186 vulnerable, redir_stack"

Invece, un sistema vulnerabile a CVE-2014-7187, stamperà a video “CVE-2014-7187
vulnerable, word_lineno” quando si tenterà di eseguire questo ciclo for.

(for x in {1..200}  do echo "for x$x in ; do :" done for x in {1..200}  do echo done  done) | bash ||
echo "CVE-2014-7187 vulnerable, word_lineno"

CVE-2014-6277 e CVE-2014-6278

Leggete direttamente il post di lcamtuf e scoprite quanto in realtà è profonda la tana del bianconiglio.

L’attacco

Aprire una shell di root e volontariamente assegnare ad una variabile
d’ambiente un payload con un comando dannoso è uno scenario d’attacco non
realistico. Non è così che la vulnerabilità viene sfruttata[^3].

Ci sono, tuttavia, numerosi vettori per portare l’attacco.

Script CGI

I CGI, o Common Gateway Interfaces, sono delle pagine web
dinamiche scritte solitamente in Perl o per i più avventurosi in C o usando la
bash stessa. Solitamente uno script CGI utilizza le variabili d’ambiente per
passare informazioni, comandi, richieste dell’utente a tool terzi presenti
sulla macchina, per eseguire compiti specifici.

Ad esempio HTTP_USER_AGENT può essere usata per passare al programma
informazioni su chi lo sta chiamando, magari per fare multiplexing su vari
servizi ad esempio. Se eseguo una richiesta HTTP, mettendo uno dei pattern
d’attacco dello shellshock in questo campo HTTP e se questo campo viene messo
in una variabile d’ambiente usata da una shell, sono nei guai. Concedo
all’attaccante di eseguire codice arbitrario con i privilegi dell’utente che in
quel momento sta eseguendo il web server. Si spera non root. Si spera.

SSH e DHCP

Possibili vettori d’attacco possono essere anche
OpenSSH grazie alla funzionalità di ForceCommand e
all’uso delle variabili d’ambiente come buffer per memorizzare i comandi da
eseguire e i server DHCP che possono essere configurati per passare pattern
d’attacco a client ed eseguire così codice arbitrario.

Ma quindi opensource vuol dire veramente sicuro?

Spesso confrontandomi davanti ad una birra, quando si parlava di cose
tecnologiche, la dicotomia opensource-sicurezza saltava fuori.

Il software opensource è più sicuro. Il codice è lì a portata di tutti.
Abbasso W$nZ0ZZ! … Così dicevano.

Col senno di poi, questa tesi ha una seria lacuna. Il software opensource è più
sicuro, perché il codice è lì a portata di tutti ma se e solo se qualcuno
il codice lo guarda.

La vulnerabilità era lì, latente, dalla versione 1.13 della bash datata
1992.

22 anni fa.

Questo fa perdere un po’ di certezze anche al fanboi più accanito. Se non si
investe tempo e risorse per fare revisioni del codice per issue di security
anche sul software opensource, lo scenario come quello di questa 4 giorni di
fuoco è quello che ci aspetta.

Lo vedremo nella seconda parte, quando analizzeremo dove è il problema nel
codice della shell, ma stiamo parlando di un pachiderma software non più
mantenuto. Parliamo di codice con uno stile di programmazione che potremmo
definire antidiluviano.

E tutto questo, ha portato ad un software non di qualità e insicuro.

Nonostante, come nel caso di
heartbleed,
la vulnerabilità fosse lì sotto gli occhi di tutti da più di dieci anni.

Mac OS X ed i suoi utenti

Apple ha cura dei propri utenti… ne ha molta cura e li tratta come stupidi.
Sappiamo tutti che la GUI di Mac OS X è fantastica, ma molti utenti usano anche
il Mac per quello che è… un sistema Unix.

Cito il commento di Apple sull’esposizione dei propri utenti, non lo traduco
per evitare di introdurre errori.

The vast majority of OS X users are not at risk to recently reported bash
vulnerabilities,” an Apple spokesperson told iMore. “Bash, a UNIX command
shell and language included in OS X, has a weakness that could allow
unauthorized users to remotely gain control of vulnerable systems. With OS X,
systems are safe by default and not exposed to remote exploits of bash unless
users configure advanced UNIX services. We are working to quickly provide a
software update for our advanced UNIX users.
(fonte: iMore

Brillante deduzione. Se non configuri alcun servizio che accetti connessioni e
magari se tieni il Mac offline allora sei al sicuro da #shellshock.

Per favore, interrompete un attimo la lettura ed alzatevi in piedi per
tributare l’ufficio stampa Apple dell’applauso per la #fuffaware dell’anno.

Mac OS X, come tutti i server unix di questo mondo, può essere vulnerabile…
basta che ospiti un Apache con mod_cgi abilitato ed una pagina dinamica che
usa crea una variabile d’ambiente a fronte di un input dell’utente e
l’exploit è servito.

Per la cronaca, la fix per i sistemi della mela morsicata è per fortuna
disponibile.

Off by one

22 anni.

22 anni senza che persona alcuna pensi sia arrivato il momento di fare una code
review di security su quel software opensource che tutti usiamo.

La bellezza dell’opensource non sta in una presunta sicurezza imposta da una
forza superiore. La bellezza dell’opensource è che la comunità può fare
queste revisioni, perché il codice è aperto e disponibile a tutti.

Se la comunità non lo fa, si perde la bellezza ed il senso di avere il codice
aperto. E giustifica chi, forse perché di parte, afferma che il software
commerciale ha maggiori investimenti in revisioni di sicurezza. Il codice tanto
è chiuso, non potremo mai verificare.

Enjoy!

UPDATE 1
Grazie a @guly che mi ha ricordato i concetti
base delle sottrazioni e per avermi segnalato che mi ero dimenticato dei CVE
scoperti da
lcamtuf

UPDATE 2
Grazie a epinna per la segnalazione sul typo

  1. da qui il nome, per analogia con il mondo dei molluschi 

  2. sì posso capirlo. Lanciare sudo comando è meno veloce di lanciare n
    comandi al secondo all’interno di una sessione con un bel # come prompt dei
    comandi e mostrare al mondo che siamo i Billy the Kid della tastiera. Tuttavia,
    se volete essere dei buoni sysadmin e non rischiare di brasare la vostra
    macchina per un errore, dovete lavorare come utente non privilegiato ed usare
    sudo alla bisogna.
    [^3]: Paolo ama la lingua italiana. to exploit è figo come verbo, ma
    exploitata è ridicolo da sentirsi figurarsi da leggersi. 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *