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
profanity-verifier — Verifica dimostrabile per CVE-2022-40769: la chiave privata di un EOA rientra nello spazio delle chiavi raggiungibile tramite Profanity? | Kitploit
Strumenti/GitHubGitHub/artsbykriss/profanity-verifier
Password CrackingScanner di VulnerabilitàAnalisi delle VulnerabilitàExploitCrittografiaPaper e Ricerca
GitHubartsbykriss/profanity-verifier

profanity-verifier

Verifica dimostrabile per CVE-2022-40769: la chiave privata di un EOA rientra nello spazio delle chiavi raggiungibile tramite Profanity?

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
Vedi Repository
117h 14m faNon ancora revisionato

profanity-verifier

Verifica dimostrabile per CVE-2022-40769: la chiave privata di un EOA si trova nello spazio delle chiavi raggiungibile dal generatore di vanity address Profanity? Se sì, la chiave è recuperabile e l'account (e tutto ciò che controlla) può essere svuotato da chiunque.

Nessuna euristica. Il risultato è un booleano supportato da una ricerca completa dell'esatto spazio delle chiavi, riproducibile rieseguendo lo stesso shard.

Il bug, dal sorgente originale

Dispatcher.cpp, createSeed():

root@kitploit:~
std::random_device rd;
std::mt19937_64 eng(rd());                 // seeded with only 32 bits  <- CVE-2022-40769
std::uniform_int_distribution<cl_ulong> distr;
cl_ulong4 r;
r.s[0] = distr(eng); r.s[1] = distr(eng);  // 256-bit seed, used directly
r.s[2] = distr(eng); r.s[3] = distr(eng);  // as the private key

Il kernel OpenCL prende poi G^k per quella chiave e avanza, incrementando la chiave di uno a ogni round finché l'indirizzo non corrisponde al pattern richiesto. Quindi l'intero spazio delle chiavi raggiungibile è:

root@kitploit:~
key(x, i) = mt19937_64(x) as a 256-bit scalar + i
x ∈ [0, 2^32)    the 32-bit seed (four billion possibilities)
i ∈ [0, depth]   rounds the generator ran

Cosa fa questo programma

  1. Percorre all'indietro dalla chiave pubblica del candidato: P_j = P − j·G per j ≤ depth. Se Profanity ha generato la chiave, uno di questi punti è una chiave pubblica di seed.
  2. Scansiona i seed nel suo shard; per ogni x deriva mt19937_64(x) e il suo indirizzo.
  3. Una corrispondenza significa che P_j è la chiave pubblica del seed, quindi la chiave privata del candidato è seed(x) + j — recuperabile, quindi svuotabile.

Una corrispondenza è una prova. Nessuna corrispondenza sull'intero intervallo dei seed è la prova del contrario, fino alla profondità scelta.

Verificato

  • MT19937-64 corrisponde esattamente a libstdc++. I valori grezzi di std::mt19937_64 per i seed 0, 1, 12345 e 4294967295 sono stati confrontati limb per limb con un programma g++ che usa std::mt19937_64 + std::uniform_int_distribution<unsigned long long>; identici.
  • Due librerie di curve indipendenti concordano. Gli stessi vettori di test sono stati prodotti con k256 (Rust puro) e secp256k1 (binding libsecp256k1): seed 0 → 0xfef2583edde5637dad990bc5d05d52c8247019cf, seed 12345 → 0x7712c45360f5dfa3a622a815b6073f0351050f13.
  • --selftest verifica derivazione, indirizzo, camminata sulla catena, recupero tramite camminata all'indietro e una scansione end-to-end dei seed che trova un seed noto.

Eseguitelo voi stessi:

root@kitploit:~
cargo run --release -- --selftest

Utilizzo

root@kitploit:~
profanity-verifier --address 0x... [--pubkey 0x...] --shard i/n [--depth 16777216]
  • --pubkey — la chiave pubblica non compressa del candidato (64 byte di x||y, con o senza il prefisso 0x04). Recuperala da qualsiasi transazione firmata dall'indirizzo. Senza di essa, si può testare solo la posizione 0 nella catena.
  • --shard i/n — la porzione dello spazio dei seed a 32 bit da cercare, così il lavoro si parallelizza tra più macchine.
  • --depth — quanto in avanti lungo la catena del generatore cercare. 2^24 copre un vanity a sei caratteri con margine; valori più profondi costano memoria e tempo.

L'output è una singola riga JSON, ad esempio:

root@kitploit:~
{"address":"0x...","shard":"0/64","depth":16777216,"seeds_checked":67108864,"seconds":833.4,"match":true}

Il seed e la chiave privata non vengono mai stampati né memorizzati. Vengono emessi solo il booleano, l'indirizzo e lo shard, così un risultato può essere pubblicato senza consegnare a nessuno la chiave.

Esecuzione su larga scala

.github/workflows/verify.yml distribuisce la ricerca su una matrice di job (candidate, shard) su runner pubblici.

Throughput misurato: ~20.000 seed/s su 2 core (libsecp256k1). L'intero spazio dei seed 2^32 è di ~59 core-ore, quindi 64 shard × 4 core ≈ 14 minuti di tempo reale per candidato — gratis su un repository pubblico.

Avvia con la lista dei candidati:

root@kitploit:~
gh workflow run profanity-verify -f candidates='[{"address":"0x...","pubkey":"0x..."}]' -f shards=64

Limitazioni

  • Presuppone che il generatore abbia usato std::mt19937_64 di libstdc++, cosa che il confronto limb per limb copre. Build contro una libreria standard diversa avrebbero una mappatura diversa.
  • depth limita la ricerca. Un candidato generato dopo una ricerca insolitamente lunga (pattern vanity molto lunghi) può trovarsi oltre tale limite.
  • La copertura completa richiede una chiave pubblica. Senza una firma dall'indirizzo, è testabile solo la posizione 0 nella catena.
  • Un risultato negativo dice "non nello spazio Profanity" — non dice nulla su qualsiasi altra debolezza.
Scarica lo strumento