Come evitare il reverse engineering di un file APK?


764

Sto sviluppando un'app di elaborazione dei pagamenti per Android e voglio impedire a un hacker di accedere a qualsiasi risorsa, risorsa o codice sorgente dal file APK .

Se qualcuno modifica l'estensione .apk in .zip, può decomprimerlo e accedere facilmente a tutte le risorse e risorse dell'app e, usando dex2jar e un decompilatore Java, può anche accedere al codice sorgente. È molto semplice decodificare un file APK per Android - per maggiori dettagli vedi la domanda Stack Overflow Ingegnerizzazione inversa da un file APK a un progetto .

Ho usato lo strumento Proguard fornito con l'SDK di Android. Quando eseguo il reverse engineering di un file APK generato utilizzando un keystore firmato e Proguard, ottengo un codice offuscato.

Tuttavia, i nomi dei componenti Android rimangono invariati e alcuni codici, come i valori-chiave utilizzati nell'app, rimangono invariati. Come da documentazione Proguard, lo strumento non può offuscare i componenti menzionati nel file manifest.

Ora le mie domande sono:

  1. Come posso impedire completamente il reverse engineering di un APK Android? È possibile?
  2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?
  3. C'è un modo per rendere l'hacking più difficile o addirittura impossibile? Cosa posso fare di più per proteggere il codice sorgente nel mio file APK?

120
Sembra che tu stia usando la "sicurezza per oscurità" se il tuo schema di elaborazione dei pagamenti si basa sul funzionamento del cliente che rimane segreto.
PeterJ,

43
Hai mai pensato di scrivere le parti importanti del codice in C / C ++ e di aggiungerle come libreria compilata? Possono essere smontati nel codice assembly, ma la retroingegnerizzazione di una grande libreria dall'assembly richiede molto tempo.
Leone,


60
Benvenuti nella questione fondamentale della creazione di qualsiasi risorsa digitale. Gli hacker possono arrivare al livello di istruzione della macchina, quindi se un computer è in grado di leggere il file, allora può essere hackerato aperto / copiato, nessuna offuscamento o DRM può mai fermare completamente un determinato hacker. Se hai bisogno di sicurezza, assicurati che le chiavi private non siano mai nel sorgente e sappi che in fase di progettazione solo l'isolamento (hardware remoto e / o dedicato) può mai proteggerle.
Keith,

16
Tieni presente che, a seconda di ciò che fa la tua app di elaborazione dei pagamenti, potrebbero esserci delle norme normative e legali che riguardano la tua app e potrebbero esporti potenzialmente a gravi sanzioni: consulta la conformità PCI, a partire da pcicomplianceguide.org/pcifaqs.php#11 .
Bloopletech,

Risposte:


372

 1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?

AFAIK, non esiste alcun trucco per evitare completamente il reverse engineering.

E anche molto ben detto da @inazaruk: Qualunque cosa tu faccia al tuo codice, un potenziale attaccante è in grado di cambiarlo in qualsiasi modo lo ritenga fattibile . Fondamentalmente non puoi proteggere la tua applicazione dalla modifica. E qualsiasi protezione inserita può essere disabilitata / rimossa.

 2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?

Puoi fare diversi trucchi per rendere più difficile l'hacking. Ad esempio, utilizzare l'offuscamento (se si tratta di codice Java). Questo di solito rallenta significativamente il reverse engineering.

 3. C'è un modo per rendere l'hacking più duro o addirittura impossibile? Cosa posso fare di più per proteggere il codice sorgente nel mio file APK?

Come dicono tutti, e come probabilmente saprai, non esiste una sicurezza al 100%. Ma il punto di partenza per Android, integrato da Google, è ProGuard. Se hai la possibilità di includere librerie condivise , puoi includere il codice necessario in C ++ per verificare le dimensioni dei file, l'integrazione, ecc. Se hai bisogno di aggiungere una libreria nativa esterna alla cartella della libreria del tuo APK su ogni build, puoi usarla dal suggerimento di seguito.

Inserire la libreria nel percorso della libreria nativa che per impostazione predefinita è "libs" nella cartella del progetto. Se hai creato il codice nativo per il target 'armeabi', mettilo in libs / armeabi . Se è stato creato con armeabi-v7a, mettilo sotto libs / armeabi-v7a.

<project>/libs/armeabi/libstuff.so

1
Per la transazione di pagamento ho usato lo standard ISO 8585, in questo momento lo schema per questo standard è in coppia chiave-valore utilizzando la raccolta HashMap di Java e quando eseguo il reverse engineering su apk ottengo tutto lo schema. È possibile evitare lo schema ottenere esposto tramite reverse engineering. Il tuo ultimo suggerimento su Share libraries può essere utile in questo caso? Doy hai qualche link in modo che io possa ottenere esposizione alle librerie di condivisione in Android.
sachin003,

4
che ne dici di crittografare le tue stringhe nel codice e decrittografarle in fase di esecuzione? Se esegui la decrittografia su un server remoto, come suggerito da altre persone, non ottieni il problema che la chiave di decrittografia si trova nei sorgenti.
Kutschkem,

sì, la crittografia è il modo, ma non è sicuro di non essere compromesso. Se sto crittografando String per decrittografarli, ho bisogno di un ID univoco nel codice. e se qualcuno è in grado di decompilarlo, sarà molto facile ottenere l'ID univoco.
Bhavesh Patadiya,

perché hai aggiunto elementi modificati ? è tutto normale.
Mohammed Azharuddin Shaikh,

@hotveryspicy: sì, ora ho rimosso il segno "modificato" dalla risposta. Ho modificato la mia risposta perché voleva sapere di più su come le librerie di condivisione sono utili in questo caso.
Bhavesh Patadiya,

126

AFAIK, non puoi proteggere i file nella directory / res più di quanto siano protetti in questo momento.

Tuttavia, ci sono dei passaggi che puoi adottare per proteggere il tuo codice sorgente, o almeno quello che fa se non tutto.

  1. Usa strumenti come ProGuard. Ciò offuscherà il tuo codice e renderà più difficile la lettura quando decompilato, se non impossibile.
  2. Sposta le parti più critiche del servizio fuori dall'app e in un servizio Web, nascosto dietro un linguaggio lato server come PHP. Ad esempio, se hai un algoritmo che ti richiede un milione di dollari per scrivere. Ovviamente non vuoi che le persone lo rubino dalla tua app. Sposta l'algoritmo e falla elaborare i dati su un server remoto e utilizza l'app per fornirli semplicemente. Oppure usa NDK per scriverli nativamente in file .so, che hanno molte meno probabilità di essere decompilati rispetto agli apk. Non credo che esista un decompilatore per i file .so al momento (e anche se lo facesse, non sarebbe buono come i decompilatori Java). Inoltre, come indicato da @nikolay nei commenti, è necessario utilizzare SSL quando si interagisce tra il server e il dispositivo.
  3. Quando si memorizzano valori sul dispositivo, non archiviarli in un formato non elaborato. Ad esempio, se hai un gioco e stai memorizzando la quantità di valuta di gioco che l'utente ha in SharedPreferences. Supponiamo che siano le 10000monete. Invece di salvare 10000direttamente, salvalo usando un algoritmo come ((currency*2)+1)/13. Quindi, invece di 10000, salvi 1538.53846154in SharedPreferences. Tuttavia, l'esempio sopra non è perfetto e dovrai lavorare per trovare un'equazione che non perda la valuta a causa di errori di arrotondamento ecc.
  4. Puoi fare una cosa simile per le attività sul lato server. Ora per un esempio, prendiamo effettivamente la tua app per l'elaborazione dei pagamenti. Supponiamo che l'utente debba effettuare un pagamento di $200. Invece di inviare un $200valore non elaborato al server, invia una serie di valori più piccoli, predefiniti, che si sommano $200. Ad esempio, disporre di un file o di una tabella sul server che equipari le parole ai valori. Quindi diciamo che Charliecorrisponde a $47e Johna $3. Quindi, invece di inviare $200, è possibile inviare Charliequattro volte eJohnquattro volte. Sul server, interpretare ciò che significano e aggiungerlo. Questo impedisce a un hacker di inviare valori arbitrari al tuo server, poiché non sanno quale parola corrisponde a quale valore. Come ulteriore misura di sicurezza, potresti avere un'equazione simile al punto 3 anche per questo, e cambiare le parole chiave ogni nnumero di giorni.
  5. Infine, puoi inserire un codice sorgente casuale inutile nella tua app, in modo che l'hacker stia cercando un ago in un pagliaio. Inserisci classi casuali contenenti frammenti da Internet o solo funzioni per calcolare cose casuali come la sequenza di Fibonacci. Assicurati che queste classi vengano compilate, ma non vengano utilizzate dall'effettiva funzionalità dell'app. Aggiungi abbastanza di queste false classi e l'hacker avrebbe difficoltà a trovare il tuo vero codice.

Tutto sommato, non c'è modo di proteggere la tua app al 100%. Puoi renderlo più difficile, ma non impossibile. Il tuo server web potrebbe essere compromesso, l'hacker potrebbe capire le tue parole chiave monitorando gli importi delle transazioni multiple e le parole chiave che invii per esso, l'hacker potrebbe scrupolosamente esaminare la fonte e capire quale codice è un manichino.

Puoi solo contrattaccare, ma non vincere mai.


136
Invece di fare trucchi con i valori che invii al tuo server, usa SSL e convalida correttamente il certificato del server. La sicurezza per oscurità è generalmente una cattiva idea.
Nikolay Elenkov il

48
puoi inserire codice sorgente casuale inutile nella tua app . Neanche questo può davvero aiutare. Questo non farà che gonfiare l'applicazione, rendendo anche più difficile la manutenzione.
Anirudh Ramanathan,

4
Potresti anche falsificare l'uso del codice inutile e inviare i dati al server che lo eliminerà. Forse una falsa sicurezza, ma un dolore nel culo per il potenziale hacker, giusto?
Benoit Duffez,

19
Se il tuo algoritmo vale un milione di dollari, solo perché non c'è un decompilatore per i .sofile non significa che non riesco a leggere l'assemblaggio :) Molti di questi cadono nella stessa trappola, solo offuscando invece di proteggerti adeguatamente. L'offuscamento funziona solo se non vale la pena seguire un attaccante, quindi se costruisci qualcosa su queste tecniche faresti meglio a sperare che non diventino popolari, altrimenti sei fregato perché all'improvviso la tua base di codice non è mantenibile e ha bisogno di enormi cambiamenti.
Phoshi,

23
Non capisco perché questa risposta abbia un punteggio così alto. 3. e 4. per uno sono semplicemente stupidi e non equivalgono a nessuna sicurezza.
Matti Virkkunen,

117

In nessun momento della storia dell'informatica è mai stato possibile prevenire il reverse engineering del software quando ne si dà una copia funzionante al proprio aggressore. Inoltre, con ogni probabilità, non sarà mai possibile .

Con ciò capito, esiste una soluzione ovvia: non dare i tuoi segreti al tuo aggressore. Sebbene non sia possibile proteggere i contenuti dell'APK, ciò che è possibile proteggere è tutto ciò che non si distribuisce. In genere si tratta di un software lato server utilizzato per operazioni come l'attivazione, i pagamenti, l'applicazione delle regole e altri succosi frammenti di codice. Puoi proteggere beni preziosi non distribuendoli nel tuo APK. Invece, configura un server che risponde alle richieste della tua app, "usa" le risorse (qualunque cosa ciò significhi) e quindi restituisce il risultato all'app. Se questo modello non funziona per le risorse che hai in mente, allora potresti voler ripensare la tua strategia.

Inoltre, se il tuo obiettivo principale è prevenire la pirateria delle app : non preoccuparti nemmeno. Hai già bruciato più tempo e denaro su questo problema di quanto qualsiasi misura antipirateria possa mai sperare di salvarti. Il ritorno sugli investimenti per risolvere questo problema è così basso che non ha senso nemmeno pensarci.


21
Il primo paragrafo è la risposta migliore. Se il tuo aggressore controlla l'hardware, sarà sempre in grado di sconfiggere il tuo software in qualche modo. Tutto ciò che deve veramente essere protetto deve rimanere sull'hardware che controlli, è semplice. E anche il paragrafo finale, sul ROI, è perfetto.
Daniel Pryden,

88

Prima regola della sicurezza delle app: qualsiasi macchina a cui un utente malintenzionato ottiene l'accesso fisico o elettronico senza restrizioni ora appartiene al tuo aggressore, indipendentemente da dove si trovi effettivamente o da cosa l'hai pagato.

Seconda regola della sicurezza delle app: qualsiasi software che lasci i confini fisici all'interno dei quali un attaccante non può penetrare ora appartiene al tuo attaccante, indipendentemente da quanto tempo hai impiegato per codificarlo.

Terza regola: qualsiasi informazione che lasci quegli stessi confini fisici che un attaccante non può penetrare ora appartiene al tuo attaccante, non importa quanto sia prezioso per te.

Le basi della sicurezza informatica si basano su questi tre principi fondamentali; l'unico computer veramente sicuro è quello chiuso in una cassaforte, dentro una gabbia di Farraday, dentro una gabbia d'acciaio. Ci sono computer che trascorrono la maggior parte delle loro vite di servizio proprio in questo stato; una volta all'anno (o meno), generano le chiavi private per le autorità di certificazione radice attendibili (di fronte a una miriade di testimoni con telecamere che registrano ogni centimetro della stanza in cui si trovano).

Ora, la maggior parte dei computer non viene utilizzata in questi tipi di ambienti; sono fisicamente all'aperto, collegati a Internet tramite un canale radio wireless. In breve, sono vulnerabili, così come il loro software. Pertanto non ci si deve fidare di loro. Ci sono alcune cose che i computer e i loro software devono sapere o fare per essere utili, ma bisogna fare attenzione a garantire che non possano mai sapere o fare abbastanza per causare danni (almeno non danni permanenti al di fuori dei limiti di quella singola macchina ).

Sapevi già tutto questo; ecco perché stai cercando di proteggere il codice della tua applicazione. Ma qui sta il primo problema; gli strumenti di offuscamento possono rendere il codice un casino per un essere umano che cerca di scavare, ma il programma deve ancora essere eseguito; ciò significa che il flusso logico effettivo dell'app e i dati che utilizza non sono interessati dall'offuscamento. Data una certa tenacia, un utente malintenzionato può semplicemente annullare l'offuscamento del codice, e ciò non è nemmeno necessario in alcuni casi in cui ciò che sta guardando non può essere nient'altro che ciò che sta cercando.

Invece, dovresti cercare di assicurarti che un utente malintenzionato non possa fare nulla con il tuo codice, non importa quanto sia facile per lui ottenerne una copia chiara. Ciò significa che non esistono segreti codificati, poiché tali segreti non sono segreti non appena il codice lascia l'edificio in cui è stato sviluppato.

Questi valori-chiave che hai hardcoded dovrebbero essere completamente rimossi dal codice sorgente dell'applicazione. Invece, dovrebbero trovarsi in uno dei tre posti; memoria volatile sul dispositivo, che è più difficile (ma non impossibile) per un utente malintenzionato ottenere una copia offline di; permanentemente sul cluster di server, a cui controlli l'accesso con un pugno di ferro; o in un secondo archivio di dati non correlato al dispositivo o ai server, ad esempio una scheda fisica o le memorie dell'utente (il che significa che alla fine sarà nella memoria volatile, ma non deve durare a lungo).

Considera il seguente schema. L'utente inserisce le proprie credenziali per l'app dalla memoria nel dispositivo. Sfortunatamente, devi fidarti che il dispositivo dell'utente non è già stato compromesso da un keylogger o da un Trojan; il meglio che puoi fare al riguardo è implementare la sicurezza a più fattori, ricordando le informazioni identificative difficili da falsificare sui dispositivi utilizzati dall'utente (MAC / IP, IMEI, ecc.) e fornendo almeno un canale aggiuntivo tramite che può essere verificato un tentativo di accesso su un dispositivo sconosciuto.

Le credenziali, una volta inserite, vengono offuscate dal software client (usando un hash sicuro) e le credenziali in testo normale vengono scartate; hanno servito al loro scopo. Le credenziali offuscate vengono inviate su un canale protetto al server autenticato con certificato, che le esegue nuovamente l' hashing per produrre i dati utilizzati per verificare la validità dell'accesso. In questo modo, il client non sa mai cosa viene effettivamente confrontato con il valore del database, il server delle app non conosce mai le credenziali in chiaro dietro ciò che riceve per la validazione, il data server non sa mai come vengono prodotti i dati che archivia per la validazione, e un uomo in la parte centrale vede solo incomprensibili anche se il canale sicuro fosse compromesso.

Una volta verificato, il server trasmette un token sul canale. Il token è utile solo all'interno della sessione sicura, è composto da rumore casuale o da una copia crittografata (e quindi verificabile) degli identificativi di sessione e l'applicazione client deve inviare questo token sullo stesso canale al server come parte di qualsiasi richiesta fare qualcosa. L'applicazione client lo farà molte volte, perché non può fare nulla che coinvolga denaro, dati sensibili o qualsiasi altra cosa che possa essere dannosa da sola; deve invece chiedere al server di eseguire questa attività. L'applicazione client non scriverà mai alcuna informazione sensibile nella memoria persistente sul dispositivo stesso, almeno non in testo normale; il client può chiedere al server sul canale sicuro una chiave simmetrica per crittografare tutti i dati locali, che il server ricorderà; in una sessione successiva il client può richiedere al server la stessa chiave per decrittografare i dati da utilizzare nella memoria volatile. Quei dati non saranno neanche l'unica copia; tutto ciò che il client memorizza dovrebbe anche essere trasmesso in qualche forma al server.

Ovviamente, ciò rende l'applicazione fortemente dipendente dall'accesso a Internet; il dispositivo client non può eseguire nessuna delle sue funzioni di base senza una corretta connessione e autenticazione da parte del server. Non diverso da Facebook, davvero.

Ora, il computer che l'aggressore vuole è il tuo server, perché esso e non l'app / dispositivo client è la cosa che può fargli guadagnare denaro o causare dolore ad altre persone per il suo divertimento. Va bene; ottieni molto più denaro per i tuoi soldi spendendo denaro e sforzi per proteggere il server che nel tentativo di proteggere tutti i client. Il server può essere protetto da tutti i tipi di firewall e altri sistemi di sicurezza elettronica e inoltre può essere fisicamente protetto da acciaio, cemento, accesso con chiave magnetica / pin e videosorveglianza 24 ore su 24. Il tuo aggressore dovrebbe essere davvero molto sofisticato per ottenere direttamente qualsiasi tipo di accesso al server e dovresti (dovresti) saperlo immediatamente.

Il meglio che un utente malintenzionato può fare è rubare il telefono e le credenziali di un utente e accedere al server con i diritti limitati del client. Se ciò dovesse accadere, proprio come la perdita di una carta di credito, l'utente legittimo dovrebbe essere istruito a chiamare un numero 800 (preferibilmente facile da ricordare, e non sul retro di una carta che porterebbe nella borsa, nel portafoglio o nella valigetta che potrebbe essere rubato insieme al dispositivo mobile) da qualsiasi telefono a cui possano accedere che li colleghi direttamente al servizio clienti. Dichiarano che il loro telefono è stato rubato, forniscono alcuni identificativi univoci di base e l'account è bloccato, tutte le transazioni che l'attaccante potrebbe essere stato in grado di elaborare vengono ripristinate e l'attaccante torna al punto di partenza.


1
risposta perfetta !! ho adorato il tuo modo di ottenere dati dal server con un token crittografato, penso che dopo questo sia quasi impossibile decodificare.
Dharam,

So che è un po 'tardi, ma per quanto riguarda l'accesso alla parte di accesso al server. Servizi come Microsoft Azure ti offrono qualcosa del genere per accedere al loro server: MobileServiceClient mClient = new MobileServiceClient ("MobileServiceUrl", // Sostituisci con l'URL del sito sopra "AppKey", // sostituisci con la chiave dell'applicazione) e praticamente chiunque ha accesso a quello che può accedere al loro server e modificarlo
edwinj

@edwinj - Nessun problema nell'informatica che non può essere risolto con un altro livello di riferimento indiretto. Lo snippet fornisce l'idea di base per accedere a un servizio client mobile di Azure; fornisce un livello base di sicurezza contro i "drive-by" della porta principale di Microsoft. A sua volta è possibile aggiungere ulteriori livelli, come richiedere una chiave di sessione (fondamentalmente quale sia il token crittografato) su qualsiasi chiamata di servizio e per ottenere quella chiave, devono prima autenticarsi con una combinazione di conoscenza delle credenziali e dello schema di crittografia.
KeithS

1
Una delle migliori risposte
debo.stackoverflow,

64

 1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?

Questo non è possibile

 2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?

Quando qualcuno cambia un'estensione .apk in .zip, quindi dopo aver decompresso, qualcuno può facilmente ottenere tutte le risorse (tranne Manifest.xml ), ma con APKtool si può anche ottenere il vero contenuto del file manifest. Ancora una volta, un no.

 3. C'è un modo per rendere l'hacking più duro o addirittura impossibile? Cosa posso fare di più per proteggere il codice sorgente nel mio file APK?

Ancora una volta no, ma puoi prevenire fino a un certo livello, cioè

  • Scarica una risorsa dal Web ed esegui un processo di crittografia
  • Utilizzare una libreria nativa precompilata (C, C ++, JNI, NDK)
  • Esegui sempre alcuni hash ( chiavi MD5 / SHA o qualsiasi altra logica)

Anche con Smali, le persone possono giocare con il tuo codice. Tutto sommato, non è POSSIBILE.


7
@TrevorBoydSmith: la crittografia non aiuta molto quando il sistema operativo è open source e rootable. Il sistema ha bisogno di una chiave per decrittografare l'APK ed eseguire roba. E se il sistema ha una chiave e ho accesso illimitato al sistema, allora so dove trovare la chiave e posso accedervi. Significa che ora ho anche la chiave .
cHao,

4
@TrevorBoydSmith: Tuttavia, è la parte "come fare" che uccide l'intera idea. Semplicemente non c'è modo di eseguire direttamente il codice crittografato; ad un certo punto, il codice decrittografato deve essere disponibile. Ciò significa che (1) deve esserci una chiave (a cui io, come root, probabilmente ho accesso), e (2) potrei anche essere in grado di trovare la copia chiara nella RAM e non preoccuparmi comunque della crittografia.
cHao,

3
@TrevorBoydSmith: il problema è che, in questo caso, non puoi semplicemente aumentare il costo sufficiente per renderlo inutile. Non stiamo parlando di chiavi per forzare il bruto qui; stiamo parlando di averli già : il sistema operativo deve avere le chiavi e abbiamo il sistema operativo. L'unico modo per risolverlo sarebbe rendere il sistema operativo irrintracciabile. Buona fortuna; anche Apple non riesce a gestirlo. :)
cHao,

3
@TrevorBoydSmith: non credo sia impossibile aumentare i costi in generale . Penso (e dico), in particolare , che il tuo suggerimento sia impossibile - perché lo è . MATLAB non è Android e ha alcune libertà che Android non ha. In particolare, ha offuscamento dalla sua parte; è molto più difficile nascondere una chiave di crittografia. Android non può farlo. Chiunque abbia il codice sorgente saprebbe dove si nascondono le chiavi e avrebbe uno strumento per recuperarle entro 10 minuti dall'annuncio della funzione. Non è solo possibile farlo; è decisamente banale .
cao

6
@TrevorBoydSmith: non ho insistito per niente del genere. Quello che sto insistendo è che statico, mutevole, mobile, ecc . Non importa . In un sistema operativo open source, la crittografia da sola non può proteggere il codice da chiunque possa decodificarlo. Poiché posso leggere il codice che farebbe la decrittazione, indipendentemente da come la chiave viene acquisita, utilizzata e / o archiviata, posso vedere come l'hai fatta e replicarla - ancora più facilmente di quanto potrei invertire un po 'di segreto codice dell'app.
cHao,

37

Non è possibile evitare al 100% il reverse engineering dell'APK di Android, ma è possibile utilizzare questi modi per evitare di estrarre più dati, come codice sorgente, risorse dal proprio APK e risorse:

  1. Utilizzare ProGuard per offuscare il codice dell'applicazione

  2. Utilizzare NDK utilizzando C e C ++ per inserire il core dell'applicazione e proteggere parte del codice nei .sofile

  3. Per proteggere le risorse, non includere tutte le risorse importanti nella cartella delle risorse con APK. Scarica queste risorse al momento del primo avvio dell'applicazione.


7
Il terzo sta davvero facilitando il lavoro degli aggressori. Annusare la comunicazione di rete è più semplice del reverse engineering.
ottenuto il

Per risolvere il problema del terzo, si potrebbe crittografare il contenuto scaricato e / o utilizzare una connessione crittografata (ad esempio SSL / TLS)
Stradivari,

1
La crittografia della connessione protegge dalle persone che annusano o modificano il traffico. Nel caso in cui l'utente stesso sia dannoso (cioè ha il tuo apk e sta cercando di hackerarlo), otterrà comunque il contenuto utilizzando la tua app, estraendo risorse come utente root; ma sì aiuta contro semplici attacchi di fiuto.
Kevin Lee,

In aggiunta a ciò: 4) usa dexguard per una maggiore offuscamento ma è pagato 5) usa il file OBB per il download delle risorse al momento del download dell'app, aiuterà anche a ridurre le dimensioni dell'app
Ashok Kumar

35

Gli sviluppatori possono adottare le seguenti misure per impedire in qualche modo un APK di furto,

  • il modo più semplice è usare strumenti come ProGuardoffuscare il loro codice, ma fino ad ora, è stato abbastanza difficile impedire completamente a qualcuno di decompilare un'app.

  • Inoltre ho sentito parlare di uno strumento HoseDex2Jar . Si interrompe Dex2Jarinserendo un codice innocuo in un APK Android che confonde e disabilita Dex2Jare protegge il codice dalla decompilazione. Potrebbe in qualche modo impedire agli hacker di decompilare un APK in codice java leggibile.

  • Utilizzare alcune applicazioni lato server per comunicare con l'applicazione solo quando è necessario. Potrebbe aiutare a prevenire i dati importanti.

Non puoi assolutamente proteggere completamente il tuo codice dai potenziali hacker. In qualche modo, potresti rendere difficile e un po 'frustrante il compito di decompilare il tuo codice. Uno dei modi più efficienti è scrivere nel codice nativo (C / C ++) e archiviarlo come librerie compilate.


3
HoseDex2Jar è quasi inutile. Deve solo confondere dex2jar e può essere facilmente bloccato. smali / apktool, ecc. funzionano perfettamente con APK "hosed".
Nikolay Elenkov il

@NikolayElenkov Sai come funziona HoseDex2Jar? Quello che hanno usato per evitare o confondere dex2jar. Perché non riesco a caricare il mio file apk sul web per usare HoseDex2Jar. Se riesco a fare qualcosa come HoseDex2Jar per confondere dex2jar, sarà difficile hackerare usando lo strumento dex2jar.
sachin003,

1
Forse hai frainteso il mio punto: quello che fa HoseDex2Jar è reimballare il tuo APK in modo che il popolare strumento dex2jar non possa (fuori dalla scatola) invertirlo. Comunque altri strumenti possono, ed è molto facile sconfiggerlo in generale. Inutile usarlo. Nessuno ha menzionato Dexguard I (dell'autore di ProGuard; non gratuito), ma è un lavoro da guardare. Fa qualche cosa in più dell'offuscamento 'regolare'.
Nikolay Elenkov,

Il C ++ non può mai essere invertito? è difficile ma possibile. e ci sono strumenti che ti possono aiutare come hex-rays.com/products/decompiler/index.shtml (sì, hanno la versione ARM. Non è così facile da ottenere).
dkzm,

si, @VikartiAnatra: ho anche menzionato in qualche modo, potresti renderlo difficile
Sahil Mahajan Mj,

24

Ecco alcuni metodi che puoi provare:

  1. Usa offuscamento e strumenti come ProGuard .
  2. Crittografa alcune parti di origine e dati.
  3. Utilizzare un checksum integrato proprietario nell'app per rilevare manomissioni.
  4. Introdurre il codice per evitare il caricamento in un debugger, ovvero consentire all'app di rilevare il debugger e uscire / terminare il debugger.
  5. Separare l'autenticazione come servizio online.
  6. Usa la diversità delle applicazioni
  7. Utilizzare la tecnica di impronta digitale, ad esempio, per le firme hardware dei dispositivi da diversi sottosistemi prima di autenticare il dispositivo.

23

 1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?

Impossibile

 2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?

Impossibile

 3. C'è un modo per rendere l'hacking più duro o addirittura impossibile? Cosa posso fare di più per proteggere il codice sorgente nel mio file APK?

Più difficile - possibile, ma in realtà sarà più difficile soprattutto per l'utente medio, che sta solo cercando su google guide di hacking. Se qualcuno vuole davvero hackerare la tua app, prima o poi verrà hackerata.


22

 1. Come posso evitare completamente il reverse engineering di un APK Android? È possibile?

Questo è impossibile

 2. Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?

Gli sviluppatori possono adottare misure come l'uso di strumenti come ProGuard per offuscare il loro codice, ma fino ad ora è stato abbastanza difficile impedire completamente a qualcuno di decompilare un'app.

È uno strumento davvero eccezionale e può aumentare la difficoltà di "invertire" il codice riducendo al contempo l'impronta del codice.

Supporto ProGuard integrato: ProGuard è ora fornito con gli strumenti SDK. Gli sviluppatori possono ora offuscare il loro codice come parte integrante di una build di rilascio.

 3. C'è un modo per rendere l'hacking più duro o addirittura impossibile? Cosa posso fare di più per proteggere il codice sorgente nel mio file APK?

Durante la ricerca, sono venuto a conoscenza di HoseDex2Jar . Questo strumento proteggerà il tuo codice dalla decompilazione, ma sembra che non sia possibile proteggerlo completamente.

Alcuni dei link utili, è possibile fare riferimento a loro.


21

La domanda principale qui è che i file dex possono essere decompilati e la risposta è che possono essere "una specie di". Ci sono disassemblatori come dedexer e smali .

ProGuard, correttamente configurato, offuscherà il tuo codice. DexGuard, che è una versione estesa commerciale di ProGuard, può aiutare un po 'di più. Tuttavia, il tuo codice può ancora essere convertito in smali e gli sviluppatori con esperienza di reverse engineering saranno in grado di capire cosa stai facendo da smali.

Forse scegliere una buona licenza e farla rispettare dalla legge nel miglior modo possibile.


4
Come nota a margine (dichiarazione di non responsabilità: IANAL) - la licenza non proteggerà l'applicazione in tutte le giurisdizioni in tutte le circostanze (ad esempio in alcuni paesi in Europa è consentito disassemblare per aumentare la compatibilità).
Maciej Piechotka,

12

Il tuo cliente dovrebbe assumere qualcuno che sa cosa sta facendo, che può prendere le giuste decisioni e può farti da mentore.

Parla sopra di te che hai qualche possibilità di cambiare il sistema di elaborazione delle transazioni sul back-end è assurdo: non dovresti avere il permesso di apportare tali modifiche architettoniche, quindi non aspettarti di esserlo.

La mia logica su questo:

Poiché il tuo dominio è l'elaborazione dei pagamenti, è lecito ritenere che PCI DSS e / o PA DSS (e la potenziale legge statale / federale) saranno significativi per la tua attività - per essere conforme devi dimostrare di essere sicuro. Per essere insicuri, scoprire (tramite test) che non si è sicuri, quindi correggere, ripetere il test, eccetera fino a quando la sicurezza non può essere verificata a un livello adeguato = modo costoso, lento e ad alto rischio per il successo. Per fare la cosa giusta, pensare in anticipo, impegnare talenti con esperienza nel lavoro, sviluppare in modo sicuro, quindi testare, correggere (meno), eccetera (meno) fino a quando la sicurezza può essere verificata a un livello adeguato = economico, veloce, modo a basso rischio per il successo.


8

Come persona che ha lavorato ampiamente su piattaforme di pagamento, inclusa un'applicazione di pagamento mobile (MyCheck), direi che è necessario delegare questo comportamento al server, nessun nome utente o password per il processore di pagamento (qualunque esso sia) dovrebbe essere archiviato o hardcoded nell'applicazione mobile, questa è l'ultima cosa che vuoi, perché la fonte può essere compresa anche se offuschi il codice.

Inoltre, non dovresti archiviare carte di credito o token di pagamento sull'applicazione, tutto dovrebbe essere, di nuovo, delegato a un servizio che hai creato, ti consentirà anche in seguito, essere più conforme alla norma PCI e le società di carte di credito hanno vinto respiro al collo (come hanno fatto per noi).


7

Le altre risposte votate qui sono corrette. Voglio solo fornire un'altra opzione.

Per alcune funzionalità che ritieni importanti, puoi ospitare il controllo WebView nella tua app. La funzionalità verrebbe quindi implementata sul tuo server web. Sembrerà che stia funzionando nella tua applicazione.


@Sarel Botha sì per gli schermi IMP Ho già usato la webview e sì questo è anche un modo per mantenere la sicurezza, sto accettando la tua risposta.
sachin003,

7

Se vogliamo rendere il reverse engineering (quasi) impossibile, possiamo mettere l'applicazione su un chip altamente antimanomissione, che esegue internamente tutte le cose sensibili e comunica con alcuni protocolli per rendere possibile il controllo della GUI sull'host. Anche i chip antimanomissione non sono al 100% resistenti alle crepe; hanno semplicemente impostato la barra molto più in alto rispetto ai metodi software. Ovviamente, questo è scomodo: l'applicazione richiede una piccola verruca USB che contiene il chip da inserire nel dispositivo.

La domanda non rivela la motivazione per voler proteggere questa applicazione in modo geloso.

Se l'obiettivo è migliorare la sicurezza del metodo di pagamento nascondendo i difetti di sicurezza che l'applicazione potrebbe avere (noti o meno), è completamente sbagliata. I bit sensibili alla sicurezza dovrebbero infatti essere di provenienza aperta, se ciò è possibile. Dovresti rendere il più semplice possibile per qualsiasi ricercatore di sicurezza che riveda la tua applicazione per trovare quei bit, controllare il loro funzionamento e contattarti. Le domande di pagamento non devono contenere certificati incorporati. Vale a dire, non ci dovrebbe essere alcuna applicazione server che si fidi di un dispositivo semplicemente perché ha un certificato fisso dalla fabbrica. Una transazione di pagamento deve essere effettuata solo sulle credenziali dell'utente, utilizzando un protocollo di autenticazione end-to-end correttamente progettato che preclude la fiducia nell'applicazione, nella piattaforma o nella rete, ecc.

Se l'obiettivo è impedire la clonazione, a parte quel chip a prova di manomissione, non c'è niente che puoi fare per proteggere il programma dall'ingegnerizzazione inversa e dalla copia, in modo che qualcuno incorpori un metodo di pagamento compatibile nella propria applicazione, dando diventare "clienti non autorizzati". Esistono modi per rendere difficile lo sviluppo di client non autorizzati. Uno sarebbe quello di creare checksum basati su istantanee dello stato completo del programma: tutte le variabili di stato, per tutto. GUI, logica, qualunque cosa. Un programma clone non avrà esattamente lo stesso stato interno. Certo, è una macchina a stati che ha simili transizioni di stato visibili esternamente (come si può osservare da ingressi e uscite), ma quasi lo stesso stato interno. Un'applicazione server può interrogare il programma: qual è il tuo stato dettagliato? (vale a dire dammi un checksum su tutte le tue variabili di stato interne). Questo può essere confrontato con il codice client fittizio che viene eseguito sul server in parallelo, attraversando le transizioni di stato autentiche. Un clone di terze parti dovrà replicare tutti i cambiamenti di stato rilevanti del programma originale al fine di fornire le risposte corrette, che ne ostacoleranno lo sviluppo.


7

Concordato con @Muhammad Saqib qui: https://stackoverflow.com/a/46183706/2496464

E @Mumair offre una buona base di partenza: https://stackoverflow.com/a/35411378/474330

È sempre sicuro supporre che tutto ciò che distribuisci al dispositivo dell'utente appartenga all'utente. Chiaro e semplice. Potresti essere in grado di utilizzare gli strumenti e le procedure più recenti per crittografare le tue proprietà intellettuali, ma non c'è modo di impedire a una determinata persona di "studiare" il tuo sistema. E anche se l'attuale tecnologia potrebbe rendere loro difficile l'accesso indesiderato, domani potrebbe esserci un modo semplice o addirittura solo l'ora successiva!

Quindi, ecco che arriva l'equazione:

When it comes to money, we always assume that client is untrusted.

Anche in un'economia di gioco semplice. (Soprattutto nei giochi! Ci sono utenti più "sofisticati" e le lacune si diffondono in pochi secondi!)

Come restiamo al sicuro?

La maggior parte, se non tutti, dei nostri sistemi di elaborazione delle chiavi (e ovviamente del database) situati sul lato server. E tra client e server, si trovano comunicazioni crittografate, convalide, ecc. Questa è l'idea del thin client.



4

Schema di firma APK v2 in Android N

La classe PackageManager ora supporta la verifica delle app mediante lo schema di firma APK v2. Lo schema di firma APK v2 è uno schema di firma a file intero che migliora significativamente la velocità di verifica e rafforza le garanzie di integrità rilevando eventuali modifiche non autorizzate ai file APK.

Per mantenere la compatibilità con le versioni precedenti, un APK deve essere firmato con lo schema di firma v1 (schema di firma JAR) prima di essere firmato con lo schema di firma v2. Con lo schema di firma v2, la verifica non riesce se si firma l'APK con un certificato aggiuntivo dopo aver firmato con lo schema v2.

Il supporto dello schema di firma APK v2 sarà disponibile più avanti nell'anteprima per sviluppatori N.

http://developer.android.com/preview/api-overview.html#apk_signature_v2


2
La firma apk v2 impedisce solo la manomissione delle risorse, ma non rende più difficile la retroingegnerizzazione ...
Louis CAD

1
Inoltre puoi semplicemente rimuovere la firma e firmarla nuovamente. La firma v2 è solo un blocco di dati nel file APK.
Robert,

4

Non c'è modo di evitare completamente il reverse engineering di un APK. Per proteggere le risorse e le risorse dell'applicazione, è possibile utilizzare la crittografia.

  • La crittografia renderà più difficile il suo utilizzo senza decrittazione. La perdita di alcuni potenti algoritmi di crittografia renderà più difficile il cracking.
  • Aggiunta di un codice di spoof nella logica principale per rendere più difficile il cracking.
  • Se riesci a scrivere la tua logica critica in qualsiasi lingua madre e questo sicuramente renderà più difficile il decompilamento.
  • Utilizzando qualsiasi framework di sicurezza di terze parti come Quixxi

3

Fondamentalmente non è possibile. Non sarà mai possibile. Tuttavia, c'è speranza. Puoi usare un offuscatore per renderlo così alcuni attacchi comuni sono molto più difficili da eseguire, tra cui cose come:

  1. Rinominare metodi / classi (quindi nel decompilatore ottieni tipi come a.a )
  2. Flusso di controllo offuscato (quindi nel decompilatore il codice è molto difficile da leggere)
  3. Crittografia di stringhe e possibilmente risorse

Sono sicuro che ce ne sono altri, ma quelli principali. Lavoro per un'azienda chiamata PreEmptive Solutions su un offuscatore .NET . Hanno anche un offuscatore Java che funziona per Android e uno chiamato DashO .

L'offuscamento ha sempre un prezzo, però. In particolare, le prestazioni sono generalmente peggiori e di solito richiede un po 'di tempo in più per le versioni. Tuttavia, se la proprietà intellettuale è estremamente importante per te, di solito ne vale la pena.

Altrimenti, l'unica scelta è quella di far sì che la tua applicazione Android passi attraverso un server che ospita tutta la vera logica della tua applicazione. Questo ha una sua parte di problemi, perché significa che gli utenti devono essere connessi a Internet per usare la tua app.

Inoltre, non è solo Android ad avere questo problema. È un problema su ogni app store. È solo una questione di quanto sia difficile accedere al file del pacchetto (ad esempio, non credo sia molto facile su iPhone, ma è ancora possibile).


Sfortunatamente se si hackerasse il client (l'app) sarebbero in grado di vedere il formato di comunicazione e creare il proprio server :(
Jocky Doe

3

Non è possibile evitare completamente l'IR ma rendendoli più complessi internamente, si rende più difficile per gli aggressori vedere il chiaro funzionamento dell'app, che può ridurre il numero di vettori di attacco.

Se l'applicazione gestisce dati altamente sensibili, esistono varie tecniche che possono aumentare la complessità del reverse engineering del codice. Una tecnica consiste nell'utilizzare C / C ++ per limitare la facile manipolazione del runtime da parte dell'attaccante. Ci sono ampie librerie C e C ++ che sono molto mature e facili da integrare con le offerte Android JNI. Un utente malintenzionato deve prima aggirare le restrizioni di debug per attaccare l'applicazione a un livello basso. Ciò aggiunge ulteriore complessità a un attacco. Le applicazioni Android dovrebbero avere Android: debuggable = "false" impostato nel manifest dell'applicazione per impedire una facile manipolazione del tempo di esecuzione da parte di un utente malintenzionato o malware.

Verifica della traccia - Un'applicazione può determinare se è attualmente tracciata o meno da un debugger o altro strumento di debug. Se viene rintracciato, l'applicazione può eseguire un numero qualsiasi di possibili azioni di risposta all'attacco, come scartare chiavi di crittografia per proteggere i dati dell'utente, avvisare un amministratore del server o altre risposte di questo tipo nel tentativo di difendersi. Ciò può essere determinato controllando i flag di stato del processo o usando altre tecniche come il confronto del valore di ritorno di ptrace attach, il controllo del processo parent, i debugger della black list nell'elenco dei processi o il confronto di timestamp in diversi punti del programma.

Ottimizzazioni : per nascondere calcoli matematici avanzati e altri tipi di logica complessa, l'utilizzo delle ottimizzazioni del compilatore può aiutare a offuscare il codice oggetto in modo che non possa essere facilmente smontato da un utente malintenzionato, rendendo più difficile per un utente malintenzionato comprendere il codice particolare. In Android ciò può essere ottenuto più facilmente utilizzando librerie compilate in modo nativo con NDK. Inoltre, l'utilizzo di un LLVM Obfuscator o di qualsiasi SDK di protezione fornirà una migliore offuscamento del codice macchina.

Stripping binaries : lo stripping dei binari nativi è un modo efficace per aumentare la quantità di tempo e il livello di abilità richiesto a un utente malintenzionato al fine di visualizzare la composizione delle funzioni di basso livello dell'applicazione. Spogliando un binario, la tabella dei simboli del binario viene rimossa, in modo che un utente malintenzionato non possa eseguire facilmente il debug o il reverse engineering di un'applicazione. È possibile fare riferimento a tecniche utilizzate su sistemi GNU / Linux come lo sstriping o l'utilizzo di UPX.

E alla fine devi essere consapevole dell'offuscamento e di strumenti come ProGuard.


3

Se la tua app è così sensibile, dovresti considerare la parte di elaborazione dei pagamenti sul lato server. Prova a modificare gli algoritmi di elaborazione dei pagamenti. Usa l'app Android solo per raccogliere e visualizzare le informazioni dell'utente (ad esempio il saldo del conto) e invece di elaborare pagamenti con codici Java, invia questa attività al tuo server utilizzando un protocollo SSL sicuro con parametri crittografati. Crea API completamente crittografate e sicure per comunicare con il tuo server.

Naturalmente, può anche essere hackerato e non ha nulla a che fare con la protezione dei codici sorgente, ma considera un altro livello di sicurezza per rendere più difficile per gli hacker ingannare la tua app.


2

I chip TPM (Trusted Platform Module) non devono gestire il codice protetto per te? Stanno diventando comuni sui PC (specialmente quelli Apple) e potrebbero già esistere nei chip degli smartphone di oggi. Sfortunatamente non esiste ancora alcuna API del sistema operativo per utilizzarla. Spero che Android aggiunga supporto per questo giorno. Questa è anche la chiave per ripulire i contenuti DRM (su cui Google sta lavorando per WebM).


2

Nulla è sicuro quando lo si mette a disposizione degli utenti finali, ma alcune pratiche comuni potrebbero rendere più difficile per l'utente malintenzionato rubare dati.

  • Inserisci la tua logica principale (algoritmi) nel lato server.
  • Comunicare con server e client; assicurarsi che la comunicazione tra server e client sia protetta tramite SSL o HTTPS; o utilizzare altre tecniche algoritmi di generazione di coppie di chiavi (ECC, RSA). Assicurarsi che le informazioni riservate rimangano crittografate end-to-end.
  • Utilizzare le sessioni e scaderle dopo un intervallo di tempo specifico.
  • Crittografare le risorse e recuperarle dal server su richiesta.
  • Oppure puoi creare un'app ibrida che accede al sistema tramite la webviewprotezione di risorse + codice sul server

Approcci multipli; questo è ovvio che devi sacrificare tra prestazioni e sicurezza


2

Vedo quella buona risposta in questa discussione. Oltre a te puoi usare facebook redexper ottimizzare il codice. Redex funziona a .dexlivello in cui proguard funziona come .classlivello.



1

Come posso proteggere tutte le risorse, le risorse e il codice sorgente dell'app in modo che gli hacker non possano hackerare il file APK in alcun modo?

Un file APK è protetto con l' algoritmo SHA-1 . Puoi vedere alcuni file nella cartella META-INF dell'APK. Se estrai qualsiasi file APK e ne cambi il contenuto e lo zip nuovamente e quando esegui quel nuovo file APK su un computer Android, non funzionerà, perché gli hash SHA-1 non corrisponderanno mai.


Questo è vero; ma è banale dimettersi dall'APK (con un certificato diverso) e tutto funzionerà di nuovo. È possibile verificare quale firma è stata utilizzata per firmare l'APK dall'interno dell'applicazione stessa ed errori se il certificato cambia, ma è solo leggermente meno banale modificare questo codice dall'applicazione.
David dato il

Ciò potrebbe impedire al dispositivo Android di eseguire codice modificato, ma è comunque possibile estrarre facilmente il codice pertinente e scrivere il nuovo codice su un PC che fa quello che vuoi.
Sarel Botha,

1

Anche se sono d'accordo che non esiste una soluzione al 100% che protegga il tuo codice, ora v3 di HoseDex2Jar è disponibile se vuoi provarlo.


1

Strumento: utilizzando Proguard nell'applicazione può essere limitato al reverse engineering dell'applicazione


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.