#MSeguridad de los automóviles
Muchas aplicaciones implementan una función de seguridad llamada Entrega de certificados, creando algunos problemas cuando se intenta interceptar el tráfico entre la aplicación y el servidor. Hoy, vamos a cubrir los fundamentos de Certificate PInning y dar algunos ejemplos de cómo evitarlo usando un móvil Android.
La vinculación de certificados es una medida de seguridad que protege su comunicación en línea estableciendo una conexión de confianza entre su dispositivo y una web o servicio específico. Verifica el certificado digital presentado por el servidor para asegurarse de que coincide con un conjunto predefinido de credenciales de confianza. De este modo, aunque los atacantes obtengan un certificado fraudulento, no podrán interceptar tus datos.
Antes de descompilar y modificar algo, puedes abrirlo con jadx:
Si quiero descompilar:
apktool d test.apk
En res/xml, bajo Recursos en JADX, no encontré ninguna directiva network_security_config, así que tengo dos caminos a seguir:
Descompila la aplicación, añádela a mano, compila y firma la aplicación y luego instálala en el dispositivo.
Instale el certificado burp, pero a nivel de sistema.
A) Primero descompilo y voy a crear un nuevo archivo llamado network_security_config en la ruta res/xml/:
<?xml version=”1.0″ encoding=”utf-8″?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src=”user”/>
<certificates src=”system”/>
</trust-anchors>
</base-config>
(Configuración de seguridad de la red)
Además, tengo que añadir la directiva en el archivo AndroidManifest.xml:
<application android_allowBackup=”false” android_networkSecurityConfig=”@xml/network_security_config” android_appComponentFactory=”androidx.core.app.CoreComponentFactory” android_icon=”@mipmap/ic_launcher” android_label=”@string/app_name” android_name=”com.lucyapp.MainApplication” android_requestLegacyExternalStorage=”true” android_theme=”@style/AppTheme”>
<activity android_configChanges=”keyboard|keyboardHidden|orientation|screenSize|uiMode” android_label=”@string/app_name” android_launchMode=”singleTask” android_name=”com.lucyapp.MainActivity” android_screenOrientation=”portrait” android_windowSoftInputMode=”adjustResize”>
Una vez listo, empiezo a compilar la aplicación:
apktool b prueba => donde TEST es la carpeta descompilada de la aplicación. La aplicación resultante estará en la carpeta test/dist/test.apk
Para firmarlo, voy a crear una clave:
keytool -genkey -v -keystore my-release-key.keystore -alias gabiTEST -keyalg RSA -keysize 2048 -validity 10000 => cambia gabiTEST por lo que quieras, igual que el nombre del almacén de claves, el mío en este caso es mi-llave-de-liberación.keystore. Este último se guardará en la carpeta donde se esté ejecutando todo.
Ahora a firmarlo:jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore test/dist/test.apk gabiTEST
Para ver que todo ha ido bien, puedes correr:
jarsigner -verify -verbose -certs test/dist/test.apk[...]tarro verificado.
Advertencia:
Este tarro contiene entradas cuya cadena de certificado no es válida. Motivo: Error en la creación de la ruta PKIX: sun.security.provider.certpath.SunCertPathBuilderException: no se ha podido encontrar una ruta de certificación válida para el destino solicitado.
Este tarro contiene entradas cuyo certificado firmante es autofirmado.
El algoritmo de compendio SHA1 se considera un riesgo para la seguridad. Este algoritmo se desactivará en una futura actualización.
El algoritmo de firma SHA1withRSA se considera un riesgo para la seguridad. Este algoritmo se desactivará en una futura actualización.
Este tarro contiene firmas que no incluyen una marca de tiempo. Sin una marca de tiempo, es posible que los usuarios no puedan validar este tarro después de que caduque alguno de los certificados del firmante (a partir del 2048-10-19).
El certificado del firmante caducará el 2048-10-19.
A veces la aplicación no está alineada, así que tienes que alinearla:
/Users/0x1gab/Library/Android/sdk/build-tools/29.0.2/zipalign -v 4 test/dist/test.apk test_aligned.apk
Ahora sólo queda instalar:
~/D/c/1 ❯❯❯ adb install test/dist/test.apk
Realizar la instalación por streaming
Éxito
B) Para instalar el certificado burp como SYSTEM, vamos a hacer lo siguiente:
Vaya a BURP y descargue el certificado de exportación en formato DER.
Conviértalo a formato PEM: openssl x509 -inform DER -in cert.der -out burp.pem
Obtén el valor hash del asunto, pregúntale a César cuál es y renombra el certificado con ese valor:
openssl x509 -inform PEM -subject_hash_old -in burp.pem |head -1 =>> 9a5ba575 mv burp.pem HASH.o =>> mv burp.pem 9a5ba575.o
Ahora, como esto es sistema, vamos a tener que montar el sistema de ficheros en RW para poder hacer el push a donde Android guarda los certificados del sistema, porque si no aparecerá este error:
~/D/c/1 ❯❯❯ adb push 9a5ba575.o /system/etc/security/cacerts
adb: error: failed to copy ‘9a5ba575.o’ to
‘/system/etc/security/cacerts/9a5ba575.o’: remote couldn't create file: Sistema de archivos de sólo lectura
9a5ba575.o: 0 archivos empujados. 0.2 MB/s (1375 bytes en 0.006s)
A veces, debido a las versiones de Android, aunque monte el FS como RW, no podré copiarlo. Por lo tanto, en lugar de montar todo el sistema de archivos, lo que se puede hacer es montar sólo la partición que quiero escribir:
adb shell su -c “‘mount -o rw,remount /system'” => OK ~/D/c/1 ❯❯❯ adb push 9a5ba575.o /system/etc/security/cacerts/9a5ba575.o => 1 archivo empujado. 0.4 MB/s (1375 bytes en 0.003s) OK
Finalmente, le doy permisos 644 y reinicio:
- chmod 644 /system/etc/security/cacerts/.0
- reiniciar
Si todo va bien, no deberíamos tener problemas de fijación de certificados 😀 .En caso de que haya algo que no hayamos visto (que fue lo que me pasó a mí), tenemos varias opciones:
- Toca a mano el código fuente del APK, borra las entradas de Certificate Pinning y compila de nuevo.
- Utiliza algún framework, como XPOSED.
- Usa a Frida.
En mi caso, XPosed no me funcionó. Igualmente, el APK se descarga en el móvil desde: https://repo.xposed.info/module/de.robv.android.xposed.installerPor otro lado, Frida. Para instalarlo:
- Se descarga el servidor Frida => https://frida.re/docs/android/
- adb push frida-server /data/local/tmp/
- adb shell “chmod 755 /data/local/tmp/frida-server”
- adb shell “/data/local/tmp/frida-server &”. => Servicio funcionando OK, no devuelve nada.
Frida tiene muchos scripts ya construidos para muchas cosas. En mi caso utilicé uno para SSL Unpinning. Para ello, primero inicio el servidor y luego desde mi máquina ejecuto Frida:
frida -codeshare sowdust/universal-android-ssl-pinning-bypass-2 -U com.lucyapp

