lunes, 5 de mayo de 2008

Cifrando los datos de un pendrive

Acostumbramos a llevar en nuestros pendrives información privada. El problema es que estos dispositivos tienen una tendencia especial a perderse :P.

Una posible solución es cifrar el sistema de ficheros del pendrive, desgraciadamente la mayoría los tenemos formateados en FAT y este sistema no admite cifrado.

Ningún problema para nosotros, si no admite cifrado el sistema de ficheros, pues nos hacemos un programa que lea el dispositivo en linux y lo cifre todo haciendo a los datos XOR con nuestra clave.

#include<stdio.h>

#define PENDRIVE "/dev/sdb1"
#define BUFFERSIZE 4096

int main(){
int i, j, leido, nBytes;
FILE *fichero;
int buffer[BUFFERSIZE];

fichero=fopen(PENDRIVE, "rw+");

//Hallar el tamanio del fichero
fseek(fichero, 0, SEEK_END);
nBytes=ftell(fichero);
fseek(fichero, 0, SEEK_SET);

//Leer,escribir y encriptar el fichero/dispositivo
for(i=0;i<nBytes;i+=BUFFERSIZE){
leido=fread(buffer, 1, BUFFERSIZE, fichero);
fseek(fichero, -leido, SEEK_CUR);

for(j=0;j<leido;j++) buffer[j]=buffer[j]^0x12345678;

fwrite(buffer, leido, 1, fichero);

if(i%(BUFFERSIZE*1000)==0){
printf("%.1f%\n",(i*100.0)/nBytes);
}
}

fclose(fichero);
}

En este caso la clave es 0x12345678 (en hexadecimal), y el dispositivo /dev/sdb1.
Sirve tanto para pendrives, disquetes, ficheros, todo en linux es un fichero.
Para desencriptarlo tan solo hay que volver a ejecutar el programa.

Si alguien intenta leer los datos del pendrive cuando están cifrados, simplemente parecerá que el pendrive no tiene formato ya que también se encripta la tabla FAT.

Evidentemente el algoritmo de encriptación se puede mejorar, tan solo es una idea.

sábado, 29 de diciembre de 2007

Primeros pasos con jQuery

jQuery es una librería de JavaScript, su principal utilidad es dar un acceso más claro y sencillo a los elementos de la web mediante la filosofía DOM.

La librería es muy sencilla de instalar, tan solo hay que ir a la web de jQuery, descargar la última versión, subirla al servidor web e incluirla en donde queráis usarla de la siguiente forma (como cualquier fichero javascript):

<script type="text/javascript" src="jquery.js"></script>

Casi todos los códigos que usen jQuery comenzarán así:

$(document).ready(inicializar);

¿Qué significa esa línea de código? "Cuando se descargue la página web por completo llama a la función 'inicializar'".

Esa función 'inicializar' será la que asignará cada evento a cada elemento del DOM de la página.
Para los ejemplos voy a utilizar una web con 6 botones y una caja de texto:

<html>
<title>Titulillo</title>
<h1>Prueba</h1>

<body>

<input type="button" id="boton1" value="click">
<input type="button" id="boton2" value="click">
<input type="button" id="boton3" value="click">
<input type="button" id="boton4" value="click">
<input type="button" id="boton5" value="click">
<input type="button" id="boton6" value="click">
<input type="text" id="text1" value="click">

</body></html>

La función 'inicializar' sería algo como lo que sigue:

function inicializar(){
$("input").click(BotonClick);
$("input").hover(
function() { $(this).addClass("blanco"); $(this).removeClass("rojo");},
function() { $(this).addClass("rojo"); $(this).removeClass("blanco"); }
);
}

Esta función asocia a todos los elementos "input" de la página el evento "click" con la función 'BotonClick', así que cada vez que hagamos click en un botón de la página o en la caja de texto se ejecutará esa función.

La segunda hace lo mismo con el evento "hover", pero en esta ocasión se le asocian dos funciones, la primera se ejecutará cuando el ratón pase por encima de un elemento "input" y la segunda cuando salga de su espacio.

Otra diferencia es que las funciones asociadas son anónimas (no se pueden llamar desde otro sitio).

¿Qué hacen esas funciones? El código de las dos es muy parecido, añaden al objeto la clase rojo y eliminan la clase blanca y viceversa.

¿Para qué? Asociando los objetos de la página mediante clases se pueden manipular de forma más sencilla, por ejemplo, en el caso anterior si la página tuviera el siguiente código css:

<style>

.blanco{
background-color:#ffffff;
}

.rojo{
background-color:#ff0000;
}

</style>

Los elementos "input" de la página cambiarían de rojo a blanco y de blanco a rojo al pasar por encima de ellos con el ratón.

Hay muchas posibilidades, otro ejemplo de lo que se puede hacer:

function BotonClick(){
$(this).hide();
}

El elemento en el que se haga click desaparecerá, gracias a cosas como esta se puede reconstruir la interfaz de una página dinámicamente.

viernes, 21 de diciembre de 2007

Enviar formularios con javascript

Normalmente, el código html para enviar un formulario es algo parecido al siguiente:
Introduzca su nombre:
<form action="index.php" method="get">
<input name="nombre" type="text">
<input value="Enviar" type="submit">
</form>

Pero puede darse el caso, de que en nuestra página nos interese enviar el formulario al hacer click en un enlace, eso se puede solucionar mediante javascript de la siguiente forma:

Introduzca su nombre:
<form action="index.php" name="formulario" method="GET">
<input type="text" name="nombre">
<a href=javascript:document["formulario"].submit();>Enviar</a>
</form>

Aunque funciona correctamente no queda demasiado bien que el usuario vea el código javascript al pasar por encima del enlace, se puede ocultar cambiandolo por lo siguiente:

Introduzca su nombre:
<form action="index.php" name="formulario" method="GET">
<input type="text" name="nombre">
<a href=# onclick=javascript:document["formulario"].submit();>Enviar</a>
</form>

Bueno, aunque todos los enlaces los he colocado entre las etiquetas form del formulario, pueden estar en cualquier otro sitio, por ejemplo:

Introduzca su nombre:
<form action="index.php" name="formulario" method="GET">
<input type="text" name="nombre">
</form>

<a href=# onclick=javascript:document["formulario"].submit();>Enviar</a>

Igualmente, he usado enlaces para colocar el código javascript, pero es indiferente, se puede colocar el código en cualquier elemento que soporte javascript.

jueves, 6 de diciembre de 2007

¿Como hashear contraseñas en perl?

Casi todas las aplicaciones web que hay en internet requieren registro, este registro consiste normalmente un nombre de usuario y una contraseña.

Para que la aplicación web nos pueda identificar la próxima vez que introduzcamos el usuario y contraseña es necesario que almacene estos datos de alguna forma (normalmente una base de datos).

El problema de este enfoque es que si se descubre una vulnerabilidad en la aplicación web que permita listar campos de la base de datos (por ejemplo, inyección SQL) el atacante podrá leer todos los nombres de usuario y contraseñas del sitio web.

Para solucionarlo en parte, una medida común es no guardar las contraseñas como tales en la base de datos, sino un dato derivado de la contraseña, por ejemplo, se puede pasar la contraseña a una función hash y guardar el resultado obtenido.

Para el proceso de autentificación, ahora no habrá que comparar la entrada del usuario con el valor que hay en la base de datos, sino el hash de la entrada del usuario con el valor de la base de datos, si estos resultados coinciden, la autentificación será correcta.

Eligiento como función hash MD5 y como lenguaje perl, el proceso para crear el hash de una cadena es muy sencillo.

#!/usr/bin/perl

use Digest::MD5 qw(md5 md5_hex md5_base64);

$hash1=md5("pass");
$hash2=md5_hex("pass");
$hash3=md5_base64("pass");

print $hash1 . "\n";
print $hash2 . "\n";
print $hash3 . "\n";

Como se puede ver, he usado tres formas distintas para la misma función hash, la primera (md5) da el resultado en binario, la segunda (md5_hex) en hexadecimal y la tercera (md5_base64) en base 64. Se puede elegir cualquiera de ellas.

martes, 11 de septiembre de 2007

Introducción a las herramientas de depuración de linux

En todos los sistemas operativos que merezcan ese nombre hay una serie de utilidades para depurar programas. Para comentar las de linux voy a basarme en el siguiente mini-programa.

#include <stdio.h>

int main(){
char cadena[1024];
printf("Introduce el pass: ");
scanf("%s", cadena);

if(!strcmp(cadena, "esteeselpass")) printf("Correcto\n");
else printf("Incorrecto\n");
}

Si compilamos ese fichero con gcc, obtendremos un ejecutable, yo le he llamado "prueba".

La primera utilidad es objdump, con ella se puede desensamblar ejecutables, bueno, eso y algunas cosas más.

objdump -d prueba > prueba.asm

Ahora en prueba.asm tenemos el fichero con el código desensamblado.

Intentemos averiguar el password del programa anterior, para ello hay que saber algo de ensamblador. Sabemos que en algún momento hay un salto condicional (je, jne, jz, jnz...) que es el que nos lleva a la situación de error, buscando estos saltos podemos ir rápido sobre el código y averiguar la zona en la que se produce la comprobación.

8048472:    e8 d9 fe ff ff           call   8048350 
8048477: 8d 85 f0 fb ff ff lea 0xfffffbf0(%ebp),%eax
804847d: 89 85 e0 fb ff ff mov %eax,0xfffffbe0(%ebp)
8048483: c7 85 dc fb ff ff e3 movl $0x80485e3,0xfffffbdc(%ebp)
804848a: 85 04 08
804848d: c7 85 d8 fb ff ff 0d movl $0xd,0xfffffbd8(%ebp)
8048494: 00 00 00
8048497: fc cld
8048498: 8b b5 e0 fb ff ff mov 0xfffffbe0(%ebp),%esi
804849e: 8b bd dc fb ff ff mov 0xfffffbdc(%ebp),%edi
80484a4: 8b 8d d8 fb ff ff mov 0xfffffbd8(%ebp),%ecx
80484aa: f3 a6 repz cmpsb %es:(%edi),%ds:(%esi)
80484ac: 0f 97 c2 seta %dl
80484af: 0f 92 c0 setb %al
80484b2: 89 d1 mov %edx,%ecx
80484b4: 28 c1 sub %al,%cl
80484b6: 89 c8 mov %ecx,%eax
80484b8: 0f be c0 movsbl %al,%eax
80484bb: 85 c0 test %eax,%eax
80484bd: 75 0e jne 80484cd
80484bf: c7 04 24 f0 85 04 08 movl $0x80485f0,(%esp)
80484c6: e8 b5 fe ff ff call 8048380
80484cb: eb 0c jmp 80484d9
80484cd: c7 04 24 f9 85 04 08 movl $0x80485f9,(%esp)
80484d4: e8 a7 fe ff ff call 8048380

En este código vemos que se hace un scanf, unas operaciones intermedias, luego hay un jne que nos lleva a un puts o a otro (salidas por pantalla diferentes según una condición).

Ahora que ya sabemos por que zona movernos, podemos usar gdb.

gdb es un debugger gnu para linux, ejecutamos:

gdb prueba

En el listado de arriba desensamblado se puede ver que la instrucción que hace la comparación de las cadenas introducida y correcta es la siguiente:

80484aa:    f3 a6                    repz cmpsb %es:(%edi),%ds:(%esi)

asi que dentro de gdb, ejecutamos:

break *0x80484aa

Con lo que la ejecución se parará justo en esa instrucción, ejecutamos:

run

info registers

Obtenemos el valor de edi y esi, en mi caso 0x80485e3 y 0xbf86a3d8, inspeccionamos lo que hay en esas direcciones de memoria:

x/s 0x80485e3
x/s 0xbf86a3d8

Nos aparecen el pass que hemos introducido, y el ¡correcto!

Hay otra forma de conseguir que el programa nos de "su aprobación":

80484bb:    85 c0                    test   %eax,%eax
80484bd: 75 0e jne 80484cd

Vamos a la instrucción justo anterior a la del salto, el test (0x80484bb) ponemos un breakpoint ahí, si ejecutamos:

info registers

Vemos que eax vale 1, asi que la condición nos llevará al error, pero vamos ha hacer lo siguiente:

set $eax=0

Después pulsamos la 'c' para continuar...y obtenemos el mensaje que queríamos obtener aún habiendo introducido mal la contraseña.

martes, 21 de agosto de 2007

Programación orientada a objetos sencilla y elegante

La mayoría de los programadores cuando piensan en programación orientada a objetos piensa en java o c++, pero hay muchos lenguajes que implementan esta técnica y algunos mucho mejor que en c++ y java.

Me ha llamado la atención python, para mí uno de los mejores lenguajes para aprender orientación a objetos, más que nada, por su sencillez.

¿Qué hay que hacer para definir una clase en python?
Imaginemos que queremos definir una clase llamada pareja que tiene dos atributos, con una única operación, sumarlos.

class pareja:
def __init__(self, a=0, b=0):
self.a=a
self.b=b
def sumar(self):
return self.a+self.b

Simplemente eso, __init__ siempre es el constructor, y tal y como lo he definido se pueden crear objetos así:

p=pareja(2,3)

O así:

p=pareja()

O incluso así:

p=pareja(b=2)

Añadiendo un parámetro más, ¡se puede tener el constructor por defecto, por parámetros y por copia con un mismo método y así de simple!

Otro aspecto son los iteradores, tanto en java como c++, cuando quieres recorrer un array, con un iterador, hay que declarar el iterador indicando su tipo, crear un bloque for que vaya desde it.begin hasta it.end, etc...

En python esto es mucho más fácil, ¿como se recorre un array de objetos?

for i in array:
print i

Da igual si el array es de números, de listas, de objetos complejos, o incluso si el array es una cadena de carácteres.

Una última cosa, normalmente hay que pelearse con las bases de datos para ir guardando los objetos, vamos, para que sean persistentes. En python esto no es problema, simplemente haciendo:

pickle.dump(objeto, fichero)

Se guarda el objeto en el fichero, y haciendo:

objeto=pickle.load(fichero)

Se carga el objeto desde el fichero, sin más complicaciones.

jueves, 9 de agosto de 2007

Aprendiendo AJAX desde cero

AJAX es una tecnología usada para la web, permite la carga asíncrona de contenidos. Los que no sepais que es os pongo un ejemplo muy sencillo.

Si entráis a hotmail (no windows live), y queréis leer un mensaje, hacéis click en el enlace y tenéis que esperar a que cargue la nueva página. En gmail, por el contrario, pincháis en el mensaje que quereis leer y se despliega, no hace falta esperar a que cargue de nuevo toda la página.
El segundo método de carga usa AJAX, mientras que el primero es una petición al servidor de las de toda la vida.

AJAX no es nada por si mismo, es la unión de javascript, el objeto XMLHttpRequest y XML.

La arquitectura de una aplicación AJAX es la siguiente, se tiene un programa en javascript en el cliente, y este, mediante el objeto XMLHttpRequest se comunica con el servidor según convenga mostrando directamente el resultado en el cliente. No es necesario recargar la página, lo que se hace es ir cambiando el contenido dinámicamente sobre la misma página.

Cuando digo que se comunica con el servidor puede ser tanto desplegar una opción, como cambiar el texto de toda la página o mandar una petición al servidor para darnos de alta, cualquier cosa.

¿Cómo se crea el programa en javascript para poder comunicarse con el servidor? Pues lo primero es un método casi estándard, la creación del objeto XMLHttpRequest de la siguiente forma:

if(window.XMLHttpRequest) { obj=new XMLHttpRequest(); }
else {
try { obj=new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { alert('El navegador no tiene el objeto XMLHttpRequest'); }
}

Después, para hacer las peticiones hay que usar un código como el siguiente:

obj.open('GET', 'registro.txt');
obj.onreadystatechange = tratarTexto ;
obj.send('');

Creado el objeto, mandamos (por el método GET) una petición al servidor del fichero registro.txt, cuando cambie el estado del objeto XMLHttpRequest se llamará a la función 'tratarTexto'. Esta función puede ser algo como lo siguiente:

if(obj.readyState==4){
respuesta=obj.responseText;
zonaRegistro=document.getElementById(zonaRegistro);
zonaRegistro.innerHTML=respuesta;
}

El estado 4 es el estado en el que la petición ha finalizado correctamente, en la documentación se pueden consultar los demás estados por si son necesarios.
Obtenemos el objeto que apunta al elemento de la página 'zonaRegistro' y lo rellenamos con la respuesta que hemos obtenido en el servidor.

Para terminar, supongamos que el registro que estábamos manejando arriba viene de un formulario, en lugar de mandarlo a un script en perl (por ejemplo) lo que hacemos es mandar una petición a dicho script mediante el objeto XMLHttpRequest. Por ejemplo:

<form name="formulario" action="javascript:peticionAJAX('script.pl', parametros);">

De esa forma podemos hacer una petición de registro al servidor mediante el script 'script.pl' y que cuando este termine y nos deje la información en 'registro.txt' devolvérsela al cliente, todo eso sin tener que recargar la página.

En este caso nos hemos comunicado con el servidor recibiendo tan solo texto, pero también se puede entregar el texto formateado en XML, es un poco más complejo, pero tampoco demasiado.