Nota del autor

Si la entrada que estás leyendo carece de imágenes, no se ve el vídeo que teóricamente lleva incrustado o el código fuente mostrado aparece sin formato, podéis conocer los motivos aquí. Poco a poco iré restableciendo la normalidad en el blog.
Este blog es un archivo de los artículos situados previamente en Lobosoft.es y ha dejado de ser actualizado. Las nuevas entradas pueden encontrarse en www.lobosoft.es. Un saludo,
Lobosoft.
Mostrando entradas con la etiqueta Windows. Mostrar todas las entradas
Mostrando entradas con la etiqueta Windows. Mostrar todas las entradas

domingo, 23 de agosto de 2009

ADS, una introducción

El sistema de archivos NTFS alberga algunas características que, no por poco conocidas por el usuario son menos usadas por los desarrolladores. Entre otras, cuenta con los flujos alternativos de datos, o Alternate Data Streams (ADS, también conocidos como named streams), que permiten adjuntar información de muy diverso tipo a los ficheros tradicionales. Los ADS van más allá de los metadatos, y permiten incluir tanta o más información como el fichero que los contiene, aunque sus características y, en especial, el escaso conocimiento o publicidad que se ha dado hasta la fecha sobre su existencia constituyen, como cualquier característica desconocida, una vulnerabilidad que puede aprovechar esta debilidad para llevar a cabo ataques sobre nuestros sistemas.


Ya que llevo tiempo deseando escribir sobre el tema, y debido a que en los últimos meses he andado con el blog “a medio gas” por diversos motivos y compromisos adquiridos, creo que lo mejor será presentar una introducción a los ADS para, a continuación, profundizar en el uso que podemos darles desde nuestras aplicaciones.


Como ya refería al comienzo, los ADS son una característica propia de NTFS, por lo que no está disponible en otros sistemas de archivos (FAT, Ext3, …). Es más, si un archivo creado en un sistema que use NTFS incluye uno o más flujos alternativos, éstos desaparecerán al copiar el archivo a otro sistema de archivos que no los soporte. Bueno, en realidad serán eliminados todos menos uno: el que tiene el archivo de forma predeterminada. Pero veamos en qué consiste exactamente un ADS.


En la siguiente gráfica, podemos ver cómo se estructura la información (datos y metadatos) de un archivo en FAT y NTFS. Vemos que en el antiguo sistema de archivos, un hipotético archivo de llamado “nombre.ext” contiene una serie de atributos (sólo lectura, archivo, oculto…) y un bloque de datos, es decir, el contenido real del archivo. En NTFS, por el contrario, el archivo contiene los atributos además de una información de seguridad (permisos) y una serie de streams asociados. El stream principal es el predeterminado que mencionaba antes. No tiene un nombre asociado y se correspondería con el bloque de datos del archivo en FAT. Es decir, al llevar un archivo NTFS a FAT mantendríamos la información de atributos y la del stream principal que se correspondería al bloque de datos, pero se perdería el resto de información, incluidos los streams o flujos alternativos. De hecho, este stream principal es obligatorio, y si por un casual creásemos un archivo directamente accediendo a uno de los streams con nombre (alternativos), el sistema crearía un stream principal de 0 bytes, vacío y sin nombre. Cabría señalar que los atributos se corresponden a todo el archivo, no al stream principal, por lo que todos los flujos son afectados por un cambio en aquellos.



Cuando un programa abre un fichero NTFS, realmente está accediendo al stream principal. Para acceder a uno de los streams alternativos debe interponerse un símbolo de dos puntos ( : ) entre el nombre del archivo y el del stream al que deseamos acceder. Al corresponderse los dos puntos con el identificador de una unidad, para acceder a un stream llamado “MiStream” dentro del archivo “C”, tendríamos que hacerlo con la secuencia con “C: MiStream”, pero el sistema siempre resuelve la ambigüedad creada dando prioridad a la identificación de unidades. Por esto, si lo que deseamos es acceder a un stream, deberíamos hacerlo con “.\C:MiStream”.


Por último, antes de entrar en algunos ejemplos sobre cómo usar los ADS desde el propio sistema operativo, indicar que los directorios también pueden tener asociados diversos ADS con nombre, pero no tienen ninguno principal o por defecto.


Desde la propia consola de comandos de Windows podemos crear y acceder a los ADS de un fichero o directorio. Obviamente, no es la mejor forma de hacerlo; sin embargo, los sistemas operativos Windows 2000 y Windows XP no ofrecen herramientas específicas para trabajar con esta característica de NTFS.


Podemos crear un archivo de texto normal y consultar su tamaño desde la consola de comandos:



Crear un stream alternativo, de nombre “Texto” con un contenido textual es tan simple como escribir sobre ese stream. Como puede observarse, un comando type solamente muestra el contenido del stream principal, el de datos. Para consultar el contenido textual del stream alternativo creado debemos usar el comando more (ni tan siquiera el type funciona, como veremos más adelante en otro ejemplo).



Si vemos el contenido del directorio, observaremos que el tamaño del fichero no ha cambiado, aunque sí la hora de modificación.



Es posible copiar un archivo dentro de un stream. Como vemos en el ejemplo, hemos incluido un archivo de imagen dentro del archivo de ejemplo sin que cambie su tamaño, considerablemente menor al de la imagen incrustada.



Por último, vemos que es posible ver el contenido del stream de texto, pero se nos hace algo más dificultoso recuperar el del binario con la imagen. En la próxima entrada veremos cómo podemos acceder a este contenido en particular.



Ahora bien: ¿para qué se usa, o qué usos podemos darle a los ADS? Bueno, en principio Microsoft introdujo los ADS en NTFS para dar soporte a funcionalidades avanzadas de sistemas UNIX, OS/2 y Macintosh, pero en la actualidad se le dan usos tan interesantes como incluir un identificador de zona (en el ADS Zone.Identifier) con información del la zona del mundo desde la que se ha descargado un determinado fichero de Internet. También algunos metadatos de los archivos, como el nombre de autor, título, comentarios, etc. son almacenados en respectivos ADS. En nuestro caso, como desarrolladores, deberíamos plantearnos la información que queremos almacenar en estos compartimentos y si es necesario realmente usarlos. En principio no debería incluirse información vital para nuestras aplicaciones, ya que una copia del archivo a través de un sistema que no use NTFS haría que se perdiese esta información. Tal vez podría sernos útil para almacenar información fácil de recuperar pero que, con el uso de los ADS, nos permite un acceso más inmediato. Sería el caso de las imágenes a pequeña escala para archivos de imagen (thumbnails), metadatos para documentos… De esta manera el archivo podría almacenarse en cualquier sistema de ficheros, pero en un NTFS mejoraríamos el rendimiento y el acceso a esta información no vital pero sí útil.


Esto es todo, de momento. En sucesivas entradas veremos algunas características más avanzadas de los ADS y, sobre todo, investigaremos un poco en torno al uso que podemos hacer de los mismos desde nuestras aplicaciones.

jueves, 26 de marzo de 2009

Cierre la puerta al salir

Hay ocasiones en las que es necesario impedir que un ordenador sea reiniciado o apagado de forma involuntaria,  sin llevar a cabo una serie de tareas, generalmente de mantenimiento o de seguridad (copias de respaldo, "limpieza" con herramientas del tipo de CCleaner). Puede ocurrir, simplemente, que deseemos programar estas tareas para que se ejecuten al final del uso diario de nuestros equipos, o bien prevenir posibles olvidos por nuestra parte.



Ante casos así, podemos echar mano de los scripts de Windows (Windows Script File .WSF, para Windows Script Host). Estos ficheros, muchos los conoceréis, albergan un script en algún lenguaje común (VBScript, JScript, Perl…), y permiten automatizar diversas tareas dentro de entornos Windows. Hasta cierto punto, guardan diversas similitudes con los scripts de NAnt y similares, que vimos en días pasados, aunque el uso que podemos dar a los mismos es ciertamente distinto.

Un script muy básico, que ejecutaría el shutdown.exe –a, podría ser el siguiente:



[?XML version="1.0"?]
[?job error="true" debug="true"?]
[job id="StopShutdown"]
[script language="VBScript"]
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run("%windir%\system32\shutdown.exe -a")
[/script]
[/job]

Se trata de un XML al que he cambiado por [ y ], para que se visualice correctamente en el blog. Para utilizarlo basta con volver a reemplazar estos signos por los originales, y guardar el archivo con extensión .WSF. Para ejecutarlo bastaría hacer doble click sobre el mismo. Con un script de este tipo conseguiríamos lo mismo que con un acceso directo a dicha herramienta, con el mencionado parámetro: detener el reinicio de nuestro sistema, cuando se ha ejecutado un shutdown, o se ha procedido a iniciar un reinicio de sistema (siempre que lleguemos a tiempo, claro está).


Ahora bien, ¿cómo conseguimos que nuestro script “abortareinicios” se ejecute al apagar el ordenador? Basta, simplemente, con incluir el script dentro de la lista de scripts de inicio y finalización del sistema, en las políticas de grupo, para este usuario. Así, ejecutamos gpedit.msc desde Inicio->Ejecutar, y tendremos ante nosotros el cuadro de diálogo Group Policy (Directiva de Equipo Local). Dentro de User Configuration, Windows Settings, Scripts (Logon/Logoff), hacemos doble clic en Logoff, e incluimos el script que acabamos de crear. Guardamos los cambios y probamos a reiniciar el equipo. A ver qué pasa ;) .




Pues, ciertamente, que el ordenador se apaga. Sin embargo, si os decidís a probarlo (este, u otro script cualquiera), observaréis cómo Windows procede, durante el apagado o el reinicio, a llevar a cabo una nueva fase de ejecución de scripts de cierre. Cuando ha llegado a esta fase, me temo, ya no es posible dar marcha atrás al proceso de apagado, pero sí podemos usar los scripts para llevar a cabo otras tareas de finalización.


Ahora bien, ya por curiosidad malsana, ¿se os ocurre algún modo de impedir el reinicio indebido del sistema por parte de los usuarios?


Para saber más: