SQLite: Hidden Data en Plain Sight

/ * <[CDATA [* / var asciidoc = {/ / Namespace!. / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / Indice generador / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / * Autor: Mihai Bazon , septiembre de 2002 * http://students.infoiasi.ro/ ~ mishoo ** Tabla de generador de contenido * Versión: 0.4 ** Siéntase libre de utilizar esta secuencia de comandos en los términos de la GNU General Public License *, siempre y cuando lo hace no suprimir o alterar este aviso. * / / * Modificado por Troy D. Hanson, septiembre de 2006. Licencia: GPL * / / * modificado por Stuart Rackham, 2006, 2009. Licencia: GPL * / / / toclevels = 1 .. 4. toc: function (toclevels) {function getText (el) {var text = ""; for (var i = el.firstChild; i = null; i = i.nextSibling!) {if (== i.nodeType 3 / * Node.TEXT_NODE * /) / / IE no habla constantes. texto + = I.Data; else if (i.firstChild = null!) Texto + = getText (i);} texto return;} function TocEntry (el, texto, toclevel) {this.element = el; this.Text = texto; this.toclevel = toclevel;} tocEntries función (EL, toclevels) {var result = new Array; var re = new RegExp ('[HH] ([1 -' + (toclevels 1) + '])') / / Función que escanea el árbol DOM para elementos de encabezado (la API DOM2 / / NodeIterator sería una mejor técnica, pero no con el apoyo de todos / / los navegadores). iterate var = function (el) {for (var i = el.firstChild;! i = null; i = i.nextSibling) {if (== i.nodeType 1 / * Node.ELEMENT_NODE * /) {var = mo re . exec (i.tagName); if (mo && (i.getAttribute ("clase") | | i.getAttribute ("className")) = "float"!) {resultado [result.length] = new TocEntry (i , getText (i), mo [1] -1);} iteración (i);}}} iterate (el); return resultado;} var toc = document.getElementById ("toc"); if (toc) {! vuelta;} / / Eliminar entradas de la TDC existentes en caso de que estamos volviendo a cargar el TOC. var tocEntriesToRemove = []; var i; for (i = 0; i «+» «+ n «.» + + nota + «

«; var id = palmos [i] getAttribute («id»);. if (id = nulos!) refs [«#» + id] = n;}} si (n == 0) noteholder.parentNode.removeChild (Bonista); else {/ / Proceso footnoterefs. for (i = 0; i

src

El título de este post no pretenden dar a entender que hay algunos nuevos datos inteligentes escondidos técnicas para sqlite, pero a alertar al lector de que los datos de la vista es a menudo van sin analizar o insuficientemente analizada.

Mi experiencia en el análisis forense de datos me ha enseñado dos cosas acerca de las bases de datos SQLite: ambos están en todas partes y poco comprendido por los examinadores. Me parece que la mayoría de los examinadores basan en «espectadores», como SQLite Database Browser o herramientas automatizadas que analizan el SQLite para ellos. Ambos enfoques pueden ser muy deficiente, sin embargo.

La práctica-no utilizan los espectadores-es defectuosa en su cara primero. SQLite Database Browser y otras aplicaciones similares son una manera rápida de visualizar el contenido de una base de datos. Pero la mayoría de los examinadores están utilizando a los espectadores a abrir las tablas en una vista «plana». Esto es similar a mirar los datos de la tabla en una hoja de cálculo: se ve el contenido, pero no en relación a los datos de otras tablas de la base de datos (o de otras bases de datos para el caso) como la base de datos fue diseñado para ser utilizado. Además, los datos a menudo no es significativa en la forma en que se almacena, por ejemplo, las marcas de tiempo son a menudo en algún tipo de tiempo de la época y no un formato legible para las personas.

La segunda práctica de confiar en las herramientas automatizadas significa que usted está contando con un programador (que no puede ser un examinador forense) que le diga lo que es importante en la base de datos y usted está confiando en las habilidades SQLite del codificador, que puede ser careciendo. (Lo que sigue no es una diatriba en contra de un producto, sino simplemente un ejemplo de mi punto) Por ejemplo Cellebrite Physical Analyzer analiza el Sms.db iPhone (sms / iMessage) en un informe ordenado, bien formado. Pero no incluye el rowID en la salida, que es un número entero de incremento automático aplicado a cada mensaje enviado o recibido. Desde el rowID, se puede saber si se han eliminado los mensajes siguientes, pero no se sabe que desde el informe automático de Cellebrite. ¿Y qué pasa cuando su herramienta automatizada no analiza una base de datos que ha descubierto?

Exigir respuestas (Aprender a consulta)

La clave para entender SQLite es aprender el lenguaje de consulta de estructura (SQL). Uno de los mejores recursos en línea que he encontrado para esto es w3schools.com. Las lecciones son breves, y en menos de una docena de sesiones de 5-10 minutos, usted tendrá los fundamentos de SQL bajo su cinturón. Y con los conceptos básicos, puede lograr mucho.

El lenguaje de consulta está diseñado para ser legible por humanos, que, dicho sea de paso, hace que sea más fácil de recordar . Se compone de frases compuestas de sujetos y predicados. Por ejemplo, para ver todo el contenido de una tabla:

SQLite programa de línea de comandos (modo de línea de comandos)
 $  sqlite3 some.db 'select * from alguna_tabla;' 
1 | some_data
2 | some_more_data

Utilización de la sentencia SQL anterior, nuestro tema es "select *", que se traduce como "seleccionar todos los campos" (o columnas, si se quiere), y el predicado, "de alguna_tabla" es bastante explica por sí mismo. La tabla "alguna_tabla" se encuentra en la base de datos SQLite "some.db". Para ser breve, en una consulta SQL, le decimos al motor de base de lo que queremos (sujeto), seguido de los calificadores (predicados).

Encontrar SQLite bases de datos para el análisis

Entonces, ¿cómo podemos superar las deficiencias de la base de datos SQLite común técnicas de análisis? Vamos a tomar un examen reciente que realicé como ejemplo. Yo estaba buscando para las comunicaciones grabadas en una copia de seguridad v.6.1.3 iPhone iOS. Yo había restaurado la copia de seguridad a su estructura de archivo original (DOMINIO / ruta) para facilitar el análisis. Después de examinar el Sms.db, descubrí un gran bloque de mensajes eliminados (por análisis ROWID) durante el tiempo que fue objeto de la investigación. Los mensajes no eran recuperables (más en la recuperación de SQLite registros eliminados otra vez).

decidí echar un vistazo a otras aplicaciones de comunicaciones que podrían haber sido pasados ​​por alto cuando el usuario se borre información. Por desgracia, yo no conozco todas las diferentes aplicaciones disponibles para los dispositivos móviles de Apple de comunicación y probablemente nunca lo hará. Puedo obtener una lista de las aplicaciones instaladas en el dispositivo de la Info.plist en el directorio de copia de seguridad, pero en realidad, que en realidad no me ayudará mucho porque, como he dicho, no me reconozco a muchos de ellos. Yo hago saben, sin embargo, que la mayoría de las aplicaciones de comunicaciones almacenan sus datos en bases de datos SQLite. Así que busco en las personas:

BASH
 $  find archivo-f ejecutivo unback tipo / {} ; | SQLite grep 
unback / HomeDomain / Library / Voicemail / voicemail.db: base de datos SQLite 3.x
unback / HomeDomain / Library / SMS / sms. db: Base de datos SQLite 3.x
unback / HomeDomain / Library / Safari / Bookmarks.db: base de datos SQLite 3.x, el usuario versión

31 unback / AppDomain-com.cardify.tinder / Documentos / Tinder.sqlite: base de datos SQLite 3.x
...

 Nota

he restaurado la copia de seguridad de iTunes a un directorio llamado unback en consonancia con el método utilizado por la biblioteca de software libimobiledevice abierta, que ofrece un dispositivo de copia de seguridad / utilidad unback, así como otros útiles para el análisis iDevice.

Se puede ver que yo uso el encontrar para buscar archivos (tipo F) en el directorio "unback" y ejecute el archivo class="monospaced"> para determinar el tipo de archivo. Me toqué los resultados a través del comando grep , filtrando para "SQLite". Con el comando, aparece una lista de archivos de SQLite, es cierto, pero yo todavía no sé lo que hay todos son. Algunos son familiares y / o evidentes, pero otros no. Tome el último elemento de la lista abreviada arriba: Yesca por Cardify. Yo nunca había oído hablar de yesca (así como muchas otras aplicaciones que aparecieron en los resultados).

Conseguir un Peek Inside

Sería más informativo para listar las bases de datos, y luego echar un vistazo a los cuadros que figuran en cada uno. Mientras que los nombres de tabla no necesariamente le indican el contenido, que pueden ser de carácter informativo, mientras que en el modo de "triage" de datos. Así que, ¿cómo podemos modificar nuestro comando find para mostrarnos las bases de datos, así como sus mesas?

BASH (incorporando SQLite línea de comandos Programa)
 $  find unback /-type f | i mientras lee; no presentar $  i | grep-q SQLite;  
[$ ? = 0] && (echo $ i; sqlite3 $ i mesas;. Eco); hecho
unback / HomeDomain / Library / Voicemail / voicemail.db
_SqliteDatabaseProperties correo de voz

unback / HomeDomain / Library / Safari / Bookmarks.db
bookmark_title_words folder_ancestors sync_properties />

unback / HomeDomain / Library / SMS / Sms.db
_SqliteDatabaseProperties chat_message_join

manija del accesorio mensaje de chat />

unback / AppDomain-com.cardify.tinder / Documentos / Tinder.sqlite
ZLIKE zphoto Zuser Z_METADATA
ZMESSAGE ZPROCESSEDPHOTO Z_5SHAREDFRIENDS Z_PRIMARYKEY
...

Ok, eso es mucho más útil . Pero, ¿cómo funciona el comando? Al igual que el comando inicial, encontrar se utiliza para localizar los archivos (se excluyen los directorios). Los resultados del comando file se canalizan a un class="monospaced"> loop, que asigna a cada nombre de archivo al variable i . Al igual que en el primer comando, el archivo class="monospaced"> comando muestra el tipo de archivo que se filtra para "SQLite" por grep . La opción "-q" en grep se utiliza para mantener grep silencio;. Es el estado de salida que es de interés

Quiero que el estado de salida, o alternativamente: el estado retorno o código de salida , para realizar una prueba. Todos los comandos, scripts y funciones devuelven un estado de salida, y un código de salida de "0" significa el éxito. El estado de salida es capturado en el variable de , y recordó, al igual que todas las variables bash, anteponiendo con un signo de dólar:? $ . En el comando, pongo a prueba el estado de salida del último comando que fue grep . Si la expresión "SQLite" regular se concuerda en el archivo class="monospaced"> salida del comando, los grep salidas con "0". "[? $ = 0]" La prueba es la notación abreviada de "si el código de salida del último comando es 0", y luego hacer lo que sigue: (echo $ i; sqlite3 $ i mesas; eco.) , es decir, imprimir el nombre de archivo, imprimir las tablas de la base de datos, y luego imprimir una línea en blanco (para facilitar la lectura). I discutió los bucles while en un post anterior si tienen más interés, o usted podría mirar aquí.

Tener sentido de los datos

Desde la salida hasta el momento, veo que Yesca tiene una tabla de mensajes, así como el usuario y compartido tablas amigos. Parece que se trata de una aplicación de red social, y los datos pueden ser relevantes para la investigación. Así que, ¿cómo consigo ver el contenido de las tablas? Yo pude ver una tabla a la vez:

programa de línea de comandos SQLite
 $  sqlite3-header Tinder.sqlite 'select * from límite zmessage 5;' 
Z_PK | Z_ENT | Z_OPT | ZINBOUND | Zuser | ZCREATIONDATE | ZBODY
1 | 2 | 1 | 1 | 832 | 379798036.741 |! Hola
2 | 2 | 1 | 1 | 1156 | 379,797,384.794 | hey
3 | 2 | 1 | 1 | 832 | 379.798.729,794 | ¿Qué haces
4 |? 2 | 1 | 1 | 1318 | 379.804.817,728 | ¿Está en línea a menudo
5 |? 2 | 1 | 0 | 1318 | 379.806.963,685 |?! ¿No le gustaría saber
...

En el comando anterior, he utilizado el SQLite opción "-header" para mostrar los títulos de las columnas, y me limité la salida de cinco registros para tener una idea de los datos. Dejar caer el límite de sintaxis se traduciría en toda la tabla y todos los campos de registro que se imprime en la salida estándar (la pantalla).

¿Hay una manera que podríamos ver rápidamente algunos registros de cada mesa para ver lo que es de interés, en todo caso? ¡Por supuesto!

Programa de línea de comandos de SQLite
 $  for i en $  (SQLite3 Tinder.sqlite tablas.); ver Tabla echo: $  i;  
sqlite3 Tinder.sqlite-header "select * from $ i limito 5;" eco; hecho
...
Tabla: Zuser
Z_PK | Z_ENT | Z_OPT | ZCOMMONFRIENDCOUNT | ZCOMMONLIKECOUNT | ZGENDER | ZHASIMAGE |
ZHASUNVIEWEDMESSAGES | ZISACTIVE | ZISMATCH | ZISRECOMMENDED | />
ACTIVITYDATE | ZMATCHEDDATE | ZPINGTIME | ZBIO | ZFACEBOOKID | ZMATCHID | zname | ZUS
ERID | zImage
42 | 5 | 126 | 8 | 0 | 0 | 0 | | 0 | 1 | 1 | | 0 | | | 76.4215774536133 | 379,794,350.747 | 379794350,7
47 | 379,794,187.955 | I like pie |. 604832678 | 50f2fc2fbe8d00b3d4f58c36 | Gunter |
50d39d6024571b7803001639 |
90 | 5 | 1 | 0 | 0 | | 0 | | 0 | 0 | 0 | | 0 | | | 0.0 | | | | | # # # # # # # # # | | Gretta | |
91 | 5 | 1 | 0 | 0 | | 0 | | 0 | 0 | 0 | | 0 | | | 0.0 | | | | | # # # # # # # # # | | Hilde | |
92 | 5 | 1 | 0 | 0 | | 0 | | 0 | 0 | 0 | | 0 | | | 0.0 | | | | | # # # # # # # # # | | Agnes | |
93 | 5 | 1 | 0 | 0 | | 0 | | 0 | 0 | 0 | | 0 | | | 0.0 | | | | | # # # # # # # # # | | Johanna | | Tabla />
Z_PK | Z_ENT | Z_OPT | ZINBOUND | Zuser | ZCREATIONDATE | ZBODY
1 | 2 | 1 | 1 | 832 | 379.798.036,741 |! Hola
2 | 2 | 1 | 1 | 1156 | 379,797,384.794 | hey
3 | 2 | 1 | 1 | 832 | 379.798.729,794 | ¿Qué haces
4 |? 2 | 1 | 1 | 1318 | 379.804.817,728 | ¿Está en línea a menudo
5 |? 2 | 1 | 0 | 1318 | 379,806,963.685 | ¿No le gustaría saber />

Z_5SHAREDFRIENDS |
REFLEXIVO 42 | 90
42 | 91
42 | 92
42 | 93
42 | 94

En pocas palabras, la diferencia principal en el último comando de los ejecutados anteriormente es el uso de un class="monospaced"> bucle. El bucle for toma el ouput del class="monospaced"> de comandos,

La salida anterior demuestra lo relacional naturaleza de las bases de datos SQLite. Mirando la tabla ZMESSAGE, vemos el contenido del mensaje, pero el usuario es un número entero (campo Zuser). El entero parece correlacionar con la tabla Zuser (campo Z_PK). La sola observación de la tabla ZMESSAGE, vemos la conversación, pero no sabemos con quién se le ocurrió.

SQLite nos permite consultar las tablas en relación con hacer que sea más comprensible.

Programa de línea de comandos de SQLite
 $  sqlite3 Tinder.sqlite 'select m.z_pk, zinbound, Zuser, zname,  
zcreationdate, zbody de zmessage como m, Zuser como u, donde
m.zuser = u.z_pk límite de 5;'
Z_PK | ZINBOUND | Zuser | zname | ZCREATIONDATE | ZBODY
1 | 1 | 832 | Tobias | 379.798.036,741 |! Hola
2 | 1 | 1156 | Siegfried | 379.797.384,794 | hey
3 | 1 | 832 | Tobias | 379.798.729,794 |? Qué haces
4 | 1 | 1318 | Theoduff | 379,804,817.728 | ¿Está en línea a menudo
5 |? 0 | 1318 | Theoduff | 379.806.963,685 | ¿No te gustaría saber?

En este comando, que se especifica los campos que quería regresar a diferencia de todos los campos. Esto es necesario cuando se está relacionando tablas entre sí. Usted puede haber notado que en el predicado pregunté ambas tablas ZMESSAGE y Zuser. El "como" instrucciones crean alias para las tablas (zmessage = m, Zuser = u) para mantener el comando más conciso. En la instrucción de selección, pedí el campo zname, que se encuentra en la tabla Zuser donde Zuser de la mesa ZMESSAGE igualada Z_PK de la mesa Zuser. En la instrucción de selección, tuve que especificar el campo Z_PK ( m.z_pk ) de la tabla ZMESSAGE porque ambas tablas contienen ese campo.

Dos campos más no tienen mucho sentido en nuestro resultado: ZINBOUND y ZCREATIONDATE. ZINBOUND es una bandera, que, con un poco de contexto, me llevan a entender que 0 = 1 = enviados y recibidos. ZCREATIONDATE desprende de su valor como Mac Tiempo absoluto y sistema de archivos de marcas de tiempo compatible con esta evaluación. El caso class="monospaced"> expresión puede utilizarse para interpretar las banderas. Es el equivalente a un si / entonces en lenguajes de scripting. El datetime función convierte la época unix a una fecha legible. Debido a que los valores de la base de datos Yesca son Mac Tiempo absoluto, las marcas de tiempo tienen que primero ser convertido en unix época añadiendo 978307200 segundos.

SQLite programa de línea de comandos
 $  sqlite3-header seleccione m.z_pk, zinbound caso Tinder.sqlite 'cuando 0  
luego "enviado" al 1 entonces "recibido" end else "desconocido" como zinbound,
Zuser, zname, fecha y hora (zcreationdate + 978307200, "unixepoch", />
donde m.zuser = Límite u.z_pk 5; '
Z_PK | ZINBOUND | Zuser | ZCREATIONDATE | ZBODY
1 | recibidas | 832 | Tobias | 13/01/2013 11: 27:16 | Hola
2 | recibidas | 1156 | Siegfried | 01/13/2013 11:16:24 | oye
3 | recibidas | 832 | Tobias | 01/13/2013 11!!: 38:49 | ¿Qué haces
4 |? recibidas | 1318 | Theoduff | 01/13/2013 13:20:17 | ¿Está en línea a menudo
5 |? enviado | 1318 | Theoduff | 2013-01 -13 13:56:03 |?! ¿No le gustaría saber

Ahora tenemos datos significativos al relacionar dos tablas, interpretación de banderas (expresión caso), y la conversión de las marcas de tiempo (función de fecha y hora). Usted puede encontrar más información acerca de la expresión caso aquí, y la función de fecha y hora aquí.

Summing Up

Cubrí mucho terreno en este post, el uso encontrar , archivo class="monospaced"> , grep , y class="monospaced"> y de bucles para uso básico e intermedio del programa de línea de comandos de SQLite. Dejé mucha explicación fuera de la discusión, y yo apenas arañado la superficie del análisis SQLite. Mi objetivo era: - poner de relieve el hecho de que las herramientas automatizadas y visor los usuarios están propensos dejando una gran cantidad de datos sobre la mesa (perdón por el juego de palabras) - muestran cómo las herramientas de línea de comandos se puede utilizar para localizar rápidamente y bases de datos SQLite evalute - demuestran que el aprendizaje de las consultas de SQLite que recorrer un largo camino para llenar el vacío dejado abierta por herramientas automatizadas -. le animamos a aprender más acerca de SQLite y mejorar sus habilidades de investigación

espero empezar ahondar en el tema de análisis SQLite más específicos en futuros posts.

feliz Consultar!


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *