Después de analizar en nuestro anterior post la forma en que se almacenan los mensajes de conversaciones dentro de las bases de datos de Telegram, hemos querido comprobar si la eliminación de mensajes se realiza de forma correcta.
Recordemos que buscando los mensajes autoeliminados en los campos de las diferentes tablas de la base de datos, su rastro había sido sustituido por "None", por lo que sería necesario comprobar si dichos mensajes siguen teniendo persistencia, sin llegar a estar indexados, dentro del archivo de base de datos "tgdata.db".
Para ello, activamos una conversación con autodestrucción, y esperamos a que el texto se haya destruido.
Procedemos a lanzar el comando "strings" que nos extraerá todas las cadenas de texto que estén contenidas dentro del archivo "tgdata.db" y comprobamos que dicho mensaje se encuentre dentro del texto extraído (utilizamos "incide" y "auto destru" como palabras clave a buscar).
Como se puede observar, los mensajes aparecen en texto claro dentro del archivo, aunque en la base de datos, no se encuentran, si no que se muestra los campos como vacíos:
De esta forma, se podría recuperar los mensajes eliminados si se realiza una búsqueda en el espacio sin asignar "unallocated" antes de que sean sobrescritos al seguir creciendo la base de datos.
Nuestro amigo Luis Delgado nos ha confirmado que en sistemas Android se comporta de forma similar. Al hacer el backup con adb, aún sin estar "rooteado", se crean unos archivos de base de datos dónde se almacena los mensajes. Los mensajes marcados para autodestruirse, se eliminan de la base de datos, pero no se eliminan del archivo que los contiene. También dispone de un script en Python, que le permite automatizar la extracción de estas cadenas de texto.
Nuestro amigo Luis Delgado nos ha confirmado que en sistemas Android se comporta de forma similar. Al hacer el backup con adb, aún sin estar "rooteado", se crean unos archivos de base de datos dónde se almacena los mensajes. Los mensajes marcados para autodestruirse, se eliminan de la base de datos, pero no se eliminan del archivo que los contiene. También dispone de un script en Python, que le permite automatizar la extracción de estas cadenas de texto.
Decidimos comprobar si en otras versiones de Telegram, surgen los mismos problemas, por lo que probamos con una versión NO OFICIAL para sistemas operativos OS X "Messenger for Telegram". Hay que recordar que las únicas versiones oficiales de Telegram son las de iPhone y Android, el resto se basan en el código libre publicado.
En este caso, se crean dos bases de datos "telegram_store11.db" y "yap_store.db". En la primera se almacenan los mensajes y en la segunda, tan solo identificadores de las conversaciones cifradas.
Al igual que en el caso anterior, al buscar cadenas de texto dentro de la base de datos, es posible extraer los mensajes.
Al realizar estas pruebas, hemos visto que el comportamiento del cliente para el ordenador, no responde ante la autodestrucción de mensajes.
Al acceder a la base de datos para buscar los mensajes, observamos que éstos se hayan codificados en hexadecimal:
bb608d9f 01000080 f1f4a000 02000000 2260c93b 379779bc 379779bc 9c490f53 01000000 16637265 61746564 20656e63 72797074 65642063 68617400
ba6aeb22 02000080 a75d2001 02000000 2260c93b b5757299 b5757299 c5701053 14746573 74746573 74746573 74746573 74746573 74000000 2063ed3d
ba6aeb22 03000080 f1f4a000 02000000 2260c93b 379779bc b5757299 25711053 06416868 68686800 2063ed3d
ba6aeb22 04000080 f1f4a000 02000000 2260c93b 379779bc b5757299 9d751053 04507574 61000000 2063ed3d
ba6aeb22 05000080 a75d2001 02000000 2260c93b b5757299 b5757299 c6751053 18496e63 69646549 6e636964 65496e63 69646549 6e636964 65000000 2063ed3d
ba6aeb22 06000080 f1f4a000 02000000 2260c93b 379779bc b5757299 da751053 06526570 75746100 2063ed3d
ba6aeb22 07000080 f1f4a000 02000000 2260c93b 379779bc b5757299 05761053 04507574 61000000 2063ed3d
bb608d9f 08000080 684bdc00 02000000 e9ea184d 379779bc 379779bc c0761053 01000000 16637265 61746564 20656e63 72797074 65642063 68617400
ba6aeb22 09000080 a75d2001 02000000 e9ea184d b5757299 b5757299 d5761053 18507275 65626170 72756562 61707275 65626170 72756562 61000000 2063ed3d
ba6aeb22 0a000080 684bdc00 02000000 e9ea184d 379779bc b5757299 64771053 10546573 74657374 65737465 73746573 74000000 2063ed3d
ba6aeb22 0b000080 684bdc00 02000000 e9ea184d 379779bc b5757299 79771053 16546573 74657374 65737465 73746573 74657374 65737400 2063ed3d
ba6aeb22 01000000 684bdc00 6dbcb19d a75d2001 379779bc b5757299 7b220e53 1c486f6c 61212042 69656e76 656e6964 6f206120 74656c65 6772616d 21000000 2063ed3d
ba6aeb22 02000000 a75d2001 6dbcb19d 684bdc00 b5757299 b5757299 3c240e53 1e486f6c 61204162 656c2c20 636f6d6f 20766120 706f7220 696e6369 64653f00 2063ed3d
ba6aeb22 03000000 be43a300 6dbcb19d a75d2001 379779bc b5757299 ba240e53 054f6f6f 6f680000 2063ed3d
ba6aeb22 04000000 a75d2001 6dbcb19d be43a300 b5757299 b5757299 d9240e53 0a717565 20706173 c3b33f00 2063ed3d
ba6aeb22 05000000 a75d2001 6dbcb19d be43a300 b5757299 b5757299 e6240e53 31657374 6f792068 61636965 6e646f20 70727565 62617320 636f6e20 656c2063 6c69656e 74652070 61726120 4d616320 3a500000 2063ed3d
ba6aeb22 06000000 be43a300 6dbcb19d 00000000 379779bc b5757299 f4240e53 0647656e 69616c00 2063ed3d
ba6aeb22 07000000 11439100 6dbcb19d a75d2001 379779bc b5757299 0b280e53 1757656c 636f6d65 206d722e 74656163 68657220 f09f9881 2063ed3d
ba6aeb22 08000000 76f79a00 6dbcb19d a75d2001 379779bc b5757299 c64a0e53 04f09f91 8b000000 2063ed3d
ba6aeb22 09000000 f1f4a000 6dbcb19d a75d2001 379779bc b5757299 dc3c0f53 04486f6c 61000000 2063ed3d
Al analizar los datos obtenidos podemos ver que hay columnas que son muy similares o iguales. Por ejemplo, la primera columna tiene 2 valores:
La tercera columna parece indicar el usuario con el que se intercambia los mensajes, mientras que a partir de la octava columna se trata del mensaje codificado, hasta la última columna, que indica el final de éste.
Los dos primeros bits de la octava columna indican el tamaño del mensaje, y a continuación se puede descodificar cómodamente.
- bb608d9f: Corresponde a mensajes del sistema
- ba6aeb22: Corresponde a mensajes de usuarios
La tercera columna parece indicar el usuario con el que se intercambia los mensajes, mientras que a partir de la octava columna se trata del mensaje codificado, hasta la última columna, que indica el final de éste.
Los dos primeros bits de la octava columna indican el tamaño del mensaje, y a continuación se puede descodificar cómodamente.
Por ejemplo, para el caso del mensaje:
ba6aeb22 09000000 f1f4a000 6dbcb19d a75d2001 379779bc b5757299 dc3c0f53 04486f6c 61000000 2063ed3d
- 04: Tamaño de 04 bytes.
- 486f6c 61 = Hola
- 000000 = Se rellena el espacio restante
ba6aeb22 09000000 f1f4a000 6dbcb19d a75d2001 379779bc b5757299 dc3c0f53 04Hol a000000 2063ed3d
Como hemos visto en este artículo, el borrado de mensajes tampoco se realiza de forma segura, puesto que aunque eliminan de la base de datos, no se hace una compactación, para eliminar el espacio unallocated ni tampoco se realiza una sobrescritura de estos. En la aplicación para ordenador, tampoco mejora la situación, sí que se almacenan los mensajes codificados, pero siguen sin estar cifrados, e incluso, ni permitiendo la autodestrucción.
Por todo ello, nos asalta la duda. ¿Estos problemas se corresponden solo con los programas analizados? ¿O provienen de un fallo en la implementación de las medidas?
Abel Gómez es Pentester Senior en INCIDE
Puedes seguir sus posts en zprian.blogspot.com.es
Buen trabajo encontrando este problema. Como suele ser habitual en este tipo de aplicaciones, se trata de un problema en la implementación del cliente.
ResponderEliminarConcretamente, en la versión de Android (de la que mantengo un fork en https://github.com/slp/Telegram-FOSS) el mensaje se borra de la base de datos pero, por defecto, SQLite no elimina totalmente el contenido de la entrada, sino que la marca como reutilizable, ahorrando así CPU y acceso a disco. Con un minúsculo cambio, podemos habilitar el pragma "secure_delete", para que SQLite reescriba con ceros las entrada eliminadas.
He creado una branch en mi repo (https://github.com/slp/Telegram-FOSS/tree/sql-secure_delete) con dicho cambio, y esta tarde le haré un pull request a la versión oficial.