Buenas a todos, ya hace un tiempo que no escribo algún que otro articulo y hoy aburrido hablando con unos amigos por whatsapp me quedo la duda de si whatsapp guardaba los logs de todo lo que hicíera y efectivamente whatsapp lo hacia.
Viendo la de cositas que se estaban guardando :
- Conversaciones de tlfn a tlfn
- Chats activos
- Fotos de los perfiles que mire
- Imágenes, audios, videos que me pasarón o que pase
(Por ejemplo).
Pues me apetecio hacerle un forense y al tiempo que lo hago os haré una demo del forense a un whatsapp y vereís todos los datos que podemos sacar de utilidad.
Recrearemos un entorno en el que dispongo de acceso físico a un terminal.
El whatsapp es una buena forma de extraer información sobre el día día de la persona, se podría aplicar algo como “Dime con quien andas y te diré quien eres” pero convertido al método geek.
Empezamos con la DEMO :
Bueno, los ficheros de whatsapp se guardan por defecto en /storage/sdcard0/WhatsApp/ , y yo me enviaré los ficheros con Airdroid, una estupenda app para compartir archivos PC - Smartphone vía wifi.
Para pasar a estar conectados en “Modo de conexión remota” como ahí podeís ver solo hay que acceder a web.android.com y te logueas con tu cuenta.
Y tan solo te queda acceder al directorio y descargar los arhivos de los que extraeremos los metadatos.
Una vez descargados los ficheros voy a proceder a comentaros que podemos encontrar en cada uno de los directorios y cómo podríamos extraerles el jugo.
Tenemos “Databases”, “Media” y “Profile Pictures”, he hecho un script para que extraiga los metadatos de los db.crypt, tambien extrae los ficheros de la carpeta media(imágenes, audios, videos) y tambien extrae las imágenes encontradas en Profile Pictures.
Databases : Aqui podremos encontrarnos una serie de ficheros con extensión “db.crypt”, Whatsapp cifra los archivos SQLite con AES pero siempre usa la misma key “346a23652a46392b4d73257c67317e352e3372482177652c” y de este modo podré decodificarlos.
Media : Aqui nos encontramos con una seríe de archivos (imágenes, audios, videos y wallpapers).
Profile Pictures : Aqui nos encontraremos con todas las imágenes de perfil(de usuario) que hemos mirado desde nuestro whatsapp.
NOTA IMPORTANTE : Para extraer la información de todos estos archivos que hemos obtenido he codeado un script que automatiza todo el proceso (a excepción del proceso de obtención de los ficheros , puesto que se supone que tenemos acceso físico al terminal.)_
Ahora os mostraré un esquema en forma de arbol para comprender un poco como funciona el script que he preparado:
· WhatsApp Metadata Extractor :
_ - main_manage.py (main de consola en forma de cliente)_
_ - DB_Extractor.py (extrae los metadatos de la BD)_
_ - metaimg_extractor.py (extrae los metadatos de los .jpg encontrados)_
He dividido el proyecto en 3 scripts, main_manage es el encargado de interactuar con el cliente (el que debemos ejecutar), DB_Extractor es el encargado de realizar las consultas con la BD para extraer toda la información(la que nos interesa) y metaimg_extractor es el encargado de buscar en “Media” y en “Profile Pictures” en busca de metadatos en los archivos .jpg (La mayoria vienen con ellos eliminados por defecto pero no me digas por qué algunas imágenes no se filtran y son subidas sin filtrarse).
Sin más os dejo los codes :
main_manage.py :
\# -\*- coding: utf-8 \*-\*
import DB\_Extractor, metaimg\_extractor
class WhatsApp\_Extractor():
def \_\_init\_\_(self):
self.\_\_opt()
def \_\_opt(self):
#Uncomment the OPTION that you want to use
#self.\_\_opt1() #-> DB METADATA EXTRACTOR
#self.\_\_opt2() #-> IMG METADATA EXTRACTOR
#self.\_\_opt3() #-> BOTH, OPT1 AND OPT2
def \_\_opt1(self):
print "DB METADATA"
print "------------"
DB\_Extractor.DB\_Extractor()
print "------------"
def \_\_opt2(self):
print "IMG META"
print "------------"
metaimg\_extractor.IMG\_Meta()
print "------------"
def \_\_opt3(self):
print "DB METADATA"
print "------------"
DB\_Extractor.DB\_Extractor()
print "------------"
print "\\nIMG META"
print "------------"
metaimg\_extractor.IMG\_Meta()
print "------------"
WhatsApp\_Extractor()
DB_Extractor.py :
\# -\*- coding: utf-8 \*-\*
#Script to extract the metadata from the WhatsApp crypted DB
import sqlite3
from Crypto.Cipher import AES
class DB\_Extractor():
def \_\_init\_\_(self):
self.\_manage\_do()
def \_manage\_do(self):
try:
self.\_\_DB\_Breaker('msgstore.db.crypt')
self.\_\_DB\_conn()
self.\_\_SQL\_Consulter()
#Log exporter
except:
print "Error starting the script"
def \_\_DB\_Breaker(self, DBPath):
self.DBPath = DBPath
#breaking the hash
f = open(self.DBPath, 'rb')
key = "346a23652a46392b4d73257c67317e352e3372482177652c"
#triying to break the hash
try:
key = key.decode('hex')
cipher = AES.new(key, 1)
decoded = cipher.decrypt(f.read())
#Saving into a new db file
try:
decoded\_DB = open('metadb.db', 'wb')
decoded\_DB.write(decoded)
decoded\_DB.close()
print "metadb.db has been created in the same directory"
except:
print "An error has ocurred creating the decoded DB"
except:
print "Error decoding the hash"
def \_\_DB\_conn(self):
#triying to connect with the sqlite database
try:
self.conn = sqlite3.connect('metadb.db')
self.consult = self.conn.cursor()
except:
print "An error has ocurred connecting with the SQLite DB"
def \_\_SQL\_Consulter(self):
#Divided in :
# Messages
# Chat\_list
def \_\_Messages():
#SQLConsult
try:
self.consult.execute("SELECT key\_remote\_jid, key\_from\_me, \\
remote\_resource, status, datetime(timestamp), data, media\_url, media\_mime\_type, \\
media\_size, latitude, longitude FROM messages;")
except:
print "An error has ocurred doing the SQL Consult"
def \_\_Shower():
#Message details
#nota : parsear status, comprobar si yo envio o recivo
for data in self.consult:
try:
print "\\nMessages Details:"
print "----------------------"
if str(data\[2\]):
if str(data\[1\]) == '1':
print "From: me"
print "To: %s(group), integrant: %s"%(str(data\[0\]), str(data\[2\]))
else:
print "From: %s(group), integrant: %s"%(str(data\[0\]), str(data\[2\]))
print "To: me"
else:
if str(data\[1\]) == '1':
print "From: me"
print "To: " + str(data\[0\])
else:
print "From: " + str(data\[0\])
print "To: me"
print "Status: " + str(data\[3\])
print "Timestamp: " + str(data\[4\])
print "Message: " + str(data\[5\])
print "Media content: %s, type: %s, size: %s"%(str(data\[6\]), str(data\[7\]), str(data\[8\]))
print "Location(Lat: %s, Long: %s)"%(str(data\[9\]), str(data\[10\]))
print "----------------------"
except:
continue
print "ERROR showing message details"
\_\_Shower()
def \_\_Chat\_list():
#SQLConsult
try:
self.consult.execute("SELECT id, \\
key\_remote\_jid FROM chat\_list;")
except:
print "An error has ocurred doing the SQL Consult"
def \_\_Shower():
#Chat list details
for data in self.consult:
try:
print "\\nChat\_list"
print "ID: " + str(data\[0\])
print "Number: " + str(data\[1\])
print "----------------------"
except:
continue
print "ERROR showing chat list details"
\_\_Shower()
#Initializing
\_\_Messages()
\_\_Chat\_list()
metaimg_extractor.py :
\# -\*- coding: utf-8 \*-\*
import os, exif
class IMG\_Meta():
def \_\_init\_\_(self):
try:
self.\_\_Media\_extractor()
print "------------------------------------------------------\\n"
self.\_\_Profile\_extractor()
except:
print "An error has ocurred starting the script"
def \_\_Media\_extractor(self):
try:
images = os.listdir('Media/WhatsApp Images/')
except:
print "An error has ocurred listing the files into the directory"
def \_\_Shower():
for i in images:
print "-------------"
print i
obj = exif.extract\_EXIF('Media/WhatsApp Images/%s' % i)
print "-------------"
\_\_Shower()
def \_\_Profile\_extractor(self):
try:
images = os.listdir('Profile Pictures/')
except:
print "An error has ocurred listing the files into the directory"
def \_\_Shower():
for i in images:
print "-------------"
print i
obj = exif.extract\_EXIF('Profile Pictures/%s' % i)
print "-------------"
\_\_Shower()
Unas imágenes trabajando :
DB_Extractor :
IMG extractor :
El archivo “Exif” que importamos en el metaimg_extractor podemos encontrarlo en el proyecto de grampus en bitbucket
PD : El Forense podría llegar a hacerse en mayor profundidad, en este caso solo tratamos los datos que podrían ser más relevantes como conversaciones, envio de archivos y el análisis de los metadatos de las imágenes.
En fin, esto es todo, el script os automatizará todo el trabajo “duro”
Saludos !! , Sanko.