Blog Archive

SQL-Server

 
Rubén Garrigós

El lado oscuro de la inicialización instantánea de ficheros

2008-02-25 03:22:00 por Rubén Garrigós

La mayoría de nosotros conocemos las bondades de la inicialización instantánea de ficheros ("instant file inicialization") de SQL Server 2005. Esta funcionalidad nos permite crear nuevos ficheros de forma casi inmediata reclamando el espacio del disco sin tener que inicializar a cero cada uno de los bytes de éste. A continuación veremos el lado oscuro de esta funcionalidad mediante un ejemplillo práctico ;)

   

Vamos a crear una base de datos que contendrá una tabla con 10000 usuarios y passwords:

 

-- Creamos la base de datos

create database passwords

on primary (name=principal,FILENAME='h:\passwords.mdf')

go

use passwords

go

-- Creamos la tabla para los usuarios

create table passwords (usuario varchar(20) primary key, password varchar(50) )

go

-- Insertamos 10000 usuarios/passwords

insert into passwords

values ('usuario'+convert(varchar(10),round(rand()*1000000,0)),'password'+convert(varchar(10),round(rand()*1000000,0)))

go 10000

 

Algunos de los usuarios y passwords generados son los siguientes:

 

usuario

password

usuario544967

password1348740

usuario551831

password4504970

usuario552164

password3493560

usuario554659

password339450

usuario565960

password8894330

usuario567180

password7293700

usuario581750

password9942780

usuario586427

password867145

usuario587682

password3238022

usuario594365

password6801912

 

Pasado un tiempo, la base de datos que contiene estos passwords es eliminada de nuestro servidor de base de datos:

-- Borramos la base de datos

drop database passwords

 

Un buen día un administrador curioso de nuestro SQL Server decide que esos datos de la base de datos borrada pueden tener aún algún valor para él y decide intentar aprovechar el lado oscuro de la inicialización instantánea de ficheros. Para ello creará una base de datos y examinará el fichero a nivel de página para intentar encontrar la información previamente borrada:

-- Creamos la base de datos para curiosear

create database curioseando

on primary (name=principal,FILENAME='h:\curioseando.mdf', size=2MB)

go

-- Seleccionamos la nueva base de datos

use curioseando

go

-- Desactivamos el volcado de las páginas al log de errores

DBCC TRACEON(3604)

go

 

-- Declaración de variables para el script

declare @cadenaexec nvarchar(100)

declare @i int

 

-- Iteramos por las páginas de nuestro fichero extrayendo la información sucia de disco

set @i=0

while (@i<2048/8)

begin

    set @cadenaexec = 'DBCC PAGE (''curioseando'',1,' + convert(nvarchar(5),@i) + ',2)'

    exec (@cadenaexec)

    set @i=@i+1

end

Tras ejecutar este script se obtendrá un volcado de todas las páginas del fichero mediante el comando no documentado DBCC PAGE. En este caso hemos creado un fichero para curiosear de 2MB por lo que el bucle while debe iterar hasta la página 256 (2048KB/8KB=256 páginas). Una vez tenemos el volcado simplemente una búsqueda por la palabra "password" o "usuario" encuentra lo siguiente en la página 154:

5C38C060: 00000400 0200fc02 001a0028 00757375 †...........(.usu

5C38C070: 6172696f 35343439 36377061 7373776f †ario544967passwo

5C38C080: 72643133 34383734 30000400 0200fc02 †rd1348740.......

5C38C090: 001a0028 00757375 6172696f 35353138 †...(.usuario5518

5C38C0A0: 33317061 7373776f 72643435 30343937 †31password450497

5C38C0B0: 30000400 0200fc02 001a0028 00757375 †0..........(.usu

5C38C0C0: 6172696f 35353231 36347061 7373776f †ario552164passwo

5C38C0D0: 72643334 39333536 30000400 0200fc02 †rd3493560.......

5C38C0E0: 001a0027 00757375 6172696f 35353436 †...'.usuario5546

5C38C0F0: 35397061 7373776f 72643333 39343530 †59password339450

5C38C100: 00040002 00fc0200 1a002800 75737561 †..........(.usua

5C38C110: 72696f35 36353936 30706173 73776f72 †rio565960passwor

5C38C120: 64383839 34333330 00040002 00fc0200 †d8894330........

5C38C130: 1a002800 75737561 72696f35 36373138 †..(.usuario56718

5C38C140: 30706173 73776f72 64373239 33373030 †0password7293700

5C38C150: 00040002 00fc0200 1a002800 75737561 †..........(.usua

5C38C160: 72696f35 38313735 30706173 73776f72 †rio581750passwor

5C38C170: 64393934 32373830 00040002 00fc0200 †d9942780........

Como conclusión de este resultado debemos tener siempre bien presentes las consecuencias de nuestras acciones. La inicialización instantánea nos permite acelerar la creación de ficheros, especialmente aquellos de gran tamaño, pero a su vez nos deja abierta la puerta a la lectura de los datos borrados previamente de nuestro disco duro.

Para asegurarnos que los datos de nuestra base de datos no pueden ser recuperados de esta forma podemos optar bien por la encriptación de los datos o bien por sobrescribir la información con caracteres aleatorios antes del borrado de la base de datos.

Comments

No Comments
Leave a Comment
(*) Title:
(*) Name:
Your URL:
(*) Comments:
Follow us on: