Question Comment éviter l'ingénierie inverse d'un fichier APK?


Je développe un application de traitement des paiements pour Android, et je veux empêcher un pirate d'accéder à des ressources, des actifs ou du code source de la APK fichier.

Si quelqu'un change l'extension .apk en .zip, ils peuvent la décompresser et accéder facilement à toutes les ressources et ressources de l'application, et en utilisant dex2jar et un décompilateur Java, ils peuvent également accéder au code source. Il est très facile d'effectuer l'ingénierie inverse d'un fichier Android APK - pour plus de détails, voir Stack Overflow question Reverse engineering d'un fichier APK vers un projet.

J'ai utilisé l'outil Proguard fourni avec le SDK Android. Lorsque je désosser un fichier APK généré à l'aide d'un keystore signé et de Proguard, je reçois du code obfusqué. Cependant, les noms des composants Android restent inchangés et certains codes, comme les valeurs-clés utilisées dans l'application, restent inchangés. Selon la documentation de Proguard, l'outil ne peut masquer les composants mentionnés dans le fichier manifeste.

Maintenant, mes questions sont:

  1. Comment puis-je éviter complètement ingénierie inverse d'un APK Android? Est-ce possible?
  2. Comment puis-je protéger toutes les ressources, les ressources et le code source de l'application afin que les pirates ne puissent pas pirater le fichier APK de quelque façon que ce soit?
  3. Y at-il un moyen de rendre le piratage plus difficile ou même impossible? Que puis-je faire de plus pour protéger le code source dans mon fichier APK?

643
2017-12-13 06:42


origine


Réponses:


1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

AFAIK, il n'y a pas de truc pour éviter complètement l'ingénierie inverse.

Et aussi très bien dit par @inazaruk: Quoi que vous fassiez pour votre code, un attaquant potentiel est capable de le changer de quelque manière qu'il le juge réalisable. Vous ne pouvez fondamentalement pas protéger votre application d'être modifiée. Et toute protection que vous y mettez peut être désactivée / supprimée.

2. Comment puis-je protéger toutes les ressources, les ressources et le code source de l'application afin que les pirates ne puissent pas pirater le fichier APK de quelque façon que ce soit?

Vous pouvez faire des trucs différents pour rendre le hacking plus difficile. Par exemple, utilisez l'obfuscation (s'il s'agit d'un code Java). Cela ralentit généralement l'ingénierie inverse de manière significative.

3. Y a-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source dans mon fichier APK?

Comme tout le monde le dit, et comme vous le savez probablement, il n'y a pas de sécurité à 100%. Mais le point de départ pour Android, que Google a intégré, est ProGuard. Si vous avez la possibilité d'inclure bibliothèques partagées, vous pouvez inclure le code nécessaire en C ++ pour vérifier la taille des fichiers, l'intégration, etc. Si vous devez ajouter une bibliothèque native externe au dossier de la bibliothèque de votre APK à chaque génération, alors vous pouvez l'utiliser par la suggestion ci-dessous.

Placez la bibliothèque dans le chemin de la bibliothèque native qui est par défaut "libs" dans votre dossier de projet. Si vous avez construit le code natif pour le 'armeabi' cible puis le mettre en dessous de libs / armeabi. S'il a été construit avec armeabi-v7a alors le mettre sous libs / armeabi-v7a.

<project>/libs/armeabi/libstuff.so

323
2017-12-13 07:03



AFAIK, vous ne pouvez pas protéger les fichiers dans le répertoire / res plus qu'ils ne sont protégés en ce moment.

Cependant, il y a des mesures que vous pouvez prendre pour protéger votre code source, ou du moins ce qu'il fait si ce n'est pas tout.

  1. Utilisez des outils comme ProGuard. Ceux-ci vont obscurcir votre code, et le rendre plus difficile à lire lorsqu'il est décompilé, voire impossible.
  2. Déplacez les parties les plus critiques du service hors de l'application, et dans un service Web, caché derrière un langage côté serveur comme PHP. Par exemple, si vous avez un algorithme qui vous a pris un million de dollars à écrire. Vous ne voulez évidemment pas que les gens le volent hors de votre application. Déplacez l'algorithme et faites-le traiter les données sur un serveur distant, et utilisez l'application pour simplement lui fournir les données. Ou utilisez le NDK pour les écrire nativement dans les fichiers .so, qui sont beaucoup moins susceptibles d'être décompilés que les apks. Je ne pense pas qu'un décompilateur pour les fichiers .so existe déjà (et même si c'était le cas, il ne serait pas aussi bon que les décompilateurs Java). En outre, comme @nikolay mentionné dans les commentaires, vous devez utiliser SSL lors de l'interaction entre le serveur et l'appareil.
  3. Lorsque vous stockez des valeurs sur l'appareil, ne les stockez pas dans un format brut. Par exemple, si vous avez un jeu, et que vous stockez la quantité de monnaie dans le jeu que l'utilisateur a dans SharedPreferences. Supposons que c'est 10000 pièces de monnaie. Au lieu de sauver 10000 directement, enregistrez-le en utilisant un algorithme comme ((currency*2)+1)/13. Donc, au lieu de 10000, vous sauvegardez 1538.53846154 dans les SharedPreferences. Cependant, l'exemple ci-dessus n'est pas parfait, et vous devrez travailler pour arriver à une équation qui ne perdra pas de monnaie en erreur d'arrondi etc.
  4. Vous pouvez faire une chose similaire pour les tâches côté serveur. Maintenant, par exemple, prenons votre application de traitement des paiements. Disons que l'utilisateur doit effectuer un paiement de $200. Au lieu d'envoyer un brut $200 valeur au serveur, envoyez une série de valeurs plus petites et prédéfinies $200. Par exemple, ayez sur votre serveur un fichier ou une table qui équivaut à des mots avec des valeurs. Alors disons que Charlie Correspond à $47, et John à $3. Donc, au lieu d'envoyer $200, vous pouvez envoyer Charlie quatre fois et John quatre fois. Sur le serveur, interprétez ce qu'ils signifient et ajoutez-le. Cela empêche un pirate d'envoyer des valeurs arbitraires à votre serveur, car ils ne savent pas quel mot correspond à quelle valeur. Comme mesure supplémentaire de sécurité, vous pourriez avoir une équation similaire au point 3 pour cela aussi, et changer les mots-clés tous les n nombre de jours.
  5. Enfin, vous pouvez insérer du code source aléatoire dans votre application, afin que le pirate recherche une aiguille dans une botte de foin. Insérez des classes aléatoires contenant des extraits d'Internet, ou seulement des fonctions pour calculer des choses aléatoires comme la séquence de Fibonacci. Assurez-vous que ces classes sont compilées, mais ne sont pas utilisées par les fonctionnalités de l'application. Ajouter assez de ces fausses classes, et le pirate aurait du mal à trouver votre vrai code.

Dans l'ensemble, il n'y a aucun moyen de protéger votre application à 100%. Vous pouvez le rendre plus difficile, mais pas impossible. Votre serveur Web pourrait être compromis, le hacker pourrait comprendre vos mots clés en surveillant plusieurs montants de transaction et les mots-clés que vous envoyez pour cela, le pirate pourrait difficilement passer par la source et déterminer quel code est un mannequin.

Vous pouvez seulement riposter, mais ne jamais gagner.


117
2017-12-13 07:07



À aucun moment de l'histoire de l'informatique, il n'a jamais été possible d'empêcher l'ingénierie inverse des logiciels lorsque vous en remettez une copie de travail à votre attaquant. Aussi, très probablement, ce ne sera jamais possible.

Avec cela compris, il y a une solution évidente: Ne donnez pas vos secrets à votre attaquant. Alors que vous ne pouvez pas protéger le contenu de votre APK, ce que vous pouvez protéger est tout ce que vous ne distribuez pas. Généralement, il s'agit d'un logiciel côté serveur utilisé pour des choses comme l'activation, les paiements, l'application des règles et d'autres bits de code juteux. Vous pouvez protéger des actifs précieux en ne pas les distribuer dans votre APK. Au lieu de cela, configurez un serveur qui répond aux demandes de votre application, "utilise" les actifs (tout ce que cela peut signifier), puis renvoie le résultat à l'application. Si ce modèle ne fonctionne pas pour les actifs que vous avez en tête, alors vous voudrez peut-être repenser votre stratégie.

Aussi, si votre objectif principal est d'empêcher le piratage des applications: ne même pas déranger. Vous avez déjà brûlé plus de temps et d'argent sur ce problème que toute mesure anti-piratage pourrait éventuellement espérer vous sauver. Le retour sur investissement pour résoudre ce problème est si faible que cela n'a même pas de sens d'y penser.


103
2017-12-13 08:28



Première règle de sécurité de l'application: Toute machine à laquelle un pirate bénéficie d'un accès physique ou électronique illimité appartient maintenant à votre attaquant, peu importe où il se trouve réellement ou ce que vous avez payé pour cela.

Deuxième règle de sécurité de l'application: Tout logiciel qui laisse les limites physiques à l'intérieur desquelles un attaquant ne peut pas pénétrer appartient maintenant à votre attaquant, quel que soit le temps que vous avez passé à le coder.

Troisième règle: Toute information qui laisse ces mêmes limites physiques qu'un intrus ne peut pas pénétrer appartient maintenant à votre attaquant, peu importe la valeur que cela représente pour vous.

Les fondements de la sécurité des technologies de l'information reposent sur ces trois principes fondamentaux. Le seul ordinateur véritablement sécurisé est celui qui est enfermé dans un coffre-fort, à l'intérieur d'une cage de Farraday, dans une cage en acier. Il y a des ordinateurs qui passent le plus clair de leur vie dans cet état; Une fois par an (ou moins), ils génèrent les clés privées pour les autorités de certification racine de confiance (devant une foule de témoins avec des caméras enregistrant chaque centimètre de la pièce dans laquelle ils se trouvent).

Maintenant, la plupart des ordinateurs ne sont pas utilisés dans ces types d'environnements; ils sont physiquement à l'air libre, connectés à Internet via un canal radio sans fil. En bref, ils sont vulnérables, tout comme leur logiciel. Ils ne sont donc pas à faire confiance. Il y a certaines choses que les ordinateurs et leurs logiciels doivent savoir ou faire pour être utiles, mais il faut veiller à ce qu'ils ne puissent jamais savoir ou faire assez pour causer des dommages (du moins pas de dommages permanents en dehors des limites de cette seule machine ).

Vous saviez déjà tout cela; C'est pourquoi vous essayez de protéger le code de votre application. Mais, c'est là le premier problème; les outils d'obfuscation peuvent faire du code un gâchis pour un humain pour essayer de creuser, mais le programme doit encore fonctionner; Cela signifie que le flux logique réel de l'application et les données qu'elle utilise ne sont pas affectés par l'obscurcissement. Avec un peu de ténacité, un attaquant peut simplement désobéir le code, et ce n'est même pas nécessaire dans certains cas où ce qu'il regarde ne peut être autre chose que ce qu'il cherche.

Au lieu de cela, vous devriez essayer de faire en sorte qu'un attaquant ne puisse rien faire avec votre code, même si c'est facile pour lui d'en obtenir une copie claire. Cela signifie, pas de secrets codés en dur, parce que ces secrets ne sont pas secrets dès que le code quitte le bâtiment dans lequel vous l'avez développé.

Ces valeurs-clés que vous avez codées en dur doivent être entièrement supprimées du code source de l'application. Au lieu de cela, ils devraient être dans l'un des trois endroits; mémoire volatile sur le périphérique, ce qui est plus difficile (mais pas impossible) pour un attaquant d'obtenir une copie hors ligne de; en permanence sur le cluster de serveurs, auquel vous contrôlez l'accès avec une poigne de fer; ou dans un second magasin de données non lié à votre appareil ou à vos serveurs, comme une carte physique ou dans la mémoire de votre utilisateur (ce qui signifie qu'il sera éventuellement en mémoire volatile, mais il ne doit pas être longtemps).

Considérez le schéma suivant. L'utilisateur entre ses informations d'identification pour l'application de la mémoire dans l'appareil. Vous devez malheureusement avoir confiance que l'appareil de l'utilisateur n'est pas déjà compromis par un keylogger ou un cheval de Troie; le mieux que vous puissiez faire à cet égard est de mettre en œuvre une sécurité multifactorielle, en vous rappelant des informations d'identification difficiles à imiter sur les dispositifs utilisés par l'utilisateur (MAC / IP, IMEI, etc.) et en fournissant au moins un canal supplémentaire qu'une tentative de connexion sur un appareil non familier peut être vérifiée.

Les informations d'identification, une fois entrées, sont obscurcies par le logiciel client (à l'aide d'un hachage sécurisé) et les informations d'identification en texte brut sont supprimées; ils ont servi leur but. Les informations d'identification obfuscated sont envoyées sur un canal sécurisé au serveur authentifié par certificat, ce qui les hachage encore pour produire les données utilisées pour vérifier la validité de la connexion. De cette façon, le client ne sait jamais ce qui est réellement comparé à la valeur de la base de données, le serveur d'application ne connaît jamais les informations en clair derrière ce qu'il reçoit pour la validation, le serveur de données ne sait jamais comment les données qu'il stocke sont validées. le milieu ne voit que du charabia même si le canal sécurisé a été compromis.

Une fois vérifié, le serveur renvoie un jeton sur le canal. Le jeton n'est utile que dans la session sécurisée, est composé de bruit aléatoire ou d'une copie cryptée (et donc vérifiable) des identifiants de session, et l'application client doit envoyer ce jeton sur le même canal au serveur dans le cadre de toute requête faire quelque chose. L'application cliente fera cela plusieurs fois, car elle ne peut rien faire qui implique de l'argent, des données sensibles, ou tout ce qui pourrait être dommageable par elle-même; il doit plutôt demander au serveur de faire cette tâche. L'application cliente n'écrira jamais d'informations sensibles sur la mémoire persistante sur le périphérique lui-même, du moins pas en texte brut; le client peut demander au serveur via le canal sécurisé une clé symétrique pour crypter les données locales, ce dont le serveur se souviendra; Dans une session ultérieure, le client peut demander au serveur la même clé pour déchiffrer les données à utiliser dans la mémoire volatile. Ces données ne seront pas la seule copie non plus; Tout ce que le client stocke doit également être transmis sous une forme quelconque au serveur.

De toute évidence, cela rend votre application très dépendante de l'accès à Internet; le périphérique client ne peut effectuer aucune de ses fonctions de base sans une connexion et une authentification adéquates par le serveur. Pas différent de Facebook, vraiment.

Maintenant, l'ordinateur que l'attaquant veut, c'est votre serveur, parce que ce n'est pas l'application / l'appareil client qui peut lui faire de l'argent ou causer de la douleur aux autres pour son plaisir. C'est bon; vous obtenez beaucoup plus pour votre argent dépenser de l'argent et des efforts pour sécuriser le serveur que dans la tentative de sécuriser tous les clients. Le serveur peut être derrière toutes sortes de pare-feu et d'autres dispositifs de sécurité électroniques, et peut en outre être sécurisé physiquement derrière l'acier, le béton, l'accès par carte-clé et la surveillance vidéo 24 heures sur 24. Votre attaquant devrait être très sophistiqué pour accéder directement au serveur, et vous devriez le savoir immédiatement.

Le mieux qu'un attaquant puisse faire est de voler le téléphone et les informations d'identification d'un utilisateur et de se connecter au serveur avec les droits limités du client. Si cela se produit, tout comme la perte d'une carte de crédit, l'utilisateur légitime devrait être invité à appeler un numéro 800 (de préférence facile à retenir, et non à l'arrière d'une carte qu'il porterait dans son sac à main, son portefeuille ou sa mallette). volé à côté de l'appareil mobile) à partir de tout téléphone auquel ils peuvent accéder qui les connecte directement à votre service client. Ils déclarent que leur téléphone a été volé, fournissent un identifiant unique de base, et le compte est verrouillé, toutes les transactions que l'attaquant a pu traiter sont annulées et l'attaquant revient à la case départ.


76
2017-12-13 19:39



1. Comment puis-je éviter complètement l'ingénierie inverse d'un APK Android? Est-ce possible?

Ce n'est pas possible

2. Comment puis-je protéger toutes les ressources, les ressources et le code source de l'application afin que les pirates ne puissent pas pirater le fichier APK de quelque façon que ce soit?

Quand quelqu'un change une extension .apk en .zip, alors après la décompression, quelqu'un peut facilement obtenir toutes les ressources (sauf Manifest.xml), mais avec APKtool on peut aussi avoir le contenu réel du fichier manifeste. Encore une fois, un non.

3. Y a-t-il un moyen de rendre le piratage plus difficile, voire impossible? Que puis-je faire de plus pour protéger le code source dans mon fichier APK?

Encore une fois, non, mais vous pouvez empêcher jusqu'à un certain niveau, c'est,

  • Télécharger une ressource sur le Web et faire un certain processus de cryptage
  • Utiliser une bibliothèque native précompilée (C, C ++, JNI, NDK)
  • Toujours effectuer un peu de hachage (MD5/SHA clés ou toute autre logique)

Même avec Smali, les gens peuvent jouer avec votre code. Dans l'ensemble, ce n'est pas possible.


65
2017-12-13 07:11



100% d'évitement de l'ingénierie inverse de l'APK Android n'est pas possible, mais vous pouvez utiliser ces méthodes pour éviter d'extraire plus de données, comme le code source, les actifs de votre fichier APK et les ressources:

  1. Utilisez ProGuard pour masquer le code de l'application

  2. Utilisation NDK en utilisant C et C ++ pour mettre votre application de base et sécuriser une partie du code .so des dossiers

  3. Pour sécuriser les ressources, n'incluez pas toutes les ressources importantes dans le dossier assets avec APK. Téléchargez ces ressources au moment du premier démarrage de l'application.


35
2017-12-13 07:07



Les développeurs peuvent prendre les mesures suivantes pour empêcher un APK de voler d'une manière ou d'une autre,

  • le moyen le plus fondamental est d'utiliser des outils comme ProGuardpour brouiller leur code, mais jusqu'à présent, il a été assez difficile d'empêcher complètement quelqu'un de décompiler une application.

  • J'ai aussi entendu parler d'un outil HoseDex2Jar. Ça s'arrête Dex2Jar en insérant du code inoffensif dans un APK Android qui confond et désactive Dex2Jar et protège le code de la décompilation. Il pourrait en quelque sorte empêcher les pirates de décompiler un fichier APK en code java lisible.

  • Utilisez une application côté serveur pour communiquer avec l'application uniquement lorsque cela est nécessaire. Cela pourrait aider à prévenir les données importantes.

À tous, vous ne pouvez pas protéger complètement votre code contre les pirates potentiels. D'une certaine manière, vous pourriez rendre la tâche difficile et frustrante pour eux de décompiler votre code. L'un des moyens les plus efficaces consiste à écrire en code natif (C / C ++) et à le stocker en tant que bibliothèques compilées.


33
2017-12-13 06:55