Esta vez el mérito de obtener las claves para descifrar este formato se
lo ha llevado el autor de una aplicación de estadísticas: Chat Statitics for WhatsApp. y aunque no ha publicado los datos, si ha facilitado la tarea para que otros la obtengan de su propia herramienta.
Una vez comprada la aplicación y diseccionada, si observamos su
contenido, rápidamente se ven los métodos para cifrar y descifrar las
bases de datos de la copia de seguridad.
![]() |
dex2jar, jd-gui, etc. |
[root@digitalsec aramosf]# readelf -a libaes.so | grep FUNC 1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize 2: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit 3: 00000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail 4: 00000740 1225 FUNC GLOBAL DEFAULT 7 AES_decrypt 5: 00001470 574 FUNC GLOBAL DEFAULT 7 CRYPTO_cbc128_decrypt 7: 000016b0 1218 FUNC GLOBAL DEFAULT 7 private_AES_set_encrypt_k 8: 00001b80 605 FUNC GLOBAL DEFAULT 7 private_AES_set_decrypt_k 9: 00001de0 1249 FUNC GLOBAL DEFAULT 7 AES_encrypt 10: 000022d0 46 FUNC GLOBAL DEFAULT 7 MD5_Init 11: 00002300 258 FUNC GLOBAL DEFAULT 7 MD5_Update 12: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy 13: 00002410 429 FUNC GLOBAL DEFAULT 7 MD5_Final 14: 00000000 0 FUNC GLOBAL DEFAULT UND memset 15: 000025c0 2570 FUNC GLOBAL DEFAULT 7 Java_de_tiflo_whatsapp_st 16: 00000000 0 FUNC GLOBAL DEFAULT UND strlen 17: 00000000 0 FUNC GLOBAL DEFAULT UND fopen 18: 00000000 0 FUNC GLOBAL DEFAULT UND malloc 19: 00000000 0 FUNC GLOBAL DEFAULT UND fseek 20: 00000000 0 FUNC GLOBAL DEFAULT UND ftell 21: 00000000 0 FUNC GLOBAL DEFAULT UND fwrite 22: 00000000 0 FUNC GLOBAL DEFAULT UND fread 23: 00000000 0 FUNC GLOBAL DEFAULT UND free 24: 00000000 0 FUNC GLOBAL DEFAULT UND fclose
Analizando más lentamente estas funciones se obtienen las claves
necesarias. que le ha puesto luz a parte del código donde yo me perdía y en la que hace falta jugar con el md5.
Tras un rato hemos descubierto que la función "CRYPTO_cbc128_decrypt"
parecía una trampa, ya que el algoritmo usado realmente es: aes-cbc-192.
Al final de la mañana hemos terminado el proceso con un script para
descifrarlas automáticamente.
No hemos puesto la bandera, ya que el autor de Chat Statitics ya conocía
este método, pero por lo menos, si lo hemos liberado para que lo use
todo el mundo con sus herramientas y como no, ya está implementado en la
recuperación de mensajes eliminados de http://www.recovermessages.com.
El script en cuestión ya está en mi github
y requiere que se conozca el nombre de la cuenta asociada al móvil, que
se puede sacar de Ajustes->Cuentas y sincronización->Google
Para usarlo es tan sencillo como invocarlo así:
- python pwncrypt5.py grbnz0@gmail.com msgstore.db.crypt5 > msgstore.sdb
Y finalizo con el codiciado código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/python """ 48bits presents: 8===============================================D~~~ WhatsApp msgstore crypt5 decryptor by grbnz0 and nullsub 8===============================================D~~~ """ import sys import hashlib import StringIO from M2Crypto import EVP key = bytearray([141, 75, 21, 92, 201, 255, 129, 229, 203, 246, 250, 120, 25, 54, 106, 62, 198, 33, 166, 86, 65, 108, 215, 147]) iv = bytearray([0x1E,0x39,0xF3,0x69,0xE9,0xD,0xB3,0x3A,0xA7,0x3B,0x44, 0x2B,0xBB,0xB6,0xB0,0xB9]) def decrypt(db,acc): fh = file(db,'rb') edb = fh.read() fh.close() m = hashlib.md5() m.update(acc) md5 = bytearray(m.digest()) for i in xrange(24): key[i] ^= md5[i&0xF] cipher = EVP.Cipher('aes_192_cbc', key=key, iv=iv, op=0) sys.stdout.write(cipher.update(edb)) sys.stdout.write(cipher.final()) if __name__ == '__main__': if len(sys.argv) != 3: print 'usage %s <db> <accountname> > decrypted.db' % sys.argv[0] else: decrypt(sys.argv[1],sys.argv[2]) fuente:securitybydefault |
0 comentarios:
Publicar un comentario