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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
px-vm — Kit di reverse engineering per la VM bytecode di PerimeterX, con un disassemblatore basato su CFG, pipeline di decrittazione a 5 livelli, ricostruzione della tabella degli opcode e pulitore di emulazione stack per la ricerca sulla sicurezza nel fingerprinting del rilevamento bot. | Kitploit
Strumenti/GitHubGitHub/b9ph0met/px-vm
Analisi Dinamica (Sandboxing)Evasione IDS/IPSReverse EngineeringSicurezza WebAnalisi MalwareCrittografiaAnalisi di BinariPaper e RicercaApprendimento e FormazioneAnti-BotSpoofing dell'Impronta Digitale
5514265 mesi 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 →
GitHub
b9ph0met/px-vm

px-vm

Kit di reverse engineering per la VM bytecode di PerimeterX, con un disassemblatore basato su CFG, pipeline di decrittazione a 5 livelli, ricostruzione della tabella degli opcode e pulitore di emulazione stack per la ricerca sulla sicurezza nel fingerprinting del rilevamento bot.

Vedi Repository
Condividi

Analisi della VM di PerimeterX Auditor

Riepilogo

Questo repository documenta il reverse engineering di auditor.js di PerimeterX, una macchina virtuale basata su bytecode utilizzata come livello secondario di fingerprinting nella pipeline di rilevamento bot di PX. Questa analisi copre:

  • Estrazione del bytecode e pipeline di decrittazione a 5 livelli
  • Ricostruzione della tabella degli opcode (107 base + 40 honey + 24 padding + 16 gruppi di superistruzioni)
  • Decrittazione del pool di costanti (1230 voci, 1095 stringhe crittate)
  • Disassemblatore basato su CFG con risoluzione dei sotto-dispatch delle superistruzioni
  • Pulitore tramite emulazione dello stack che produce pseudo-codice leggibile
  • Tecniche anti-analisi: honey opcode, istruzioni sovrapposte, hashing dell'integrità del codice

Nota: Questo repository copre solo una versione (statica) della VM ed è inteso per scopi di ricerca sulla sicurezza e analisi. Non include solver dinamici o implementazioni di solver per produzione.

Contesto

Giovedì 2 aprile 2026, PerimeterX ha distribuito una nuova VM basata su bytecode come parte della loro pipeline di rilevamento bot.

Cosa contiene

auditor.js non assomiglia a un normale script sensore PX. Invece delle solite ricerche di proprietà offuscate e funzioni di raccolta:

  • 8 enormi stringhe base64 (_fg0 a _fg7), il programma VM crittato suddiviso tra variabili
  • Una funzione di decrittazione XOR (_dp) con una chiave per sito (_pk) che decomprime il JSON del programma
  • Un shuffle di Fisher-Yates che permuta la tabella degli opcode in modo che i valori del bytecode differiscano per build
  • Un ciclo di dispatch con 107+ gestori di caso, l'interprete della VM
  • Aritmetica BigInt per la crittografia RSA dell'output del fingerprint
  • Un hash di integrità del codice (_0x8df7) che esegue l'hash del codice sorgente della VM per derivare una chiave di decrittazione, in modo che qualsiasi modifica rompa silenziosamente la decrittazione del bytecode

Passo 1: Estrazione del bytecode

Il programma VM è suddiviso in 8 variabili, concatenate e poi decrittate tramite _dp() usando un cifrario XOR per sito con chiave _pk:

var _pk = 893686289;
function _dp(_b) {
    var _r = atob(_b), _o = new Array(_r.length);
    for (var _i = 0; _i < _r.length; _i++) {
        _o[_i] = String.fromCharCode(
            _r.charCodeAt(_i) ^ (((_pk >>> (8 * (_i % 4))) ^ Math.imul(_i + 1, 0x6B8B4567)) & 0xFF)
        );
    }
    return _o.join("");
}

Il risultato è un oggetto JSON con nomi di chiave offuscati di due caratteri (es. "uo" per seed, "dk" per nonce). Una tabella di mappatura li converte in nomi standard.

node extractor.js
# -> program.json

Struttura del programma

CampoDescrizione
sSeed (12755), guida tutte le operazioni crittografiche
nNonce (1603730985), randomizzazione per programma
gFlag generatore, abilita il livello di decrittazione con hash di integrità
xFlag crittato, le costanti sono crittate con XOR
cPool di costanti, 1230 voci
fFunzioni, 112 voci con bytecode crittato
ePunto di ingresso, indice funzione 0

Passo 2: Decrittazione delle costanti

Tutte le 1095 stringhe costanti sono crittate con due livelli:

Livello 1: Murmur XOR statico con chiave 4008000571, dipendente dalla posizione.

Livello 2: XOR del flusso PRNG utilizzando un LCG di glibc, inizializzato combinando il seed del programma con l'indice di ogni costante tramite l'hash moltiplicativo di Knuth.

Prima della decrittazione, il seed viene XORato con un impronta ambientale (_0xaf48), una maschera di bit a 8 bit calcolata sondando le API del browser:

BitTestChrome
0typeof window.matchMedia === "function"1
1document.elementFromPoint esiste1
2typeof window.requestAnimationFrame === "function"1
3typeof window.getComputedStyle === "function"1
4CSS.supports esiste1
5navigator.sendBeacon esiste1
6document.execCommand esiste1
7process.versions.node esiste (Node.js)0

Per Chrome: _0xaf48 = 0b01111111 = 127, dando seed effettivo = 12755 ^ 127 = 12716.

Ciò significa che lo stesso programma produce risultati di decrittazione diversi in ambienti diversi. Eseguirlo in Node.js vs Chrome vs Firefox produce seed diversi.

node decrypt_constants.js
# -> program_decrypted.json, constants_table.txt

Cosa rivelano le costanti

Le stringhe decrittate ci dicono esattamente cosa la VM sta raccogliendo come fingerprint:

Fingerprinting del browser: screenWidth, screenHeight, innerWidth, innerHeight, devicePixelRatio, colorDepth, platform, userAgent, language, timezone, timezoneOffset, forcedColors, highContrast

Tempi di performance: navigationStart, domComplete, domLoading, fetchStart, requestStart, responseEnd, secureConnectionStart, serverTiming

Crittografia RSA: BigInt, modPow, AQAB (65537 in base64), modulusLength, shiftLeft, shiftRight, getRandomValues

Sondaggio DOM/SVG: http://www.w3.org/2000/svg, createElementNS, getBoundingClientRect, getTotalLength, getBBox

Nomi dei campi PX: mtr, tst, mst, enc, sbx, fstec, pdc, prb, wvi, wva, pti, dis, los, cv, sc, jd, ads, enve, init

Riferimenti endpoint: https://fst-ec.perimeterx.net/?id=

Anti-debugger: _CMP_RCX_07;_JNZ_0x0A_EB_CC, CC|CD-04|BREAKPOINT-005

Passo 3: Tabella degli opcode

107 opcode base che coprono l'intero linguaggio JavaScript, più rumore generato dinamicamente:

40 honey opcode sono implementazioni alternative di operazioni aritmetiche/di confronto che utilizzano espressioni matematicamente equivalenti ma sintatticamente diverse. ADD potrebbe apparire come (a^b) + 2*(a&b) o -((-a)-b) o a-(-b). Ogni opcode base può avere fino a 3 varianti, generate deterministicamente dal seed. Una semplice istruzione ADD può apparire come 4 diversi valori di bytecode all'interno dello stesso programma, rompendo gli approcci di pattern-matching.

24 padding opcode sono allocati nella permutazione ma non hanno gestori e non vengono mai emessi. Esistono per espandere lo spazio degli opcode e rendere più difficile invertire lo shuffle.

16 gruppi di superistruzioni sono la caratteristica anti-analisi più importante. Quando il ciclo di dispatch risolve un opcode in un leader di superistruzione, il gestore legge un byte aggiuntivo dal flusso di bytecode e lo invia a un sotto-gestore. Il sotto-gestore può essere un'operazione completamente diversa:

Leader si risolve comeSotto-byteEffettivamente esegue
FOR_IN_NEXT74FOR_IN_NEXT
FOR_IN_NEXT100MAKE_CLOSURE
ASSIGN_OP_VAR165ASSIGN_OP_VAR
ASSIGN_OP_VAR37JMP
GET_VAR_PROP_C143SET_VAR_POP
GET_VAR_PROP_C23JMP_NULLISH

La tabella degli opcode viene mescolata tramite Fisher-Yates inizializzato con il seed effettivo, quindi i valori del bytecode differiscono per build.

node build_opcodes.js
# -> opcode_table.json, opcode_table.txt

Passo 4: Costruttore CFG

Il nucleo del toolkit. cfg.js costruisce un grafo di flusso di controllo seguendo tutti i percorsi di esecuzione da PC=0, decodificando ogni istruzione con il corretto contesto di crittazione.

Perché non un disassemblatore lineare

Scarica lo strumento