Regresé a partir de 7 días de entrenamiento a una pesadilla : los investigadores criminales impacientes arrancado un Macbook de Apple de «ver» lo que el dueño había estado haciendo en Internet en los días previos a un crimen. El portátil ha estado en pruebas durante más de un año, pero nunca examinados (no se hizo ninguna solicitud de examen), y el juicio se avecina. Un cambio en la súplica acusados menos de dos semanas antes del juicio requería un examen, pero no hay examinadores calificados estaban disponibles de inmediato. Así, alguien pensó que era una buena idea sólo para arrancar el Macbook y echar un vistazo alrededor
Safari, decidió que la Historia . plist era vieja herramienta y creó una nueva con los sitios web que los investigadores trataron de visitar – al parecer de marcadores. Por lo tanto, me enfrenté a tratar de determinar un historial de navegación en ausencia de la History.plist relevante.
Asumiendo el viejo History.plist no se ha sobrescrito, tallando 500gb para un plist no era una buena opción en la cantidad de tiempo que tenía que hacer el trabajo. Yo era consciente de los exámenes anteriores que Safari mantiene elementos de la página web en una base de datos SQLite llamado cache.db. Se encuentra en «/ Users /
El cache.db contiene cuatro tablas:. Cfurl_cache_schema_version , cfurl_cache_response, sqlite_sequence, cfurl_cache_blob_data. Los cuadros relevantes a esta discusión son cfurl_cache_response y cfurl_cache_blob_data, que me referiré como respuesta y Blob para facilitar la discusión. No voy a tratar de describir todos los elementos de estas tablas, sólo los que yo elegí para poner en práctica mi solución
la tabla de respuesta h2> La tabla de respuesta tiene el siguiente esquema:.
CREAR cfurl_cache_response MESA (
entry_id INTEGER PRIMARY KEY autoincrement UNIQUE,
Versión INTEGER, INTEGER hash_value, />
TEXTO request_key UNIQUE,
indicación_horaria NOT NULL DEFAULT CURRENT_TIMESTAMP)
CREAR cfurl_cache_response MESA (
entry_id INTEGER PRIMARY KEY autoincrement UNIQUE,
Versión INTEGER, INTEGER hash_value, />
TEXTO request_key UNIQUE,
indicación_horaria NOT NULL DEFAULT CURRENT_TIMESTAMP)
El request_key campo contiene la dirección URL del elemento de página web (html, imágenes, flash, javascript , css, etc.) Indicación_horaria El campo se encuentra en un lenguaje sencillo (aaaa-mm-dd hh: mm: ss) y no requiere la conversión de un tiempo época. El entry_id es un entero único que se relaciona directamente con los datos de la tabla con un Blob entry_id correspondiente .
La tabla BLOB
CREAR cfurl_cache_blob_data MESA (
entry_id INTEGER PRIMARY KEY,
; BLOB response_object, BLOB request_object, />
proto_props BLOB,
USER_INFO BLOB)
El
Making History
sqlite3-header cache.db» seleccione r.entry_ID, indicación_horaria, request_key de cfurl_cache_blob_data c, cfurl_cache_response r donde c.entry_id = r.entry_id y receiver_data como « % » «
La consulta anterior reduce una base de datos que contiene 6.700 elementos en 187 páginas. Amplié esto a cualquier elemento con una etiqueta HTML, en el caso de páginas manipuladas, mediante la colocación de un comodín que lleva antes de la etiqueta:
# sqlite3-header cache.db» seleccione r.entry_ID, indicación_horaria, request_key de cfurl_cache_blob_data c, cfurl_cache_response r donde c.entry_id = r.entry_id y receiver_data como ‘% % ‘»
Al añadir el comodín líder, mi historia aumentado a 261 registros. Puedo redirigir la salida a un archivo para su análisis, y puedo modificar la consulta para exportar realmente los datos en el campo receiver_data para ver el contenido real de las páginas de interés.
EDITAR :
Mejor aún, ya que los encabezados de archivos pueden muy en documentos HTML (piense «doctype» cuerdas), es la búsqueda de la etiqueta de pie de página HTML «/ html» (corchetes excluyen intencionalmente):
Courier New, Courier, monospace; font-size: x-small;»> sqlite3-header cache.db «seleccione r.entry_ID, indicación_horaria, request_key de cfurl_cache_blob_data c, cfurl_cache_response r donde c.entry_id = r.entry_id y receiver_data como ‘% / html%’ «
Por lo que permite una cadena de encabezado variables, mi historia HTML aumentó a 328 registros . Ya que he escrito una utilidad para exportar los archivos en el cache.db y he comprobado los archivos por tipo mime: hubo 349 archivos html detectados. Espero reconciliar esto en el futuro próximo.
Making Sense
No puedo tomar el tiempo para romper las consultas en este momento, pero me gustaría destacar una expresión que puede no ser familiar para los usuarios casuales sqlite:
sqlite3-header cache.db» seleccione r.entry_ID, indicación_horaria, request_key de cfurl_cache_blob_data c, cfurl_cache_response r , donde c.entry_id = r.entry_id y receiver_data como « % ‘»
En la parte resaltada anteriormente, enumero los dos tablas que son objeto de la consulta. El arrastre «c» y «r» detrás de los nombres completos de tabla son alias para los nombres completos. Los alias de ahorrar un montón de escribir, y se los ve de empleados en la cláusula select, que narra sqlite que entry_id deseo (ya que existe en ambas tablas) y en la cláusula where.
Si alguien tiene otra idea sobre cómo realizar esta tarea o es consciente de las deficiencias de este enfoque, por favor comente. Después de todo, yo estoy tratando de hacer limonada de los limones me han dado …