Una guida: il reverse engineering dell'offuscamento del codice
Pubblicato: 2021-11-17Le cifre dell'offuscamento del codice sono uno degli approcci alla sicurezza delle applicazioni più popolari per prevenire l'hacking delle applicazioni. È uno degli sforzi di AppSec suggeriti più di frequente dagli specialisti della sicurezza di tutto il mondo e spesso si occupa dei requisiti di sicurezza minimi della tua applicazione. Questa strategia viene spesso utilizzata come un importante meccanismo di difesa contro i tentativi di hacking e protegge dalle minacce tipiche come l'iniezione di codice, il reverse engineering e la manomissione delle informazioni personali dei clienti e degli utenti dell'applicazione.
Offuscamento del codice?
La pratica di offuscare gli eseguibili in modo tale che non fossero più comprensibili, intelligibili o pratici è nota come offuscamento del codice. Il codice sorgente è stato offuscato nella misura in cui è incomprensibile e difficile da afferrare per una terza parte, per non parlare dell'esecuzione. L'interfaccia utente dell'utente finale o l'output previsto del codice non sono interessati dall'oscurità. È solo un passaggio precauzionale per rendere il codice inutilizzabile per qualsiasi potenziale hacker che ha accesso al codice eseguibile di un software.
Perché è necessario offuscare il codice?
L'offuscamento del codice è particolarmente importante per il software open source, che presenta uno svantaggio significativo in termini di hackerabilità a vantaggio personale. Gli sviluppatori garantiscono che la proprietà intellettuale del loro prodotto è protetta contro i rischi per la sicurezza, l'accesso illegale e la scoperta di difetti dell'applicazione, rendendo difficile il reverse engineering di un programma.
Indipendentemente dal tipo di tecnica di oscuramento utilizzata, questo approccio limita il codice sorgente pericoloso e garantisce vari livelli di sicurezza del programma. I motivi di tempo, costi e risorse favoriscono tutti l'abbandono del codice quando viene offuscato poiché il codice decompilato viene reso illeggibile.
Tecniche per l'offuscamento del codice
L'offuscamento funziona a vari livelli: può essere implementato a livello di struttura del codice semantico/lessicale oa livello di struttura di dati/flusso di controllo. Anche le strategie di offuscamento differiscono a seconda dell'azione sul codice. In sostanza, il team di sicurezza determina il tipo di offuscamento da utilizzare sul codice in collaborazione con il team di sviluppo.
L'offuscamento dovrebbe essere rinominato.
Questo approccio comporta una denominazione confusa delle variabili in modo che lo scopo effettivo del loro utilizzo sia nascosto in modo intelligente. I decompiler hanno difficoltà a comprendere il flusso di controllo poiché i metodi e le variabili vengono rinominati con varie notazioni e numeri. Questo metodo di offuscamento è comunemente usato per nascondere il codice dell'applicazione della piattaforma Java, .NET e Android. Questo è classificato come offuscamento del layout poiché mira direttamente al codice sorgente per fornire un livello di protezione per l'applicazione.
Offuscamento dei dati
Questo metodo si concentra sulle strutture di dati utilizzate nel codice, rendendo impossibile all'hacker di accedere al vero obiettivo del programma. Ciò può comportare la modifica del modo in cui i dati vengono archiviati in memoria dal software e il modo in cui tali dati vengono elaborati per produrre il risultato finale. Questa procedura può essere eseguita in vari modi:
1. Offuscamento dell'aggregazione
Il modo in cui i dati vengono salvati nel software cambia di conseguenza. Gli array, ad esempio, possono essere suddivisi in più sottoarray a cui è possibile fare riferimento in tutto il programma.
2. Offuscamento della memorizzazione dei dati
Ciò ha un impatto sul modo in cui i dati vengono archiviati in memoria. Gli sviluppatori possono, ad esempio, alternare tra archiviazione variabile locale e globale per oscurare la vera natura del comportamento delle variabili.
3. Ottenere l'offuscamento su richiesta
Questo approccio modifica l'ordine dei dati senza modificare la funzionalità del frammento di programma/codice. Gli sviluppatori ottengono questo risultato creando un modulo distinto che viene invocato per ogni istanza del riferimento variabile.
4. Crittografia delle stringhe
Questa tecnica crittografa tutte le stringhe leggibili, risultando in codice illeggibile. Quando il software viene eseguito, devono essere decrittografati in fase di esecuzione.
5. Offuscamento del flusso di controllo/codice
Il modo in cui il controllo viene trasmesso da una porzione all'altra della codebase è fondamentale per stabilire l'obiettivo del programma. Offuscare questo flusso è spesso il modo più redditizio per pervertire il flusso del gioco. Questa strategia di offuscamento tiene a bada gli hacker rendendo loro difficile capire come e perché il codice sta seguendo un percorso specifico.
L'inclusione di istruzioni casuali e impreviste, nonché inutili istruzioni di cambio caso (codice morto) che non verrebbero mai eseguite, è uno dei modi più diffusi per realizzare questa strategia di offuscamento. Queste affermazioni non hanno altra funzione se non quella di confondere l'hacker preso di mira. Nel caso dell'orientamento condizionale del programma, questa modifica nella sequenza delle istruzioni di esecuzione del programma è estremamente utile.

È in corso il debug dell'offuscamento.
Le informazioni di debug sono spesso utili per determinare informazioni vitali sul flusso del programma e sui difetti decompilando e ricompilando il codice sorgente. È fondamentale nascondere tali dati identificativi alterandone identità, numeri di riga o disattivando completamente l'accesso ai dati di debug.
L'offuscamento dovrebbe essere affrontato.
Gli errori di programmazione della memoria si sono diffusi negli attacchi, specialmente nei linguaggi non sicuri per la memoria come C e C++. I difetti di sicurezza sono spesso causati da errori come l'accesso incontrollato all'array. L'approccio dell'offuscamento degli indirizzi rende difficile il reverse engineering poiché gli indirizzi virtuali del codice e i dati del programma vengono randomizzati ogni volta che viene eseguito il codice convertito. Di conseguenza, la maggior parte degli attacchi di errore di memoria non sono deterministici, con una probabilità di successo molto bassa.
Codifica personalizzata
Gli sviluppatori utilizzano questo approccio per crittografare le stringhe con un algoritmo personalizzato e quindi forniscono una funzione di decodifica per recuperare il codice originale.
Argomenti superati in fase di esecuzione
È possibile modificare il programma in modo tale che preveda parametri in fase di esecuzione. Per decodificare le variabili, l'utente deve disporre sia del codice che della chiave di decrittazione.
Per sviluppare un metodo di difesa a più livelli per la protezione delle applicazioni contro diverse minacce alla sicurezza, il team di sicurezza può scegliere di implementare più di una tecnica contemporaneamente.
Conclusione
Per riassumere, il solo errore di direzione è inefficace nel combattere i problemi di sicurezza avanzati. È più difficile deoffuscare il codice a causa della disponibilità di software ai e dell'abilità degli hacker, ma non è impossibile. Di conseguenza, la crittografia non è una panacea per tutti i problemi di sicurezza del software.
Il team di sviluppo potrebbe utilizzare una varietà di approcci di offuscamento del codice per proteggere il proprio codice in un ambiente non attendibile, a seconda delle esigenze di sicurezza, della natura del programma e del benchmark delle prestazioni. Questi dovrebbero essere eseguiti tenendo conto dei vantaggi e degli svantaggi di ciascun approccio. Altre iniziative AppSec, come crittografia, RASP, normative sulla conservazione dei dati e così via, dovrebbero essere supportate da questa strategia. Se combinato con soluzioni RASP come AppSealing, diventa un potente antidoto ai problemi di sicurezza odierni.