CommandsStyle

miércoles, 29 de noviembre de 2017

Un nmap para listarlos a todos, un nmap para analizar sus puertos y obtener información

Hoy vamos a hablar de nmap. Una herramienta de la que se ha hablado mucho, pero de la que en muchos casos no se saca todo el jugo que puede dar.

Un nmap para listarlos a todos, un nmap para analizar sus puertos y obtener información
Un nmap para listarlos a todos, un nmap para analizar sus puertos y obtener información


El uso más común de nmap es de listar puertos abiertos en un equipo, pero esta herramienta permite hacer muchas más cosas.

Permite descubrir los equipos conectados a una red, permite ver las versiones de los servicios que escuchan ciertos puertos... etc.

Este post no pretende ser un manual completo de nmap, para ello, existe su documentación oficial que puedes encontrar aquí o en su versión en español aquí

Para realizar todas las pruebas de este post, voy a utilizar kali linux, ya que trae instalada la herramienta nmap lo cual nos ahorra un poquito de trabajo :)

Lo primero que tenemos que hacer es ver en qué red nos encontramos conectados, ya que es sobre esta red sobre la que vamos a trabajar.

Para ver en qué red nos encontramos, utilizaremos el comando:

ifconfig

Una vez hemos obtenido nuestra IP (y por tanto ya conocemos la red a la que nos encontramos conectados), podemos empezar a trabajar con nmap.
En este caso, los ejemplos que pondremos utilizaran la red 192.168.37.0/24


Listado de equipos de una red

Nmap nos permite descubrir los equipos que hay conectados a una red. Para ello podemos utilizar varios comandos:


Resolución DNS inversa

La opción más silenciosa para los equipos de la red, es la opción -sL ya que permite hacer una resolución DNS inversa de las IPs del rango dado.

Es importante marcar que es la opción más silenciosa para los equipos de la red, ya que esta opción no envía información a dichos equipos, pero sin embargo, envía peticiones al servidor DNS de la red para intentar hacer la resolución inversa. Con lo que este servidor sí que recibe tráfico de nuestro escaneo.

El comando a utilizar seria el siguiente:

nmap 192.168.37.0/24 -sL

Hay que tener en cuenta, que esta opción en algunas redes no nos dará resultados, ya que puede que no contemos con equipos dados de alta en el servidor DNS, pero sigue siendo una opción a tener en cuenta.


Barrido ping o ping sweep

La opción -sP  realiza un descubrimiento mediante el uso de paquetes ICMP. Este modo es conocido también como barrido ping.
Para descubrir equipos, este modo envía paquetes a todas las direcciones IPs de la red que indiquemos a nmap, por lo que es un análisis más intrusivo que en el caso anterior. El comando a utilizar para este tipo de descubrimiento de equipos en la red es el siguiente:

nmap 192.168.37.0/24 -sP


Ping ARP

En ocasiones, las maquinas están configuradas para no responder a los paquetes ICMP o no están dadas de alta en el servidor DNS, lo que no nos permite realizar una resolución DNS inversa. En estos casos, podemos intentar realizar un Ping ARP.

El funcionamiento de este modo de ping, se basa en el funcionamiento del protocolo ARP.
Para explicarlo de forma simplificada, Nmap realiza una petición ARP para cada una de las IPs del rango.

Cuando una de esas IPs está siendo usada, el equipo que tiene esa dirección IP contesta con la dirección MAC y por lo tanto, nmap detecta que hay un equipo en la red utilizando dicha IP.

Para hacer uso de este tipo de descubrimiento de equipos en la red, el comando a utilizar es el siguiente:

nmap 192.168.37.0/24 -PR -sn

La opción -sn indica que no realice un escaneo de puertos, ya que por defecto la opción -PR sí que la realiza.


Listado de puertos abiertos de un equipo

Una vez que hemos conseguido saber los equipos que están conectados a una red, podemos obtener información sobre los puertos que están escuchando.
Existen varios métodos para saber los puertos que está escuchando una máquina. A continuación hablaremos sobre algunos de ellos.

En los ejemplos que vamos a indicar a continuación, vamos a suponer que la dirección de la máquina de la que deseamos obtener información es 192.168.37.129


Escaneo TCP SYN

El escaneo TCP SYN es un escaneo relativamente sigiloso, ya que no llega a completar las conexiones del protocolo TCP, pero sí que envía paquetes al objetivo.
En este escaneo, nmap únicamente inicia una conexión TCP mediante el envío de un paquete SYN a un puerto concreto y queda a la espera de recibir una respuesta.
En caso de que nmap reciba una respuesta SYN-ACK, nmap detecta que el puerto está abierto y no envía más paquetes haciendo uso de ese puerto, de modo que la conexión TCP queda a medio establecer. Pero se ha detectado si el puerto está abierto o no.

El comando para utilizar este tipo de escaneo es el siguiente:

nmap -sS 192.168.37.129


Escaneo TCP Connect

Al contrario de lo que ocurre con el escaneo TCP SYN, el escaneo TCP Connect sí que establece una conexión TCP con la maquina objetivo.

Este escaneo es un poco más ruidoso que el anterior por el simple hecho de que la conexión termina por establecerse.

El comando para utilizar este tipo de escaneo es el siguiente:

nmap -sT 192.168.37.129


Otros escaneos TCP

Existen otros métodos para determinar si un puerto está abierto o cerrado.  Estos escaneos son menos utilizados normalmente, pero conviene conocerlos.

Según el protocolo TCP, si un paquete que se envía a un puerto no contiene los bits SYN, RST o ACK, se responderá con un RST si el puerto está cerrado. En caso de que el puerto este abierto, no se responderá nada.


Escaneo Null

Este escaneo no activa ningún bit en las cabeceras TCP.
El comando para utilizar este tipo de escaneo es:

nmap -sN 192.168.37.129


Escaneo FIN

Este escaneo activa el bit FIN de la cabecera TCP.
El comando para utilizar este tipo de escaneo es:

nmap -sF 192.168.37.129


Escaneo Xmas

Este escaneo activa los bits FIN, PSH y URG.
El comando para utilizar este tipo de escaneo es:

nmap -sX 192.168.37.129


Escaneo de puertos UDP

Al igual que los puertos TCP, nmap también nos permite realizar escaneo de los puertos del protocolo UDP que está escuchando una máquina.
Para determinar si un puerto UDP se encuentra abierto o cerrado, nmap envía una cabecera UDP a un puerto.
Solo si se obtiene una respuesta a dicha cabecera, se marca el puerto como abierto. En otros casos, se marca el puerto como cerrado o como filtrado en función de la respuesta obtenida.

El comando para utilizar el escaneo de puertos UDP es el siguiente:

nmap -sU 192.168.37.129


Escaneo de versiones de servicios a la escucha

En ocasiones, nmap puede intentar obtener información sobre las versiones de los servicios que están a la escucha en los puertos abiertos.
Para habilitar esta opción, utilizaremos -sV. Esta opción se puede utilizar conjuntamente con los escaneos vistos anteriormente, de forma que podemos lanzarla con comandos similares al siguiente:

nmap -sS -sV 192.168.37.129


Escaneo de sistema operativo

Nmap ofrece la posibilidad de mostrar (Siempre que sea posible) el sistema operativo de la máquina que estamos analizando.
Para habilitar esta opción, utilizaremos la opción -O. Esta opción se puede utilizar conjuntamente con los escaneos vistos anteriormente, de forma que podemos lanzarla con comandos similares al siguiente:

nmap -sS -sV -O 192.168.37.129


Establecer rango de puertos escaneados

Nmap nos ofrece la posibilidad de escanear cualquier rango de puertos. Por defecto analiza 1000, pero le podemos indicar que analice cualquier rango con la opción -p.
Por ejemplo, si queremos realizar un escaneo de todos los puertos (del 1 al 65535) utilizaremos el siguiente comando:

nmap -sS -sV 192.168.37.129 -p 1-65535


Scripts de nmap

Una opción muy interesante de nmap es el uso de scripts para la detección de malas configuraciones, vulnerabilidades conocidas... etc.

Para utilizar estos scripts, se utiliza la opción --script seguido de una de las siguientes opciones:

• auth
Ejecuta scripts que detectan posibles contraseñas débiles, usuarios y contraseñas por defecto... etc.
• Discovery
Estos scripts nos intentan ofrecer mayor nivel de detalle del equipo objetivo. Intentan descubrir información sobre la red, información sobre los dispositivos con SNMP activos, servicios o directorios expuestos... etc.
• Intrusive
Utiliza scripts intrusivos. El uso de estos scripts puede llegar a causar un mal funcionamiento de la maquina objetivo. Hay que usar esta opción con mucho cuidado amigos :)
• Malware
Utiliza scripts que ayudan a detectar si el objetivo está infectado por malware o si tiene alguna puerta trasera instalada.
• Safe
Utiliza scripts que están catalogados como seguros. Estos scripts no suelen causar un mal funcionamiento de la maquina objetivo y ofrecen información que puede sernos de utilidad.
• Vuln
Utiliza scripts que comprueban vulnerabilidades conocidas. En caso de encontrar alguna, nos muestra el resultado.

Un ejemplo del uso de --script es el siguiente comando:

nmap -sS -sV -O 192.168.37.129 --script auth

Con todo esto, ya le hemos dado un buen repaso a nmap y a sus opciones. Espero que os haya gustado y que os sea de utilidad.

Hasta el próximo post! :)

martes, 26 de septiembre de 2017

Crea tu diccionario personalizado

Hoy vamos a ver cómo podemos generar un diccionario.
Este diccionario nos puede servir para intentar averiguar la contraseña de un usuario (para averiguar un nombre de usuario, o para lo que se nos ocurra que pueda sernos útil un diccionario) sin probar todas las posibles combinaciones.

Diccionario


Hay que tener en cuenta, que con un diccionario no nos aseguramos encontrar el dato que buscamos, en este caso una contraseña, sino que probaremos un conjunto de datos que puede contener el dato que estamos buscando.

También podemos hacer un diccionario con todas las combinaciones para hacer un ataque por fuerza bruta “clásico”con el cual si que nos aseguramos de encontrar el dato que estamos buscando, al fin y al cabo estamos probando todos los datos posibles.

Nos vamos a centrar en la creación de un diccionario de contraseñas, pero siguiendo la misma lógica, podríamos crear diccionario de usuarios o de cualquier otra cosa que necesitemos.

Lo primero que tenemos que hacer es investigar nuestro objetivo. Y como vamos a genera un diccionario de contraseñas, tenemos que investigar tanto al sistema como al usuario.

Respecto al sistema,  algunas de las preguntas que tenemos que responder son:

  • ¿Qué longitud de contraseña mínima permite el sistema?
  • ¿Qué longitud de contraseña máxima permite el sistema?
  • ¿Qué caracteres permite introducir el sistema?
  • ¿El sistema obliga a la utilización de algún carácter especial?
  • ¿El sistema obliga a la utilización de mayúsculas y números?
  • ...

Es decir, tenemos que averiguar que cuales son los requisitos de contraseña del sistema para no generar entradas en el diccionario que no sean válidas para el sistema.

Una vez hecho esto, tenemos que estudiar a nuestro usuario objetivo.

  • Nombre y apellidos
  • Fecha de nacimiento
  • Nombre de los hijos
  • Fecha de nacimiento de los hijos
  • Nombre de sus mascotas
  • Nombre y apellidos de su pareja y/o amigos
  • Series de televisión y película favorita
  • Empresa en la que trabaja

Toda la información que podamos adquirir de nuestro objetivo es bienvenida. Para esto podemos ponernos creativos, pero un clásico es utilizar las redes sociales ;)

¿Para qué queremos toda esta información?
Para responder a esta pregunta, primero hay que pensar que las contraseñas tienen que ser datos fácilmente recordables, y para el usuario común lo más fácil de recordar es todo lo que le rodea en su vida cotidiana (es decir, los datos que hemos visto anteriormente).

Un detalle importante aquí, es que debido a los requisitos de complejidad de contraseña de los sistemas, los usuarios tienden a añadir una mayúscula, o un numero a los datos que conocen.

Por ejemplo, si un usuario tiene un perro que se llama “fuego”, y el sistema requiere que la contraseña tenga un número, una posible modificación seria “fu3go”.
Siguiendo esta lógica, las modificaciones mas comunes son:

  • Cambiar:
    • “a” por “4”
    • “a” por “@”
    • “e” por “3”
    • “s” por “$”
    • “o” por “0”
    • “1” por “1”
    • “t” por “7”
  • Eliminar las vocales de las palabras.
  • Añadir el año de nacimiento al final de una palabra

Todo esto sin descuidar que puede utilizar uno de los datos anteriores sin modificar, ya que puede que cumpla los requisitos del sistema.

Una vez vista la teoría, vamos a hacer un diccionario. Para ello, utilizaremos el sistema operativo Kali, ya que trae instaladas y configuradas las herramientas “crunch” y “John the ripper”, que son las que vamos a utilizar.

Para este ejemplo, vamos a suponer que los datos de nuestro usuario son:
Nombre: Juan
Apellidos: Informatico Averno
Empresa en la que trabaja: AvernizateSA
Fecha de nacimiento:13-1-1950

Y que los requisitos de las contraseñas del sistema son:
  • Longitud de 8 caracteres como minimo
  • Al menos un numero


Es un programa que nos permite generar un diccionario en función de unas especificaciones que le indiquemos.

Es decir, podemos pedir que nos genere un diccionario con las letras "a", "b" y "c" y los números "1","2" y "3". y que las palabras que nos genere tengan una longitud comprendida entre 8 y 9 caracteres.

crunch 8 9 abc123 > diccionarioFuerzaBruta.txt

El diccionario generado contendrá entre otras las siguientes entradas:

aaaaaaa2
aaaaaaa3
aaaaaaba
aaaaaabb
aaaaaabc
aaaaaab1
aaaaaab2
aaaaaab3
aaaaaaca
aaaaaacb
aaaaaacc
aaaaaac1
aaaaaac2
aaaaaac3
aaaaaa1a
aaaaaa1b


Otra opción es utilizar los patrones de caracteres, de forma que nos inserte automáticamente todas las mayúsculas, todas las minúsculas todos los números o todos los símbolos en una posición determinada.

Teniendo en cuenta que los patrones se definen con las siguiente nomenclatura:
  • "@" = Letra minúscula
  • "," = Letra mayúscula
  • "%" = Número
  • "^" = Símbolo
Podemos crear patrones del tipo:

crunch 8 8 -t @@@@,%%^ > diccionarioFuerzaBruta2.txt

Si sabemos que la contraseña del usuario empieza por ejemplo por "AV", podemos generar un diccionario que contenga todas las entradas que empiecen por "AV".

crunch 8 8 -t AV@@,%%^ > diccionarioFuerzaBruta2.txt


NOTA: Hay que tener en cuenta, que el patrón que propongamos, tiene que ser de la misma longitud máxima y mínima que indiquemos en los primeros parámetros.

Cambien podemos hacer que crunch nos genere un diccionario realizando una concatenación de palabras formando todas las permutaciones posibles entre ellas. Esto se haría mediante el comando:

crunch 1 1 -p Juan Informatico Averno AvernizateSA 1950 > diccionario.txt

NOTA: Hay que tener en cuenta que la longitud que utilicemos sea 1 como máxima y mínima.

El diccionario generado contendra entre otras, las siguientes entradas:
JuanInformaticoAvernizateSA1950Averno
JuanInformaticoAvernizateSAAverno1950
JuanInformaticoAverno1950AvernizateSA
JuanInformaticoAvernoAvernizateSA1950

John the ripper es una herramienta que entre otras cosas que ahora no vienen al caso ;) nos permite realizar modificaciones a un diccionario de forma que sea mucho mas completo.

Podemos tomar como partida un diccionario creado con crunch, o con cualquier otra herramienta, o un diccionario que creemos "a mano".

Las modificaciones que John The Ripper aplicara al diccionario original, están definidas en el fichero /etc/john/john.conf
En concreto están justo después de la linea 
[List.Rules:Wordlist]

Aquí podemos añadir nosotros nuestras propias reglas, como pueden ser:

#Cambiar “A” por “4”
/AsA4[:c]
#Cambiar “a” por “4”
/asa4[:c]
#Cambiar “A” por “@”
/AsA@[:c]
#Cambiar “a” por “@”
/asa@[:c]
#Cambiar “E” por “3”
/EsE3[:c]
#Cambiar “e” por “3”
/ese3[:c]
#Cambiar “S” por “$”
/SsS$[:c]
#Cambiar “s” por “$”
/sss$[:c]
#Cambiar “S” por “5”
/SsS5[:c]
#Cambiar “s” por “5”
/sss5[:c]
#Cambiar “A” por “@” y “E” por “3”
/AsA@/EsE3[:c]
#Cambiar “a” por “@” y “e” por “3”
/asa@/ese3[:c]
#Cambiar “A” por “@” y “e” por “3”
/AsA@/ese3[:c]
#Cambiar “a” por “@” y “E” por “3”
/asa@/EsE3[:c]


Estos son algunos ejemplos, pero podríamos generar tantas reglas como necesitemos en función de lo completo que queramos que sea nuestro diccionario.

Para utilizar a John The Ripper para mejorar nuestros diccionarios por medio de las reglas que tengamos definidas, haremos uso del comando 

john --stdout --wordlist=diccionario.txt --rules > diccionarioCompleto.txt 

Si introducimos el diccionario que hemos generado en el ejemplo del comando crunch, el resultado tendrá entre otras, las siguientes entradas:

Ju@nInform@tico@verniz@teS@1950@verno
Ju@nInform@tico@verniz@teS@@verno1950
Ju@nInform@tico@verno1950@verniz@teS@
Ju@nInform@tico@verno@verniz@teS@1950

Por ultimo, en ocasiones puede que se generen diccionarios con entradas duplicadas, para eliminar las entradas duplicadas de un diccionario, podemos hacer uso del comando:

cat diccionario.txt | sort | uniq > diccionarioSinDuplicados.txt

Pues con esta entrada ya sabemos como generar un diccionario y como hacerle mas o menos completo en función de nuestras necesidades. Proximamente veremos como utilizar nuestro diccionario.

Hasta la siguiente! ;)

miércoles, 12 de julio de 2017

¿Tus contraseñas van al gimnasio?

¡Hola de nuevo, visitante del averno!

En el post de hoy vamos a ver como de fuerte es una contraseña.

Contraseña fuerte
Contraseña fuerte
Una contraseña fuerte es una contraseña que para adivinarse utilizando todas las combinaciones posibles se tarde tanto tiempo que no sea algo que se pueda plantear por términos de coste temporal.

O lo que es lo mismo, que tengamos que utilizar un algoritmo de fuerza bruta que utilice todas las combinaciones de caracteres permitidos para conseguir averiguar la contraseña y que al tener que probar muchas contraseñas, se tarde demasiado y no sea algo factible.

Con esto en la cabeza, vamos a empezar a hacer cálculos:

Supongamos que utilizamos el alfabeto español, que consta de 27 letras o caracteres (a, b, c, d, e, f, g, h, i, j, k, l, m, n, ñ, o, p, q, r, s, t, u, v, w, x, y, z)

Si utilizando únicamente el alfabeto español creamos una contraseña de 4 caracteres de largo (Como puede ser la palabra “hola”), el número de contraseñas posibles con este número de símbolos y con una longitud de 4 caracteres, es el siguiente:

27*27*27*27 = 27^4 = 531.441

531.441 puede parecernos un numero de contraseñas muy alto, pero un ordenador puede probar miles de contraseñas en unas horas.

Ahora bien, todo el mundo sabe que las letras pueden ser mayúsculas y minúsculas.

Si utilizamos el alfabeto español, con las letras mayúsculas y minúsculas, entonces el alfabeto que utilizamos para generar las contraseñas consta de 54 símbolos (a, b, c, d, e, f, g, h, i, j, k, l, m, n, ñ, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, Ñ, O, P, Q, R, S, T, U, V, W, X, Y, Z)

Ahora supongamos que creamos una contraseña de 4 caracteres de largo, como en el caso anterior, pero en este caso utilizamos las letras mayúsculas y creamos una contraseña (Como puede ser la palabra “Hola”).

Si un atacante quiere averiguar nuestra contraseña, necesitara probar todas las letras mayúsculas, y todas las letras minúsculas.

Como la longitud de la contraseña es 4, el número de posibles contraseñas con las mayúsculas y minúsculas de longitud 4 es:

54*54*54*54 = 54^4 = 8.503.056

Como vemos, añadiendo las mayúsculas, la contraseña se vuelve mucho más complicada de averiguar utilizando fuerza bruta. Pero… no vamos a quedarnos aquí.
Queremos una contraseña más robusta todavía, así que además de las letras mayúsculas y minúsculas, vamos a introducir los números.

Si introducimos los números, el número de símbolos con el que podemos crear la contraseña será de 64 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, ñ, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, Ñ, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9).

Utilizando este alfabeto de 64 símbolos, vamos a crear una contraseña de 4 caracteres de longitud (Por ejemplo “Hol4”).

El número de posibles contraseñas de 4 caracteres de longitud y 64 posibles símbolos asciende a:

64*64*64*64 = 64^4 = 16.777.216

El número de posibles contraseñas ha crecido un poco respecto al caso anterior, pero… ¡todavía se puede mejorar!

Vamos a introducir caracteres no alfanuméricos al alfabeto con el que generamos las contraseñas, en este caso vamos a añadir los caracteres “ !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, ~ ” lo que suma un total de 33 caracteres (Si no me equivoco :P).

Si sumamos estos 33 caracteres al alfabeto que teníamos anteriormente, obtenemos un alfabeto de 97 símbolos (a, b, c, d, e, f, g, h, i, j, k, l, m, n, ñ, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, Ñ, O, P, Q, R, S, T, U, V, W, X, Y, Z, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, ~).

Con este alfabeto de 97 símbolos, vamos a crear una contraseña de 4 caracteres de longitud igual que en los casos anteriores. (Por ejemplo “Ho!4”).

El número de posibles contraseñas de 4 caracteres de longitud y 97 posibles símbolos asciende a:

97*97*97*97 = 97^4 = 88.529.281

Ahora podemos decir que tenemos un alfabeto completito, pero… 88.529.281 posibles contraseñas… todavía son “pocas”.

Para mejorar la complejidad de la contraseña llegado este punto, lo único que podemos hacer el aumentar su longitud.

Vamos a suponer una contraseña de 8 caracteres de longitud, utilizando el alfabeto de 97 símbolos que hemos visto anteriormente.(Esto es, una contraseña como puede ser “3l@verNo”)

El número de posibles contraseñas de 8 caracteres de longitud utilizando 97 símbolos es de:

97*97*97*97*97*97*97*97 =  97^8 = 7.837.433.594.376.961

¡Este número ya está mucho mejor!

Pero hay veces que queremos proteger cuentas de administrador o información utilizando una contraseña aún más fuerte, así que vamos a ver cuántas posibles contraseñas hay con una longitud de 16 caracteres y un alfabeto de 97 símbolos. (Una contraseña como por ejemplo “1nf0rm@ticoAvern”).

97*97*97*97*97*97*97*97*97*97*97*97*97*97*97*97 = 97^16 = 61.425.365.346.268.570.446.197.767.595.521

Con 61.425.365.346.268.570.446.197.767.595.521 posibles contraseñas seguro que a nadie se le ocurre hacer una fuerza bruta probándolas todas para robarte la contraseña.

Por otro lado, es frecuente que las aplicaciones o sistemas operativos te obliguen a utilizar una longitud mínima en las contraseñas, con lo que hay combinaciones que no hay que probar en un ataque de fuerza bruta.

Por ejemplo, si un sistema nos pide una longitud mínima de 8 caracteres, un atacante nunca probara las contraseñas que tengan de 1 a 7 caracteres de longitud.

Es por ello que partiendo del ejemplo anterior, en el que planteábamos que el número de posibles contraseñas de 8 caracteres de longitud utilizando 97 símbolos era de 7.837.433.594.376.961, un atacante no probara todas ellas, ya que las que miden de 1 a 7 caracteres no las probara.

Entonces tenemos que no probara las contraseñas de 1 carácter de longitud, es decir, no probara las primeras 97 contraseñas.

Tampoco probara las de 2 caracteres de longitud, es decir:

97*97 = 97^2 = 9.409

Y así sucesivamente hasta las de 7 caracteres.

Si queremos calcular el número de contraseñas que no probara un atacante lo haremos de la siguiente manera:

97 + (97^2) + (97^3) + (97^4) + (97^5) + (97^6) + (97^7) = 81.639.933.274.759

Como podemos ver, no probara 81.639.933.274.759


Una vez visto todos los cálculos, podemos concluir que una contraseña fuerte, hace los ataques de fuerza bruta sean totalmente inviables.

Es por ello por lo que se suelen utilizar diccionarios con un número limitado de contraseñas para probar.



Espero que os haya gustado el post y que ahora seleccionéis contraseñas más seguras para protegeros.

miércoles, 5 de julio de 2017

Y tú… ¿firmas y/o cifras?

Hoy vamos a tratar el tema de la de criptografía asimétrica. Hoy he elegido este tema, ya que en futuros post vamos a tratar temas que se apoyaran en lo que veremos a continuación.

Y tú… ¿firmas y/o cifras?
Y tú… ¿firmas y/o cifras?


AVISO: Lo que vamos a encontrarnos a continuación, es una super-simplificación para explicar el funcionamiento del firmado y el cifrado de información. Es una simplificación, porque es un post para que se entienda la lógica del funcionamiento que siguen estos procesos, pero no voy a entrar en el funcionamiento a bajo nivel.

Para entender la criptografía asimétrica, también llamada criptografía de clave pública, hay que tener clara una cosa. Las claves van a estar formadas por dos “partes” o dos claves, que son una clave pública y una clave privada.

Aquí es muy importante saber que la clave pública podemos distribuirla libremente, como su propio nombre indica, es pública.

No es así con la clave privada. Esta clave tenemos que guardarla celosamente y no debemos compartirla.

Para entender el funcionamiento, vamos a poner un ejemplo con 3 sujetos ficticios: Juan, María y Pedro.

Las claves de estos 3 individuos son las que vemos a continuación:

Juan
Clave PrivadaClave Pública
Jcpv394867Jcp928347

María
Clave PrivadaClave Pública
Mcpv92783Mcp823375

Pedro
Clave PrivadaClave Pública
Pcpv02837Pcp982374

Estas claves no las vamos a poder elegir nosotros, normalmente haremos uso de algún proceso que nos proporcione cada par de claves.

Haciendo uso de la criptografía de clave pública, comúnmente vamos a poder realizar dos operaciones: firmar y cifrar.

Supongamos ahora que nuestros tres sujetos, han intercambiado sus claves, de forma que ahora tienen un “almacén de claves” donde van a guardar las claves que se han ido intercambiando.

Juan
Clave Privada
Clave Pública
Jcpv394867Jcp928347
Almacén de claves
Clave Publica De María (CPM)Mcp823375

María
Clave Privada
Clave Pública
Mcpv92783Mcp823375
Almacén de claves
Clave Publica De Pedro (CPP)Pcp982374
Clave Publica De Juan (CPJ)Jcp928347

Pedro
Clave Privada
Clave Pública
Pcpv02837Pcp982374
Almacén de claves
Clave Publica De María (CPM)Mcp823375

Ahora que ya conocemos las dos partes de una clave (La pública y la privada) y que hemos visto que las claves publicas hay que compartirlas, vamos a explicar cómo funciona el proceso de firmado y de cifrado.

La firma
El proceso de firmado se realiza utilizando la clave privada. Cuando firmamos un fichero, siempre, siempre, SIEMPRE vamos a utilizar la clave privada.

El resultado de un proceso de firma es propiamente una “firma digital”.

Hay que tener en cuenta que, para realizar una firma, se utilizan todos los bits de un fichero, por lo que si firmamos un fichero y más tarde lo modificamos, tendremos que realizar de nuevo el proceso de firmado para obtener una firma válida para el fichero modificado.

Vale y… ¿Para qué nos sirve una firma digital?

Haciendo uso de la clave pública correspondiente a la clave privada con la que se firmó el fichero, podemos verificar si la firma es correcta o no lo es.

Además, como únicamente se puede firmar haciendo uso de la clave privada, podemos verificar la identidad del firmante.

Veamos un ejemplo:
Supongamos que Juan firma un fichero, el proceso de firma vamos a representarlo de la siguiente manera:

Firma (fichero, CPVJ) = opasuiisjfahwoi

Como podemos ver, el resultado de la firma del fichero de Juan, haciendo uso de su clave privada, es “opasuiisjfahwoi”. El resultado de una firma es un conjunto de caracteres que sirve para verificar quien ha firmado el fichero, y si ha sido modificado a posteriori de realizar la firma.

Ahora supongamos que Juan, envía el fichero y la firma del fichero a María y Pedro.

Para verificar la firma, es necesaria la clave pública de Juan, por lo que… el pobre Pedro no podrá verificar si la firma es válida, ya que no tiene la clave pública de Juan.

Sin embargo, María sí que tiene la clave pública de Juan, por lo que, haciendo uso de la clave pública de Juan, el fichero y la firma del fichero, podrá verificar si la firma es válida o no, es decir, podrá verificar si el fichero realmente lo ha firmado Juan, y si el fichero no ha sufrido modificaciones después de que Juan lo firmara.

El proceso de verificación de firma, vamos a representarlo de la siguiente manera:

Verificación (fichero,firma, CPJ) = VALIDO

Como el fichero no ha sido modificado, la firma es la que ha realizado Juan, y la clave pública utilizada en la verificación es la de Juan, el proceso dará como resultado que la firma es válida.

En caso de que el fichero estuviese modificado, vamos a llamarlo fichero1, el resultado sería el siguiente:

Verificación (fichero1, firma, CPJ) = INVALIDO

Si por un casual, María se confunde, e intenta verificar el fichero original con la clave pública de Pedro, el resultado sería:

Verificación (fichero, firma, CPP) = INVALIDO

Ni que decir tiene que, si el fichero ha sido modificado, y la clave pública que se utiliza no es correcta, la verificación dará como resultado “invalido”

Verificación (fichero1, firma, CPP) = INVALIDO

Vale, enviar un documento firmado está muy bien para saber quién lo ha firmado y si ha sufrido modificaciones a posteriori, pero… ¿Qué hago si quiero enviar un fichero a alguien y que nadie pueda leerlo? Para eso está el cifrado de la información.

Como podemos ver, la firma digital, nos permite comprobar:
  • Integridad
  • Autenticación de origen
  • No repudio


El Cifrado
El proceso de cifrado nos permite crear un mensaje/fichero (a partir de un mensaje/fichero original) que únicamente podrá descifrar la persona que contenga la “clave” necesaria para el proceso de descifrado.

Para el proceso de cifrado se utiliza siempre, siempre, SIEMPRE la clave pública de la persona a la que vamos a enviar el mensaje/fichero cifrado.

Supongamos que Juan quiere enviar un fichero cifrado a María, el proceso de cifrado sería el siguiente:

Cifrado (fichero, CPM) = ficheroCifrado

Ahora, Juan, lo único que tiene que hacer es enviar el fichero “ficheroCifrado” a María, y ella lo descifrará utilizando el siguiente proceso:

Descifrado (ficheroCifrado, CPVM) = fichero

Como podemos ver, ha sido necesaria la clave privada de María, por lo que si por alguna razón, el fichero “ficheroCifrado” hubiese llegado a manos de Pedro, le faltaría la clave privada de María para poder descifrar el fichero y por tanto no podría descifrarlo.

El proceso de cifrado nos proporciona:
  • Confidencialidad

Y con esto llegamos al final del post de hoy, espero que con él podamos entender de forma básica como funciona el proceso de cifrado y firmado haciendo uso de la criptografía asimétrica.

jueves, 22 de junio de 2017

Punto de acceso... al AVERNO!

Hoy toca montar un punto del acceso wifi, y como lo vamos a controlar nosotros (que para eso es nuestro punto de acceso) también podremos visualizar el tráfico que viaja por el punto de acceso.

Punto de acceso... al AVERNO!
Punto de acceso... al AVERNO!

Para la realización de esta gran hazaña, vamos a utilizar:
  • 1 Raspberry PI (En mi caso una Raspberry pi)
    • Utilizaremos Raspbian como sistema operativo.
    • Por supuesto vas a necesitar cable de alimentación, tarjeta... ya sabes, el material bélico básico para que arranque la Raspberry pi.
  • 1 tarjeta de red (ALFA Network AWUS051NH V2) Esta tarjeta es opcional si utilizamos una Raspberry Pi 3, ya que esa versión, incorpora una tarjeta wifi.
    • He seleccionado esta tarjeta, ya que permite ponerla en modo monitor y en modo punto de acceso.

Raspberry Pi
Raspberry Pi

ALFA Network AWUS051NH
ALFA Network AWUS051NH


Lo primero que tenemos que hacer es conectar todos los aparejos a la Raspberry pi y enchufarla para que funcione (Si vale, ya sé que este paso me lo podía haber ahorrado...).

Lo siguiente que tenemos que hacer es instalar los paquetes hostapd e isc-dhcp-server.
El paquete hostapd nos permite poner la tarjeta en modo punto de acceso y configurar la red wifi que vamos a servir.

El paquete isc-dhcp-server es un pequeño servidor dhcp. Lo necesitamos porque queremos que los dispositivos que se conecten al punto de acceso obtengan una IP automáticamente.
Para instalarlos, utilizamos el siguiente comando:

sudo apt-get install hostapd isc-dhcp-server


Llegados a este punto, nos interesa ver cuáles son las interfaces de red que tenemos. Para ello lanzamos el siguiente comando:

ifconfig

Y en este caso, vamos a suponer que me entrega los siguientes datos:
La interfaz eth0 es la interfaz por la que la Raspberry pi se conecta a internet utilizando un cable RJ-45
La interfaz wlan0 es la tarjeta wifi USB (La ALFA Network AWUS051NH).

Lo siguiente que tenemos que hacer, es modificar el archivo "/etc/dhcp/dhcpd.conf".
Este fichero nos va a permitir configurar el servidor dhcp.
En este caso vamos a utilizar el editor de texto vi, pero podríamos utilizar el que queramos.

Para editar el documento, lanzamos el siguiente comando:

sudo vi /etc/dhcp/dhcpd.conf

En este fichero, localizamos las siguientes líneas:

option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;

y como esta configuración no nos interesa (no nos interesa, es porque no vamos a tener un servidor DNS ni un dominio), pues... lo comentamos y para ello añadimos una almohadilla (#) al inicio de cada línea.

Deberían quedarnos así:
#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

Ahora buscamos la línea:

#authoritative;

y la des comentamos. Con esto habilitamos el servidor como DHCP "principal" que como no vamos a tener otro pues... que menos que darle ese privilegio...

Nos debería quedar la siguiente línea:
authoritative;

Ahora tenemos que añadir las siguientes líneas:

subnet 192.168.100.0 netmask 255.255.255.0 {
    range 192.168.100.10 192.168.100.50;
    option broadcast-address 192.168.100.255;
    option routers 192.168.100.1;
    default-lease-time 600;
    max-lease-time 7200;
    option domain-name "local";
    option domain-name-servers 8.8.8.8, 8.8.4.4;
}

Lo que le indicamos en las líneas anteriores, es que la red utilizada será la 192.168.100.0 con mascará 255.255.255.0.
Las IPs proporcionadas por el servidor dhcp serán de la 192.168.100.10 a la 192.168.100.50.
La puerta de enlace/gateway será la IP 192.168.100.1 y los servidores DNS que proporcionaremos serán los de Google (8.8.8.8 y 8.8.4.4). Aquí podemos poner estor servidores DNS, o poner los que nos proporcione nuestro ISP.

Ahora tenemos que modificar el fichero "/etc/default/isc-dhcp-server".
En este fichero vamos a indicar en que interfaz de red queremos que se utilice el servidor dhcp. En nuestro caso, queremos que sea la interfaz wlan0, que es la tarjeta en la que vamos a levantar el punto de acceso y a la que se conectaran los clientes de la red wifi.

Para ello, utilizaremos el siguiente comando:

sudo vi /etc/default/isc-dhcp-server

buscamos la siguiente línea:

INTERFACES=""

y la modificamos para que quede de la siguiente manera:

INTERFACES="wlan0"

Llegados a este punto, tenemos que dar una dirección IP fija a la tarjeta de red en la que vamos a levantar el punto de acceso ya que en la configuración del servidor dhcp hemos puesto que el Gateway seria la dirección 192.168.100.1.

Para ello, tenemos que modificar el fichero "/etc/network/interfaces". Utilizaremos el siguiente comando:

sudo vi /etc/network/interfaces

Buscamos la siguiente línea:
allow-hotplug wlan0

y modificamos el fichero, para que las líneas siguientes nos queden de la siguiente manera:

allow-hotplug wlan0
iface wlan0 inet static
  address 192.168.100.1
  netmask 255.255.255.0

Una vez modificado el fichero, vamos a asignar la IP a la tarjeta de red wlan0.
Utilizaremos los siguientes comandos:

sudo ifdown wlan0
sudo ifconfig wlan0 192.168.100.1

En este punto, ya tenemos configurado el servidor dhcp.
Ahora vamos a configurar el punto de acceso (La red wifi para que nos entendamos).

Para ello, vamos a crear el fichero "/etc/hostapd/hostapd.conf"

Utilizaremos el siguiente comando:

sudo vi /etc/hostapd/hostapd.conf

El contenido del fichero que vamos a insertar es el siguiente:

interface=wlan0
ssid=puntoAccesoDelAverno
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=contrasena
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Con este contenido habilitamos la wifi protegida mediante WPA2.

Si queremos una wifi sin contraseña (Que si queremos un punto de acceso al averno/malicioso puede que nos interese para que se pueda conectar la gente libremente... guiño guiño...)

La configuración seria la siguiente:
interface=wlan0
ssid=puntoAccesoDelAverno
channel=6


Ahora tenemos que indicarle a hostapd donde está el fichero de configuración que acabamos de crear, para ello, modificamos el fichero "/etc/default/hostapd".

Utilizaremos el siguiente comando:

sudo vi /etc/default/hostapd

Localizamos la siguiente línea:
#DAEMON_CONF=""

y la modificamos para que quede de la siguiente manera:
DAEMON_CONF="/etc/hostapd/hostapd.conf"

Ahora vamos a habilitar el forwarding.
Utilizaremos el siguiente comando:

sudo su
echo 1 > /proc/sys/net/ipv4/ip_forward
exit

Pero como queremos que el forwarding se habilite automáticamente cada vez que reiniciemos la Raspberry pi, vamos a modificar el fichero "/etc/sysctl.conf".

Para ello utilizamos el comando:

sudo vi /etc/sysctl.conf

Localizamos la línea:

#net.ipv4.ip_forward=1

y la des comentamos para que quede:

net.ipv4.ip_forward=1


El siguiente paso es configurar iptables para que nos haga el enrutamiento entre la red wifi del punto del acceso y la red cableada (No es obligatorio que sea una red cableada, podemos hacer que nuestro punto de acceso se conecte a una red wifi, si tenéis dudas de cómo hacer esto, ponedlo en los comentarios :) )

Para configurar iptables, utilizaremos los siguientes comandos:

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT

Como queremos que esta configuración esté disponible cada vez que arrancamos la raspberry pi, ejecutamos el siguiente comando:

sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

Con esto almacenamos la configuración actual de iptables en el fichero "/etc/iptables.ipv4.nat"

Para que se restaure la configuración cuando reiniciemos, vamos a modificar el fichero "/etc/network/interfaces".

Utilizamos el comando:

sudo vi /etc/network/interfaces

y al final, añadimos la siguiente línea:

up iptables-restore < /etc/iptables.ipv4.nat

Vamos a levantar manualmente los dos servicios que hemos configurado anteriormente.
Para ello, utilizaremos los siguientes comandos:

sudo service hostapd start
sudo service isc-dhcp-server start

Si queremos que se ejecuten al reiniciar la Raspberry pi, tenemos que ejecutar los siguientes comandos:

sudo update-rc.d hostapd enable
sudo update-rc.d isc-dhcp-server enable


Llegados a este punto, si buscamos con algún ordenador o móvil las redes disponibles, deberíamos ver que hay una red wifi llamada puntoAccesoDelAverno.

Ahora podemos analizar el tráfico que pasa por nuestro punto de acceso y podemos combinarlos con las técnicas que hemos visto en los post anteriores, así como otras que veremos en el futuro ;)

miércoles, 7 de junio de 2017

Almacenar las contraseñas para hacer un sistema de login

Hola de nuevo.
Hoy vamos a tratar una de las preguntas con que nos encontramos cuando vamos a hacer una aplicación y queremos hacer un sistema de login.



¿Como almaceno la contraseña?

Para responder a esta pregunta, primero vamos a imaginarnos que para almacenar la información de login del usuario vamos a utilizar una tabla como la que vemos a continuación:

Tabla users
id username password

En la columna id almacenaremos los identificadores de usuarios (Esta columna en realidad no la vamos a usar, pero me gusta ponerla ;)).
En la columna username almacenaremos el nombre de los usuarios.
En la columna password... bueno ahora veremos lo que tenemos que almacenar aquí.

Opción 1
La primera de las opciones que se nos puede ocurrir es almacenar la contraseña en texto plano.
De esta forma cuando un usuario intente hacer login en nuestra aplicación, nosotros vamos a buscar el registro por username y luego, compararemos que la contraseña que nos ha dado el usuario es igual a la contraseña que tenemos almacenada en nuestra tabla.

Por ejemplo:
Supongamos que tenemos la siguiente tabla users:

Tabla users
id username password
1 Juan ContraseñaDeJuan
2 Manuel ContraseñaDeManuel

Si el usuario con username Juan intenta hacer login con la contraseña MiContraseña.

  • Primero recuperamos el registro correspondiente al username Juan.
  • Segundo, compararemos que la contraseña Micontraseña es igual a ContraseñaDeJuan.

Como Micontraseña y ContraseñaDeJuan no son la misma cadena de caracteres (¿Es evidente no? :P) rechazamos el login del usuario.

Si el usuario por el contrario introduce el username Juan y la contraseña ContraseñaDeJuan daríamos el login por bueno y dejaríamos acceder al usuario a nuestra aplicación.

Bien, hemos visto cómo funciona este sistema, pero tiene un problema.
Si por alguna razón (Dios no lo quiera), nos roban los datos de la tabla users, el atacante podrá acceder a la aplicación como un usuario normal ya que conocerá los username y las contraseñas asociadas a esos usernames.

Esto claramente es un problema. (Bueno, son 2 problemas, uno que puede acceder como un usuario normal y otro que te han robado los datos de la base de datos ;) )
Visto este problema, vamos a darle una primera solución.

Opción 2
Vamos a hacer un hash de la contraseña y vamos a almacenarlo en la base de datos.

Una función hash es una función que, dada una entrada, nos ofrece una salida (normalmente de longitud fija) y lo interesante de las funciones hash, es que se puede calcular el hash de un valor, pero no se puede hacer la operación inversa, es decir, teniendo un hash, no puedes calcular qué valor a producido ese hash.

Hay varias funciones hash, como por ejemplo MD5, SHA-1, SHA-2...

Sabiendo esto, nuestro ejemplo de login quedaría de la siguiente manera:

Tabla users
id username password
1 Juan 63819e896e0eb74eea21027dd691f98edfa080e23677955038bcd57582881fcb
2 Manuel 86e11146f8f7a2e213dcf600976aa9e00b125d81be91c22fd193019f62cc36c4

Supongamos que Juan intenta hacer login en nuestra aplicación con la contraseña MiContraseña:

  • Primero, recuperamos el registro correspondiente al username Juan.
  • Segundo, hacemos el hash de la contraseña introducida por el usuario en este caso MiContraseña.
  • Tercero, comparamos el hash recuperado de la base de datos con el hash que hemos calculado en el paso anterior.


Si el usuario introduce el username Juan y la contraseña MiContraseña (El hash SHA-2 es 1ef1870f76d31f4b5e877996faf904fd5214135c9967100ff3eda9f568b4d751), compararemos el hash SHA-2 de MiContraseña, con el campo password del registro correspondiente al username Juan.

Como ambos hashes no son iguales, rechazamos el login del usuario.

Si por el contrario, introduce el valor ContraseñaDeJuan como contraseña, cuando calculemos el hash SHA-2 de la contraseña veremos que es igual al que tenemos almacenado en el registro para el username Juan y daremos el login por bueno.

Pero este sistema sigue teniendo un pequeño problema.
Imaginemos de nuevo que nos roban los datos de la tabla. Un atacante podría calcular los hashes SHA-2 de todas las cadenas (o de las contraseñas más comunes) almacenando el par palabra-hash(palabra).

Con lo que únicamente tendría que buscar en esa tabla de hashes pre-calculados el hash correspondiente al que tenemos almacenados en nuestra tabla, para ver que palabra genera ese hash.

Luego podría utilizar el username y esa palabra para hacer login como un usuario normal de nuestra aplicación.

A esas tablas de hashes, se las suele llamar Rainbow Tables.

Llegados a este punto, tenemos que darle una solución a este nuevo problema.

Opción 3
Esta solución pasa por la utilización de un salt.
En nuestro caso, el salt, va a ser una cadena aleatoria que utilizaremos junto con la contraseña para generar el hash que vamos a almacenar en la base de datos.

En este caso, por ejemplo, cuando vallamos a generar el hash de la contraseña, vamos a concatenar la contraseña con el salt (vamos a utilizar la concatenación, pero podríamos realizar cual otra operación que quisiéramos).

También tendremos que crear una nueva fila para almacenar el salt, con lo que la tabla users nos quedara como vemos a continuación.
Tabla users
id username salt password
1 Juan idav fe2951935dbd28541b561ba5be8d06c4378f46b8a05dabe0e95c5fb5a515ee72
2 Manuel iwns e2c5a2a35873aaa35a1a5b66d5ed8f82a483fa31f307772e06eae0aa4ff9d413


Supongamos ahora que Juan intenta hacer login en nuestra aplicación con la contraseña MiContraseña:


  • Primero, recuperamos el registro correspondiente al username Juan.
  • Segundo, concatenamos el salt correspondiente a Juan con la contraseña introducida. El resultado es MiContraseñaidav.
  • Tercero, calculamos el hash SHA-2 de MiContraseñaidav que es 37884538e6ea5efc921f602bb5793810b8106a6a290e91ee80a28d98c608476c
  • Cuarto, comprobamos que el hash que hemos calculado, es el mismo que tenemos almacenado en la base de datos.

  • Como podemos ver, el hash no coincide, por lo que rechazamos el login.
    Por el contrario, si la contraseña introducida hubiese sido ContraseñaDeJuan, al concatenarle el salt
    el resultado habría sido ContraseñaDeJuanidav.
    Como el hash SHA-2 de ContraseñaDeJuanidav es fe2951935dbd28541b561ba5be8d06c4378f46b8a05dabe0e95c5fb5a515ee72 el usuario habría echo login correctamente.

    Pero ¿Que ventaja me proporciona el uso del salt?
    Supongamos que nos roban de nuevo los datos de la tabla.

    Vamos a suponer que el atacante tiene una rainbow table en la que tiene unos hashes que hashes coinciden con algunos que tenemos guardados en la base de datos.

    Supongamos que una de las palabras de la rainbow table es  PATATA da como resultado el hash asociado a Juan, fe2951935dbd28541b561ba5be8d06c4378f46b8a05dabe0e95c5fb5a515ee72.

    El atacante introducirá PATATA como contraseña, pero nosotros a PATATA le vamos a concatenar idav, que es el salt correspondiente a Juan. con lo cual el hash SHA-2 correspondiente a PATATAidav no nos dará como resultado el mismo hash que PATATA y por lo tanto el atacante no podrá hacer login.

    En este punto, podríamos pensar, bueno, como el atacante ya tiene el salt, podría hacerse una rainbow table concatenando todas las palabras y calculando sus hashes.
    Esto es cierto, pero hacer esto, lleva una cantidad de tiempo elevada (podría utilizar fuerza bruta o un ataque de diccionario).
    Además, esto únicamente le valdría para calcular la contraseña de un usuario, ya que para cada usuario, el salt es diferente y por tanto, puede que en un hipotético caso se averigüe la contraseña de un usuario, pero no la del resto (a no ser que repita este proceso para cada uno de ellos).


    Espero que después de esta parrafada haya quedado claro cuál es el mejor de los 3 métodos para hacer un sistema de login. Si tenéis alguna duda, podéis plantearla en los comentarios para intentar resolverla.

    Hasta la siguiente!

    miércoles, 31 de mayo de 2017

    Bienvenidos a... Mañana! Pero dame tus datos hoy.


    Saludos y bienvenidos a... Mañana! (No, no estoy loco, ya lo entenderéis luego :P )

    En los 2 post anteriores, vimos cómo se puede hacer un Man In The Middle y cómo combinarlo con sslstrip. Si realizaste alguna prueba, habrás visto que había conexiones que seguían utilizando HTTPs en lugar de HTTP.

    Lo que nos estaba pasando es que muchos servicios, utilizan una cabecera llamada HTTP Strict-Transport-Security o HSTS.

    Esta cabecera le indica al navegador que debe comunicarse con el servidor utilizando un protocolo seguro. Es decir, HTTPs. Siempre. Por lo tanto, esta es la razón por la que sslstrip no funcionaba :(

    Hay que tener en cuenta, que cuando instalas algunos navegadores, ya vienen con la información necesaria para que cuando conecta con ciertas webs siempre se utilice HTTPs. Otros vienen con la información de la cabecera pre-cargada para ciertas webs.

    Ahora bien, cuando se envía esta cabecera, se envía junto con un periodo de tiempo en el cual es válida esta cabecera. Este periodo de tiempo se indica con el valor max-age seguido por el número de segundos que será valida la cabecera.

    Por ejemplo:

    Strict-Transport-Security max-age=10886400

    En este caso, la cabecera es válida durante 10886400 segundos o lo que es lo mismo, 126 días.

    Si un servidor envía esta cabecera a un cliente, cuando el cliente la reciba, automáticamente su navegador intentara realizar todas las comunicaciones posteriores vía HTTPs y normalmente en todas las respuestas del servidor que utilice HSTS se enviara la cabecera.
    Esto nos lleva al punto en el que se fuerza constantemente el uso del protocolo HTTPs.
    (Hasta aquí, todo pinta mal para poder espiar las comunicaciones, lo sé)

    Por todo lo explicado anteriormente, supongamos que nuestra víctima, accede a un servicio bancario, por ejemplo www.mibancainventada.com y el servidor le envía en la primera respuesta la cabecera HSTS con un max-age de 126 días, tal y como hemos visto anteriormente.

    Si queremos que funcione el sslstrip, necesitamos que la víctima no tenga esa cabecera, es decir, o hemos realizado el ataque cuando la víctima no ha visitado la web, o cuando la victima hace mas de 126 días que ha visitado la web.

    Pero... ¿Que pasa si hacemos que la fecha y hora de la víctima cambien a una fecha y hora en la que la cabecera ya haya caducado?

    Aquí es donde entra en juego delorean (Te puedes descargar el código, lo vas a necesitar :) ).
    Delorean es un script escrito en python que nos permite responder con la información que nosotros queramos a una petición de ajuste de hora que se realice utilizando el protocolo NTP.

    Esto tiene un pequeño problema, y es que cada sistema operativo tiene una política diferente para decidir cuando es un buen momento para sincronizar su fecha y hora.

    En resumen, esto quiere decir que la efectividad de este ataque depende de la suerte que tengas para estar realizando un man in the middle en el momento en el que el sistema operativo de la víctima decida sincronizarse. (Aquí siempre podemos armarnos de paciencia)

    De forma muy simplificada el funcionamiento del protocolo NTP es el siguiente:

    Primero la victima realiza una petición a un servidor NTP.
    Petición NTP
    Petición NTP


    Luego el servidor NTP contesta con la información necesaria para que se ajuste la fecha y hora.
    Respuesta NTP
    Respuesta NTP


    Pero como nosotros tenemos hecho un Man In The Middle a la víctima, en realidad la petición hará lo siguiente:
    Petición NTP Man In The Middle
    Petición NTP Man In The Middle


    Y lo que contestara delorean será:
    Respuesta NTP Man In The Middle
    Respuesta NTP Man In The Middle



    Ahora que hemos visto la teoría, vamos a ver como montar todo esto en la práctica.

    Lo primero que hay que hacer para realizar el ataque es configurar iptables para redirigir el tráfico que utiliza el protocolo NTP.
    Es decir, redirigir el tráfico del protocolo UDP que utilice el puerto 123. Para ello utilizamos el siguiente comando:

    iptables -t nat -A PREROUTING  -p udp --dport 123 -j REDIRECT --to-port 123

    El segundo y último paso es descargar delorean (Gracias Jose Selvi por esta herramienta) y ejecutarlo en una terminal.

    ./Delorean/delorean.py

    Una vez hecho esto, cuando la víctima intente sincronizarse, delorean lo detectara, y le contestara con una fecha futura (Esto es configurable mediante parámetros en la llamada del script, pero a nosotros el funcionamiento por defecto nos sirve perfectamente)

    Y entonces, como la victima ha viajado al futuro, la información de las cabeceras HSTS habrá caducado, sslstrip hará su trabajo y nosotros podremos espiar las comunicaciones de la víctima.

    Bueno pues ya hemos visto como viajar al futuro para espiar las comunicaciones ;). Espero que os haya gustado la entrada.
    Hasta la siguiente!


    miércoles, 24 de mayo de 2017

    ¿HTTPs? No gracias

    Saludos!
    En el post anterior, vimos como podíamos realizar un ataque Man In The Middle (MitM) pero... teníamos un problema. Las conexiones que están cifradas no podíamos espiarlas.

    Hoy vamos a centrarnos en como espiar las comunicaciones que utilizan el protocolo HTTPs.

    Un investigador llamado Moxie Marlinspike ya se topó con este problema, y le dio una solución. Esta solución se llama sslstrip.

    Explicado de forma rápida, lo que hace sslstrip es permitir a un atacante, que esté realizando un ataque MitM, comunicarse con el gateway utilizando HTTPs pero reenviando el tráfico a la victima por HTTP. (y aquí está la parte divertida :) ya que las conexiones HTTP no van cifradas, y por tanto podemos espiar el tráfico )

    Es decir, el tráfico HTTPs normalmente viajaría de la siguiente manera:
    Conexión HTTPs Normal
    Conexión HTTPs Normal


    Pero cuando estamos haciendo un MitM a una víctima, realmente el tráfico viaja así:
    Conexión HTTPs Man In The Middle
    Conexión HTTPs Man In The Middle




    Y lo que hace sslstrip es que el tráfico sea el que vemos en la siguiente imagen:
    Conexión sslstrip
    Conexión sslstrip


    Ahora que ya hemos visto la teoría, vamos a ver cómo podemos llevar a cabo esto de forma práctica.

    Lo primero que tenemos que hacer es configurar iptables. Para ello lanzamos el siguiente comando en una terminal:
    iptables -t nat -A PREROUTING  -p tcp --dport 80 -j REDIRECT --to-port 10000

    Como podemos ver, lo que hacemos el redirigir el tráfico tcp que tenga como destino el puerto 80 al puerto 10000.

    El siguiente paso, es levantar sslstrip para que haga su "magia". Esto lo hacemos lanzando el siguiente comando en una terminal:

    sslstrip -l 10000

    Como podemos ver, en el comando anterior invocamos a sslstrip y con el parámetro -l 1000 le indicamos que escuche el puerto 10000.

    Como veis, con esto lo que conseguimos es que el tráfico que llega a nosotros con puerto de destino 80 utilizando el protocolo TCP, sea redirigido al puerto 10000. En el puerto 10000 sslstrip recibe el tráfico y lo redirige a la víctima.

    Llegado este punto, ya podemos espiar las comunicaciones que utilicen el protocolo HTTPs.
    Pero... si os dais cuenta, si intentáis espiar las comunicaciones de servicios bancarios, o servicios de correo muy conocidos, no podréis ya que el tráfico sigue cifrado.

    ¿La solución?

    En el siguiente post :)

    miércoles, 17 de mayo de 2017

    Man In The Middle

    Bueno, ha llegado el primer post del blog. Espero hacerlo bien ;)

    Hoy vamos a ver paso a paso como realizar un ataque man in the middle utilizando Kali, ya que esta distribución viene con casi todas las herramientas que vamos a necesitar pre instaladas.

    Este ataque busca como fin, situarnos en el medio de una comunicación, de forma que todo el tráfico pase por nosotros (y podamos espiarlo en según que condiciones, claro está).

    Es decir, el flujo normal de una comunicación sería el siguiente:


    Conexión Normal

    Pero nosotros que somos un poco cotillas, queremos que el flujo sea el siguiente:

    Conexión Man In The Middle


    Lo primero que tenemos que hacer es habilitar el IP forwarding. Con esto lo que hacemos es permitir que nuestro equipo funcione como enrutador.

    echo 1 > /proc/sys/net/ipv4/ip_forward

    Esto es necesario activarlo ya que nuestro equipo con Kali, tendrá que manejar las comunicaciones, de forma que al situarse en el medio, la comunicación siga fluyendo. De esta forma la victima continúa trabajando como lo haría normalmente sin enterarse de que está siendo atacada.

    Lo siguiente que queremos hacer es situarnos en el medio de la comunicación. Esto lo vamos a conseguir haciendo un ataque ARP Spoofing.

    El protocolo ARP explicado de forma ultra rápida lo que hace es asociar una dirección MAC con una dirección IP.

    Lo que vamos a hacer es enviar paquetes ARP Reply constantemente contra la víctima y contra su gateway, de forma que:

    • En la cache ARP de la víctima, se relacione la IP del gateway con nuestra dirección MAC 
    • En la cache ARP del gateway, se relacione la IP de la víctima con nuestra dirección MAC
    Las siguientes tablas representan los datos de las caches ARP de la víctima y del gateway:

    Cache ARP Victima
    MAC IP
    AA:AA:AA:AA:AA:11 10.0.0.1
    AA:AA:AA:AA:AA:33 10.0.0.3
    Cache ARP Gateway
    MAC IP
    AA:AA:AA:AA:AA:22 10.0.0.2
    AA:AA:AA:AA:AA:33 10.0.0.3

    Las siguientes tablas representan los datos de las caches ARP de la víctima y del gateway una vez han sido envenenadas:

    Cache ARP Victima Envenenada
    MAC IP
    AA:AA:AA:AA:AA:33 10.0.0.1
    AA:AA:AA:AA:AA:33 10.0.0.3
    Cache ARP Gateway Envenenada
    MAC IP
    AA:AA:AA:AA:AA:33 10.0.0.2
    AA:AA:AA:AA:AA:33 10.0.0.3

    Para realizar este proceso, necesitamos saber con que interfaz con estamos conectando a la red y las direcciones ips del gateway y de da víctima.

    Vamos a suponer que nos conectamos con la interfaz eth0 y las direcciones ya las tenemos en las figuras de arriba ;)

    Abrimos una terminal, y envenenamos la cache ARP del gateway utilizando el siguiente comando:

    arpspoof -i eth0 -t 10.0.0.2 10.0.0.1

    Y en la otra, en una terminal nueva y sin cerrar la anterior, envenenamos la cache ARP de la víctima ejecutando el siguiente comando:

    arpspoof -i eth0 -t 10.0.0.1 10.0.0.2

    Con esto, ya hemos conseguido situarnos en el medio de las comunicaciones entre la víctima y su gateway. Si abrimos un sniffer de red, veremos paquetes de datos de la comunicación entre ambos.

    Pero... ¿que pasa con las comunicaciones cifradas?
    Lo veremos en siguientes posts ;)

    miércoles, 10 de mayo de 2017

    Bienvenidos

    Bienvenidos al Blog del Informático Del Averno.

    Aquí podréis encontrar artículos sobre todo tipo de ideas que se me pasen por la cabeza.
    Mi primera idea es utilizarlo para tratar temas de programación, seguridad informática, hacking y otros temas relacionados con el mundo tecnológico.

    Pero... como todo el mundo sabe, las ideas van cambiando, así que quien sabe en que terminara convirtiéndose este pequeño sitio del ciberespacio.


    Un saludo y nos vemos por el averno ;)