¿Cómo evitar la ingeniería inversa de un archivo APK?

764

Estoy desarrollando una aplicación de procesamiento de pagos para Android y quiero evitar que un hacker acceda a los recursos, activos o código fuente desde el archivo APK .

Si alguien cambia la extensión .apk a .zip, puede descomprimirla y acceder fácilmente a todos los recursos y activos de la aplicación, y al usar dex2jar y un descompilador de Java, también puede acceder al código fuente. Es muy fácil aplicar ingeniería inversa a un archivo APK de Android; para obtener más información, consulte la pregunta sobre desbordamiento de pila Ingeniería inversa de un archivo APK a un proyecto .

He usado la herramienta Proguard provista con el SDK de Android. Cuando realizo ingeniería inversa de un archivo APK generado utilizando un almacén de claves firmado y Proguard, obtengo un código ofuscado.

Sin embargo, los nombres de los componentes de Android permanecen sin cambios y algunos códigos, como los valores-clave utilizados en la aplicación, permanecen sin cambios. Según la documentación de Proguard, la herramienta no puede ofuscar los componentes mencionados en el archivo Manifiesto.

Ahora mis preguntas son:

  1. ¿Cómo puedo evitar por completo la ingeniería inversa de un APK de Android? es posible?
  2. ¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?
  3. ¿Hay alguna manera de hacer que la piratería sea más difícil o incluso imposible? ¿Qué más puedo hacer para proteger el código fuente en mi archivo APK?
sachin003
fuente
120
Parece que puede estar usando "seguridad por oscuridad" si su esquema de procesamiento de pagos se basa en la operación del secreto secreto del cliente.
PeterJ
43
¿Ha considerado escribir las partes importantes del código en C / C ++ y agregarlas como una biblioteca compilada? Se pueden desmontar en código de ensamblaje, pero la ingeniería inversa de una gran biblioteca desde el ensamblaje consume mucho tiempo.
Leo
6060
Bienvenido a la cuestión fundamental de crear cualquier activo digital. Los piratas informáticos pueden llegar al nivel de instrucción de la máquina, por lo que si una computadora puede leer el archivo, entonces puede ser pirateado abierto / copiado, una cantidad de ofuscación o DRM nunca puede detener por completo a un pirata informático determinado. Si necesita seguridad, asegúrese de que las claves privadas nunca estén en la fuente y sepa en la etapa de diseño que solo el aislamiento (hardware remoto y / o dedicado) puede protegerlas.
Keith
16
Tenga en cuenta que, según lo que haga su aplicación de procesamiento de pagos, puede haber una política regulatoria y legal que afecte su aplicación y que pueda exponerlo potencialmente a sanciones severas: consulte el cumplimiento de PCI, comenzando con pcicomplianceguide.org/pcifaqs.php#11 .
bloopletech

Respuestas:

372

 1. ¿Cómo puedo evitar por completo la ingeniería inversa de un APK de Android? es posible?

AFAIK, no hay ningún truco para evitar por completo la ingeniería inversa.

Y también muy bien dicho por @inazaruk: Lo que sea que hagas a tu código, un atacante potencial puede cambiarlo de cualquier manera que él o ella lo encuentre factible . Básicamente no puede proteger su aplicación de ser modificada. Y cualquier protección que coloque allí puede ser desactivada / eliminada.

 2. ¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?

Sin embargo, puedes hacer diferentes trucos para dificultar la piratería. Por ejemplo, use ofuscación (si es código Java). Esto generalmente ralentiza significativamente la ingeniería inversa.

 3. ¿Hay alguna manera de hacer que la piratería sea más difícil o incluso imposible? ¿Qué más puedo hacer para proteger el código fuente en mi archivo APK?

Como todos dicen, y como probablemente sepan, no hay un 100% de seguridad. Pero el lugar para comenzar con Android, que Google ha incorporado, es ProGuard. Si tiene la opción de incluir bibliotecas compartidas , puede incluir el código necesario en C ++ para verificar el tamaño de los archivos, la integración, etc. Si necesita agregar una biblioteca nativa externa a la carpeta de la biblioteca de su APK en cada compilación, puede usarla por la sugerencia a continuación.

Coloque la biblioteca en la ruta de la biblioteca nativa que por defecto es "libs" en la carpeta de su proyecto. Si creó el código nativo para el objetivo 'armeabi' , póngalo en libs / armeabi . Si se construyó con armeabi-v7a , póngalo en libs / armeabi-v7a.

<project>/libs/armeabi/libstuff.so
Bhavesh Patadiya
fuente
1
Para la transacción de pago, he utilizado el estándar ISO 8585, en este momento el esquema para este estándar está en par clave-valor usando la colección HashMap de Java y cuando realizo ingeniería inversa en apk obtendré todo el esquema. Es posible evitar que el esquema se obtenga expuesto a través de ingeniería inversa. ¿Puede su última sugerencia de compartir bibliotecas útiles en este caso? Doy, tienes enlaces para que yo pueda exponerme a las bibliotecas compartidas en Android.
sachin003
44
¿qué hay de encriptar sus cadenas en el código y descifrarlas en tiempo de ejecución? Si realiza el descifrado en un servidor remoto, como sugirieron otras personas, no tiene el problema de que la clave de descifrado esté en las fuentes.
kutschkem
Sí, el cifrado es muy sencillo, pero no es seguro que no sea hackeado. Si estoy encriptando String para descifrarlos, necesito una identificación única en el código. y si alguien puede descompilarlo, será muy fácil obtener la identificación única.
Bhavesh Patadiya
¿Por qué agregaste cosas editadas ? Todo es regular.
Mohammed Azharuddin Shaikh
@hotveryspicy: sí, ahora eliminé la marca "editada" de answer.Edité mi respuesta porque quería saber más sobre cómo Compartir bibliotecas útiles en este caso.
Bhavesh Patadiya
126

AFAIK, no puede proteger los archivos en el directorio / res más de lo que están protegidos en este momento.

Sin embargo, hay pasos que puede seguir para proteger su código fuente, o al menos lo que hace si no todo.

  1. Use herramientas como ProGuard. Esto ofuscará su código y hará que sea más difícil de leer cuando se descompila, si no imposible.
  2. Mueva las partes más críticas del servicio fuera de la aplicación y a un servicio web, oculto detrás de un lenguaje del lado del servidor como PHP. Por ejemplo, si tiene un algoritmo que le tomó un millón de dólares para escribir. Obviamente, no quieres que las personas lo roben de tu aplicación. Mueva el algoritmo y haga que procese los datos en un servidor remoto, y use la aplicación para simplemente proporcionarle los datos. O utilice el NDK para escribirlos de forma nativa en archivos .so, que tienen muchas menos probabilidades de descompilarse que los apks. No creo que exista un descompilador para archivos .so incluso a partir de ahora (e incluso si lo hiciera, no sería tan bueno como los descompiladores de Java). Además, como @nikolay mencionó en los comentarios, debe usar SSL al interactuar entre el servidor y el dispositivo.
  3. Al almacenar valores en el dispositivo, no los almacene en un formato sin formato. Por ejemplo, si tiene un juego y está almacenando la cantidad de moneda del juego que el usuario tiene en SharedPreferences. Asumamos que son 10000monedas. En lugar de guardar 10000directamente, guárdelo usando un algoritmo como ((currency*2)+1)/13. Entonces, en lugar de 10000guardarlo 1538.53846154en SharedPreferences. Sin embargo, el ejemplo anterior no es perfecto, y tendrá que trabajar para llegar a una ecuación que no pierda vigencia debido a errores de redondeo, etc.
  4. Puede hacer algo similar para las tareas del lado del servidor. Ahora, por ejemplo, tomemos su aplicación de procesamiento de pagos. Digamos que el usuario tiene que hacer un pago $200. En lugar de enviar un $200valor sin formato al servidor, envíe una serie de valores más pequeños y predefinidos que sumen $200. Por ejemplo, tenga un archivo o tabla en su servidor que iguale palabras con valores. Entonces digamos que Charliecorresponde a $47, y Johna $3. Entonces, en lugar de enviar $200, puede enviar Charliecuatro veces yJohncuatro veces. En el servidor, interpreta lo que significan y súmalo. Esto evita que un hacker envíe valores arbitrarios a su servidor, ya que no saben qué palabra corresponde a qué valor. Como medida adicional de seguridad, también podría tener una ecuación similar al punto 3 para esto, y cambiar las palabras clave cada nnúmero de días.
  5. Finalmente, puede insertar código fuente inútil aleatorio en su aplicación, de modo que el hacker esté buscando una aguja en un pajar. Inserte clases aleatorias que contengan fragmentos de Internet, o simplemente funciones para calcular cosas aleatorias como la secuencia de Fibonacci. Asegúrese de que estas clases se compilan, pero no son utilizadas por la funcionalidad real de la aplicación. Agregue suficientes de estas clases falsas, y el hacker tendría dificultades para encontrar su código real.

Con todo, no hay forma de proteger su aplicación al 100%. Puedes hacerlo más difícil, pero no imposible. Su servidor web podría verse comprometido, el pirata informático podría descubrir sus palabras clave mediante el monitoreo de múltiples cantidades de transacciones y las palabras clave que envíe, el pirata informático podría pasar minuciosamente a través de la fuente y descubrir qué código es falso.

Solo puedes defenderte, pero nunca ganar.

Raghav Sood
fuente
136
En lugar de hacer trucos con los valores que envía a su servidor, use SSL y valide correctamente el certificado del servidor. La seguridad por oscuridad es generalmente una mala idea.
Nikolay Elenkov
48
puedes insertar código fuente inútil aleatorio en tu aplicación . Esto tampoco puede ayudar realmente. Esto solo aumentará su aplicación, mientras que también hará que sea más difícil de mantener.
Anirudh Ramanathan
44
También podría usar el código inútil y enviar los datos al servidor que lo descartará. Falsa seguridad tal vez, pero un dolor en el culo para el posible hacker, ¿verdad?
Benoit Duffez
19
Si su algoritmo vale un millón de dólares, solo porque no haya un descompilador para .soarchivos no significa que no pueda leer el ensamblaje :) La mayoría de estos caen en la misma trampa, solo se ofuscan en lugar de protegerse adecuadamente. La ofuscación solo funciona si no vale la pena el tiempo de un atacante para seguirla, así que si construyes algo sobre estas técnicas, es mejor que esperes que no se vuelvan populares, de lo contrario estarás jodido porque de repente tu base de código no se puede mantener y Necesita grandes cambios.
Phoshi
23
No entiendo por qué esta respuesta tiene una puntuación tan alta. 3. y 4. para uno son simplemente tontos y no representarán ninguna seguridad en absoluto.
Matti Virkkunen
117

En ningún momento de la historia de la informática ha sido posible evitar la ingeniería inversa del software cuando le entrega una copia de trabajo a su atacante. Además, lo más probable es que nunca sea posible .

Con eso entendido, hay una solución obvia: no le des tus secretos a tu atacante. Si bien no puede proteger el contenido de su APK, lo que puede proteger es cualquier cosa que no distribuya. Por lo general, este es un software del lado del servidor utilizado para cosas como la activación, pagos, cumplimiento de reglas y otros jugosos bits de código. Puede proteger activos valiosos al no distribuirlos en su APK. En su lugar, configure un servidor que responda a las solicitudes de su aplicación, "use" los activos (lo que sea que eso signifique) y luego envíe el resultado a la aplicación. Si este modelo no funciona para los activos que tiene en mente, es posible que desee repensar su estrategia.

Además, si su objetivo principal es evitar la piratería de aplicaciones : ni se moleste. Ya ha gastado más tiempo y dinero en este problema de lo que cualquier medida contra la piratería podría esperar salvarlo. El retorno de la inversión para resolver este problema es tan bajo que ni siquiera tiene sentido pensarlo.

tylerl
fuente
21
El primer párrafo es la mejor respuesta. Si su atacante controla el hardware, siempre podrá derrotar su software de alguna manera. Cualquier cosa que realmente necesite protección debe permanecer en el hardware que controlas, es tan simple como eso. Y el párrafo final, sobre el ROI, también es perfecto.
Daniel Pryden
88

Primera regla de seguridad de la aplicación: cualquier máquina a la que un atacante obtenga acceso físico o electrónico sin restricciones ahora pertenece a su atacante, independientemente de dónde se encuentre realmente o de lo que haya pagado.

Segunda regla de seguridad de la aplicación: cualquier software que deje los límites físicos dentro de los cuales un atacante no puede penetrar ahora pertenece a su atacante, independientemente de cuánto tiempo haya dedicado a codificarlo.

Tercera regla: cualquier información que deje esos mismos límites físicos que un atacante no puede penetrar ahora pertenece a su atacante, sin importar lo valioso que sea para usted.

Los fundamentos de la seguridad de la tecnología de la información se basan en estos tres principios fundamentales; la única computadora verdaderamente segura es la que está encerrada en una caja fuerte, dentro de una jaula Farraday, dentro de una jaula de acero. Hay computadoras que pasan la mayor parte de su vida útil solo en este estado; una vez al año (o menos), generan las claves privadas para las autoridades de certificación raíz de confianza (frente a una gran cantidad de testigos con cámaras que graban cada centímetro de la habitación en la que se encuentran).

Ahora, la mayoría de las computadoras no se utilizan en este tipo de entornos; están físicamente al aire libre, conectados a Internet a través de un canal de radio inalámbrico. En resumen, son vulnerables, como es su software. Por lo tanto, no se puede confiar en ellos. Hay ciertas cosas que las computadoras y su software deben saber o hacer para ser útiles, pero se debe tener cuidado para garantizar que nunca puedan saber o hacer lo suficiente como para causar daños (al menos no daños permanentes fuera de los límites de esa única máquina )

Ya sabías todo esto; Es por eso que está tratando de proteger el código de su aplicación. Pero, ahí radica el primer problema; las herramientas de ofuscación pueden hacer que el código sea un desastre para que un humano intente cavar, pero el programa aún tiene que ejecutarse; eso significa que el flujo lógico real de la aplicación y los datos que usa no se ven afectados por la ofuscación. Dada un poco de tenacidad, un atacante puede simplemente desenmascarar el código, y eso ni siquiera es necesario en ciertos casos donde lo que está mirando no puede ser otra cosa que lo que está buscando.

En cambio, debe intentar asegurarse de que un atacante no pueda hacer nada con su código, sin importar cuán fácil sea para él obtener una copia clara del mismo. Eso significa que no hay secretos codificados, porque esos secretos no son secretos tan pronto como el código abandona el edificio en el que lo desarrolló.

Estos valores clave que ha codificado deben eliminarse por completo del código fuente de la aplicación. En cambio, deberían estar en uno de los tres lugares; memoria volátil en el dispositivo, que es más difícil (pero aún no imposible) para un atacante obtener una copia fuera de línea; permanentemente en el clúster de servidores, al que controla el acceso con un puño de hierro; o en un segundo almacén de datos no relacionado con su dispositivo o servidores, como una tarjeta física o en las memorias de su usuario (lo que significa que eventualmente estará en una memoria volátil, pero no tiene que ser por mucho tiempo).

Considere el siguiente esquema. El usuario ingresa sus credenciales para la aplicación desde la memoria al dispositivo. Desafortunadamente, debe confiar en que el dispositivo del usuario no esté comprometido por un keylogger o un troyano; lo mejor que puede hacer a este respecto es implementar la seguridad multifactor, recordando información de identificación difícil de falsificar sobre los dispositivos que ha utilizado el usuario (MAC / IP, IMEI, etc.) y proporcionando al menos un canal adicional al que se puede verificar un intento de inicio de sesión en un dispositivo desconocido.

Las credenciales, una vez ingresadas, son ofuscadas por el software del cliente (utilizando un hash seguro), y las credenciales de texto sin formato se descartan; Han cumplido su propósito. Las credenciales ofuscadas se envían a través de un canal seguro al servidor autenticado con certificado, que las vuelve a cifrar para generar los datos utilizados para verificar la validez del inicio de sesión. De esta manera, el cliente nunca sabe qué se compara realmente con el valor de la base de datos, el servidor de aplicaciones nunca conoce las credenciales de texto sin formato detrás de lo que recibe para la validación, el servidor de datos nunca sabe cómo se producen los datos que almacena para la validación, y un hombre en el centro solo ve galimatías incluso si el canal seguro se vio comprometido.

Una vez verificado, el servidor transmite un token por el canal. El token solo es útil dentro de la sesión segura, está compuesto de ruido aleatorio o una copia encriptada (y por lo tanto verificable) de los identificadores de sesión, y la aplicación cliente debe enviar este token en el mismo canal al servidor como parte de cualquier solicitud hacer algo. La aplicación cliente lo hará muchas veces, porque no puede hacer nada que involucre dinero, datos confidenciales o cualquier otra cosa que pueda ser dañina por sí misma; en su lugar, debe pedirle al servidor que realice esta tarea. La aplicación cliente nunca escribirá ninguna información confidencial en la memoria persistente del dispositivo, al menos no en texto plano; el cliente puede pedirle al servidor a través del canal seguro una clave simétrica para encriptar cualquier dato local, que el servidor recordará; en una sesión posterior, el cliente puede pedirle al servidor la misma clave para descifrar los datos para usar en la memoria volátil. Esos datos tampoco serán la única copia; cualquier cosa que el cliente almacene también debe transmitirse de alguna forma al servidor.

Obviamente, esto hace que su aplicación dependa en gran medida del acceso a Internet; el dispositivo cliente no puede realizar ninguna de sus funciones básicas sin una conexión y autenticación adecuadas por parte del servidor. No es diferente a Facebook, de verdad.

Ahora, la computadora que el atacante quiere es su servidor, porque no es la aplicación / dispositivo del cliente lo que le puede hacer ganar dinero o causar dolor a otras personas por su disfrute. Está bien; obtienes mucho más por tu dinero gastando dinero y esfuerzo para proteger el servidor que al tratar de proteger a todos los clientes. El servidor puede estar detrás de todo tipo de cortafuegos y otros dispositivos de seguridad electrónica, y además puede estar físicamente asegurado detrás de acero, concreto, acceso con tarjeta / pin y vigilancia por video las 24 horas. Su atacante necesitaría ser muy sofisticado para obtener cualquier tipo de acceso al servidor directamente, y usted (debería) saberlo de inmediato.

Lo mejor que puede hacer un atacante es robar el teléfono y las credenciales de un usuario e iniciar sesión en el servidor con los derechos limitados del cliente. Si esto sucede, al igual que perder una tarjeta de crédito, se debe indicar al usuario legítimo que llame al número 800 (preferiblemente fácil de recordar, y no en el reverso de una tarjeta que llevarían en su bolso, billetera o maletín que podría ser robado junto con el dispositivo móvil) desde cualquier teléfono al que puedan acceder que los conecte directamente a su servicio al cliente. Afirman que su teléfono fue robado, proporcionan un identificador único básico, y la cuenta está bloqueada, cualquier transacción que el atacante haya podido procesar se revierte, y el atacante vuelve al punto de partida.

KeithS
fuente
1
Respuesta perfecta !! Me encantó su forma de obtener datos del servidor con algún token cifrado, creo que esto es casi imposible de decodificar después de eso.
dharam
Sé que esto es un poco tarde, pero ¿qué pasa con el acceso a la parte del servidor? Servicios como Microsoft azure le proporciona algo como esto para acceder a su servidor: MobileServiceClient mClient = new MobileServiceClient ("MobileServiceUrl", // Reemplace con la URL del sitio "AppKey" anterior, // reemplace con la clave de aplicación esto) y casi cualquier persona que tiene acceso a eso puede acceder a su servidor y editarlo
edwinj
@edwinj: no hay problema en informática que no pueda resolverse con otra capa de indirección. Su fragmento proporciona la idea básica para acceder a un servicio de cliente móvil de Azure; Proporciona un nivel básico de seguridad contra los "pases de acceso" de la puerta de entrada de Microsoft. A su vez, puede agregar capas adicionales, como requerir una clave de sesión (básicamente, cuál es el token cifrado) en cualquier llamada de servicio, y para obtener esa clave, primero deben autenticarse con una combinación de conocimiento de las credenciales y el esquema de cifrado.
KeithS
1
Una de las mejores respuestas.
debo.stackoverflow
64

 1. ¿Cómo puedo evitar por completo la ingeniería inversa de un APK de Android? es posible?

Esto no es posible

 2. ¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?

Cuando alguien cambia una extensión .apk a .zip, luego de descomprimir, alguien puede obtener fácilmente todos los recursos (excepto Manifest.xml ), pero con APKtool se puede obtener el contenido real del archivo de manifiesto. De nuevo, un no.

 3. ¿Hay alguna manera de hacer que la piratería sea más difícil o incluso imposible? ¿Qué más puedo hacer para proteger el código fuente en mi archivo APK?

De nuevo, no, pero puede evitar hasta cierto nivel, es decir,

  • Descargue un recurso de la Web y realice un proceso de cifrado
  • Utilice una biblioteca nativa precompilada (C, C ++, JNI, NDK)
  • Siempre realice un hashing ( teclas MD5 / SHA o cualquier otra lógica)

Incluso con Smali, la gente puede jugar con tu código. Con todo, no es POSIBLE.

Mohammed Azharuddin Shaikh
fuente
77
@TrevorBoydSmith: el cifrado no ayuda mucho cuando el sistema operativo es de código abierto y se puede rootear. El sistema necesita una clave para descifrar el APK y ejecutar cosas. Y si el sistema tiene una clave y tengo acceso ilimitado al sistema, entonces sé dónde encontrar la clave y puedo acceder a ella. Lo que significa que ahora tengo la llave también .
cHao
44
@TrevorBoydSmith: Sin embargo, es la parte de "cómo hacerlo" que mata toda la idea. Simplemente no hay forma de ejecutar código cifrado directamente; en algún momento, el código descifrado debe estar disponible. Lo que significa que (1) debe haber una clave (a la que yo, como root, probablemente tenga acceso), y (2) incluso podría encontrar la copia clara en la RAM y no preocuparme por el cifrado de todos modos.
cHao
3
@TrevorBoydSmith: El problema es que, en este caso, simplemente no puede aumentar el costo lo suficiente como para que no valga la pena. No estamos hablando de llaves de fuerza bruta aquí; estamos hablando de tenerlos ya : el sistema operativo debe tener claves y nosotros tenemos el sistema operativo. La única forma de solucionarlo sería hacer que el sistema operativo no sea rooteable. Buena suerte con eso; incluso Apple no puede manejarlo. :)
cHao
3
@TrevorBoydSmith: No creo que aumentar el costo en general sea ​​imposible. Creo (y digo), en particular , que su sugerencia es imposible, porque lo es . MATLAB no es Android y tiene ciertas libertades que Android no tiene. En particular, tiene ofuscación de su lado; Es mucho más difícil ocultar una clave de cifrado. Android no puede hacer eso. Cualquiera que tenga el código fuente sabría dónde se esconden las claves y tendría una herramienta para recuperarlas dentro de los 10 minutos posteriores al anuncio de la función. No solo es posible hacer eso; Es francamente trivial .
cHao
66
@TrevorBoydSmith: No he insistido en nada de eso. Lo que insisto es que la estática, el cambio, el movimiento, etc. no importan . En un sistema operativo de código abierto, el cifrado por sí solo no puede proteger el código de nadie que pueda realizar ingeniería inversa. Debido a que puedo leer el código que haría el descifrado, independientemente de cómo se adquiera, use y / o almacene la clave, puedo ver cómo lo hizo y replicarlo, incluso más fácilmente de lo que podría revertir algunos súper secretos código de la aplicación
cHao
37

No es posible evitar al 100% la ingeniería inversa del APK de Android, pero puede usar estas formas para evitar extraer más datos, como el código fuente, los activos de su APK y los recursos:

  1. Use ProGuard para ofuscar el código de la aplicación

  2. Use NDK usando C y C ++ para poner el núcleo de su aplicación y asegurar parte del código en .soarchivos

  3. Para proteger los recursos, no incluya todos los recursos importantes en la carpeta de activos con APK. Descargue estos recursos al momento de iniciar la aplicación.

ρяσѕρєя K
fuente
77
El tercero realmente está facilitando el trabajo de los atacantes. Oler la comunicación de red es más fácil que la ingeniería inversa.
totten
Para resolver el problema del tercero, se podría cifrar el contenido descargado y / o utilizar una conexión cifrada (por ejemplo, SSL / TLS)
Stradivari
1
Cifrar la conexión protege contra las personas que huelen o modifican el tráfico. En el caso de que el usuario mismo sea malicioso (es decir, tiene su apk y está intentando hackearlo), seguirá obteniendo el contenido utilizando su aplicación, extrayendo recursos como usuario root; pero sí ayuda contra ataques simples de olfateo.
Kevin Lee
Además de eso: 4) use dexguard para una mayor ofuscación, pero se paga 5) use el archivo OBB para la descarga de activos al momento de descargar la aplicación, también ayudará a reducir el tamaño de la aplicación
Ashok Kumar
35

Los desarrolladores pueden seguir los siguientes pasos para evitar el robo de un APK de alguna manera,

  • la forma más básica es usar herramientas como ProGuardofuscar su código, pero hasta ahora, ha sido bastante difícil evitar por completo que alguien descompile una aplicación.

  • También he oído hablar de una herramienta HoseDex2Jar . Se detiene Dex2Jaral insertar código inofensivo en un APK de Android que confunde, deshabilita Dex2Jary protege el código de la descompilación. De alguna manera, podría evitar que los piratas informáticos descompilen un APK en un código Java legible.

  • Use alguna aplicación del lado del servidor para comunicarse con la aplicación solo cuando sea necesario. Podría ayudar a prevenir los datos importantes.

En absoluto, no puede proteger completamente su código de los posibles piratas informáticos. De alguna manera, podría dificultarles una tarea un poco frustrante para que descompilen su código. Una de las formas más eficientes es escribir en código nativo (C / C ++) y almacenarlo como bibliotecas compiladas.

Sahil Mahajan Mj
fuente
3
HoseDex2Jar está al lado de inútil. Solo 'confunde' dex2jar y puede bloquearse fácilmente. smali / apktool, etc. funcionan bien con los APK 'con manguera'.
Nikolay Elenkov
@NikolayElenkov ¿Sabes cómo funciona HoseDex2Jar? Lo que han usado para evitar o confundir dex2jar. Porque no puedo subir mi archivo apk a la web para usar HoseDex2Jar. Si puedo hacer algo como HoseDex2Jar para confundir a dex2jar, entonces será difícil hackear usando la herramienta dex2jar.
sachin003
1
Tal vez no entendiste mi punto: lo que HoseDex2Jar hace es reempacar tu APK para que la popular herramienta dex2jar no pueda (fuera de la caja) revertirlo. Sin embargo, otras herramientas pueden hacerlo, y es muy fácil derrotarlo en general. No tiene sentido usarlo. Nadie mencionó la cosa Dexguard I (por el autor de ProGuard; no es gratis), pero es un trabajo de observación. Hace algo más que la ofuscación 'regular'.
Nikolay Elenkov
C ++ nunca se puede revertir? Es difícil pero posible. y hay herramientas para ayudarlo con eso, como hex-rays.com/products/decompiler/index.shtml (sí, tienen una versión ARM. No es tan fácil de obtener).
dkzm
sí, @VikartiAnatra: también mencioné De alguna manera, podrías hacerlo difícil
Sahil Mahajan Mj
24

Aquí hay algunos métodos que puedes probar:

  1. Use ofuscación y herramientas como ProGuard .
  2. Cifre alguna parte de la fuente y los datos.
  3. Use una suma de verificación incorporada patentada en la aplicación para detectar la manipulación.
  4. Introduzca el código para evitar cargar en un depurador, es decir, permita que la aplicación tenga la capacidad de detectar el depurador y salir / eliminar el depurador.
  5. Separe la autenticación como un servicio en línea.
  6. Usar diversidad de aplicaciones
  7. Utilice la técnica de huellas digitales para, por ejemplo, firmas de hardware de los dispositivos de diferentes subsistemas antes de autenticar el dispositivo.
Shan
fuente
23

 1. ¿Cómo puedo evitar por completo la ingeniería inversa de un APK de Android? es posible?

Imposible

 2. ¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?

Imposible

 3. ¿Hay alguna manera de hacer que la piratería sea más difícil o incluso imposible? ¿Qué más puedo hacer para proteger el código fuente en mi archivo APK?

Más difícil: posible, pero de hecho será más difícil principalmente para el usuario promedio, que solo busca en Google las guías de pirateo. Si alguien realmente quiere hackear tu aplicación, será hackeada, tarde o temprano.

janot
fuente
22

 1. ¿Cómo puedo evitar por completo la ingeniería inversa de un APK de Android? es posible?

Eso es imposible

 2. ¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?

Los desarrolladores pueden tomar medidas como usar herramientas como ProGuard para ofuscar su código, pero hasta ahora, ha sido bastante difícil evitar por completo que alguien descompile una aplicación.

Es una herramienta realmente excelente y puede aumentar la dificultad de 'revertir' su código mientras reduce la huella de su código.

Soporte ProGuard integrado: ProGuard ahora está empaquetado con las herramientas SDK. Los desarrolladores ahora pueden ofuscar su código como parte integrada de una compilación de lanzamiento.

 3. ¿Hay alguna manera de hacer que la piratería sea más difícil o incluso imposible? ¿Qué más puedo hacer para proteger el código fuente en mi archivo APK?

Mientras investigaba, llegué a saber sobre HoseDex2Jar . Esta herramienta protegerá su código de descompilación, pero parece que no es posible proteger su código por completo.

Algunos enlaces útiles, puede consultarlos.

Robin Hood
fuente
21

La pregunta principal aquí es si se pueden descompilar los archivos dex y la respuesta es que pueden ser "algo así". Hay desensambladores como dedexer y smali .

ProGuard, configurado correctamente, ofuscará su código. DexGuard, que es una versión comercial extendida de ProGuard, puede ayudar un poco más. Sin embargo, su código aún se puede convertir en smali y los desarrolladores con experiencia en ingeniería inversa podrán averiguar lo que está haciendo desde el smali.

Tal vez elegir una buena licencia y hacerla cumplir por ley de la mejor manera posible.

Abhishek Sabbarwal
fuente
44
Como nota al margen (descargo de responsabilidad: IANAL): la licencia no protegerá la aplicación en todas las jurisdicciones en todas las circunstancias (por ejemplo, en algunos países de Europa se permite el desmontaje para aumentar la compatibilidad).
Maciej Piechotka
12

Su cliente debe contratar a alguien que sepa lo que está haciendo, que puede tomar las decisiones correctas y puede asesorarlo.

Hablar más arriba acerca de que tiene alguna capacidad para cambiar el sistema de procesamiento de transacciones en el backend es absurdo: no se le debe permitir hacer tales cambios arquitectónicos, así que no espere poder hacerlo.

Mi razonamiento sobre esto:

Dado que su dominio es el procesamiento de pagos, es seguro asumir que PCI DSS y / o PA DSS (y la posible ley estatal / federal) serán importantes para su negocio; para cumplir con los requisitos debe demostrar que está seguro. Para ser inseguro, descubra (a través de las pruebas) que no es seguro, luego repare, vuelva a probar, etc. hasta que la seguridad pueda verificarse en un nivel adecuado = forma costosa, lenta y de alto riesgo para el éxito. Para hacer lo correcto, piense por adelantado, comprometa talento experimentado para el trabajo, desarrolle de manera segura, luego pruebe, arregle (menos), etcétera (menos) hasta que se pueda verificar la seguridad en un nivel adecuado = económico, rápido, camino de bajo riesgo al éxito.

Straya
fuente
8

Como alguien que trabajó extensamente en plataformas de pago, incluida una aplicación de pagos móviles (MyCheck), diría que debe delegar este comportamiento al servidor, no debe almacenarse ningún nombre de usuario o contraseña para el procesador de pagos (lo que sea) codificado en la aplicación móvil, eso es lo último que desea, porque la fuente se puede entender incluso cuando se ofusca el código.

Además, no debe almacenar tarjetas de crédito o tokens de pago en la aplicación, todo debe delegarse nuevamente en un servicio que creó, también le permitirá más adelante, cumplir con PCI con mayor facilidad y las compañías de tarjetas de crédito ganaron No respires por el cuello (como lo hicieron por nosotros).

Itai Sagi
fuente
7

Las otras respuestas votadas aquí son correctas. Solo quiero ofrecer otra opción.

Para determinadas funciones que considere importantes, puede alojar el control WebView en su aplicación. La funcionalidad se implementaría en su servidor web. Parecerá que se está ejecutando en su aplicación.

Sarel Botha
fuente
@Sarel Botha sí para pantallas IMP Ya utilicé webview y sí, esta también es una forma de mantener la seguridad, estoy aceptando tu respuesta.
sachin003
7

Si queremos hacer que la ingeniería inversa (casi) sea imposible, podemos colocar la aplicación en un chip altamente resistente a la manipulación, que ejecuta todas las cosas sensibles internamente y se comunica con algún protocolo para hacer posible el control de la GUI en el host. Incluso los chips resistentes a la manipulación no son 100% a prueba de grietas; solo ponen el listón mucho más alto que los métodos de software. Por supuesto, esto es un inconveniente: la aplicación requiere un poco de verruga USB que contiene el chip para insertarlo en el dispositivo.

La pregunta no revela la motivación para querer proteger esta aplicación tan celosamente.

Si el objetivo es mejorar la seguridad del método de pago ocultando cualquier falla de seguridad que pueda tener la aplicación (conocida o no), está completamente equivocada. De hecho, los bits sensibles a la seguridad deben ser de código abierto, si eso es factible. Debe hacer que sea lo más fácil posible para cualquier investigador de seguridad que revise su aplicación encontrar esos bits y examinar su funcionamiento, y contactarlo. Las aplicaciones de pago no deben contener ningún certificado incrustado. Es decir, no debería haber una aplicación de servidor que confíe en un dispositivo simplemente porque tiene un certificado fijo de fábrica. Una transacción de pago debe hacerse solo con las credenciales del usuario, utilizando un protocolo de autenticación de extremo a extremo diseñado correctamente que impida confiar en la aplicación, la plataforma, la red, etc.

Si el objetivo es evitar la clonación, a excepción de ese chip a prueba de manipulaciones, no hay nada que pueda hacer para proteger el programa de la ingeniería inversa y la copia, de modo que alguien incorpore un método de pago compatible en su propia aplicación, dando elevarse a "clientes no autorizados". Hay formas de dificultar el desarrollo de clientes no autorizados. Una sería crear sumas de verificación basadas en instantáneas del estado completo del programa: todas las variables de estado, para todo. GUI, lógica, lo que sea. Un programa de clonación no tendrá exactamente el mismo estado interno. Claro, es una máquina de estado que tiene transiciones de estado similares externamente visibles (como se puede observar por entradas y salidas), pero apenas el mismo estado interno. Una aplicación de servidor puede interrogar al programa: ¿cuál es su estado detallado? (es decir dame una suma de comprobación sobre todas tus variables de estado interno). Esto se puede comparar con el código de cliente ficticio que se ejecuta en el servidor en paralelo, pasando por las transiciones de estado genuinas. Un clon de terceros tendrá que replicar todos los cambios de estado relevantes del programa genuino para dar las respuestas correctas, lo que dificultará su desarrollo.

Kaz
fuente
7

De acuerdo con @ Muhammad Saqib aquí: https://stackoverflow.com/a/46183706/2496464

Y @Mumair da unos buenos pasos iniciales: https://stackoverflow.com/a/35411378/474330

Siempre es seguro asumir que todo lo que distribuye al dispositivo de su usuario pertenece al usuario. Llano y simple. Es posible que pueda utilizar las últimas herramientas y procedimientos para cifrar sus propiedades intelectuales, pero no hay forma de evitar que una persona determinada 'estudie' su sistema. E incluso si la tecnología actual puede dificultarles el acceso no deseado, puede haber alguna manera fácil mañana, ¡o incluso solo la próxima hora!

Por lo tanto, aquí viene la ecuación:

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

Incluso en una economía tan simple como en el juego. (¡Especialmente en los juegos! ¡Hay usuarios más 'sofisticados' allí y las lagunas se extienden en segundos!)

¿Cómo nos mantenemos a salvo?

La mayoría, si no todos, de nuestros sistemas de procesamiento de claves (y base de datos, por supuesto) ubicados en el lado del servidor. Y entre el cliente y el servidor, se encuentran comunicaciones cifradas, validaciones, etc. Esa es la idea del cliente ligero.

Zennichimaro
fuente
4

Esquema de firma APK v2 en Android N

La clase PackageManager ahora admite la verificación de aplicaciones utilizando el esquema de firma APK v2. El esquema de firma APK v2 es un esquema de firma de archivo completo que mejora significativamente la velocidad de verificación y fortalece las garantías de integridad al detectar cualquier cambio no autorizado en los archivos APK.

Para mantener la compatibilidad con versiones anteriores, se debe firmar un APK con el esquema de firma v1 (esquema de firma JAR) antes de firmar con el esquema de firma v2. Con el esquema de firma v2, la verificación falla si firma el APK con un certificado adicional después de firmar con el esquema v2.

La compatibilidad con el esquema de firma APK v2 estará disponible más adelante en N Developer Preview.

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

tiagolr
fuente
2
La firma v2 de Apk solo evita que se alteren los recursos, pero no dificulta la ingeniería inversa ...
Louis CAD
1
Además, puede eliminar la firma y volver a firmarla. La firma v2 es solo un bloque de datos en el archivo APK.
Robert
4

No hay forma de evitar por completo la ingeniería inversa de un APK. Para proteger los recursos y recursos de la aplicación, puede usar el cifrado.

  • El cifrado hará que sea más difícil usarlo sin descifrarlo. Elegir un algoritmo de cifrado fuerte hará que el descifrado sea más difícil.
  • Agregar un código falso en su lógica principal para hacer más difícil el craqueo.
  • Si puede escribir su lógica crítica en cualquier idioma nativo y eso seguramente dificultará la descompilación.
  • Usar marcos de seguridad de terceros como Quixxi
inmutable
fuente
3

Básicamente no es posible. Nunca será posible Sin embargo, hay esperanza. Puede usar un ofuscador para hacerlo, por lo que algunos ataques comunes son mucho más difíciles de llevar a cabo, incluyendo cosas como:

  1. Cambiar el nombre de los métodos / clases (por lo que en el descompilador obtienes tipos como a.a)
  2. Ofuscando el flujo de control (por lo tanto, en el descompilador, el código es muy difícil de leer)
  3. Cifrar cadenas y posiblemente recursos

Estoy seguro de que hay otros, pero esos son los principales. Trabajo para una compañía llamada PreEmptive Solutions en un ofuscador .NET . También tienen un ofuscador Java que funciona para Android y uno llamado DashO .

Sin embargo, la ofuscación siempre tiene un precio. En particular, el rendimiento suele ser peor y, por lo general, requiere algo de tiempo extra para los lanzamientos. Sin embargo, si su propiedad intelectual es extremadamente importante para usted, entonces generalmente vale la pena.

De lo contrario, su única opción es hacer que su aplicación de Android pase a un servidor que aloje toda la lógica real de su aplicación. Esto tiene sus propios problemas, porque significa que los usuarios deben estar conectados a Internet para usar su aplicación.

Además, no solo Android tiene este problema. Es un problema en todas las tiendas de aplicaciones. Es solo una cuestión de lo difícil que es acceder al archivo del paquete (por ejemplo, no creo que sea muy fácil en los iPhones, pero aún es posible).

Earlz
fuente
Desafortunadamente, si uno piratea al cliente (la aplicación), podría ver el formato de comunicación y crear su propio servidor :(
Jocky Doe
3

No es posible evitar por completo la ER, pero al hacerlos más complejos internamente, hace que sea más difícil para los atacantes ver el funcionamiento claro de la aplicación, lo que puede reducir la cantidad de vectores de ataque.

Si la aplicación maneja datos altamente sensibles, existen varias técnicas que pueden aumentar la complejidad de la ingeniería inversa de su código. Una técnica es usar C / C ++ para limitar la fácil manipulación en tiempo de ejecución por parte del atacante. Existen amplias bibliotecas C y C ++ que son muy maduras y fáciles de integrar con las ofertas de Android JNI. Un atacante primero debe eludir las restricciones de depuración para atacar la aplicación en un nivel bajo. Esto agrega más complejidad a un ataque. Las aplicaciones de Android deben tener android: debuggable = "false" establecido en el manifiesto de la aplicación para evitar la manipulación fácil del tiempo de ejecución por parte de un atacante o malware.

Verificación de rastreo : una aplicación puede determinar si un depurador u otra herramienta de depuración la está rastreando actualmente. Si se rastrea, la aplicación puede realizar cualquier cantidad de posibles acciones de respuesta de ataque, como descartar claves de cifrado para proteger los datos del usuario, notificar a un administrador del servidor u otro tipo de respuestas en un intento de defenderse. Esto se puede determinar verificando los indicadores de estado del proceso o utilizando otras técnicas como comparar el valor de retorno de ptrace attach, verificar el proceso padre, depurar listas negras en la lista de procesos o comparar marcas de tiempo en diferentes lugares del programa.

Optimizaciones : para ocultar cálculos matemáticos avanzados y otros tipos de lógica compleja, la utilización de optimizaciones del compilador puede ayudar a ofuscar el código objeto para que un atacante no pueda desarmarlo fácilmente, lo que hace que sea más difícil para un atacante obtener una comprensión del código particular. En Android, esto se puede lograr más fácilmente utilizando bibliotecas compiladas de forma nativa con el NDK. Además, el uso de un ofuscador LLVM o cualquier SDK protector proporcionará una mejor ofuscación del código de la máquina.

Eliminar los archivos binarios : eliminar los archivos binarios nativos es una forma efectiva de aumentar la cantidad de tiempo y el nivel de habilidad requerido de un atacante para ver la composición de las funciones de bajo nivel de su aplicación. Al quitar un binario, se quita la tabla de símbolos del binario, de modo que un atacante no puede depurar o aplicar ingeniería inversa a una aplicación fácilmente. Puede referirse a las técnicas utilizadas en sistemas GNU / Linux como sstriping o usando UPX.

Y, por último, debe tener en cuenta la ofuscación y las herramientas como ProGuard.

Sanket Prabhu
fuente
3

Si su aplicación es tan sensible, debería considerar la parte de procesamiento de pagos en el lado del servidor. Intente cambiar sus algoritmos de procesamiento de pagos. Use la aplicación de Android solo para recopilar y mostrar información del usuario (es decir, el saldo de la cuenta) y, en lugar de procesar pagos dentro de los códigos Java, envíe esta tarea a su servidor utilizando un protocolo SSL seguro con parámetros cifrados. Cree una API totalmente encriptada y segura para comunicarse con su servidor.

Por supuesto, también puede ser pirateado y no tiene nada que ver con la protección de los códigos fuente, pero considérelo otra capa de seguridad para dificultar que los hackers engañen su aplicación.

Muhammad Saqib
fuente
2

¿No se supone que los chips TPM (Trusted Platform Module) administran el código protegido por usted? Se están volviendo comunes en las PC (especialmente las de Apple) y es posible que ya existan en los chips para teléfonos inteligentes de hoy. Desafortunadamente, todavía no hay una API del sistema operativo para usarla. Esperemos que Android agregue soporte para este día. Esa también es la clave para limpiar el contenido DRM (en el que Google está trabajando para WebM).

robUx4
fuente
2

Nada es seguro cuando se lo pone a los usuarios finales, pero algunas prácticas comunes pueden dificultar que el atacante robe datos.

  • Ponga su lógica principal (algoritmos) en el lado del servidor.
  • Comunicarse con el servidor y el cliente; asegúrese de que el servidor y el cliente de comunicación en blanco y negro estén protegidos mediante SSL o HTTPS; o use otras técnicas de algoritmos de generación de pares de claves (ECC, RSA). Asegúrese de que la información confidencial permanezca cifrada de extremo a extremo.
  • Use sesiones y expire después de un intervalo de tiempo específico.
  • Cifre recursos y recójalos del servidor a pedido.
  • O puede hacer una aplicación híbrida que acceda al sistema a través de webviewproteger recurso + código en el servidor

Enfoques múltiples; esto es obvio que tienes que sacrificarte entre rendimiento y seguridad

mumair
fuente
2

Puedo ver esa buena respuesta en este hilo. Además puedes usar facebook redexpara optimizar el código. Redex funciona en el .dexnivel donde Proguard funciona como .classnivel.

Asma
fuente
1

¿Cómo puedo proteger todos los recursos, activos y código fuente de la aplicación para que los hackers no puedan hackear el archivo APK de ninguna manera?

Un archivo APK está protegido con el algoritmo SHA-1 . Puede ver algunos archivos en la carpeta META-INF de APK. Si extrae un archivo APK y cambia su contenido y lo vuelve a comprimir y cuando ejecuta ese nuevo archivo APK en una máquina Android, no funcionará, porque los hash SHA-1 nunca coincidirán.

Jeegar Patel
fuente
Esto es verdad; pero es trivial renunciar al APK (con un certificado diferente) y todo volverá a funcionar. Es posible verificar qué firma se ha utilizado para firmar el APK desde la propia aplicación y generar un error si el certificado cambia, pero es un poco menos trivial editar este código fuera de la aplicación.
David dado el
Esto puede evitar que el dispositivo Android ejecute código modificado, pero aún así puede extraer fácilmente el código relevante y escribir un nuevo código en una PC que haga lo que desee.
Sarel Botha
1

Si bien estoy de acuerdo en que no hay una solución al 100% que proteja su código, la versión 3 de HoseDex2Jar ya está disponible si desea probarlo.

Godfrey Nolan
fuente
1

Herramienta: el uso de Proguard en su aplicación puede restringirse a la ingeniería inversa de su aplicación

Mayank Nema
fuente