499 parole
2 minuti
Autenticazione SPID con TOTP senza App

Autenticazione SPID con TOTP senza App#

Un giorno stavo navigando su reddit e mi è apparso fra i consigliati un post di un ragazzo che spiegava come era riuscito a ricavare il TOTP dal proprio servizio SPID. Il servizio a cui fa riferimento il post e che uso attualmente io è Lepida ID.

Come funzionano le app di autenticazione#

Dal post reddit

Usando LepidaID, il telefono entra a conoscenza di tutte le informazioni necessarie per impersonare una persona: username, password, secret TOTP.

Le normali registrazioni 2FA invece prevedono il solo scan del QR da telefono, facendo sì che l’unica cosa che c’è nel telefono sia il secret TOTP.

Problemi di Lepida ID#

  • Unico PIN: Con una app separata serve doversi ricordare un PIN di protezione solo per l’OTP di Lepida, quando usando normali app TOTP serve un PIN di protezione unico per proteggere l’accesso a tutti i siti protetti da 2FA.

  • Backup crittografati: Le normali app TOTP hanno anche funzionalità migliori di LepidaID, come backup crittografati.

  • Standard: TOTP è lo standard di fatto per la 2 Factor Authentication, ben collaudato e usato da Google, Facebook, Amazon, GitHub, e una miriade di altri siti. Offuscarlo senza motivo è assurdo e controproducente, quando ci si potrebbe semplicemente allineare alle pratiche e agli strumenti già esistenti e molto ben gestiti, senza la presunzione di volerli reinventare (male).

Come funziona l’offuscamento di Lepida ID#

L’app LepidaID mette in atto un offuscamento davvero banale, quasi vergognoso e perculante: un semplice cifrario a sostituzione.

Per capirlo il ragazzo ha fatto reverse engineering dell’app.

  1. Scarica l’APP
  2. unzip APK
  3. enjarify classes.dex
  4. procyon it/lepida/id/authenticator/CifrarioSostituzione.class

Il decoder risultante è questo:

import sys

encoded = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
decoded = "ORJ2LCE4BPSHAWFTU7YD3NZ5M6IXQGVK"

res = []
for c in sys.argv[1]:
    idx = encoded.find(c.upper())
    if idx == -1:
        res.append(c)
    else:
        res.append(decoded[idx])

print("".join(res))

Ottenere codice TOTP offuscato#

Per fare questo l’utente del post ha fatto un serie di operazioni davvero complicate e contorte ma per fortuna un altro utente è riuscito a creare uno script che automatizasse il processo.

Eccolo qua

#!/usr/bin/python3

import argparse
from urllib.parse import urlparse, parse_qs

import qrcode


START_URL = 'https://id.lepida.it/lepidaid/app/associaAppLogin?1-1.0-loginSMS-loginDiv-loginForm-entra&X-App-Id=PROD-LEPIDAIDAPP-A&X-App-Version=2.0.0'


def decode_secret(secret: str) -> str:
    encoded = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
    decoded = 'ORJ2LCE4BPSHAWFTU7YD3NZ5M6IXQGVK'

    res = []
    for c in secret:
        idx = encoded.find(c.upper())
        if idx == -1:
            raise RuntimeError(f"secret has character {c!r} not from the right set")
        else:
            res.append(decoded[idx])

    return "".join(res)


def main():
    parser = argparse.ArgumentParser(description='Uso di LepidaID con app TOTP standard e sicure')
    parser.add_argument("url", nargs="?", action="store",
                        help="URL con le informazioni TOTP; se non specificato, fornisce istruzioni per ottenerlo")
    args = parser.parse_args()

    if args.url is not None:
        auth_url = args.url
    else:
        print(f'Vai su {START_URL} e segui le istruzioni.')
        print(f'Quando raggiungi una pagina che dice "end login page", incolla l\'URL qui:')
        auth_url = input("URL: ")

    url = urlparse(auth_url)
    qs = parse_qs(url.query)
    key = qs["secretKey"][0]
    secret = decode_secret(key)

    otpauth = f"otpauth://totp/LepidaID?secret={secret}&algorithm=SHA1&period=30&digits=6&issuer=id.lepida.it"

    img = qrcode.make(otpauth)
    img.save("/tmp/qr.png")
    print("Scritto /tmp/qr.png")

    # qr = qrcode.QRCode()
    # qr.add_data(otpauth)
    # qr.print_ascii(out=sys.stdout)


if __name__ == "__main__":
    main()

Seguendo questo script verrà generato un qr code che una volta inquadrato permetterà a qualsiasi authenticatori di autenticarvi su SPID.

Ciao a tutti devstoniani

The Devstone

Autenticazione SPID con TOTP senza App
https://thedevstone.com/posts/autenticazione-spid-con-totp/
Autore
The Devstone
Pubblicato il
2024-10-11