11 votos

¿Firma del APK verificada pero advierte que el archivo "no está protegido por la firma"?

Estoy usando apksigner para verificar la autenticidad de un Google Podcast apk que descargué de un espejo apk. Este apk (y las versiones anteriores) se verifica con éxito (v1/v2/v3) y devuelve el código de salida 0, pero en la salida veo esta advertencia:

ADVERTENCIA: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader no está protegido por la firma. No se detectarán las modificaciones no autorizadas en esta entrada JAR. Elimina o mueve la entrada fuera de META-INF/.

No entiendo cuál es el impacto de esto. Si el APK está firmado y verificado, ¿por qué veo esta advertencia? ¿Significa que el APK podría ser troyanizado o modificado? ¿Cómo podría un atacante explotar eso?

Estoy descargando algunas versiones antiguas de algunas aplicaciones de Google y quiero estar seguro de que no tienen troyanos, por lo que estoy tratando de verificar la autenticidad antes de instalarlas en mi teléfono.

12voto

pr0nin Puntos 353

Resumen

La advertencia que has encontrado sólo se aplica a la firma del APK v1, pero como el archivo APK está firmado con firmas adicionales de los esquemas de firma más nuevos, puedes ignorar con seguridad este mensaje ya que cada modificación en el archivo APK puede ser detectada por los esquemas de firma más nuevos.

Sin embargo, aunque la firma pueda ser verificada no significa que el archivo APK sea genuino. Todavía podría ser renunciado después de la modificación, por lo que debe comparar cuidadosamente los compendios de certificados (mostrados al verificarlos usando apksigner verify --verbose --print-certs ) del APK a verificar y compararlo con otros archivos APK del mismo desarrollador de aplicaciones. Vea esta respuesta de ¿Cómo puedo verificar la autenticidad de un archivo APK que he descargado? para saber cómo comparar el compendio de certificados de un APK.

Explicación detallada

En primer lugar como puedes ver lo que te sale es un AVISO no un ERROR. Si el archivo(s) relevante(s) del archivo APK ha sido modificado la verificación fallará y obtendrá un mensaje de ERROR.

Para entender el mensaje de advertencia que recibiste necesitas entender un poco de Java y cómo funcionan las firmas de Java (APK signature v1). Esta firma antigua se almacena dentro del JAR en dos archivos: META-INF/CERT.SF y META-INF/CERT.RSA . Por supuesto, una firma no puede firmar los archivos en los que está escrita, por lo que esos archivos quedan excluidos por la firma.

Además, el directorio META-INF es la ubicación del MANIFEST.MF - un archivo que sólo es relevante para Java en el escritorio, pero que no es utilizado por Android en absoluto.

Puede haber archivos adicionales en el directorio META-INF, teniendo en cuenta la disposición estándar de los directorios de Java no se debe almacenar ningún código dentro de los archivos del directorio META-INF.

Debido a todo esto, Sun, como inventor original de Java, decidió excluir el directorio META-INF de la firma del código Java en absoluto. Varios años después, Google sólo utilizó la firma de Java para los archivos APK, que ahora se conoce como firma APK v1.

Por lo tanto, para la firma del APK v1 los archivos dentro del directorio META-INF no están cubiertos por la firma y por lo tanto pueden ser modificados sin ser reconocidos si sólo se verifica

Debido a varios ataques a la propia firma APK (como incluir el mismo archivo varias veces con diferente contenido en el APK) Google decidió desarrollar una firma APK completamente nueva que no se aplica sobre el contenido del APK sino sobre el propio archivo APK en general. Este fue el comienzo de la firma APK v2 y sus sucesores.

Estos nuevos esquemas de firma del APK firman el contenido completo del APK a la vez, sin excluir un solo archivo que se almacena dentro del archivo APK.

Volviendo al APK de Google Podcast, al verificarlo con apksigner sale lo siguiente:

java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com.apk"
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
WARNING: META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader not protected by signature. Unauthorized modifications to this JAR entry will not be detected. Delete or move the entry outside of META-INF/.

Como puedes ver el archivo APK está firmado no sólo por una firma v1 sino también por una firma v2, v3 y v4. Esto significa que la ADVERTENCIA sólo se aplica a la firma creada por el esquema v1. Puedes comprobarlo fácilmente modificando un solo carácter dentro del archivo META-INF/services/com.google.protobuf.GeneratedExtensionRegistryLoader ya que se almacena sin comprimir dentro del archivo APK. Puedes simplemente abrir el archivo APK en un editor hexadecimal, modificar un carácter en la sección que pertenece a ese archivo (es la primera entrada ZIP dentro del APK) y luego nuevamente verificar el APK:

java -jar apksigner.jar verify --verbose "Google Podcasts Discover free trending podcasts_v1.0.0.301897054_apkpure.com - modified.apk"
DOES NOT VERIFY
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. CHUNKED_SHA256 digest mismatch. Expected: <ac8a15569352655a22f13d3c565c2c0e5c62dc70c8f6f8c10f6fbfa63decb19b>, actual: <aa5622cd904500c38424562ef4b5be9e5716d10a85985a41f35e4ed834cee8fe>
ERROR: APK Signature Scheme v3 signer #1: APK integrity check failed. VERITY_CHUNKED_SHA256 digest mismatch. Expected: <56eeebd545733fd6408cd6a30b8bcf98a557076167902b6d9502b5aca86b78e89b42220000000000>, actual: <c37e1e1436cfd62f89592c48211ffb6ad2f1dff0f69d2203072f1e6c3872a5919b42220000000000>

Como puedes ver ahora la firma del APK se considera inválida. No sé por qué la firma v3 falla primero, puede ser que las firmas no se verifiquen en orden v1, v2, v3... Desde mi punto de vista todas las firmas excepto la v1 deberían fallar en el archivo APK modificado.

0 votos

¡Gracias Robert (+1 por ahora ;)! Tal vez también quieras señalar que el hecho de que la verificación tenga éxito no significa que no tengas un troyano (o lo que sea), ya que se podría haber utilizado una clave de firma completamente diferente. AFAIR jarsigner -certs -verify -verbose puede utilizarse para mostrar los detalles del certificado utilizado. Pero entonces, si el APK fue descargado en actualización una aplicación ya instalada, Android no aceptaría la actualización si las firmas no coinciden - por lo que sólo sería relevante para las primeras instalaciones.

1 votos

@Izzy: Gracias Izzy, tienes razón. He excluido esto de mi respuesta porque ya está cubierto por la respuesta que "newguy" ha enlazado en la pregunta: Android.stackexchange.com/a/218161/104486 De ahí que suponga que ya está al tanto de ese tema, pero para otros usuarios podría seguir siendo relevante.

0 votos

Genial, ¡gracias! Especialmente usando apksigner en lugar de jarsigner Así que la v2+ también está cubierta. Me upvote de nuevo, pero ni siquiera un mod puede hacer eso :D

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X