Mostrando entradas con la etiqueta forensics. Mostrar todas las entradas
Mostrando entradas con la etiqueta forensics. Mostrar todas las entradas

2021/01/05

Selección de los archivos rescatados de un disco de Apple

Resumen, una persona borró un disco con un montón de backups de la forma:

Backup-AAA-MM-DD

Antes le corrí photorec y recuperé más de dos millones de archivos, iba a borrar algunos y con suerte reducir a medio millón, que igual es mucho, me he apiadado de la persona y le voy a meter más cerebro y trabajo.

 

Debido al conflicto entre hacer un proceso generico y lo particular de la información de la persona, lo que voy a dejar acá registrado no sirve como procedimiento, sirve para que te inspire. Además, no sabés cuántas veces tuve que reeescribir todo esto debido a los cambios producidos por cada nuevo descubrimiento.

En el caso en particular de la Apple, hay una cantidad considerable de archivos de importancia forense pero irrelevantes para mi objetivo.

Cuando estás explorando, como no sabés muy bien a dónde vás, el orden no importa mucho, pero hay que tener en cuenta algunas optimizaciones:

Si vamos a buscar archivos duplicados, hay que calcular md5 de cada archivo, entonces es mejor descartar antes de calcular por que el cálculo de md5 para muchos archivos consume mucho tiempo. 

 

Acciones

 

Hay algunas acciones que hay que repetir tras ejecutar otra, por ejemplo la lista de archivos hay que rehacerla tras renombrar las carpetas con la fecha tentativa.

 

Obtener lista de archivos

 

find . -type f > 00_archivos.txt

 

Obtener e identificar extensiones


cat 00_archivos.txt | rev | \
  cut -d "." -f 1 | rev | sort | \
  uniq -c | sort -nr > extensions_full.txt 

Puede haber basura, en mi caso todos los archivos que no tienen extensión, se pude filtrar o más fácil editar extensions_full.txt

Armé tres blacklists de extensiones:

[system]

plist$
DS_Store$

[photorec]

[0-9]\+.jpg$

[local]

.*txt$
.java$
.h$
.c$
etc...


Podría hacer blacklists más precisas, pero no vale la pena, mil archivos más o menos cuando estás con medio millón no lo amerita, al menos al comienzo. 

 

Descartar extensiones

 

Para el análisis trabajamos sobre 00_archivos con las blacklists:


wc -l 00_archivos.txt
2327955

grep -v -f local_extension_blacklist.txt \
   -f photorec_extension_blacklist.txt \
   -f system_extension_blacklist.txt 00_archivos.txt  | wc -l

890914

 

Archivos y extensiones eliminables


plist

Sirven para guardar información de apliciones, son 400 mil, chau.

 

.DS_Store


Contiene metadata de las carpeta como iconitos y posiciones, 30 mil, chau

 

txt

 

La persona no usa archivo de texto plano y además hay un número desproporcionado, 700 mil. Miré unos veinte al azar y parecen fragmentos xml, chau.

Si la persona hubiera usado archivos txt, debería haber creado alguna regla, ya sea con grep o con yara [1][2] para selecionar.

 

t*.jpg 


Los archivos con nombre t* son thumbnails que photorec extrajo de otros archivos, lo cual está ok para el propósito original de la herramienta, otros 40 mil menos


Analizar la cantidad


Este fué el análisis que me hizo comprender que en realidad no habían carpetas originales, sólo agrupamientos de 500 archivos.


for DIR in *; do
  echo -n "$DIR : "
  ls -1 "$DIR" \
  | grep -v -f photorec_extension_blacklist.txt \
  |  wc -l
done

 

Detectar y eliminar repeticiones

 

Obtener los hashes de los archivos cuyas extensiones no están en las blacklists.

grep -v -f local_extension_blacklist.txt \
   -f photorec_extension_blacklist.txt \
   -f system_extension_blacklist.txt 00_archivos.txt \
  > 01_archivos.txt

cat 01_archivos.txt | while read FILE; do
   md5sum "$FILE";
done > 01_hashes.txt

900 mil hashes, cinco horas...

 

Lo que te queda es:

hash..hash  ./recup_dir.xxx/fxxxxxxx.ext

Esto lo ordena:

sort 01_hashes.txt > 01_hashes.sort.txt

Esto extrae los hashes, elimina y cuenta los repetidos y ordena las frecuencias obtenidas:

cut -b -33 01_hashes.sort.txt | uniq -c | sort -nr \
> 02_only.unique.hashes.txt

Si contamos la líneas, sabemos cuantos archivos quedarán al final:

wc -l 02_only.unique.hashes.txt
243172

Ya casi estamos, salvo que no sé si me alcanza el lugar, veamos cuál es la situación:

  • El disco a rescatar tiene casi 900 GB libres
  • El disco de rescate tiene 120 GB libres
  • El rescate mide 730 GB.

 

Escenarios


Hay varios caminos a tomar:

 

Proyección ingenua

 

Tenía más de dos millones de archivos, queda un décimo de archivos, el rescate en bruto mide 730 GB, con unos 80 GB me arreglo para el rescate neto.

Mi instinto me dice que los archivos más grandes no estan tan repetidos.

 

El camino sin retorno

 

Hago el rescate neto sobre el disco a rescatar.

Lo bueno es que ya queda el disco tal como lo voy a devolver.

Lo malo es que si quisiera repetir el proceso no puedo pues ya pisé una parte.

 

El camino del cobarde con plata

 

Como tengo otro disco más, me puedo dar el lujo de copiar a otro lado.

 

La apuesta ingeniosa

 

Si en lugar de copiar, elimino los repetidos, no hay problema de espacio. Pero si me equivoco o quisiera recuperar algo perdido, tendría que repetir el proceso desde cero.

 

La solución ingeniosa


Si en lugar de borrar o copiar, simplemente muevo las cosas, no hay problemas de espacio, no toco el disco a rescatar, no pierdo los duplicados, que de todos modos no los necesito.


Lo cual me lleva inexorablemente a la respuesta correcta: borrar los repetidos.

La pregunta ahora es por qué hice todos estos rodeos. Muy sencillo. Por un lado no está mal pensar un poco más allá de lo evidente. Y fundamentalmente, por que me quedé enviciado con la idea de que los repetidos me iban a servir para identificar las carpetas, cosa ya descartada, así que a borrar.

¿Cuál sería la regla para borrar?

  • Leer cada linea de 01_hashes_sort, que es (hash,ruta)
    • Si es la primera de una serie de repeticiones, saltear
    • Si no es la primera de una serie, buscar y eliminar la ruta.

Más cerca de la implementación:

  • Leer la primera línea
  • Tomar nota del hash
  • Leer cada línea
    • Si el nuevo hash coincide, eliminar ruta 
    • Si no, tomar nota del nuevo hash

Más cerca de la implemetanción en awk:

  • Decidir que el hash tiene un valor arbitrario imposible
  • Leer cada línea
    • Si el nuevo hash coincide, eliminar ruta
    • Si no, tomar nota del nuevo hash

En awk:

BEGIN { hash="" }

/.*/ {
  if ( $1 == hash ) {
    print "rm " $2 " # " $1;
  } else {
    hash = $1;
    print "# keep " $2 " " $1;
  }
}


Cuando tengo miedo de embarrarla, acostumbro genera la impresión de los comandos en lugar de la ejecución concreta.


awk -f run.awk < 01_hashes.sort.txt > job.sh

Y compruebo que parezca correcto:

grep "# keep " job.sh | wc -l
243172

Y coincide, vamos para adelante.

sh job.sh

No termina nunca, es increiblemente ineficiente, si lo tuviera que hacer otra vez, vería la manera de que cada rm reciba varios archivos a la vez. 


Si estás en el medio del borrado y te asalta la impaciencia, esto te dice el porcentaje de lo realizado, te dejo de ejercicio entenderlo:


echo $(( $(grep -n  -m 1 $(ps ax | grep "rm " | grep -ve grep | grep -o "rm .*" | cut -b 4-) job.sh | cut -d":" -f 1) * 100 / $( grep "rm " job.sh | wc -l  )   ))

 

Si soy muy sagaz quizás ya te diste cuenta del error que cometí, lo noté mientras esperaba que termine el borrado, el primer borrado... ¿ya te diste cuenta?

El análisis de los repetidos fue sobre los archivos que no están en las blacklists de extensiones. Falta borrar esos tambien. Esta vez cada rm recibe 100 archivos

echo -n "rm "
count=0;
grep -f local_extension_blacklist.txt \
     -f photorec_extension_blacklist.txt \
     -f system_extension_blacklist.txt \
     00_archivos.txt \
| while read FILE;  do
   count=$(( $count + 1 ))
   echo -n " $FILE "
   if [ $count -eq 100 ] ; then
     echo
     echo -n "rm "
     count=0;
   fi;
done > job2.sh


wc -l job2.sh
14370

Ese número por 100 más 647764 de los borrados duplicados da 2084764 y más 243172 nos queda 2327936, que se parece bastante al número total de archivos recuperados, 2327955, tiene 19 de diferencia que debe ser el número de archivos de la última línea de job2.sh


 

El final


Y el empujoncito final, agrupar.

Para que la persona pueda hacer algo con todo esto que quedó, generé esta estructura:

  • rescatado
    • imagenes
      • jpg
      • png
      • otras
    • documentos
      • pdf
      • doc
      • docx
      • otros 
    • otros

 

y asi..

El problema es que de algunos tipos de archivos hay hasta más de 10 mil ejemplares y no es buena idea trabajar con carpetas tan grandes, de hecho photorec las hace de 500. Hay que hacer un script tal que tome cada archivo y lo ponga en una carpeta según la jerarquía anterior y además los amontone en carpetas según un límite.


Lo primero es recuperar nuestra frecuencia de extensiones, igual que antes pero con distintos nombre:


find . -type f > 10_archivos.txt

cat 10_archivos.txt | rev | \
  cut -d "." -f 1 | rev | sort | \
  uniq -c | sort -nr > extensions_full.txt

Estos son algunos de mis números:

 

  52000 png
  21000 jpg
  19000 html
  12000 gz
  11000 xml
   8500 pdf
   3000 docx
   1700 gif
   1500 sqlite
   1200 zip
    700 mov
    200 wav
    100 mp3
 

Pensaba particionar pero me cansé, hice un listado para cada tipo (audio, video, comprimidos), con nombre "mover.txt" y luego generé un archivo de patrones:


cat mover.txt| while read EXT; do
   echo ".*\.$EXT$";
done > mover.pattern 

Esto da algo así como:

.*\.mov$
.*\.avi$
.*\.mp4$
.*\.mpg$
.*\.swf$
.*\.webm$

Luego ejecuté:

grep -f mover.pattern 10_archivos.txt | while read FILE; do
  mv "$FILE" rescate/video;
done

Y así para cada grupo.

Elegí algunas extensiones eliminarlas, por ejemplo sqlite. Usé algo parecido a lo anterior, pero

grep -f borrar.pattern 10_archivos.txt | xargs rm

 

Si se le hace inusable a la persona, me dá el disco de regreso y haré el particionamiento.

Para copiar al disco original que tiene hfs plus como filesystem, tuve que pasarme a otra máquina basada en ubuntu para poder instalar hfsprogs, kali no lo tiene a la vista.
 
sudo mount -t hfsplus -o remount,force,rw /media/xxx

Luego, el disco está con root como owner y  hay un usuario 99.99, así que tuve que copiar como root y luego:
 
chown -R 99.99

 

Lo que no fué

 

Esto lo menciono pues me gusta el razonamiento, pero al hacer el análisis de cantidades de archivos por carpeta con lo que pensaba que me ayudaría a descubrir cuáles eran de datos y cuáles del sistema, me encontré con que las carpetas de rescate sólo cumplen la función de no hacer una sola carpeta con millones de archivos, no hay rastro de las estructura, son sólo archivos sueltos.

 

Esperaba que hubieran carpetas que representaran a la misma carpeta pero siendo la misma a travéz del tiempo. De ser así:

  • Hay carpetas del sistema que no nos interesan.
  • Hay carpetas de datos que no nos interesan.

Si en esta instancia eliminara los repetidos, tendría esta situación:

  • carpeta 01 (yo no lo sé pero es la última versión)
    • archivo 01
    • archivo 02
    • archivo 03
  • carpeta 02 
    • archivo 01
    • archivo 02
    • archivo 03

Me resulta más útil poder asignar una fecha a cada carpeta utilizando la fecha más vieja que encuentre adentro pero menor a la fecha de rescate y luego usar las repeticiones para poder relacionar cuales carpetas son la misma.

 

for DIR in  recup_dir.*; do
  date=$( ls "$DIR" --full-time -l \
         | grep -ve 2021-01-01 \
         | head -2 | tail -1 \
         | sed 's/ \+/ /g' | cut -d" " -f 6 )
  if [ $date ] ; then
    echo mv "$DIR" "$DIR.$date"
    mv "$DIR" "$DIR.$date"
  else
    echo "NO DATE FOR $DIR"
  fi
done


Este es el script para revertir:

ls -d recup_dir* | grep "-" | while read DIR;  do
  DST=$(  echo "$DIR" | cut -d "." -f -2 )
  mv $DIR $DST
done


[1] https://seguridad-agile.blogspot.com/2019/11/identificando-versiones-de-programas.html

[2] https://seguridad-agile.blogspot.com/2019/03/jugando-con-los-rayos-1-obteniendo-el.html

 


2021/01/03

Recuperación de archivos en disco de Apple

Una persona conocida tuvo un problemita con un disco con una Apple, ni sabe bien, aparentemente perdió todos los archivos en un reemplazo de discos, no encuentra los discos viejos, conserva un disco de backup al cual borró.

En esta entrada doy una visión quizás menos técnica, es el complemento del contexto teórico que le faltó al rescate de la memoria de una cámara, donde sí están los detalles técnicos.


Existe una baja probabilidad de recuperar algo, veamos qué se puede hacer.

Lo primero es usar una instancia de linux en modo rescate/forense. Esto es, que el sistema no haga ningún tipo de modificación sobre ningún disco sin que se lo pidamos explícitamente. Para este escenario de rescate no es tan necesario pero sí para uno forense, donde hay que conservar intactas las evidencias. Por pura disciplina obremos como si fuera forense.

En el modo forense enfrentamos un adversario, alguien que ha intentado ocultar o eliminar información, en el modo rescate, el adverario es la torpeza del usuario o la mera mala suerte.

Lo ideal sería tener un bloqueador de escritura de hardware como lo que tengo en el trabajo, pero con la cuarentena no tengo acceso. Para windows existe un driver de encase que hace que todo lo que montes esté read-only, pero eso es por la tara de usar windows, en linux alcanza con montar read-only. Es verdad que podés fallar, pero tambien se te puede escapar un sudo rm -rf /


¿a quién no le ha pasado?
¿a quién no le ha pasado?

 

Dado que no tengo ganas de ajustar una instalación normal a "modo forense", voy a usar una máquina cualquiera arrancando con Kali Linux en modo forense, pero sin confiar, le voy a dar otro disco antes y ver que no le haga automount y cuando haga el mount sea read-only.

Kali Linux es una distribución orientada a la seguridad, se puede instalar o usar en modo live, que es lo que haré. No puedo anticipar mucho más pues no sé que voy a encontrar, no sé que particiones usa Apple, no sé nada.

 

Manos a la obra

 

Habiendo iniciado Kali, le conecto un disco cualquiera y verifico que no se haya montado y compruebo montarlo en modo read-only.

 

Es un poco desconcertante que te muestre en el desktop un ícono con las partición disponible para montar. No sé que no entendí de forense, evidentemente es para alguien con mas calle, pues cuando le hice doble click lo montón read-write. Ni me ofreció con el botón derecho el modo de montar.

No importa, es verdad que quien necesita hacer algo forense probablemente dedica buena parte de su tiempo a eso y no se le escapan estos detalles, nosotros los esporádicos, bien atentos.

Conecté entonces el disco a recuperar y uno de capacidad igual o superior. Monté el disco de rescate y tal como mostré en el rescate de la memoria de una cámara, usé photorec, le indiqué origen y destino y a esperar... cuatro horas dijo al comenzar, le llevó....

Seguramente ayudaría que los discos estuvieran conectados en distintas interfaces, pero es lo que tenía, no quiero saber lo que hubiera tardado de tratarse de USB 2.

Asumí que el uso de ambos discos sería similar y por eso puse el pendrive de inicio en USB2 y los discos juntos en USB3. Cuando llevaba 13 horas, para diagnosticar preferí usar ssh en lugar de interactuar directamente con la máquina, pues al ser una notebook, es incómoda por el teclado, el mousepad, la pantalla de muy alta resolución pero poco tamaño y por estar tirada en el piso.

Sólo tuve que ejecutar

sudo service ssh start

para poder entrar remoto.

Antes de investigar, ya que estoy me gustaría ver como marcha photorec, pero no tengo ganas de ir a mirar y desbloquear la sesión:

sudo apt install scrot

export DISPLAY=:0

scrot desktop.png

Ese scrot me captura la pantalla, lo transfiero por sftp y... nada, tiene que estar desbloqueada la sesión, no vale la pena, es menos esfuerzo ir hasta ahí, a menos que...

sudo loginctl unlock-sessions

no funcionó, hay que desactivar el screen-lock, demasiado esfuerzo, lo más correcto es abrir photorec dentro del programa screen para poder des/conectarse desde cualquier sesión, otra vez será.

Ahora falta evitar el sftp.

Para ello, en lugar de conectar con ssh conectamos con ssh -X, que permite abrir allá una aplicación y que su visualización sea aca.

xdg-open desktop.png

Casi, la abre pero no acá, si no allá, por el DISPLAY=:0, hay que decirle a scrot de otra manera.

Además en lugar de abrir con un visor usa un navegador, le lleva mil años, fijate como esta el load average:

 

La carga del sistema
La carga del sistema


Todo el manoseó es entonces:

ssh -X kali@192.168.1.xxx

scrot --display :0 desktop.png

ristretto desktop.png

Ojo que si ya existe desktop.png, sin avisarte salva como desktop_000.png

La mejor manera para la próxima vez:

  • Montar los discos desde la máquina
  • Correr photorec dentro de screen 
  • Hacer detach
  • Conectar con ssh -X
  • Abrir screen y hacer attach

Y cuidado con que no se active nada de Power Saving,  tras estar sin actividad, pues me mató la máquina. Por costumbre al reiniciar eliminé lo que ya había rescatado, probablemente fue un error, pues al arrancar nuevamente photorec, halló un archivo  que evidentemente es el journal y me ofreció continuar la sesión anterior, como que está preparado para sufrir interrupciones, mala suerte, ahí se perdieron dos horas más.

 

Volviendo al análisis del tráfico de los discos, hallé una buena fuente, vamos a probar algunos comandos.

dstat

sudo apt install dstat

Esta herramienta mide de todo, pero hoy sólo nos interesan los discos.

dstat -d 5

 

dstat
dstat

 

No hallé como decirle que use siempre MB para que no cambie la escala.

 

iostat

 

iostat
iostat

Parece indicar lo mismo: Aunque hay más bytes leidos que escritos, no hay una proporción tal que indique que una escritura más lenta podría ser mejor.

Una prueba que quise hacer fue saturar la lectura y la escritura para comparar con la obtenida. Para ello suspendí photorec y mirá lo que pasó con 10 segundos de intervalo:


suspendido
suspendido

 

Estuvo casi un minuto terminando de escribir, eso más bien indica que el cuello de botella es la escritura.

La lectura:

if=/dev/sdc of=/dev/null


saturación lectura
saturación lectura

La escritura:

if=/dev/zero of=borrar.bin

 

saturación escritura
saturación escritura


Para poder seguir de modo responsable el experimento, debería repetir las mediciones para USB2, pero no vale la pena, USB3 es 10 veces más rápido.

 

Recuperación

 

El disco este se usaba como backup, confiando en que el original estaba ok, se borró y se comenzó a usar nuevamente como backup. Luego se cayó en cuenta que el original no estaba ok, desesperación.

Para empeorar la cosa, pasaron varios meses entre las operaciones y la detección del inconveniente.

Lo que espero encontrar son un montón de carpetas borradas de la forma "Backup AAAA-MM-DD" con sus contenidos. Esto implica una alta repetición de archivos.

Para detectarlos voy a usar una técnica como la utilizada cuando lidié con archivos duplicados que es hashear todos los archivos y eliminar los duplicados


Lo que encontré:

5000 carpetas con nombre "recup_dir.NNNN" y con la fecha actual, en una estructura plana, esto es, no hay carpetas anidadas.

2000000 de archivos con nombres de una letra (f, r, t), un número de cerca de diez cifras, de los cuales el 10% tiene un nombre tras "_"

Cuando la letra es:

f: archivo, cuando además tiene un nombre, la fecha correcta, si no la actual.

t: thumbnail hallado dentro de algún archivo, fecha actual.


Al aplicar la técnica de agrupar por md5, se redujo a "sólamente" medio millón de archivos. Al quitar los thumbnails, 30 mil menos.

Abrí algunos archivos al azar y parecen estar ok. 

Los nombres de los archivos no parecen corresponder al nombre original si no a algo tomado de la metadata.


Le dejé a la persona dueña de los datos el trabajito de buscar lo que le interese.

















 


2020/04/30

FSM vs SQL, algunas consideraciones de correlación de eventos


Hace como un año comencé a desplegar unas alarmas en el trabajo utilizando FSM para procesar los logs y obtener alertas tempranas ante ciertos incidentes.

Luego me dí cuenta que pude haberlo hecho utilizando consultas SQL, lo cual me llevó a reflexionar mucho sobre el tema, hacer algunas prueba y preparar una charla que dí en el trabajo de modo virtual pero no podré dar afuera por que todas las conferencias medio que están caidas.

Esto viene a ser un resumen de lo que pudiste haber visto en FLiSOL, H4CK3D, OWASP Latam Tour, LACNIC y no digo Ekoparty por que nunca me aceptan nada.

Voy a asumir que tenés una idea de los temas, que sólo te estoy aportando las relaciones entre las ideas. Además yo no soy ninguna autoridad de conocimiento, sólo estoy expresando opiniones más o menos bien sustentadas.



Voy a usar el siguiente vocabulario, los dos primeros corresponden al uso común y el último lo uso para manejarnos ahora.

Evento: cada cambio sin connotación positiva o negativa
Incidente: un cambio con connotación negativa
Caso: conjunto de eventos en análisis que conducen a un incidente.

Un caso simple


Partamos de un sencillo requerimiento atemporal, no hay tiempo ni información variable involucradas.


Si hay una conexión a la IP_perimetral en el puerto 8081 desde una IP_externa que no está en la red 211.10.10.0/24 y tiene cierto "DATO", quiero una alarma, evitarlo o incluso agredir.

Esta es un típica regla stateless, se puede resolver con lógica combinacional:

[grafico logico]

IP destino en IP_perimetral
   AND
puerto es 8081
   AND
IP origen NOT en red 211.10.10.0/24
   AND
mensaje contiene "DATO"

Tambien con una consulta SQL:

SELECT * FROM conexiones 
   WHERE
      ip_destino IN (SELECT  ip FROM red_perimetral)
   AND
     port_destino = 8081
   AND
     ip_origen NOT IN ( SELECT ip FROM red_externa)
   AND
     datos like “%DATO%”;


O con una FSM de un solo estado, que contendría la lógica combinacional previamente citada, en pseudo-C:

if ( 
  pertence( IP_destino , IP_perimetral) )
  & puerto == 8081
  & ! pertenece(IP_origen, 211.10.10.0.24)
  & strpos("DATO", mensaje) {
    generar_alerta();
}



Algunos atributos apropiados para nuestros ejemplos:
  • Origen
  • Destino
  • Tipo de mensaje
  • Contenido del mensaje
  • Longitud del mensaje
  • Horario

Un caso complejo



Si hay un scan desde una IP_externa y desde esa misma IP hay luego una conexión con un DATO y luego se ve ese DATO en una copia entre nodos internos de una IP_interna_origen a una IP_interna_destino y finalmente hay una conexión saliente de esa ip interna de destino con ese DATO, quiero una alarma, evitarlo o incluso agredir.

Que es difícil de leer, mejor no lo leas, leé esto:

Si se da la siguiente secuencia de eventos
  • Scan desde una IP_externa
  • Conexión desde esa IP_externa con un DATO
  • Copia de datos entre dos nodos con ese DATO desde una IP_interna_origen a una IP_interna_destino
  • Conexión saliente de la IP_interna_destino con ese DATO
 entonces quiero una alarma, evitarlo o incluso agredir

Fijate que las partes coloreadas no están predefinidas, son variables que deben
concidir entre las distintas partes de la reglas

A los atributos previamente mencionados se suma "Relación entre los mensajes".

Lógica combinacional


Este es el terreno de Boole, es prácticamente instántanea, corre a la velocidad máxima de propagación entre compuertas si está implementada en hardware, que es factible usando FPGA. Si corre en software, son pocas y simples instrucciones. Cuando se le agrega memoria, se llama secuencial, siendo un caso particular es la FSM.

FSM


Dice wikipedia que:

Un autómata finito (AF) o máquina de estado finito es un modelo computacional que realiza cómputos en forma automática sobre una entrada para producir una salida.

Que es lo mismo que hace cualquier proceso o programa, lo específico es que es un cierto modelo computacional, mirá los componentes de una FSM:


  • estados
  • entradas
  • salidas
  • función estado(estado,entrada)
  • función salida(estado,entrada)
  • estado inicial

Un proceso genérico no tiene necesariamente la función de estado, ni siquiera estados.

Las funciones de entrada y salida son combinacionales, quizás con efectos colaterales cuando hay más memoria que estado en sí.


Un ejemplo muy natural por decir de algún modo es un operating system scheduler que es su expresión más baja se reduce a esto:




Lo que está diciendo es que cuando se crea un nuevo proceso, va al estado "Ready To Run". Cuando el OSS decide que corra, Running, del cual puede salir cuando termina, cuando se le termina el tiempo asignado de ejecución y el OSS lo regresa a R2R o cuando pide una operación que implica largos tiempos de espera como acceso a un periférico. El sistema operativo detecta eso y elije mandarlo a dormir para liberar la CPU para otro proceso. Cuando la operación de entrada salida concluye, el proceso pasa nuevamente a R2R y así.


Como se implementa, puede ser como en mi demo con el estado atributo en la instancia, pero tambien puede estar el objeto (o estructura) en una tabla y una de sus columnas ser el estado. Tambien y me gusta más intuitivamente pues nunca implementé un OSS, en tablas o listas separadas, una para cada estado.

Consulta SQL


Asumo que sabés al menos que es un join sencillo.

En el contexto de lo que estamos analizando, estas son las principales características para comparar entre FSM y consulta SQL:

En la FSM el tiempo está implícito, hace falta que los eventos lleguen ordenados, falla si no. No hace falta guardar estos eventos, sí algún que otro dato para parametrizar las reglas y para el reporte final. Esos datos y el overhead de las instancias de cada caso genera un consumo creciente de memoria. Dado que da una respuesta de muy baja latencia, puede ser usada en situación de bloqueo, esto es que no sólo alerte sino impida la acción final del ataque. Es más difícil de programar pues es... programar, justo.

Las Consultas SQL por su lado necesitan el tiempo pero este está explícito en el timestamp del mensaje y necesita conservar los mensajes, de lo cual se encarga el DB Engine con todo sus ventajas de escalamiento. No lo veo mucho en situación de bloqueo, quizás si para un sistema transaccional pero no para algo donde la latencia sea crítica. Es más fácil de programar pues no es programar, es escribir SQL, lo cuál al comienzo es más difícil cuando es complejo, pero luego es más de lo mismo.


Una FSM puede alimentarse de un batch ordenado. O sea que tambien se puede usar para detectar en archivos históricos. Me imagino que no debe ser más eficiente que DB pues las DB estan diseñadas para ser eficientes en ese escenario.

Como machete, FSM vs Query SQL:



FSM
Query SQL
Tiempo
Implícito
Explícito
Orden de eventos
Indispensable
Indiferente
IO
Stream
Stream/batch
Almacenamiento
Descartable
Indispensable
Memoria
Creciente si no se purga
DB Engine (*)
Real Time
Hard (sniffer)
Soft
Modo
Detección y Bloqueo
Detección
Escalamiento
Provisto por S.O.
Provisto por DB
Conocimientos
Programación
SQL
Cambios lógica
Difícil
Fácil
Embebible
Si
Mmmh


Con embebible me refiero a que se podría tomar un microntrolador y/o FPGA y hacer un modulito que se conecte a la red y cumpla alguna función digna de mención, no tanto con una DB, para la cual hace falta un sistema operativo detras, mmmh, por eso, mmmh, no.

Características compartidas

  • Hay que tener en cuenta un "tiempo de vida", un "timeout", tras el cual un caso debe ser desestimado en el caso de FSM o una antigüedad de log ignorada en el de SQL. Esto reduce el tamaño de la DB/espacio en memoria.
  • Pueden haber alertas intermedias, en el caso de FSM simplemente emitir mensajes en estados previos al final, en el de SQL consultas que no incluyan las últimas condiciones, una especie de copiar->pegar->podar de la consulta.

Para SQL hay un optimización híbrida, en lugar de ejecutar siempre toda la consulta, buscar la condición del último evento, en nuestro ejemplo una conexión hacia el exterior, si existe, hacer la consulta completa. Quizás las optimizaciones que hacen los DB Engines hacen eso o se les puede sugerir, sé muy poco de DB.

Dicho de otra manera, cuando llega el último evento, me fijo si han ocurrido las condiciones para llegar hasta ahí.

Hice una demo que está en github, te cuento:

Modificá export.php y generás la base de datos para las Consultas SQL, que están en el archivo... consultas.sql.

SimpleFSM.java es una POC para casos no solapados, es para concentrarse en un ejemplo de FSM y en la lógica y cuestiones secundarias como leer de STDIN.

FSM.java es la implementación más correcta, donde una una colección de casos, de paso, las clases deberían llamarse CasoSimple y Caso, no el nombre de la implementación, pero cuando lo hice estaba mas concentrado en la FSM que en las recomendaciones de Domain Driven Design.

Fijate que al pasar de SimpleFSM a FSM el evento que lleva al primer estado es extraido de la  lógica común. Para entender bien mirá la evolución por el paso intermedio, FSM2, que debería llamarse FSM_fail, donde estoy haciendo dos cosas a la vez: la FSM y la gestión de la colección.

Lo correcto es hacer FSM y de ahí fijarse como optimizar para que los loops terminen antes si pueden y esas cositas.

2019/10/07

Ejemplo de rescate de memoria de cámara

Un pariente borró accidentalmente sus fotos y videos de una cámara que encima tiene rota la tapita de las pilas, detallo acá lo hecho para restaurarlas:

El camino fácil


Primero, obtener una imagen de la memoria, hay que insertarla y ver que dice dmesg cómo encontrarla:

[69.899754] sd 8:0:0:0: [sdb] 7741440 512-byte logical blocks: (3.96 GB/3.69 GiB)
[69.906898] sdb: sdb1


Para ser estrictamente forenses, debimos haber desactivado el automount, para evitar cualquier escritura sobre el disco, en particular en Mint Mate me parece que con

gsettings set org.mate.meda-handling automount false

ya estamos. Recordá que si el disco se monta automáticamente, se hace read write y algo toca, aunque en este caso no debería hacer diferencia.

Luego con fdisk explorarla, por curiosidad y costumbre:


$> sudo fdisk /dev/sdb -l
Disk /dev/sdb: 3,7 GiB, 3963617280 bytes, 7741440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start     End Sectors  Size Id Type
/dev/sdb1        8192 7741439 7733248  3,7G  b W95 FAT3
2

Otro motivo para no tomar la imagen hubiese sido estar recuperando información de un almacenamiento mayor al espacio disponible.

Para buscar lo borrado, el programa photorec ha resultado muy efectivo,

sudo apt install testdisk

Puede trabajar directamente sobre la memoria con sudo o sobre la imagen, mejor sobre la imagen, de paso no le damos sudo.

photorec sd.img

Con sudo seguramente hubiese mostrado la sd.


Hay que elegir si revisar todo el disco o la partición que encuentra, en este caso la partición. Si se hubiera borrado la tabla de particiones... whole disk.


Hay que elegir el formato, en este caso sabemos


 Elegimos que busque en toda la partición


 Y finalmente donde dejar lo rescatado




En el caso de esta vieja Kodak, recuperó imágenes y videos como esperábamos y además unos xmls, .ini y sqlite que como no aportan nada los ignoré.

Las fotos que comienzan con f son fotos, las que comienzan con t son previews.

Para ver el resultado, en Mint y parecidos con abrir la primera imagen se puede ver con el visor y luego pasar a modo galería o ir avanzando con la flecha. Como detalle de calidad se pueden rotar las imágenes que lo necesiten y al salir de visor ofrecerá guardar

Como no estaba seguro del orden, ejecuté el siguiente script que extrae la fecha de la metadata y compone un nuevo nombre:



Pongo una imagen en lugar de texto en parte por que se vé mas lindo, en parte por mala gente así tenés que tipear, lo cual te ayuda a familiarizarte con bash.


Con respecto a videos rotados, se pueden corregir con:


ffmpeg -i f0316864.avi -vf "transpose=2"  fixed.avi


o mejor aún con:


mencoder -vf rotate=2 f0316864.avi -oac copy -of lavf -lavfopts format=mpeg4 -ovc lavc -lavcopts vcodec=mpeg4 -o fixed2.avi


que conserva la calidad. El format y el vcodec dependeran del formato del video.

He visto recomendado usar avidemux pero ya teniendo ffmpeg y memcoder instalados, preferí no seguir instalando cosas. Quizás avidemux resuelva automáticamente lo del formato.

El camino difícil


No me gustan mucho los hubiese, seguramente, hubiera, supongo que dejé  más arriba, así que borré la tabla de particiones de la sd y trabajé directamente sobre ésta, para recorrer el camino de sudo y la falta de espacio.

Mirando más arriba la salida de fdisk dice que la partición empieza en 8192 * 512 y mirando lo primero que encontré, la tabla de particiones está bien al comienzo.



sudo dd if=/dev/zero bs=1024 count=1 of=/dev/sdb

Ojo que si te equivocás con of podés perder el disco. Si me dedicara a esto probablemente siempre usaría una virtual o una máquina de descarte. Si te equivocás con count o bs lo suficiente, te metés con los datos, por ello es mejor trabajar sobre la imagen previamente obtenida, pero no olvidemos que esto es un ejercicio, nunca necesitaríamos borrar la tabla de particiones.

Tampoco uses if=/dev/null, ya que como input no te da nada y nada escribe, necesitás ceros.




sudo photorec /dev/sdb



Si no le decís explícitamente la ruta, te muestra lo que haya.




Le dás Search, Other... (me faltó la captura y ya me aburrí)



 y anda otra vez.




Detalles de terminación


Además, la cámara estaba un poco rota, la tapita no cerraba por que volaron las muesquitas en la bisagra y en la punta contraria.



Lo bueno es que tiene para atornillar, sólo hay que hallar la pieza apropiada y el tornillo apropiado para no usar cinta adhesiva, para algo llevo años juntando tornillos y todo tipo de basura, como un perfil de aluminio de mosquitero:




Los comandos acá utilizados y otros de utilidad los comparto en github.

2015/03/01

Wipe



Papel


Lamentablemente tuve que tirar mi colección de Linux Journal en papel, hacía años que las almacenaba sin ninguna utilidad salvo conservar el número 170, donde me habían publicado un truquito. Tenía como 10 años, cerca de 50 kilos de papel. De paso se fueron dos o tres libros, algunos números de Sólo Progamadadores, Elektor y otras revistas. También apuntes viejos de facultad y artículos impresos fácilmente recuperables y de consulta nula, supongo que casi 75 kilos y más de un metro de estante.



Hace años había intentado ubicar las Linux Journal en alguna biblioteca, pero a las dos o tres que contacté no les interesó y estoy seguro que pregunté en alguna lista, pero quizás no y debí haberlo hecho ahora, pero ya he tenido experiencia en intentar regalar cosas y tiene un cierto costo, reproduzco a continuación los resultados de un proyecto, llamado "Metro Cúbico", que era el espacio que calculaba liberar en casa al deshacerme de todo el hardware obsoleto que tenía.


Metro cúbico de hardware




computadora macintosh seretirado german B
computadora macintosh performa 475 250MB y memoria retirado german B
computadora macintosh quadra 605, 250M, memoria, floppy retirado german B ira vitrina de la UTN Rosario
computadora macintosh quadra 700, memoria, hd retirado german B ira vitrina de la UTN Rosario
computadora macintosh classic II retirado german B pisapapeles
Impresora epson actionprinter 2000 (parece ok)retirado Alberto Lplan canje
computadora acer 80486 sx 33 (bastante ok)volquete
terminal wyse 60 (eeprom borrado) volquete
terminal ibm 3196 con teclado (ok)volquete
computadora pentium pro 200 sin cpu (no funca)volquete
monitor apple mo401 (14 pulgadas)retirado Ariel N
Computadora compaq amdk6 350Mhz 190MB hd 3.5 GB cd (video usb audio) onboard retirado matias m en uso
telefono inalambrico panasonic 900mhz (quizas ok)labi
calculadora hp25 (quizas ok)labi
Compaq pocketpc (completamente desarmada)labi
La era de las maquinas espirituales - Ray Kurzweil retirado Pablo B leyendo
Computadora pentium 200 mmx 32 o 64 MB Acer(funciona)retirada Diego Gen uso
2 consolas atari 2600 (estado desconocido)retiradas Diego G
The ultimate DOS programmer's guide - Mueeller Wang 1991retirado Diego Gen uso
teclado usb macintosh (sucio)retirado matias h
2 teclados usb macintosh (estado desconocido)retirado Ariel N en uso
The C++ Programming Language (2nd ed. 1991) Bjarne Stroustrupretirado Damian F no usado aun
monitor philips 107s (leve fallo cable)retirado federico v arreglado y usado satisfactoriamente
computadora pentium 200 mmx, 32Mb, floppy (ok)retirado victor t
laptop ibm 560, floppy, 40Mb, 1G (arreglable)Retirado Matias M quizas se arregle y use
gabinete externo scsi (ok)Retirado Matias M
placa video S3 Virge DXRetirado Victor Ten uso
hub 3com (muy roto) labi
hub asante 1016-iq, management, snmp (un poco roto) labi
gabinete externo scsi (ok) labi
fax xerox workcentre 365 (bastante roto) cartonero
modem racal-milgo rmd 3222 (no se) labi
computadora macintosh 512k (no se) retirado diego gdescartada
computadora macintosh lc3 (no se) retirado diego gaprovechada
Discos y memoria (ok) retirado Melisa H
Discos y memoria (ok) retirardo Pablo R


Actualización 2024/01/29: ver https://seguridad-agile.blogspot.com/p/material-cyberciruja.html


Con este mail cierro la experiencia de haber regalado hardware a los participantes de estas listas. Me habia quedado escrito hace un tiempo y revisando los drafts lo hallé.

Les comparto este balance pues he aprendido varias cosas que bien le puede servir a quien se encuentre en una situación parecida, no solo a nivel personal sino tambien profesional, viendo que hacer con un jugoso stock de hardware obsoleto.

Partamos de que lo que estaba ofreciendo, ahi pueden ver tambien la última columna de feedback, no era muy interesante para el promedio de las personas, incluso técnicas. Como llegué yo a interesarme es un tema que trasciende esta discusión.

¿Como medir el resultado? Si es desde un punto de vista estrictamente de impresión, es bueno, me alegra que, por ejemplo, Federico V. haya reemplazado su choto monitor de 15 rayado por un choto monitor de 17, jeje. Me resultó un tanto tedioso tener que insistirles a personas que se habian mostrado interesadas en que ratificaran o rectificaran su interés y obraran de acuerdo a ello.

Desde una medición más objetiva, la experiencia no es tan buena. Le dediqué cerca de dos días hábiles en total, durante los cuales envié 55 mails y recibí 75.

Que cada haga su cuenta, pero con un sueldo neto de $3k/$6k/$9k/$12k/$15k hubiese sido de $250/$500/$750/$1000/$1250 de "lucro cesante", asi que tirarlos en un volquete ($???) hubiese sido mejor.

Dejar en la calle para que sea retirado por cartoneros implica el riesgo de generar basura, pues algunos procesan in situ. Tambien los muchachos de la esquina pueden llegar a destrozar por la mera diversión, yo lo hacia a esa edad, no les puedo reclamar nada.

Otro inconveniente es que semejante cantidad de "tecnología" en la calle puede provocar en el ojo inexperto una impresión de falsa prosperidad que puede incitar al delito.

Ahora cambiemos de punto de vista, de donante a receptor.

Al ofrecer una serie de publicaciones a la biblioteca, me encontré con un casi rechazo. Cuando indagué, el motivo fue muy claro: "hay mucha gente que trae cosas totalmente inútiles y despues se enojan si las tiramos". Eso me recordó cuando hace unos años le ofrecí a algún docente una dual pentium 100 y que tambien con desconfianza me preguntó por mis condiciones. Sorprendido le dije que no tenía ninguna. Me explicó que solían tener problemas con empresas que le traian cosas pero ponian condiciones con respecto a su uso. O el caso de una bruta máquina que necesitaba una pequeña reparación de u$s5000 (uno a uno).

Es por eso que cada vez que llevo cosas al labi les aclaro: "úsenlo, regálenlo, véndanlo o tírenlo".

En mi vida pasada como factotum técnico informático de varias empresas pequeñas, he notado que tiende a acumularse el hardware obsoleto y casi obsoleto, que resulta más caro usarlo que almacenarlo. Sin embargo, podría ser útil en las manos apropiadas. Surge entonces la idea de la donación y goto al comienzo del mail.


Estas son algunas de las descripciones que hubieron en una segunda experiencia:


Scanner microtek scanmaker II sp (sp significa "single pass", el modelo anterior pasa tres veces, una para cada color), con una placa scsi isa 16 bits y el cable, todo funcionando. Si alguien quiere sólo el scanner para destriparlo, esta ok, estoy haciendo espacio.

Computadora pentium 133 doble procesador, mother micronics, la cresta de la ola en su momento, con gabinete, disquetera (3.5) y fuente, bus eisa con placa de red 100VG-ANYLAN (eisa), que funciona como ethernet de 10, placa token ring (eisa), algo de memoria (tiene cuatro pares de slots), no se cuanta hay instalada y video pci. ¡Todo un desafío!



IBM thinkpad a21e, pantalla ok, teclado ok, fuente ok, bateria ok, lector cd o dvd, modem interno pero extraible de 56k, sin memoria, sin hd, sin bolso y con la nvram corrupta. Según he averiguado la solución económica en el mundo desarrollado es comprar un mother nuevo en ebay. El plan B lo ofrece, si no me equivoco un australiano que vende un soft y unos diagramas de un circuito para interrumpir el boot y reflashearla. El plan C, el más realista, es descuartizarla.


La Sabiduría que he adquirido de todo esto es que lo mejor es tirar todo furtivamente a la basura cerca de la hora de recolección, para no llamar la atención ni generar basura colateral.

Aún así no logro ser completamente racional y estoy esperando a que pase un cartonero con carrito para darle las LJ y los apuntes, son muchos kilos.


Habiendo terminado con el papel, ¿qué hacer con los medios magnéticos y ópticos?

Almacenamiento


Tenía 20 cassettes, 100 cds, 10 ZIPs, 10 diskettes de 5.25 y 150 de 3.5.




Lo principal a tener en cuenta es no perder información. Pero si en todos estos años no extrañaste lo que hay en esos diskettes, probablemente no valga la pena revisarlos.

Lo segundo en no "perder" información, o sea, que alguien pueda acceder a esa información. Pero si no recordás bien que hay en los disquettes, ¿cómo saber que borrar? Entonces uno debería borrar todo, pues el que dice "3COM drivers" quizás tiene otra cosa.

Hay que hacer borrado seguro de cada diskette/zip, para lo cual hay que armar una máquina con disquetera y quizás ide o scsi y... suficiente, ¿para qué querríamos limpiar los diskettes? Para que alguien los use, cosa cada día menos probable y ya habíamos aprendido antes que donar puede ser caro. Así que mejor...


¡¡¡¡...a destruir!!!!


Los cassettes, que sólo tenían música, fueron desarmados y la cinta usada como serpentina en una fiesta infantil. Los cds rotos uno a uno con dos alicates dentro de una bolsa para que no saltaran los pedacitos por todos lados. Para el resto consideré primero pedirle a un compañero de trabajo que probara hasta donde llegaba una bala, pero eso me postergaba el asunto. Luego, usar el taladro, pero me pareció sucio, así que opté por el destornillador caliente.






En la pila de papel siempre hay facturas, recibos, exámenes médicos y académicos, formularios, agendas con información confidencial o sensible y por que no, listas de claves de administración, que es conveniente incinerar.

Disposición


Los diskettes destruidos fueron desperdigados dentro de un contenedor de basura de modo tal que se desalentara su recolección. Esto tiene que ver menos con privacidad que con solidaridad, ya que su destrucción no es evidente y podría dañar una disquetera.


Conclusión


Por lo general me ha resultado más barato, divertido y gratificante destruir que reciclar o reutilizar.

En términos de privacidad, es un esfuerzo innecesario, ya que yo no soy un "blanco interesante", pero he utilizado las prácticas de quien si lo es. Si uno fuera un "blanco muy, muy interesante", sería conveniente la incineración completa o shredding.

Un buen trabajo práctico de Ingeniería Electrónica o Informática Forense sería armar una disquetera/zip/cd reader, los programas y el preparado para lidiar con el agujero en el disco.