Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2022-0778 — Proof-of-concept exploit per CVE-2022-0778, che dimostra un ciclo infinito in BN_mod_sqrt di OpenSSL tramite un certificato X.509 appositamente creato con parametri di curva non primi, consentendo attacchi denial-of-service. | Kitploit
Strumenti/GitHubGitHub/drago-96/cve-2022-0778
Analisi delle VulnerabilitàExploitCrittografiaAnalisi di BinariPaper e RicercaApprendimento e Formazione
GitHubdrago-96/cve-2022-0778

CVE-2022-0778

Proof-of-concept exploit per CVE-2022-0778, che dimostra un ciclo infinito in BN_mod_sqrt di OpenSSL tramite un certificato X.509 appositamente creato con parametri di curva non primi, consentendo attacchi denial-of-service.

Vedi Repository
1814684 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2022-0778

La vulnerabilità scoperta innesca un ciclo infinito nella funzione BN_mod_sqrt() di OpenSSL durante l’analisi di una chiave di curva ellittica. Ciò significa che un certificato X.509 creato ad arte può causare un DoS su qualsiasi server non ancora patchato.

Il cuore della vulnerabilità risiede nell’analisi delle chiavi EC con punti in formato compresso: durante l’analisi di questo tipo di chiavi, OpenSSL tenterà di espandere il punto compresso, cercando di calcolare una radice quadrata modulo il primo p su cui è definita la curva. Tuttavia, la primalità di p non viene verificata in nessun punto, nemmeno in BN_mod_sqrt() per la quale è un requisito; quindi un bug nell’implementazione causerà un ciclo infinito a causa del fatto che p non è primo come previsto.

La spiegazione in cinese è disponibile sul mio blog OpenSSL CVE-2022-0778漏洞问题复现与非法证书构造

Crediti

  • Tavis Ormandy per aver scoperto e divulgato la vulnerabilità
  • Drago per aver pubblicato il test contro BN_mod_sqrt()
  • catbro666 per aver effettivamente creato un certificato X.509 che blocca il server
  • wllm-rbnt per l’utile strumento asn1template

Come testare

Il prerequisito è avere installato gcc e una versione vulnerabile di OpenSSL.

Per il bug in BN_mod_sqrt(): compila con gcc -o my_bad_sqrt my_bad_sqrt.c -lcrypto, esegui ./my_bad_sqrt e guardalo bloccarsi per sempre! :D

Con un certificato: esegui openssl x509 -in certs/cert.der.new -inform DER -text -noout sulla riga di comando; anche questo si blocca.

Raggiungere il ciclo

La funzione BN_mod_sqrt() implementa l’algoritmo Tonelli-Shanks per trovare una radice quadrata modulare, cioè dato un intero a e un numero primo p, restituisce un valore r tale che r^2 == a (mod p).

Analizzando il commit che corregge la vulnerabilità, vediamo che il colpevole è il ciclo che trova l’indice minimo i per cui b^(2^i)==1 (mod p), dove b è definito prima nell’algoritmo.

Il ciclo viene cambiato da

i = 1;
if (!BN_mod_sqr(t, b, p, ctx))
    goto end;
while (!BN_is_one(t)) {
    i++;
    if (i == e) {
        ERR_raise(ERR_LIB_BN, BN_R_NOT_A_SQUARE);
        goto end;
    }
    if (!BN_mod_mul(t, t, t, p, ctx))
        goto end;
}

a

for (i = 1; i < e; i++) {
    if (i == 1) {
        if (!BN_mod_sqr(t, b, p, ctx))
            goto end;
    } else {
        if (!BN_mod_mul(t, t, t, p, ctx))
            goto end;
    }
    if (BN_is_one(t))
        break;
}

Nel secondo caso c’è un ciclo for limitato dalla variabile e; nel codice originale invece c’è solo un controllo per il caso i==e all’interno di un ciclo while.

Poiché questi cicli sono all’interno di un ciclo più grande che per ogni iterazione imposta il nuovo valore di e al valore corrente di i, proviamo la seguente strategia d’attacco:

  1. nella prima esecuzione del ciclo esterno, fare in modo che alla fine i=1; per questo, abbiamo bisogno che b^2=1 (mod p).
  2. in questo modo, durante la seconda esecuzione avremo e=1, e se riusciamo ad entrare nel ciclo interno il controllo i==e fallirà sempre
  3. se riusciamo ad avere sempre t != 1 (mod p), rimarremo nel ciclo per sempre

Nota che i primi due passi possono effettivamente accadere in un’esecuzione “normale”, cioè con un p primo. Tuttavia, se p è composto possiamo anche soddisfare il terzo passo!

Un po’ di matematica

L’algoritmo Tonelli-Shanks funziona scrivendo p - 1 = 2^e * q, con q dispari. Questo è anche l’ordine del gruppo moltiplicativo degli interi modulo p, e i valori e e q verranno usati molte volte durante l’esecuzione; tuttavia, se p non è primo, l’ordine del gruppo moltiplicativo non sarà p-1, e questo ci aiuterà ad entrare nel ciclo infinito.

In particolare, b è inizializzato come b = a^q (mod p), il che significa che se p fosse primo, allora b avrebbe ordine una potenza di 2, che poi troveremo usando il ciclo.

Ma se impostiamo p = r * s, l’ordine del gruppo moltiplicativo è (r-1)*(s-1) = r*s - r - s + 1 invece di r*s-1. L’algoritmo usa il valore q per ottenere un elemento y di ordine esattamente 2^e; tuttavia, quando p non è primo, il valore q non avrà un significato speciale per l’ordine, quindi l’elemento y non avrà ordine una potenza di due modulo p=r*s.

Poiché alla fine del primo ciclo esterno b viene impostato a b = b*y^(e-i) (mod p), alla sua seconda iterazione il ciclo interno cercherà di trovare un valore i per cui b^(2^i) == 1 (mod p), ma fallirà dato che y non è più garantito avere ordine una potenza di due.

L’exploit

I numeri nell’exploit sono molto semplici: prendiamo r=17, s=41, che danno p=r*s=697. Ciò significa che i valori calcolati di e e q saranno p-1 = 2^3 * 87.

Scegliamo quindi a=696, il che significa a == -1 (mod p) e anche b == -1 (mod p) quando inizializzato. Questo soddisfa il passo 1 impostando e=1 per il ciclo esterno successivo.

Poi b sarà impostato a un elemento con ordine non una potenza di 2, e il ciclo interno rimarrà bloccato cercando di trovare un i per cui b^(2^i)==1 (mod p).

Creazione di un certificato pericoloso

OK, ora creiamo un certificato pericoloso che contiene parametri di curva espliciti non validi con un punto base codificato in forma compressa.

I file di questa sezione si trovano nella cartella certs.

Creazione di un certificato normale con parametri di curva espliciti

Per prima cosa dobbiamo creare una chiave privata EC. Poiché vogliamo un certificato target con parametri di curva espliciti, anche la chiave deve contenere parametri di curva espliciti.

$ openssl ecparam -out ec.key -name prime256v1 -genkey -noout -param_enc explicit -conv_form compressed

Poi, per comodità, abbiamo auto-firmato un certificato e lo abbiamo emesso in formato DER.

$ openssl req -new -x509 -key ec.key -out cert.der -outform DER -days 360 -subj "/CN=TEST/"

Controlliamo le informazioni del certificato. Contiene parametri di curva espliciti come previsto.

$ openssl x509 -in cert.der -text -noout -inform DER
...
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
                    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
                    00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
                    bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
                    60:4b
                Generator (compressed):
                    03:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
                    40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
                    98:c2:96
                Order:
                    00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
                    ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
                    63:25:51
...

Creazione di un certificato non valido

Ora dobbiamo modificare i valori di questi parametri: Prime, A, B, Generator. Devono soddisfare l’equazione sottostante

dove p è il Prime, a è il parametro A e b è il parametro B. p, a, b insieme determinano una curva. Decomprimere un punto significa calcolare la coordinata Y dalla corrispondente coordinata X.

Scarica lo strumento