jueves, 31 de mayo de 2018

JWT 1

Buenas noches, si me pase mas de un mes sin postear, la verdad si lo deseaba pero por temas de trabajo que a uds siempre les menciono, me alejo un poco, pero bueno ya estoy de vuelta, vamos con todo.
Ya seguramente algunos desarrolladores han implementado la autenticación por token JWT(jason web token).

Background:
Este token es una firma cifrada, que permite al API identificar a nuestros usuarios. Este token se produce  del lado cliente y el mismo API es el que se encarga de decifralo, es decir no se guarda en el servidor. Esto permite tener una gran escalabilidad para entornos web y mobiles.
La composicion es de 3 cadenas separadas por ".":

GET /index.php HTTP/1.1
Host: atacamejwt.com
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://atacamejwt.com/register.php
Cookie: auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InVzZXIxIiwiaWF0IjoiMTUyNzgxODM4OCJ9.YTI2Y2UyM2FkMjcyOTA4ZGMzZDEwZjA1ODFlMTYwMmIwYjM5ZTY5MTRkMWU4NjUyMmUzN2VkYmQzMTZjZDg2Nw
Connection: close

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InVzZXIxIiwiaWF0IjoiMTUyNzgxODM4OCJ9.YTI2Y2UyM2FkMjcyOTA4ZGMzZDEwZjA1ODFlMTYwMmIwYjM5ZTY5MTRkMWU4NjUyMmUzN2VkYmQzMTZjZDg2Nw

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9 = header
eyJsb2dpbiI6InVzZXIxIiwiaWF0IjoiMTUyNzgxODM4OCJ9=Payload
YTI2Y2UyM2FkMjcyOTA4ZGMzZDEwZjA1ODFlMTYwMmIwYjM5ZTY5MTRkMWU4NjUyMmUzN2VkYmQzMTZjZDg2Nw = Firma
La primera es el header, se decodificamos en base 64 podemos ver lo siguiente:
{"alg":"HS256","typ":"JWS"}
Esta compuesto por el algoritmo cryptografico HMAC256, que asegura la integridad pero puede escojer otro algoritmo, si miremos:

  • RSA based
  • Elliptic curves
  • HMAC
  • None
Bueno aqui esta el detalle el valor "None", que es lo que hace este valor, como menciona, hace que no lleve ninguna firma, probablemente su implementacion fue para realizar un debug a la aplicación

La segunda es el payload, si decoficamos en base 64:
{"login":"user1","iat":"1527818388"}
Podemos observar que se compone por el usuario que se esta logeando a la aplicación y un valor IAT, el cual refleja cuando el JWT fue emitido, osea no es algun identificador.
La tercera es la firma, que se conforma por el header y el payload mas una clave secreta que se localiza en el servidor, aqui otra posible vulnerabilidad

Al ataque:
El primer vistazo de la autenticación de un usuario, que lo denominaremos "user1" es la siguiente:
Vemos que se usa el token JWT para producir una sesion con "user1"


Pero que pasa si alteramos este token, pensemos.
Que pasa si decodifico el header y cambio el valor de "HS256" por un None, esto a que me sujeta, a que se anule la firma que contiene una clave secreta, que para obtenerla tendria practicamente que haber comprometido previamente todo el backend.
hacemos lo siguiente:
{"alg":"HS256","typ":"JWS"}
por:
{"alg":"None","typ":"JWS"}
ya tenemos la primera parte, ahora vayamos por más, si el usuario administrador fuera "admin", ya sin firma, ¿podemos logearnos como tal?, entonces tambien cambiemos el payload:
{"login":"user1","iat":"1527818388"}
por:
{"login":"admin","iat":"1527818388"}
Listo que queda, volver a codificar, pero ojo no olvidemos que el valor de firma deberia tener una valor nulo, entonces hacemos lo siguiente:
base64(<header>).base64(<payload>).Listo veamos cual fue el resultado:



Exactamente ahora somos el usuario "admin".
Posible solución, busquemos librerias donde no se use el "None"  o que durante la validación se verfique el algoritmo usado.
https://www.owasp.org/index.php/JSON_Web_Token_(JWT)_Cheat_Sheet_for_Java#NONE_hashing_algorithm
Bueno, un gusto otra vez.

viernes, 20 de abril de 2018

SSRF - una de las clasicas

Esta semana ha sido un poco jodido, debido a que realice un update a mi kernel en linux y perdí entre tantas cosas mi acceso a mis virtuales, bueno realmente quería realizar un upgrade total a mis sistemas operativos en dual boot, asi que no hay mejor oportunidad que esta para darle de baja a mis SO, el problema es la cantidad de data que tengo almacenada, que ya van 2 dias en migración a otro disco duro.


Bueno al punto, ¿que es SSRF site server remote forgery?, similar a su primo hermano CSRF, permite mediante la modificación de una funcionalidad, mal configurada, manipular los datos entrantes para servir como una especie de pivoteo hacia todo lo que este dispositivo tenga en su "route table".
Para entender gráficamente:

Que es lo que se logra, mediante un servidor vulnerable, permitir desde barrer (sweep ping) los servidores internos, interactuar con ciertos puertos y hasta lograr ataques con xss, sqli, xxe, xpath, etc, siempre y cuando los servidores expuestos, tenga esta vulnerabilidad, interesante no?
veamos:
voy a simular tener un servidor con la vulnerabilidad SSRF:
ip ssrf:192.168.0.102(ssh:10222,http:80)
dentro de su  red tengo conectado otros servidores, que podrian no estas expuestos en un inicio:
ip expuesto:192.168.0.112.
Bien comenzemos:

servidor que permite proyector una imagen dede un sitio remoto, poniendo la ruta de la imagen.
Proxiamos con burp el request y lo modificamos el puerto por un valor 10222.

Ahora para explicar un poco, el puerto 10222, lo configure en el mismo servidor vulnerable(192.168.0.102), el cual corresponde al servicio SSH, veamos el resultado, dice "SSH-2.0-OpenSSH ...", que quiere decir, que es como si mandaramos un netcat al puerto SSH y ahora ponemos nuestra emogi de "ohhh".
Como ven , se esta permitiendo interactuar con otros puertos, veamos ahora interamos usar este servidor para localizar otros servidores, logicamente, recordemos que es un esquema de laboratorio, asi que tendre otro servidor expuesto, como si fuera un servidor en la DMZ.

Lo que hago aca, es cambiar los ultimos digitos de la red 192.168.11x en un rango del 0 a 9, es decir:
recorrer 192.168.0.110, 192.168.0.111 .... 192.168.0.109, tratando de localizar un ojetivo interno.
Si validamos la respuesta del host "192.168.0.110" , dice claramente "no route to host"
Veamos ahora la respuesta con un host activo:
Se nota la diferencia, como ven la diferencia esta siempre en la respuesta, siempre cuando se fuzzea algun parámetro, es importante validar la respuesta.
Ahora tenemos al host, veamos sus puertos abiertos:
Si notan, ahora recorremos los puertos mas conocidos, para mi ejemplo, 22,23,80,443, veamos la respuesta en el puerto 23, dice "connetion refused", pero ahora veamos que paso con un puerto abierto:

Notan que la respuesta no arroja el mismo mensaje, entonces ya tenemos un puerto abierto, perfecto, ahora hagamos reconocimiento a directorios o archivos  mas conocidos en una app web, empezemos:
Como se nota, estamos recorriendo los siguientes directorios o archivos mas conocidos: admin, manager, cgi-bin, veamos la respuesta: claramente vemos un mensaje de cabecera "404" que indica eso que no encuentra el directorio, veamos que pasa si lo encuentra:
Como ven, ahora sale un mensaje "403", de prohibido, el cual nos permite deducir que si existe el directorio pero por reglas en el apache, no es posible el acceso.

Que posible solución podriamos tener, quizas el uso de CORS que permite tener una politica como "same-origen", el uso de listas blancas podria ser tambien funcional.
Bueno por el momento fin del post.


jueves, 29 de marzo de 2018

Copytesters!

Dicen que en la competencia esta el gusto, claro el gusto de ser mas competitivo cada día.
Últimamente veo en linkedin mucha gente que con una facilidad increíble, se ponen como titulo, "pentester" o "hacker etico" o "consultor experto en seguridad informática" o mas graciosos aun, "risk advisory pentester maximum" (no es broma).
La verdad yo mañana me puedo poner "astronauta de la nasa" y no pasa nada, estos tags como que te los puedes ganar o los puedes inventar, la idea es vender al fin y al cabo, como sea, pero se vende.

El punto es cuando esta competencia se torna desleal y cuando te tomas en forma literal el hecho de "vender por vender", fuera de abaratar los precios con avisos como "somos los mas bajos en el mercado"(como si los conocimientos fueron los mas bajos que tienes en el mercado), en también realizar pentesting, tratando de efectuar una copia exacta, mismos albunes de Panini bambas.

Lo simpático es que esta gente, que entiendo tiene limitantes técnicas (espero que alguna vez hagan al menos una diferencia en sus presentaciones y para eso se "estudia"), no tiene la capacidad de leer e interpretar algo ya incluso elaborado, lógicamente por lo primero en mi párrafo.
Encontrarse con estas copias baratas y luego anunciarse como experto pentesting, en lo personal me causa gracia y mas aun si trabajan en multinacionales, con horarios de oficina, muy peinaditos y listos para vender, donde creen que encontraran "hackers" debajo de cada piedra.

Lo bueno de este blog es que me sirve de catarsis.
Hasta la próxima, espero sea pronto.

Escalando privilegios linux/ nfs

Prometí escribir un poco mas, pero bueno por temas de tiempo, entre el trabajo (pentesting) y la familia como que llega la noche o el pequeño tiempo para descansar, lo trato de aprovechar.

Bueno, hace no mucho realizando un reto en particular, me encontré con una forma poco habitual de escalar privilegios a través de nfs, para entender como fue lo que realice pues me atreví a simular este reto en un VM y validar cual es el parámetro que me permitía realizar este escalamiento de privilegios.

Background:

¿Que es nfs?:
"El Network File System (Sistema de archivos de red), o NFS, es un protocolo de nivel de aplicación, según el Modelo OSI. Es utilizado para sistemas de archivos distribuido en un entorno de red de computadoras de área local. Posibilita que distintos sistemas conectados a una misma red accedan a ficheros remotos como si se tratara de locales."
wikipedia

En resumen, da la facilidad de mantener un carpeta compartida, la cual puede ser accedida por distintos sistemas, similar al smb o samba pero focalizado a un propósito.
Para configurar los parametros tenemos la siguiente estructura:
archivo:
/etc/exports
<export> <host1>(<options>) <hostN>(<options>)...

donde para entender lo mejor como funciona hagamos un ejemplo:
/another/exported/directory 192.168.0.3(rw,sync)
Done
/another/exported/directory = al directorio que sera compartido
192.168.0.3 = el host o la red cual esta compartiendo
(rw,sync) = las opciones que tendrá, una sera de ro(read only).

Opción root squash

Entre las opciones ademas de permitir escritura, lectura, existe otras 2 opciones que la acompañan, una es wdelay y la otra es "root_squash, mayores detalles aqui
Que dice esta opción ultima en particular:
Previene que los usuarios en modo root conectado de forma remota pueden conservar sus mismos privilegios y se les asigna un id de usuario para el usuario nfsnobody:
Veamos en forma practica:

Primero identificamos si este protocolo esta activo y cual es la carpeta que se esta compartiendo:


Carpeta compartida y red cual se esta compartiendo

Ahora validemos que parámetros están activos en el servidor remoto, como vemos se permite lectura y escritura.

Montemos sobre es carpeta y creamos un archivo a ver que pasa:
Creamos la carpeta "compartido", montamos y creamos el archivo hola.txt

Nosotros podemos validar que el archivo ha sido creado con permisos de root:root(ya que nuestro usuario es root).
Ahora validemos en el servidor remoto los permisos del archivo creado creada:
permisos de archivo

perfecto no "heredo" los permisos de root, veamos que pasa si quitamos ese parámetro:
Cambio de parámetro

Reiniciamos el servicio en el host remoto y volvamos a compartir:

creación de archivo

Ahora volvemos a validar los permisos, pero desde el usuario sin privilegios:

permisos para root root.


Como vemos, hemos podido crear un archivo remotamente con permisos "heredados"(se que ciertamente no es la palabra técnica, pero ayuda a entender que paso), con usuario "root" y en el grupo "root".
¿Ahora que se les ocurre?