Asterisk Dialstring Injection
by admin on Mar.06, 2010, under Asterisk, Sicurezza, Telefonia, VoIP
Qualche giorno fa il ricercatore Hans Petter Selasky ha messo in all’erta la comunità degli sviluppatori, implementatori ed utenti di Asterisk, circa il rischio di una possibile string injection nel dialplan del PBX, molto simile nel principio di funzionamento alla ben nota SQL injection.
Molti protocolli VoIP, compresi IAX2 e SIP, possiedono un set piuttosto esteso di caratteri utilizzabile per la definizione delle extensions, come separatori nelle applicazioni dial() e queue(), e all’interno delle dialstring che tali applicazioni inviano ai channel drivers in Asterisk.
Questa caratteristica, se non opportunamente controllata, e qualora sia presente un carattere jolly, come nell’esempio seguente:
[from_internal]
exten => _X.,1,Dial(SIP/${EXTEN})
rende possibile l’esecuzione di chiamate normalmente non consentite.
In un caso simile, diviene infatti possibile forgiare un INVITE con dati come 300&Zap/g1/4565554321 per creare, in uscita, un channel addizionale non previsto.
Ovvero, come nella SQL injection, quella che è una caratteristica programmaticamente importante si trasforma in una vulnerabilità qualora manchi un rigido controllo dell’imput consentito.
Il fenomeno è facilmente verificabile anche utilizzando solamente la console di Asterisk:
*CLI> console dial 444&SIP/voipcheap.com/00393213245678@from_internal
== Console is full duplex
-- Executing [444&SIP/voipcheap.com/00393213245678@from_internal:1] Dial(”Console/dsp”, “SIP/444&SIP/voipcheap.com/00393213245678″) in new stack
== Using SIP RTP CoS mark 5
*CLI> [Mar 6 18:24:41] WARNING[4284]: chan_sip.c:5329 create_addr: No such host: 444
[Mar 6 18:24:41] WARNING[4284]: app_dial.c:1745 dial_exec_full: Unable to create channel of type ‘SIP’ (cause 20 - Unknown)
== Using SIP RTP CoS mark 5
– Called voipcheap.com/00393213245678
[Mar 6 18:24:41] NOTICE[4197]: chan_sip.c:17763 handle_response_invite: Failed to authenticate on INVITE to ‘”asterisk” ;tag=as67de60de’
– SIP/voipcheap.com-00000002 is circuit-busy
== Everyone is busy/congested at this time (2:0/1/1)
– Auto fallthrough, channel ‘Console/dsp’ status is ‘CONGESTION’
<< Hangup on console >>
Nell’esempio la chiamata non procede oltre solo per il fatto di non avere impostato alcun account relativo al provider sip, che di conseguenza non la ha autorizzata.
In ragione di quanto appena visto, si rende quanto mai opportuno far filtrare la variabile ${EXTEN}, prima del suo effettivo utilizzo, da funzioni che accettino solamente i caratteri previsti dal programmatore del dialplan. Tali funzioni possono essere FILTER(), oppure REGEX(), come nell’esempio seguente:
[from_internal]
exten => _X.,1,gotoif(${REGEX(”&,/|@” ${EXTEN})}?bad_context,s,1)
…
[bad_context]
exten => s,1,playback(invalid)
exten => s,2,congestion


