-+ Anonymous? -+ Caso práctico. -+ -+ nitr0us *noSPAM* 0hday.org -+ México -+ 01/Mayo/2008 1.- INTRODUCCIÓN Este pequeño texto surgió por la duda que me nació al leer un post[1] en el foro de la CUM (Comunidad Underground México) en el cual alguien pregunta lo siguiente: "¿Como puedo evitar que una página sea vista mediante un proxy?". Así pues, decidí hacer unas pequeñas búsquedas y pruebas en diferentes escenarios de "anonimicidad". Estas pruebas serán presentadas en los siguientes apartados. El lector debe conocer la idea general de un proxy y encabezados HTTP, en este documento me referiré a proxy como cualquier servidor intermediario entre dos puntos (Ej. atacante y víctima). 2.- MARCO TEORICO Cuando un usuario quiere esconder su IP real cuando visita una página, por lo regular va a sitios donde diariamente se exponen decentas de servidores proxys "anónimos", toma uno de ellos, configura su explorador para pasar através de dicho proxy y verifica si tiene salida, sino, toma otro proxy de la lista y ... Voila ! www.showmyip.com dice que estoy conectado desde Rusia. La información transmitida del cliente al servidor está disponible para el servidor en ciertas variables de entorno. Cada unidad de información es un valor de cierta variable. Si una unidad de información no fué transmitida, entonces la variable de entorno correspondiente estará vacía. [2] Algunas de esas variables de entorno son: REMOTE_ADDR – Dirección IP desde se conectó al servidor Web (el cliente). HTTP_VIA – Sino está vacia, significa que se utilizó un proxy. El valor contenido será la dirección IP del proxy, además, dicho proxy agregó el encabezado HTTP "Via". HTTP_X_FORWARDED_FOR – Sino está vacia, significa que se utilizó un proxy. El valor contenido es la IP real del cliente, además, el proxy agregó el encabezado HTTP "X-Forwarded-For". El encabezado "X-Forwarded-For" es un estandar "de facto" para identificar la IP de un cliente conectándo a un servidor Web através de un Proxy HTTP. [3] Entonces, la forma más sencilla de obtener la dirección IP de un usuario en PHP es mediante la utilización de $_SERVER['REMOTE_ADDR'], sin embargo este valor no siempre es el que estamos buscando, hay veces en que las visitas llegan a nuestro web através de proxys de que ocultan su dirección IP. [4] Bueno, con eso basta para comprender los casos prácticos mostrados a continuación. 3.- CASOS PRÁCTICOS Como herramienta de ayuda, utilizé la bien conocida función "phpinfo()", acompa- ñada de un servidor Web Apache. Recordemos que esta función imprime los encabezados HTTP recibidos, así como también las variables de entorno del servidor. 3.1.- CONEXIÓN SIN UTILIZAR SERVIDOR PROXY phpinfo() nos imprime: ++VARIABLES DE ENTORNO++ REMOTE_ADDR 189.132.64.106 ++ENCABEZADOS HTTP++ HTTP Request GET /phpinfo.php HTTP/1.1 Host 189.132.64.106 User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 Accept text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain; q=0.8,image/png,*/*;q=0.5 Accept-Language es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding gzip,deflate Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive 300 Connection keep-alive Referer http://189.132.64.106/ RESULTADOS: Nada fuera de lo común 3.2.- CONEXIÓN UTILIZANDO UN SERVIDOR PROXY Proxy a utilizar: 203.144.160.251 Puerto: 8080 www.ip2location.com nos dice que el proxy es de Tailandia phpinfo() nos imprime: ++VARIABLES DE ENTORNO++ REMOTE_ADDR 203.144.160.251 HTTP_X_FORWARDED_FOR 189.132.64.106 ++ENCABEZADOS HTTP++ HTTP Request GET /phpinfo.php HTTP/1.1 Host 189.132.64.106 User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 Accept text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain; q=0.8,image/png,*/*;q=0.5 Accept-Language es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding gzip,deflate Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 X-Forwarded-For 189.132.64.106 Cache-Control max-stale=0 Connection Keep-Alive RESULTADOS: La variable REMOTE_ADDR nos dice que la página fué vista desde 203.144.160.251 (Proxy) y la variable HTTP_X_FORWARDED_FOR nos muestra la IP del cliente 189.132.64.106. Cabe mencionar que si hubiese pasado por más proxys, en este encabezado se hubiesen listado dichas IPs, separadas por comas. 3.3.- CONEXIÓN UTILIZANDO UN SERVIDOR PROXY, PERO HACIA UN SERVIDOR QUE ESTÁ DETRÁS DE UN PROXY/FIREWALL. phpinfo() nos imprime: ++VARIABLES DE ENTORNO++ REMOTE_ADDR 192.168.1.253 HTTP_X_FORWARDED_FOR 189.132.64.106, 203.144.160.251 HTTP_VIA 1.1 firewall.xxxxxx.com.mx:80 (squid/2.6.STABLE10) ++ENCABEZADOS HTTP++ HTTP Request GET /phpinfo.php HTTP/1.0 Accept text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain; q=0.8,image/png,*/*;q=0.5 Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 Accept-Encoding gzip,deflate Accept-Language es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3 Cache-Control max-age=259200, max-stale Host xxxxxx.com.mx User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 Via 1.1 firewall.xxxxxx.com.mx:80 (squid/2.6.STABLE10) X-Forwarded-For 189.132.64.106, 203.144.160.251 RESULTADOS: Este ejemplo es el más ilustrativo. Para mayor entendimiento, la conexión está hecha de esta manera: Conexión desde mi máquina hasta www.xxxxxx.com.mx. |nitr0us| ------- |proxy| -------|firewal.xxxxxxx.com.mx|-------|Servidor Web| 189.132.64.106 203.144.160.251 192.168.1.253 192.168.1.1 Así pues, desde mi máquina salen los encabezados HTTP, llegan al proxy, el cual agrega a la cabezera "X-Forwarded-For" con el valor de su IP. Luego llega al firewall (que hace NAT a la red interna con Squid Proxy instalado), el cual agrega la cabecera "Via". Entonces, el servidor fué alcanzado desde REMOTE_ADDR (192.168.1.253) pero en realidad, la cabecera X-Forwarded-For nos muestra la lista de IPs por donde pasó el paquete. 3.4.- CONEXIÓN UTILIZANDO LA RED TOR [5] phpinfo() nos imprime: ++VARIABLES DE ENTORNO++ REMOTE_ADDR 91.121.102.64 ++ENCABEZADOS HTTP++ HTTP Request GET /phpinfo.php HTTP/1.1 Host 189.132.64.106 User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 Accept text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain; q=0.8,image/png,*/*;q=0.5 Accept-Language es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding gzip,deflate Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection close RESULTADOS: Pues a diferencia de las demás pruebas utilanzo un proxy de pormedio, en esta no se ve la cabecera X-Forwarded-For, por consiguiente tampoco existe la variable de entorno HTTP_X_FORWARDED_FOR. En conclusión, utilizar TOR es una forma de conectarse a un servidor de forma más anónima, a expensas de velocidad. 4.- CONCLUSIONES La mejor conclusión, es la unión de los resultados de cada una de las pruebas llevadas acabo. Se puede decir que, dependiendo del servidor que esté instalado en el proxy, será el nivel de anonimicidad que se tenga, ya que algunos servidores agregan ciertos valores a ciertas cabeceras y otros simplemente la omiten. También nos dimos cuenta que utilizando la red TOR se puede obtener un mayor anonimato. 5.- DESPEDIDA Bueno, nada que decir... Saludos a mi bro CRAc por hacer unas pruebas... Saludos a todos mis compas de #0hday.org, CUM, beavis, alt3kx, Optix, hkm y a todos los demás... Saludos. 6.- REFERENCIAS [1] http://www.hakim.ws/cum/index.php?topic=21236.0 [2] http://www.freeproxy.ru/en/free_proxy/faq/proxy_anonymity.htm [3] http://en.wikipedia.org/wiki/X-Forwarded-For [4] http://www.eslomas.com/index.php/archives/2005/04/26/obtencion-ip-real-php/ [5] http://www.torproject.org/ [6] http://www.thepcspy.com/read/getting_the_real_ip_of_your_users 7.- APENDICE Código simple para obtener la IP real de un usuario [6] /** * Call as: $userp = GetUserIP(); */ function GetUserIP() { if (isset($_SERVER)) { if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) return $_SERVER["HTTP_X_FORWARDED_FOR"]; if (isset($_SERVER["HTTP_CLIENT_IP"])) return $_SERVER["HTTP_CLIENT_IP"]; return $_SERVER["REMOTE_ADDR"]; } if (getenv('HTTP_X_FORWARDED_FOR')) return getenv('HTTP_X_FORWARDED_FOR'); if (getenv('HTTP_CLIENT_IP')) return getenv('HTTP_CLIENT_IP'); return getenv('REMOTE_ADDR'); }