Archivo de la categoría ‘Proyectos’

Seguridad: Sniffing. Capítulo Segundo-> Protocolos IP, DNS, TCP/UDP y Ethernet/ARP

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.

 

Protocolos ARP, IP, DNS y TCP/UDP

Internet como estructura básica está muy bien, pero es necesario así mismo una serie de protocolos que haga posible la comunicación entre distintos dispositivos interconectados por todo el mundo. Imaginemos dos personas, una en España y otra en Francia, una habla español y la otra francés. Para comunicarse hacen uso del teléfono ordinario, lo cual hace que puedan hablar de forma simultánea, en tiempo real y de forma eficaz. Pero si habla cada uno en un idioma diferente será imposible que se entiendan. Es decir, es necesario una serie de protocolos, de normas, de… para que todos entiendan correctamente todo. Vamos a tratar quizás los más importantes de ellos de cara a nosotros, no significa que no existan otros protocolos igualmente importantes o imprescindibles, pero estos son los que para nuestra tarea es importante conocer bien:

  • IP
  • DNS
  • TCP/UDP
  • Ethernet/ARP

Hay que tener presente que estos protocolos no nacen de la nada, nacen de la necesidad de crear comunicaciones fiables, que perduren en el tiempo, que sean eficaces y simples en la medida que sea posible. Comencemos entonces.

 

 

Protocolo IP

Las siglas IP provienen de “Internet Protocol” (Protocolo de Internet), no obstante esto puede ser confuso, dado que el término IP puede hacer referencia a la suite de protocolos IP que hacen posible el modelo TCP/IP, o incluso podemos referirnos muchas veces a IP para designar una “Dirección IP”. Pero detrás de todo ello, IP en sí no es más que un protocolo más que hace posible el modelo TCP/IP, aunque por supuesto pueda ser uno de los más importantes en todos ellos.

El objetivo del protocolo IP es poder entregar/recibir paquetes (recordemos que en el nivel 3 del modelo OSI, nivel de red, la unidad de información se denominaba paquete) a/desde diferentes orígenes y destinos, de modo que cada paquete tenga un origen y un destino claro. Dicho de otro modo, es el protocolo que indica el host al que se debe de enviar el paquete o el host que lo está enviando. Aunque la referencia más inmediata que solemos tener del protocolo IP es el aspecto de una dirección IP, no podemos olvidar como se hace esto posible o que significa eso que se conoce como dirección IP. Actualmente, existen dos especificaciones diferentes para el protocolo IP, aunque sería más correcto hablar de versiones diferentes. Una es la que aún se encuentra como uso mayoritario, posiblemente copando el 98% de todo Internet a día de hoy y conocida como IPv4. La segunda aun en expansión y de implantación muy lenta desde hace ya muchos años su sucesora, IPv6.

 

IPv4

Quizás la diferencia más señalada de estas dos versiones tiene relación directa con el espacio de direcciones que soporta cada una de estas. De este modo, el protocolo IPv4 permite tan solo direcciones IP de 32 bits, lo que quiere decir que aun si se pudiese asignar una a una todas las direcciones de forma independiente (aunque esto no funciona así), “tan solo” se tendrían disponibles un total de 4.294.967.296 direcciones diferentes. 4 Mil millones de direcciones pueden parecer suficientes si tenemos en cuenta que el planeta cuenta con una población aproximada de unos 6 mil millones de habitantes. No obstante el crecimiento de los dispositivos a la red ha tenido en los últimos años un aumento exponencial. Ni siquiera las tecnologías de traducción de direcciones como NAT, el uso por parte de los ISP de direcciones IP dinámicas o los espacios IP reservados para redes privadas son suficientes para evitar el agotamiento de direcciones IPv4, lo que ha producido que a día de hoy el espacio de direcciones IPv4 esté literalmente agotado. Si los datos son ciertos, y parece que lo son, a día de hoy la ICANN habría ya entregado el último paquete de direcciones IPv4, estando por tanto disponibles tan solo los paquetes de direcciones IP gestionados por los propios gobiernos regionales. Estamos en el año 2010, y parece que con toda seguridad en uno o dos años todo el espacio de direcciones esté completamente agotado.

¿Qué es una dirección IPv4?

Casi con toda seguridad, cualquier lector que pueda estar leyendo estas letras habrá visto alguna vez una dirección IPv4, la cual no es otra que un número dividido en 4 octetos. En realidad, la división de ese número de 32 bits en 4 octetos es meramente una cuestión de comodidad a la hora de poder trabajar con ellos, es por ello que no se suele usar la notación hexadecimal siquiera, la cual tendría más sentido dado que acortaría la dirección a la hora de recordarla y/o escribirla:

11000000

10101000

00000000

00000001

C0

A8

00

01

192

168

000

001

La representación clásica de estas direcciones es por tanto la separación de cada octeto con un punto: 192.168.0.1

Hemos dicho anteriormente que no era cierto que en un espacio de direcciones IP de 32 bits se pudiesen tener otorgar 2^32 direcciones diferentes. El sistema de dirección IPv4 reduce considerablemente este número debido a su propio funcionamiento, como por ejemplo direcciones reservadas, subredes, direcciones broadcast…

En realidad, una dirección IP no identifica tan solo el host origen/destino, sino también la subred a la que pertenece. Históricamente se utilizó la misma división de los octetos como divisiones entre redes y host, de este modo se podía usar el primer, segundo y tercer octeto para la identificación de las redes, y el segundo, tercero y cuarto octeto para la identificación de los host. De este modo por ejemplo, si pudiésemos disponer de todo el espacio IPv4 para nosotros podíamos utilizar tan solo el primer octeto para identificar una red concreta y el resto de los 3 octetos para identificar los host. Es decir, podríamos constituir un máximo de 256 redes diferentes, cada una de ella con 2^24 hosts. Recordemos que un octeto son 8 bits, 256 valores diferentes. Pero si lo que necesitásemos sería tener muchas redes y pocos host podríamos del mismo modo hacerlo al revés, tener 2^24 redes diferentes y cada una de ella con 256 hosts.

A día de hoy esta práctica es normal encontrarla en redes simples, pero esto no es en modo alguno una norma, y es posible usar el número de bits que se desee tanto para el número de las redes como el número de los hosts, es decir… podemos poner un punto de separación virtual en cualquier lugar de los 32 bits de una dirección IPv4. Es por ello que se requiere de un sistema o de algún identificador que diga que parte será la usada para una tarea y para la otra. Y es cuando aparece la “Máscara de subred”. Se llama máscara porque realmente lo que hace es enmascarar los bits que se usarán para cada tarea. Básicamente se realiza una operación AND lógica entre la dirección IP origen/destino y la máscara de subred. Aquellos bits que son cero serán los que identifican el host, y el resto estará indicando exactamente la subred. La única restricción es que los bits usados para una cosa o la otra deben ser consecutivos, no se pueden intercalar bits para ser usados como subred/host. Visto esto, supongamos que tenemos la misma IP ejemplo anterior:

11000000 10101000 00000000 00000001 -> Dirección IP binaria del host, correspondiente a su notación decimal: 192.168.0.1
11111111 11111111 11111111 00000000 -> Máscara de Subred, correspondiente a su notación decimal: 255.255.255.0
—————————————————- -> Operación Lógica AND
11000000 10101000 00000000 00000000 -> Red: 192.168.0 Host: .1 (192.168.0.1)

Otra forma común de expresar la máscara de subred es utilizando una barra inclinada después de la dirección IP especificando el número de bits que se han otorgado para la identificación de la subred. Por ejemplo, continuando con el ejemplo anterior:

IP: 192.168.0.1
Máscara: 255.255.255.0

Podríamos expresarlo como:

192.168.0.1/24 dado que en realidad son 24 bits los que han sido usados para la subred. En este caso el esquema coincidirá con la separación de la subred/host por los octetos, pero como hemos dicho, la máscara podría haber sido perfectamente 255.255.255.240.0 -> 192.168.0.1/20 lo que significaría que la parte de la red es identificada por 20 bits.

¿Por qué es tan importante tener configurado correctamente esta máscara? Los nodos de red como los routers necesitan conocer a quien enviar cada paquete. Para hacer esto el router tiene que mirar en sus tablas de rutado, de este modo puede identificar la subred al que pertenece el destino y enviárselo. Si la máscara de subred no es correcta, el router no dispondrá en sus tablas de rutado dicha red, y no podrá entregar el paquete.

Aunque cualquier sistema interno podría hacer uso cualesquiera del protocolo IP y de sus direcciones, este no es empleado de forma arbitraria. En teoría se podría usar cualquier máscara de subred para cualquier IP, pero la ICANN ya desde el principio (como máximo organismo que mantiene u otorga las IP) tiene perfectamente definido diferentes clases de IP y su finalidad. Podemos decir que todo el espacio de direcciones IP se encuentra perfectamente organizado en 5 diferentes clases:

Clases

Bits Primer Octeto

Rango IP

Máscara de Red

Número de Redes

Hosts/red

Direc. Broadcast

Clase A

0xxxxxxxx

1.0.0.0-126.255.255.255

255.0.0.0

126

16777214

x.255.255.255

Clase B

10xxxxxx

128.0.0.0-191.255.255.255

255.255.0.0

16382

65534

x.x.255.255

Clase C

110xxxxx

192.0.0.0-223.255.255.255

255.255.255.0

2097150

254

x.x.x.255

Clase D (Multicast)

1110xxxx

224.0.0.0-239.255.255.255

-

-

-

-

Clase E (I+D)

11110xxxx

240.0.0.0-255.255.255.255

-

-

-

-

 

Propósito

Rangos IP Reservadas

Máscara de Red

Número de Redes

Hosts/red

Direc. Broadcast

IP “Comodín”

0.0.0.0-0.255.255.255

255.0.0.0

1

16777214

0.255.255.255

Loopback

127.0.0.0-127.255.255.255

255.0.0.0

1

16777214

127.255.255.255

Enlace Local

169.254.0.0-169.254.255.255

255.255.0.0

1

65534

169.254.255.255

Sin Uso

192.0.0.0-192.0.0.255

255.255.255.0

1

254

192.0.0.255

TEST-NET-1

192.0.2.0-192.0.2.255

255.255.255.0

1

254

192.0.2.255

6TO4

192.88.99.0-192.88.99.255

255.255.255.0

1

254

192.88.99.255

Pruebas

198.18.0.0-192.19.255.255

255.128.0.0

2

131070

198.19.255.255

TEST-NET-2

198.51.100.0-198.51.100.255

255.255.255.0

1

254

198.51.100.255

TEST-NET-3

203.0.113.0-203.0.113.255

255.255.255.0

1

254

203.0.113.255

Broadcast

255.255.255

-

1

1

255.255.255.255

 

Antes de explicar algunas peculiaridades de este sistema, se hace necesario hablar ya de IP Privada Vs IP Pública

Del esquema anterior se podría inferir que la ICANN podría asignar cualquier IP o rango de estas a cualquier entidad/organización/persona que desease, pero esto no es así. No solo ya de por sí podemos ver que algunos de los rangos mostrados ya de por sí se encuentran reservados para propósitos específicos (los cuales hablaremos más adelante) y que podemos llamar como IPs Reservadas. Pero aún hay más. Con el fin de poder expandir enormemente el número de dispositivos que pudiesen conectarse a la Red de Redes y con el fin de poder crear Redes sin necesidad de estar conectadas a Internet, surgió la necesidad de usar rangos IP reservados exclusivamente para el uso privado. A estas IPs son las que conocemos como IPs Privadas. Es evidente que por el otro lado tendríamos lo que llamamos IPs Públicas. Al contrario de los rangos IP públicas, las IPs privadas y reservadas son usadas de forma simultánea en todas partes del mundo sin constituir esto un problema, ya que dichas IPs se usan tan solo dentro del marco de una Red Privada. Dicho de otro modo, cada usuario puede si desea hacer uso de los rangos de IP Privada para crear la red que mejor se ajuste a sus necesidades. El caso de las IPs reservadas es un poco más peculiar, dado que su uso generalmente no está orientado a identificar un host concreto, sino más bien son usadas por otros servicios, los cuales como ya hemos dicho se tratará más adelante.

El uso de IPs privadas para la creación de una Red Privada es muy ventajoso, pero si se desea usar conectar dicha red privada a Internet es necesario un dispositivo (generalmente hardware) que pueda convertir de algún modo nuestras direcciones IP privadas en públicas. Y esto lo conocemos como Network Address Traslation (NAT) o traductor de direcciones de red.

Se estableció así los 3 rangos diferentes de IPs privadas dentro de todo el espacio IPv4. Es evidente que al estar reservadas estas para dicho fin, no podrán ser usados para otro. Cada rango cae dentro precisamente de cada una de las 3 clases de IP principales, de este modo cada usuario/empresa/organización puede usar aquellas que más se ajuste a sus necesidades.

 

Clases

Rango IP

Máscara de Red

Direc. Broadcast

Clase A

10.0.0.0-10.255.255.255

255.0.0.0

10.255.255.255

Clase B

172.16.0.0-172.31.255.255

255.255.0.0

172.x.255.255

Clase C

192.168.0.0-192.168.255.255

255.255.255.0

192.168.255.255

 

Es muy común por tanto hablar tanto de IP privada como IP pública. Al contrario de lo que pueda pensarse, la IP privada es la que menos importancia podría tener nuestro sistema de puertas para fuera, dado que lo que realmente identifica nuestra red desde el exterior es nuestra IP pública. Son los dispositivos de red como los routers los que hacen posible el intercambio de información entre las redes privadas e Internet.

Vamos a explicar algunas cuestiones de las clasificaciones anterior a la par que vamos a aprovechar para añadir algunos términos más:

  • IP Privada: Ya hemos hablado de ella, son rangos específicos dentro del espacio de direcciones, de uso exclusivamente propio, no tiene valor más allá de nuestra red.
  • IP 0.0.0.0: Este será la primera IP reservada que nos encontremos. La IP 0.0.0.0 es digamos la IP comodín, es decir, hace referencia a cualquier IP, ya que es necesario en multitud de tareas poder usar una IP que signifique “Todas”. Pensar en cuando se desea aplicar una regla en un firewall para permitir todas las IPs, o denegar todas. La dirección 0.0.0.0 es ese “Todas”.
  • IP 127.0.0.0: También se conoce como IP de retroalimentación, de Loopback, IP del propio host. Si la IP 0.0.0.0 hace referencia a Todas, la IP de Loopback hace referencia siempre a sí mismo. Es decir, para un equipo, sea cual sea la IP que tenga asignada él se podrá siempre identificar a sí mismo para tareas locales como 127.0.0.1. Esto es tremendamente útil, dado que no depende de la IP que pueda tener asignada para poder hacer uso de sus propios recursos de red.
  • Enlace Local: Rango de IP usado tan solo en ámbitos locales por ciertos servicios, por ejemplo por APIPA, un sistema usado para configuración automática de IP cuando otros sistemas como DHCP no están disponibles.
  • Test-NET-X: Son rangos reservados para ser usados en documentación y/o ejemplos didácticos, así como en código fuente ejemplo.
  • 6TO4: Con la inminente salida de IPv6, se ha reservado un espacio por el cual podrá circular contenido IPv6 hacia direcciones IPv4 y viceversa. Esto es necesario dado que no se puede implementar un sistema que sea diferente de la noche a la mañana, y durante un tiempo (posiblemente largo) ambos estándares deberán de convivir uno con el otro, ya que el soporte hardware de los dispositivos personales, así como dispositivos de red, es completamente necesario. Este rango será usado para facilitar esta tarea.
  • ID de Red: Si uno es cuidadoso y realiza las multiplicaciones por sí mismo, se dará cuenta que siempre desaparecen dos posibles direcciones que podrían usarse para hosts. Es decir, por ejemplo para el rango de clase C 192.168.10.0, decimos que tenemos disponibles un total de 254 hosts para dicha red. ¿De dónde sale este número? Dado que la máscara de Red es 255.255.255.0, tan solo podríamos tener un total de 256 hosts, el último octeto es el que estaría reservado para ello. Lo que sucede es que dos de ellas podemos decir que se encuentran reservadas. En el ejemplo puesto, la dirección IP 192.168.10.0 no podría ser usada jamás para identificar un hosts, dado que dicha dirección en dicho ejemplo sería la red misma, es decir el ID de red.
  • Dirección de Broadcast: Continuando con el punto anterior, para la red 192.168.10.0 y la máscara de subred 255.255.255.0, existe otra dirección reservada conocida como dirección de broadcast. Esta dirección es muy importante, dado que es por así decirlo el canal de comunicación común de toda nuestra red. Esta dirección es siempre el último host de la red, en este caso sería 192.168.10.255. Pero que es ¿Broadcast?

    Existen diferentes modos de comunicación entre diferentes dispositivos. Quizás el método más simple sería aquel en el que un host mantiene una comunicación directa con otro hosts. En este caso hablaríamos de Unicast. Pero es posible que el hosts con el que queremos entablar una comunicación no sea siempre el mismo, sea tan solo uno pero dependiendo de ciertas circunstancias pueda ser uno u otro, por ejemplo en función de la distancia entre ambos. La comunicación sería de nuevo tan solo entre dos hosts, aunque el destino no tendría que estar específicamente tipificado. En este caso estaríamos hablando de Anycast. Unicast y Anycast es posiblemente los dos sistemas de comunicación más usados, pero muchas veces se puede tener la necesidad de tener que enviar un mensaje a más de un hosts. Así, por Multicast entendemos un sistema de comunicación de uno a muchos, en el que esos muchos forman entre ellos un colectivo propio dentro de la misma red por supuesto. Por último, podemos desear poder enviar o comunicarnos con todos los hosts de nuestra red, en un esquema de “Uno a Todos”, y es lo que llamamos Broadcast. Un ejemplo sencillo de broadcast es la televisión, sale de un emisor pero el receptor somos todos, no va dirigida a nadie en particular, y el ejemplo más común de multicast podría ser los servicios de televisión por internet.

    Visto esto, comprendemos el significado de la dirección broadcast de nuestra red, dado que muchos mensajes son necesarios emitirlos a todos los miembros de nuestra red, ya sean informativos o con simples fines distributivos. Podemos decir por tanto que el último host de una red, queda también reservado y no puede ser usado como un host concreto.

  • Subred: En realidad el término “Máscara de Red” sería tan solo aplicable a la máscara por defecto de una IP según su clase. Por ejemplo, la máscara de red para una IP de clase C será 255.255.255.0. Esto es importante, dado que no se debe de confundir con una Subred o una Máscara de Subred. Según la clasificación anterior, se podría pensar que no hay necesidad de subredes, dado que el espacio ya está dividido en diferentes clases que se amoldan a la gran mayoría de todos los interesados. Es cierto que la ICANN jamás otorgaría una IP de clase A a un particular, dado que sería una pérdida absurda de direcciones IP, ningún usuario particular tendría la necesidad de crear una red de 16777214 dispositivos. Al contrario, la ICANN tiene (solía asignar, dado el agotamiento de estas) asignado tan solo IPs de clase A a los propios gobiernos de cada país o a grandes empresas/organizaciones, la mayoría de ellas por razones históricas, como Intel, MIT… Hay que tener en cuenta que la ICANN tan solo disponía de 126 paquetes de direcciones de clase A. Por el contrario la ICANN asignaba IPs de clase B a grandes empresas y organizaciones de forma común, pensar que en este caso ya no disponía de tan solo 126 paquetes, sino 16380. Y por último los paquetes de clase C que serían los que podrían ser otorgados a particulares.

    Aunque este reparto pueda parecer suficiente, lo cierto es que no lo es. Según esto, si un particular recibiese por parte de la ICANN un red de clase C con sus 256 IPs, por ejemplo la red 193.125.222.0, el usuario tan solo podría tener una red con 256 hosts. Pero qué pasa si el usuario quiere tener 2 redes diferentes en vez de tan solo una? No podría. En cambio, podría tener un router en la entrada de su red, con una máscara de subred de 255.255.255.192, lo cual me daría la posibilidad de tener 4 subredes distintas, cada una de ella con 62 (64 menos el ID de red y la dirección de broadcast). Así, la dirección IP 193.125.222.2 pertenecería a la subred 1, mientras que la IP 193.125.222.130 pertenecería a un host en la subred 3.

    De este modo, la creación de subredes es el método más eficiente para la gestión de las propias IPs. Es evidente que nunca podremos trabajar con máscaras más pequeñas que la máscara por defecto que tenemos, pero si podemos trabajar con máscaras más grandes para seccionar y optimizar la red.

  • Clase D: Las direcciones de clase D están reservadas para usarse de manera interna para propósitos de multicast. Ya hemos explicado esta técnica, pero como saben los dispositivos que dirección multicast escuchar? Lo normal es que antes de que esto sea posible, un host tiene que realizar una petición de unión a un grupo multicast, petición que realizará a través de una dirección multicast. Después de esto, el dispositivo de red (generalmente un router) reenviará el mensaje de él o para él al resto, dado que el conoce quienes son todos los miembros del grupo multicast.
  • Clase E: Tan solo se puede decir que es un rango de IP reservado para poder hacer pruebas, experimentos…. o simplemente para futuros usos.
  • IP 255.255.255.255: Esta IP sería algo así como la dirección de Broadcast para redes no constituidas. Si comprendemos que la dirección 0.0.0.0 es la dirección IP que hace referencia a cualquier hosts, la dirección IP 255.255.255.255 sería su IP de broadcast, siempre por supuesto hablando dentro de una red local, una red privada.

 

A pesar del uso de direcciones IP privadas con dispositivos NAT y al excelente trabajo de gestión de la ICANN para aprovechar al máximo las direcciones IPv4, ha sido muy normal el uso de direcciones IP dinámicas. Esto no es más que una práctica de los ISP para asignarnos IPs que podríamos llamar de “sesión”. Es evidente que jamás todos los clientes de un mismo ISP estarán conectados a la red de manera simultánea, luego sería un desperdicio de IPs. Imaginar que un ISP tiene arrendado un paquete de un millón de IPs y tiene un millón de clientes, luego asigna una a cada uno de ellos y problema resuelto. Pero como hemos dicho es evidente que esto no será jamás así, y a lo mejor las estadísticas dicen que en el mejor de los casos se forman picos de 700.000 usuarios conectados. Dicho ISP podría por lo tanto tener un paquete IPs de tan solo 700.000 direcciones, lo que le costaría sensiblemente menos. Como se gestionan estas IPs? En realidad igual que las IPs estáticas. Cuando conectamos a nuestro ISP este nos asigna una IP temporal. Dicho tiempo puede venir dado en función de la sesión o de un tiempo concreto. Una vez se da dicha circunstancia, la IP es liberada y la próxima conexión/sesión usará otra IP. De este modo si apagamos por las noches el router por ejemplo, nuestro ISP podrá reasignar dicha IP a otro cliente que quiera establecer una conexión. Por tanto, consideramos una IP dinámica aquella que varía de forma habitual con el tiempo o por conexión, e IP estática aquella que persiste. Por supuesto, el concepto aplicado a un ISP es exactamente igual que aplicado a una red local (LAN), donde la IP puede ser asignada de forma estática (por ejemplo estableciéndola en el mismo adaptador) o dinámica (por ejemplo usando servidores DHCP).

El uso de una IP dinámica o estática tiene pros y contras. Por un lado el uso de IPs dinámicas por parte de los ISP les ahorra dinero en cuanto a número de IPs necesarias, así como aumenta la seguridad y privacidad de cara al usuario, dado que su IP nunca será fija y por ende un difícil objetivo de amenazas externas. Pero por otro lado el uso de IP estáticas permite tener acceso a una serie de servicios mayores, como cualquier servicio que sea IP dirigido. Al ser la IP estática nuestro equipo/red estará siempre identificada desde el exterior, haciendo muy sencillo el uso de servidores Web/eMail o cualquier otro que nos imaginemos.

Para terminar completamente con IPv4, y dado que a estas alturas deberíamos de conocer a menos a groso modo el funcionamiento del modelo OSI/TCPIP, es interesante conocer como es un paquete IP. Recordemos que en cada nivel se encapsulará el contenido de nivel superior con el contenido añadido del nivel propio. En el caso del protocolo IP, es un protocolo de nivel 3, el cual tomará el mensaje del nivel de transporte como SDU, y le añadirá una cabecera propia, para poder así conformar el PDU del nivel 3, es decir, un paquete IP, tal y como lo encontramos en las especificaciones de 1981.

Versión

IHL

DiffServ

Longitud

Identificación

Flag

Desplazamiento de Fragmentos

TTL

Protocolo

CheckSum

IP Origen

IP Destino

Opciones (Variable)

Padding (Variable)

  • Versión (4 bits): Contendrá la versión del protocolo. Para la versión IPv4 el valor de dichos bits será 0100 (4).
  • IHL (4 bits): Es la longitud de la cabecera expresada en grupos de 32 bits. Es decir, si la cabecera tiene un total de 160 bits, 160/32 => IHL = 5.
  • DiffServ (8 bits): Originalmente usado para TOS (Type Of Service), fue sustituido en un RFC de 1998 para su uso como “Differenced Services” (Servicios Diferenciados), un sistema para QoS
  • Longitud (16 bits): Especifica el tamaño en Bytes del paquete IP completo. Al tener un campo de 16 bits podemos inferior directamente que el tamaño del paquete IP mayor que podemos tener es de 65535 Bytes (64KB)
  • Flag (3 bits): El bit de mayor peso se fuerza a cero y no es usado. El segundo bit especifica si el paquete se podrá o no fragmentar, de estar marcado como no fragmentar y es necesaria su fragmentación para enviarlo, este paquete se descartará. El bit de menor peso especifica si hay más fragmentos o no los hay.
  • Desplazamiento de Fragmentos (13 bits): A groso modo especifica el byte al que pertenece dicho fragmento. si es el primer fragmento tendrá un offset (desplazamiento) de 0, si fuese el segundo pues dependiendo ya de la fragmentación necesaria. ¿Por qué es la fragmentación necesaria? Podemos asimilarlo a la segmentación en el modelo OSI. Cada red tiene una unidad máxima de transmisión llamada MTU que precisamente especifica el tamaño máximo de un paquete. Esta es una limitación de la red, no del protocolo, esto es importante. La longitud máxima de un paquete IP es de 64KB, en cambio los enlaces Ethernet estándar suelen ser de 1500 Bytes, luego la fragmentación se puede convertir en algo “normal”. Esto significa que si se desea enviar por ejemplo una cantidad de datos de 5000 Bytes y tenemos una conexión ADSL con un MTU de 1492 bytes (cosa habitual), dicha información se deberá de fragmentar en paquetes IP más pequeños, cada paquete con un tamaño máximo (cabecera IP + datos) de 1492.

    Si atendemos a la cabecera IP expuesta arriba, cada fila corresponde a un total de 32 bits. Por tanto, la cabecera IP más corta que podríamos tener sería aquella que no se tiene el campo “Opciones”, lo que sería por tanto: 32 bits * 5 (filas) = 160 bits / 8 = 20 Bytes. La cabecera IP más larga que se puede estipular por otro lado serían 60 Bytes. Supongamos que disponemos por tanto de una Cabecera IP de un tamaño de 20 Bytes (la cabecera más simple). Si nuestra conexión ADSL tan solo puede manejar paquetes IP de 1492 Bytes significa que la cantidad de datos que pueden añadirse a nuestro paquete IP sería de 1492 – 20 = 1472 Bytes. Si deseamos enviar esos 5000 Bytes, será necesario crear paquetes IP más pequeños, en este caso un total de 4 paquetes:

    Cabecera IP 1 (20 Bytes)

    1º Cuarto SDU (Offset 0, tamaño = 1472 Bytes

    Cabecera IP 2 (20 Bytes)

    2º Cuarto SDU (Offset 1472, tamaño = 1472 Bytes

    Cabecera IP 3 (20 Bytes)

    3º Cuarto SDU (Offset 2944, tamaño = 1472 Bytes

    Cabecera IP 4 (20 Bytes)

    4º Cuarto SDU (Offset 4416, tamaño = 583 Bytes

  • TTL (8 bits): Tiempo de vida, es un contador que se establece a un número dado. Cada salto que de nuestro paquete, el dispositivo de red pertinente que procese el paquete decrecerá en uno su valor. Si el TTL llega a Cero, el paquete será descartado por la red (por cualquier dispositivo de red que lo esté procesando en ese momento). Esto es una medida de seguridad para evitar que paquetes perdidos puedan circular de forma indefinida por la red.
  • Protocolo (8 Bits): Estos 8 bytes representan un número que identifica el protocolo de nivel superior que está contenido en los datos que porta el paquete IP. El protocolo IP trabaja en el nivel 3 (nivel de red), pero los datos que maneja proceden del nivel superior 4, nivel de transporte. No obstante un paquete IP puede enviar como datos un protocolo de nivel 3 adjunto como datos, como es el caso de ICMP por ejemplo. Poner la lista completa es un poco absurdo, dado que casi con toda seguridad la mayoría de ellos jamás lleguemos a verlos en la vida. Quien lo desee puede acudir al RCF 790 para conocer la lista completa. Pero si cabe destacar los protocolos más usados:

    Protocolo = 1 -> ICMP; Protocolo = 6 -> TCP; Protocolo = 17 -> UDP;

  • CheckSum (16 bits): El protocolo IPv4 realiza una operación de checksum en la cabecera para garantizar la integridad NO EL PAQUETE COMPLETO, sino de la cabecera IP. Para ello se van sumando en complemento a uno cada 16 bits de la cabecera. Una vez terminada la suma se le realiza el complemento a uno al resultado y es este el que se inscribe en este campo. A la hora de verificarlo es igual, si el resultado obtenido (omitiendo el campo checksum) es el mismo que el que está en el cabecera, el paquete es válido.
  • IP Origen/IP Destino (32 bits cada campo) : Pues no es más que eso, la IP del sistema que envía el paquete y la IP del destino. Cabe decir que en teoría es posible modificar este dato a voluntad, lo cual deja ver lo relativamente vulnerable que es el protocolo ante el IP Spoofing (al menos en teoría)
  • Opciones y Padding (Variable, de 0 a 40 bytes): Este campo es de obligada implementación en el stack TCP/IP, pero dependerá de cada protocolo y cada paquete que sea necesario su uso o no. Es por ello la importancia del campo IHL. Si este campo tiene un valor de 5 significará que el campo Opciones no estará presente, y la cabecera tendrá una longitud fija de 20 Bytes. En cambio, el IHL pude tener un valor de entre 6-13, lo que implicará que el campo de opciones se está usando y tiene una longitud también conocida, entre 0-40 Bytes, gracias al padding final que se le añade.

    Este campo se utiliza en algunas redes por temas de seguridad por ejemplo, en el que en estos campos se indica que el contenido es considerado desde sensible a alta seguridad, o también se puede usar para indicar la fecha del paquete mismo o especifique una ruta concreta que deba de seguir el paquete.

    El Padding es simplemente un relleno que se le añade al campo de opciones para que este concluya en múltiplo de 32 bits, luego puede tener un tamaño de entre 1-31 bits, de esta forma no se rompe la estructura de la cabecera y simplemente conociendo el IHL es posible conocer exactamente el tamaño de la cabecera.



IPv6

Como se ha dicho, posiblemente la causa más urgente a solucionar es el agotamiento del espacio de direcciones IPv4. Esto es algo que era previsible no ahora, sino hace ya unos años. En 1998 se terminaron las especificaciones IPv6, y evidentemente como característica más marcada fue ampliar a 128 bits los 32 bits de las direcciones IPv4, lo que permitiría un número virtualmente infinito de direcciones. En realidad no es que sea infinito, pero de unos 4 mil millones pasaríamos a unos 3.4 x 10^38, es decir, 34 con 37 ceros a su derecha. Dicho de otro modo, se podría entregar a cada persona del mundo un espacio de direcciones miles millones… de veces superior que todo el espacio de direcciones IPv4, y eso solo para cada habitante!! Es evidente que esta será la diferencia más significativa entre IPv4, pero como veremos tampoco es la única.

Hay que tener en cuenta el por qué se clasificaron las direcciones IPv4 del modo que se hizo, y no fue otro que el de la buena gestión del espacio de este. Pero en IPv6 este problema desaparece, ya que podemos disfrutar prácticamente de un espacio ilimitado de direcciones, luego el esquema que conocemos a día de hoy se parte completamente y muchos de los conceptos y tecnologías usadas a día de hoy desaparecen… y desaparecerán en los próximos años. Como organizaríamos el espacio de direcciones IP si pudiésemos disponer de forma ilimitada de estas?

En realidad la única complejidad que tiene IPv6 frente a IPv4 es que posee unas reglas mucho más específicas de direcciones, de este modo también es más fácil tener un reparto de direcciones de forma mucho más lógico y ordenado. La idea básica que se tendrá siempre presente es que si una interfaz de red tiene asignada de fábrica un ID único llamado comúnmente dirección MAC (de 48 bits), se podría usar dicha MAC como extremo último de una dirección IPv6.

¿Qué es una dirección IPv6?

Si bien a día de hoy la penetración de IPv6 es mínima, estas direcciones comenzarán a formar parte de nuestra vida de forma bastante habitual dentro de muy pocos años. En este caso hablamos de un espacio de direcciones inicial de 128 bits, es decir, 2128 direcciones posibles. Con IPv4 la forma más habitual de representarla era por medio de 4 octetos: 4*8= 32bits en notación decimal. El problema es que si se usase el mismo esquema para las direcciones IPv6 se necesitarían 16 octetos, lo que resultaría en una dirección realmente grande de expresar:

125.223.0.25.158.231.45.0.0.0.0.0.98.250.115.23

Es evidente que no es una forma eficiente de representación. En lugar de la representación clásica IPv4, se usan 8 agrupaciones de dos octetos y en formato hexadecimal, no decimal. De este modo la dirección antes expresada podría simplificarse como:

7DDF:0019:9EE7:2D00:0000:0000:62FA:7317

A priori puede parecer que se tiene la misma complejidad, pero no es así. Para empezar 1 byte en decimal tiene una representación de hasta 3 dígitos, mientras que en hexadecimal jamás pasará de 2 valores. Además, es más cómodo la agrupación en bloques de 16 bits que de 8. Aun así, las reglas de notación se expanden precisamente para evitar la complejidad de representación, permitiendo la simplificación de estas direcciones. Por ejemplo, cuando un grupo de 16 bits posee tan solo ceros, es posible acotar los 4 en uno solo. Por otro lado, se puede si se desea omitir incluso todas las palabras (16 bits) siempre y cuando estas tengan un valor de “cero” y se encuentren contiguas entre sí. Dicho esto, de la dirección anterior podríamos simplificarla como:

7DDF:0019:9EE7:2D00:0:0:62FA:7317

Pero también podríamos representarla como:

7DDF:0019:9EE7:2D00::62FA:7317 (nótese los :: contiguos)

De este forma es posible acotar bastante la representación de estas. Pero en realidad esto tan solo es un efecto secundario de tener que manejar bloques de direcciones tan enormes. Y del mismo modo que el espacio de direcciones IPv4 se encuentra clasificado, con IPv6 sucede exactamente lo mismo, salvo con matices, dado que aquí desaparece la necesidad y los conceptos de Clases de IP, y prácticamente todas las IPs IPv6 pueden clasificarse como reservadas, de enlace local y Unicast. Pero veamos que sucede con la máscara de red/subred.

A pesar de tener un número de IPs virtualmente ilimitado, la necesidad de constituir redes independientes es evidente. El concepto de máscara de red/subred será usado prácticamente del mismo modo, aunque es cierto que de forma un tanto diferente. IPv6 pretende ser completamente jerárquico, lo que hará que sea también más eficiente a la hora de conocer el destino de un paquete (de cara a los router). Esta es la clasificación actual del espacio IPv6 según la IANA:

Prefijo

Uso

0000::/8

Reservada por IETF

0100::/8

Reservada por IETF

0200::/7

Reservada por IETF

0400::/6

Reservada por IETF

0800::/5

Reservada por IETF

1000::/4

Reservada por IETF

2000::/3

Unicast Global

4000::/3

Reservada por IETF

6000::/3

Reservada por IETF

8000::/3

Reservada por IETF

A000::/3

Reservada por IETF

C000::/3

Reservada por IETF

E000::/4

Reservada por IETF

F000::/5

Reservada por IETF

F800::/6

Reservada por IETF

FC00::/7

Unicast Única Local

FE00::/9

Reservada por IETF

FE80::/10

Unicast de Enlace Local

FEC0::/10

Reservada por IETF

FF00::/8

Multicast

  • Reservada por la IETF:

    La IETF es un organismo que gestiona el funcionamiento de todo esto. Son rangos de IPs que simplemente no están asignados a ninguna tarea.

  • Unicast Global:

    Aquí encontraríamos el espacio IPv6 que sería usado de manera global para especificar cualquier dispositivo de red, lo que en IPv4 podríamos conocer como IPs Públicas. Estas IPs tienen una estructura en común:

    Prefijo de Red

    Subred

    ID de interface

    n bits

    m bits

    128-n-m bits

El prefijo de red tiene la función del rutado principal dentro de todo Internet, podemos ver este como los bloques principales de IPs que se entregarían a los ISP o las grandes multinacionales por parte de los administradores de zona como RIPE, ARIN y otros.

La Subred sería administrada de manera local por los administradores de dichos bloques con la finalidad de configurar sus propias redes.

El ID de interface sería la punta de la flecha que señalaría cada host en concreto, de forma única dentro de cada subred y a su vez dentro de cada red principal. Este ID de interface vendrá a ser de forma similar a lo que hoy en día entendemos como dirección MAC de un dispositivo de red. Dicho de otro modo, cada IPv6 señalará directamente a cada adaptador de red en Internet.

Aun así, el mismo rango de direcciones posibles dentro de las direcciones Unicast Globales, se encuentra dividido y asignado de forma diferente:

Rango IP

Asignado a

2001:0000::/29 – 2001:01F8::/29

IANA

2001:0200::/29 – 2001:03F8::/29

APNIC

2001:0400::/29 – 2001:05F8::/29

ARIN

2001:0600::/29 – 2001:07F8::/29

RIPE NCC

2001:0800::/29 – 2001:09F8::/29

No asignado aun

2001:0A00::/29 – 2001:0BF8::/29

No asignado aun

2001:0C00::/29 – 2001:0DF8::/29

No asignado aun

2001:0E00::/29 – 2001:0FF8::/29

No asignado aun

2001:1000::/29 – 2001:11F8::/29

No asignado aun

No asignado aun

2001:FE00::/29 – 2001:FFF8::/29

No asignado aun


Una vez se vaya agotando cada bloque asignado a cada RIR, se le reasignaría un nuevo bloque.

  • Unicast Única Local:

    Este rango sería el equivalente al usado para las direcciones privadas en la actual IPv4. Su estructura no obstante sería exactamente igual que las direcciones IPv6 Unicast globales. Al igual que las direcciones privadas IPv4, las direcciones Unicast Únicas Locales tan solo tienen un ámbito de uso interno, y no serán (no deberían al menos) ser enrutadas fuera de la red local. De todos modos y por seguridad, el prefijo de red en este caso se establece en 40 bits, el cual será generado de forma aleatoria con el objetivo de que si en algún momento un paquete IPv6 con IPv6 única Local fuese enrutado al exterior y del exterior inyectado a otra red local, tener la garantía de que no correspondería a ningún hosts de esta. Dicho de otro modo, la probabilidad de que el host externo existiese sería a todos los efectos prácticamente nula, dado que teóricamente la IP generada para uso local sería única en toda Internet. Todo el resto del rango pasaría a ser administrado por la persona a cargo de la red a voluntad, del mismo modo que configuramos nuestras redes privadas. De este modo tendremos la posibilidad si así lo deseamos de conectar nuestra red directamente a Internet o aislarla de esta. Si fuese este último caso, es evidente que sería necesario hacer uso de dispositivos NAT para traducir las direcciones locales a una dirección IPv6 Unicast Global en caso de querer conectar dicha red al exterior, del mismo modo que se realiza a día de hoy con IPv4

  • Unicast de Enlace Local:

    A diferencia de Unicast única local, en este caso la IPv6 no solo no tendría un ámbito local, sino que esta no sería única. Es decir… esa misma IP podría ser encontrada en otros puntos del planeta, todo lo contrario que lo que sucede con el apartado anterior, que pese a ser de ámbito local pueden considerarse IPs únicas. Estas IPs corresponderían a las que en IPv4 podríamos llamarlas IPs APIPA, es decir, IPs de autoconfiguración propia sin necesidad siquiera de un enlace a un nodo de red:


    Prefijo de Red (10 bits)

    Subred (54 bits)

    ID de interface (64 bits)

    1111111011

    0

    Host


  • Multicast:

    En IPv6 el término IP Broadcast desaparece, y tan solo permanece el de Multicast. A fin de cuenta para enviar un paquete a toda una misma red no hace falta una dirección específica, ya que todos estos hosts pueden formar parte de un mismo grupo Multicast. Es decir, en IPv6 las direcciones de punto final :FF señalarían a hosts concretos.

    Por ello se reserva un rango específico para direcciones Multicast. Estas, si poseen una estructura algo diferente a las direcciones Unicast vistas hasta el momento, y tiene su lógica. Estas direcciones Multicast pueden tener tanto un ámbito local como global, por lo tanto se requerirán de ciertos bits específicos para esta diferenciación:


    Prefijo de Red (8 bits)

    Flag (4 bits)

    Ámbito ( 4 bits)

    ID de grupo (112 bits)

    11111111

    0 | R | P | T

    Ver tabla

    ID

Flag: Especifican algunas opciones de la IP multicast, como por ejemplo si la IP es permanente (T) o si es una IP que pertenece al propio prefijo de red (P).
Ámbito: Según el valor que tome, especificará el alcance de la dirección Multicast. Así por ejemplo, para un ámbito 1110 la IP multicast sería escuchada de manera global, mientras que si es 0010 el ámbito sería local. Las especificaciones completas las podemos encontrar si lo deseamos en el RFC 4291.

En adición de esto, existen ya preestablecidos grupos estándares, así como especificaciones mucho más amplias de cómo usar estas IPsv6 Multicast, pero tampoco es demasiado importante para nosotros.

  • IP no especificada e IP de Loopback:

    Del mismo modo que en IPv4 existen las IPs especiales 0.0.0.0 como IP comodín e IP 127.0.0.1 conocida como IP de retroalimentación o Loopback, en IPv6 existe exactamente lo mismo. Así la IP no especificada será la correspondiente a ::/128, mientras que la IP de Loopback corresponderá a ::1/128.

 

Además del ingente espacio de direcciones IP, IPv6 posee principalmente tres grandes mejoras frente a IPv4. La primera es que IPv6 está creado de base para ser usado con IPSec, protocolo punto a punto para el cifrado de las conexiones. Esto no significa que IPSec será usado en todo internet, sino que su implementación es obligada y cualquier sistema preparado para ello. La segunda característica es que los propios hosts y nodos extremos podrán auto negociar su propia IP, sin necesidad de un servidor DHCP. El proceso se realiza gracias al nuevo protocolo ICMPv6. El host enviará así un paquete ICMPv6 de descubrimiento a la dirección multicast de enlace local y si existe un router configurado para ello en un extremo, este le responderá directamente con los ajustes de configuración de este, según la estructura actual de su red. La tercera mejora son los conocidos como los paquetes Jumbo. Estos no son desconocidos, ya que actualmente son usados en redes GigaEthernet para mejorar la transmisión de los datos, ya que es posible exceder el MTU de la red, enviando paquetes con un mayor tamaño.

De cara a como es en sí un paquete IPv6 (su cabecera) hay que destacar la simplificación que se ha realizado de la actual IPv4:

Versión

Clase de Tráfico

Etiqueta de Flujo

Longitud

Cabecera Siguiente

Límite de saltos

IP Origen

IP Destino



  • Versión (4 bits): Corresponde exactamente igual al valor de IPv4, es decir, específica la versión del protocolo. Para IPv6 tomará por tanto un valor de 0110
  • Clase de Tráfico (8 bits): Similar a al campo DiffServ de IPv4. Su objetivo es proveer al protocolo capacidades QoS, es decir, capacidades para priorización del tráfico, dado que por desgracia el ancho de banda siempre será limitado.
  • Etiqueta de Flujo (20 bits): Aun se encuentra en experimentación. La idea original consistía en la posibilidad de poder etiquetar los paquetes de forma que fuese adecuado para aplicaciones en tiempo real como VoIP, o para sistemas QoS no estándares. No es un requerimiento actual, y puede establecerse todo a ceros si no es usado. Recordemos que IPv6 es aún un protocolo experimental que está en sus primeras fases. Hasta que no pase X tiempo en el entorno real y a gran escala, no se podrá con casi toda seguridad retocarlo para obtener las mejores prestaciones.
  • Longitud (16 bits): Especifica ni más ni menos la longitud en bytes de los datos que serán enviados por el paquete sin contar la propia cabecera. Es decir, si el SDU de la capa superior ocupa 60KB, la longitud será 60KB. A esto hay que añadir que IPv6 permite extensiones de la cabecera para añadir funcionalidades opcionales. Estas extensiones de la cabecera NO forman parte de la cabecera en sí, e irían justo antes del SDU. Esto quiere decir que el tamaño de las extensiones de la cabecera sí será contabilizado en este campo. Al ser un campo de 16 bits permitirá de nuevo un tamaño máximo de paquete de unos 64KB.
  • Cabecera Siguiente (8 Bits): Tiene la misma funcionalidad que el campo “protocolo” de IPv4. Especifica la cabecera que se encontrará después de la cabecera actual. En IPv4 hacía referencia prácticamente tan solo al protocolo usado en el SDU superior, pero aquí puede especificar también las extensiones de cabecera, como por ejemplo extensión de cabecera para fragmentos.
  • Límite de Saltos (8 bits): Es el campo TTL (Time To Live) de IPv4. Cada salto que dé el paquete, este contador será decrementado en 1. Si llegase a cero, el paquete se descarta de la red.
  • IP Origen/Destino (128 bits cada campo): Cada dirección IPv6 de 128 bits, primero la IP de origen y después la IP destino.

Es interesante ver como por ejemplo se ha eliminado de la cabecera IPv6 el checksum, dejando la comprobación de integridad directamente sobre los niveles superiores e inferiores. Aunque las ideas en papel son buenas, hay que tener en cuenta que las estadísticas y la realidad son otras. A lo mejor en un principio se estimó que la comprobación de la integridad de una cabecera IP era adecuado a principios de Internet dado la poca fiabilidad de las redes antiguas. A día de hoy se ha demostrado que la comprobación de la cabecera en IPv4 quizás tan solo era útil (es decir, existía un error y este era detectado) en un porcentaje tan ínfimo que su uso ha dejado de ser necesario, máxime cuando niveles superior e inferiores ya poseen controles de integridad adecuados (los cuales antes también existían)

Las extensiones de cabecera son igualmente parte imprescindible de IPv6. Si bien es cierto que la cabecera base ha sido completamente reducida, parte de las opciones que existían en IPv4 ahora las podremos encontrar como extensiones. Estas extensiones serán indicadas en el campo “cabecera siguiente” antes descrito, que nos dirá que cabecera será la que encontraremos justo después de la cabecera base, es decir, antes de los datos superiores. Estas cabeceras no obstante jamás serán procesadas por un nodo de red, esto quiere decir que todos los nodos de los saltos intermedios que de un paquete desde el origen al destino, tan solo se procesará la cabecera base. Las extensiones de cabecera serán por tanto tan solo procesadas cuando el paquete alcance su destino final. La única excepción se dará cuando exista la extensión de cabecera Hop-By-Hop. La cual será siempre añadida como primera extensión de cabecera e identificada por “Cabecera siguiente” como un cero.

Las extensiones especificadas actualmente en IPv6, así como su orden (en caso de que exista más de una extensión de cabecera) es el siguiente:

Cabecera IPv6 Base
Cabecera Hop-By-Hop
Cabecera de Opciones de destino (Para ser procesada tan solo por el primer destino/salto)
Cabecera de Rutado
Cabecera de Fragmentos
Cabecera de encapsulación de seguridad de los datos
Cabecera de Opciones del destino (Para ser procesada tan solo por el destino final)
Cabecera de nivel superior

Cada cabecera tiene sus campos y opciones concretos, que podríamos especificar pero sería rizar más el rizo. De todos modos se puede acudir a las especificaciones para obtener las especificaciones detalladas en el RFC 2460. Lo que es evidente es que cada cabecera de extensión tendrá un campo que será también “Siguiente Cabecera”, puesto que en IPv6 puede existir más de una extensión de cabecera. No obstante, el tamaño de estas extensiones será siempre un número múltiplo de 64 bits, con la idea de que en ningún momento se pierda la alineación de los 64 bits (La cabecera completa de un paquete IPv6 será por tanto siempre múltiple de 64)

Para terminar con IPv6, hay que tener en cuenta que algunos protocolos asociados a IPv4 son modificados ligeramente para poder soportar IPv6, como es el caso por ejemplo de ICMPv6 o DCHPv6. Es evidente que por ello IPv4 e IPv6 son completamente incompatibles entre ellos. No obstante, durante algunos años viviremos posiblemente una utilización de ambos. Esto será posible no porque ambos protocolos sean compatibles, sino porque se usarán técnicas de túneles para poder lograr esta interoperabilidad. Es decir, cuando un router obtenga una petición IPv6 y quiera enviarla por una red IPv4 tendrá que encapsular el paquete IPv6 como un paquete IPv4 estándar. El paquete podrá viajar así a través de toda la red IPv4 hasta el nodo destino, en el cual el paquete IPv4 se abriría para dar origen al paquete IPv6 que sería rutado a través de la red IPv6. Este mismo concepto puede ser usado a la inversa. El problema principal al que uno se encuentra es el soporte hardware de IPv6, así como de técnicas de túneles descrita.

Para que un usuario a día de hoy pueda realizar una conexión a redes IPv6 de forma directa, necesitará primero que su ISP tenga una infraestructura IPv6 ya creada (cosa que actualmente es muy raro que tengan), por no hablar de que el router de cada particular sea compatible con IPv6. De cara a los PCs de los usuarios esto no es problema en Windows ni en Linux desde hace tiempo. El soporte para IPv6 existe desde hace tiempo y los equipos estarían perfectamente preparados para recibir direcciones IPv6 y conectarse a las redes pertinentes. Microsoft implementó además del soporte nativo IPv6 técnicas de túneles como Teredo para permitir la interoperabilidad, aunque como he dicho actualmente la penetración de IPv6 es mínima. Poco a poco las pruebas van terminándose, y además urge un nuevo espacio de Direcciones, IPv6 como hemos dicho está acabado. El principal problema por tanto recae tan solo en los routers y otros dispositivos de red, si no tenemos soporte en ellos, así como en las redes de nuestro ISP, no podremos hacer mucho. Veamos un ejemplo de conexión a una red IPv6:

Interfaz en Windows 7 para IPv6:

Adaptador de Ethernet Local Area Connection:
Sufijo DNS específico para la conexión. . :
Descripción . . . . . . . . . . . . . . . : Marvell Yukon PCI-E

Gigabit Ethernet Controller #2
Dirección física. . . . . . . . . . . . . : xx-xx-x-xx-xx-xx
DHCP habilitado . . . . . . . . . . . . . : sí
Configuración automática habilitada . . . : sí
Dirección IPv6 . . . . . . . . . . . . . :2002:xxxx:xxxx:x:xxxx:xxxx:xxxx:xxxx(Preferido)
Dirección IPv6 temporal. . . . . :2002:xxxx:xxxx:x:xxxx:xxxx:xxxx:xxxx(Preferido)
Vínculo: dirección IPv6 local. . . : xxxx::xxxx:xxxx:xxxx:xxxx%12 (Preferido)

Dirección IPv4. . . . . . . . . . . . . . : 192.168.x.x(Preferido)
Máscara de subred . . . . . . . . . . . . : 255.255.255.0
Concesión obtenida. . . . . . . . . . . . : sábado, 05 de junio de 2010 21:05:12
La concesión expira . . . . . . . . . . . : miércoles, 13 de julio de 2146 3:39:47
Puerta de enlace predeterminada . . . . . : xxxx::xxx:xxxx:xxxx:xxxx%12
192.168.x.x
Servidor DHCP . . . . . . . . . . . . . . : 192.168.x.x
Servidores DNS. . . . . . . . . . . . . . : 192.168.x.x
NetBIOS sobre TCP/IP. . . . . . . . . . . : habilitado

 

Petición DNS IPv6:

ipv6.l.google.com: type AAAA, class IN, addr 2a00:1450:8002::68
Name: ipv6.l.google.com
Type: AAAA (IPv6 address)
Class: IN (0×0001)
Time to Live: 5 minutes
Data length: 16
Addr: 2a00:1450:8002::6a

 

Paquete TCP/IPv6:


 

 

Protocolo DNS

Domain Name System (o Sistema de Nombres de Dominio en español) es la segunda piedra angular en la que se sustenta no solo Internet, sino todas las rede en general. Al igual que IP, DNS no es más que un espacio de direcciones por así decirlo, aunque sería más correcto usar el término de espacio de nombres. Es curioso el hecho de que incluso los menos instruidos en la materia en algún momento ha escuchado o ha tenido que tratar con IPs, pero en cambio los términos DNS parecen mucho más difusos y raramente tenidos en cuenta, quizás tan solo cuando el ISP nos da la configuración de nuestra línea. No obstante, gracias al sistema DNS conocemos internet como la conocemos. ¿Es realmente necesario el sistema DNS? No, su existencia no nace de una “necesidad” propiamente dicha, sino de ser un recurso de increíble valor para cualquier persona, dada las limitaciones mentales que todo el mundo tenemos: Siempre conoceremos el nombre de una persona, pero solo algunos de sus números de teléfono.

El sistema DNS puede verse por tanto como un sistema de mapeo de direcciones IP a nombres. Es simple, cualquier persona del mundo será capaz de recordar nombres como google.es, microsoft.com, intel.com o theliel.es con infinita más facilidad que recordar (en el mismo orden): 216.239.59.104, 207.46.197.32, 198.175.96.33, 188.121.46.128. Y eso por supuesto si tenemos en cuenta el sistema actual IPv4, si tenemos en cuenta la proximidad de IPv6 el problema sería infinitamente mayor. Es evidente por tanto que aun cuando técnicamente no es imprescindible, de cara a las capacidades limitadas del ser humano podemos decir que sí lo es.

Cada vez que hacemos mención en alguna red (ya sea local o externa) de un nombre de domino, el sistema DNS hace posible la comunicación con dicho host, lo que sucede es que este sistema trabaja aparentemente siempre de forma transparente para nosotros, del mismo modo que para un usuario que navega por internet no entiende de IPs ni las necesita, lo cual no significa que sin saberlo las esté empleando de forma continuada.

Hay que tener presente como se vio en el capítulo anterior, que al igual que se gestiona el espacio de direcciones IP, se gestiona el espacio de nombres. Esto quiere decir que no existirán dos nombres iguales para el mismo dominio. ¿Dominio? Esto es algo que también se explicó. El sistema DNS es jerárquico, dividido por así decirlo en dominios, de forma que cada dominio superior gestiona sus dominios secundarios, y estos secundarios los dominios terciarios y así sucesivamente. Ya vimos el papel de la ICANN a la hora de gestionar los dominios de primer nivel y como se delegan los dominios de segundo o tercer nivel a cada autoridad. También se habló de los servidores raíces y de función, pero aquí veremos realmente la importancia de estos, así como el funcionamiento real del sistema DNS. En esta ocasión vamos a suponer un ejemplo, y de este todo el funcionamiento DNS, comenzando por el ejemplo más simple y aumentando su complejidad:

 

  • Caso 1: No necesaria resolución DNS, especificación de IP de forma directa

    El caso más sencillo que podemos ver es cuando realizamos una solicitud directamente sobre una IP. Por ejemplo si deseamos obtener acceso a un recurso de red interna y conocemos de antemano la IP de dicho servidor. Si en el explorador de archivos de Windows tecleamos la ruta \\192.168.5.23 (por supuesto damos por hecho una correcta configuración de puerta de enlace, máscara de subred e IP), el PC se comunicará directamente con el host especificado, en este caso sin siquiera necesidad de acceder a la puerta de enlace del router, ya que la tabla ARP del sistema ya contiene la dirección de este (más adelante se verá el protocolo ARP), con lo que se hace la petición sobre la propia dirección MAC:

    Interfaz: 192.168.5.2 — 0xc
    Dirección de Internet Dirección física Tipo
    192.168.5.1 00-xx-xx-xx-xx-xx dinámico
    192.168.5.23 00-xx-xx-xx-xx-xx dinámico

    En el caso que la petición sea realizada en el navegador, por ejemplo especificando de forma directa la IP del servidor de google en España: “216.239.59.104″, el proceso será exactamente igual, la petición saldrá por nuestro router e irá directamente hacia dicha IP (nuestro paquete irá saltando de router en router hasta alcanzar el host indicado, pero sin ninguna necesidad de uso del sistema DNS:

    tracert 216.239.59.104

    1 <1 ms <1 ms <1 ms Alpha5 [192.168.x.1]
    2 35 ms 35 ms 36 ms 192.168.153.1
    3 35 ms 35 ms 32 ms 209.Red-81-46-42.staticIP.rima-tde.net [81.46.42.209]
    4 80 ms 42 ms 42 ms So6-0-0-0-grtmadno1.red.telefonica-wholesale.net.10.16.84.in-addr.arpa [84.16.10.65]
    5 43 ms 64 ms 64 ms Xe9-1-0-0-grtpartv2.red.telefonica-wholesale.net [84.16.15.174]
    6 65 ms 65 ms 63 ms Xe0-3-0-0-grtpartv1.red.telefonica-wholesale.net [84.16.12.213]
    7 * * * Tiempo de espera agotado para esta solicitud.
    8 77 ms 72 ms 104 ms 209.85.251.40
    9 76 ms 74 ms 72 ms 209.85.248.95
    10 75 ms 78 ms 75 ms gv-in-f104.1e100.net [216.239.59.104]

     

  • Caso 2: Resolución DNS en archivo local

    En este caso no se hace uso del sistema DNS como tal, sino de archivos de texto existentes en cada equipo que contienen precisamente este mapeo de nombres-IPs. Históricamente era el sistema usado para esta tarea, y aun cuando a día de hoy el sistema DNS es usado de forma global, este sistema se continúa usando de forma relativamente extendida, aunque generalmente por propósitos un tanto diferentes. Ya hemos hablado alguna vez de ello: El archivo “Hosts”. Este archivo presente en la gran mayoría de todos los sistemas operativos es el que mantiene esta lista, puesto que no es más que una lista. En Windows por ejemplo podemos encontrarlo en “C:\Windows\System32\Drivers\etc\Hosts”, mientras que en Linux lo encontramos en “/etc/hosts”. Veamos un ejemplo de este fichero:

    192.168.x.52 alpha
    192.168.x.52 beta.com
    209.85.229.104 google.es
    127.0.0.1 webpeligrosa.com

    Dado este fichero LOCAL de nuestro sistema, nuestro sistema estaría en condiciones de aceptar los primeros nombres en lugar de las direcciones IPs. Así, para acceder al hosts con la IP 192.168.x.52 se puede realizar conociendo su IP o su nombre de dominio, en este caso “alpha”. El segundo caso, beta.com es exactamente igual, solo recordar que el sistema jerárquico actual de dominios de primer nivel, segundo nivel… es una cuestión de eficiencia, organización y acuerdos, para una resolución local no es necesario tener el hombre de host asociado a un dominio TLD (de primer nivel).

    Más interesante es el tercer caso. Los dos primeros hacen referencia a direcciones locales, mientras que la tercera es una dirección global. Pero el proceso es el mismo. Sin la existencia de un sistema DNS como el actual, el archivo hosts de cada PC debería de tener dicha entrada si se quisiese poder acceder al servidor de google.es sin necesidad de conocer la IP de este. En este caso la IP mostrada es la IP real de google.es, esto es muy importante saberlo, puesto ¿qué sucedería si la IP que hemos añadido a dicho archivo realmente no perteneciese al servidor de google.es? El archivo hosts es un archivo de mapeo, sean las direcciones mapeadas legítimas o no. Esto quiere decir que si sustituimos dicha entrada del archivo hosts por ejemplo esta otra:

    217.146.186.221 google.es

    tendríamos algo tan gracioso como acceder a la web de Yahoo cuando en el navegador introducimos google.es. El mapeo del archivo hosts prevalece sobre cualquier resolución de nombres externa. ¿Qué utilidad puede tener esto? A día de hoy muchos tipos de malware modifican el archivo de hosts para enviar a los afectados a sitios donde realizar pishing o webs con código maligno para lanzar exploits o ataques XSS (entre otros) contra el usuario.

    El último caso, y posiblemente el más usado a día de hoy, es la redirección de ciertas páginas a la dirección IP de Loopback. Esta simple práctica abre la posibilidad a un sin fin de posibilidades, como por ejemplo el filtrado de hosts, ya que cualquier hosts redirigido a la dirección de Loopback será anulado por así decirlo (siempre que en el equipo local no tenga levantado ningún servidor web, claro está. Así por ejemplo en el caso mostrado, si redirigimos la URL webpeligrosa.com, que por ejemplo conocemos es altamente dañina, a nuestra dirección de Loopback, en cualquier momento que el PC intente una conexión a dicho host, ya sea premeditado o por la intervención de un malware, nuestro equipo la enviará a la dirección de Loopback, y con ello la web no será válida.

    Estos archivos hosts, este sistema tiene una gran serie de ventajas, pero tienen tres características que lo hacen completamente inviable de cara a una red extensa: La primera de ella es que un archivo local de estas características es fácil de administrar cuando los hosts a filtrar son pocos, en cambio si el número es elevado tendríamos desde problemas de rendimientos (cientos de miles de direcciones supondría tamaños de archivos considerables) hasta entradas duplicadas. El segundo problema es aún peor. Si poseemos un archivo de hosts con la resolución de 10 equipos, y uno de ellos cambia de IP es fácil localizarlo y cambiarlo. Si manejamos archivos de hosts de cientos o miles de equipos, se hace imposible la actualización de estos archivos. La tercera es que no dispone de ningún sistema centralizado, esto significa que cada archivo hosts debería de ser almacenado en principio de forma local, y cualquier actualización de cualquier hosts tendría que ser modificada en todos los equipos.

  • Caso 3: Resolución DNS en caché local

    Sin un archivo de hosts ni especificación de la dirección IP de forma directa, el equipo necesita de un sistema “superior” que permita darle a conocer dicha IP, y es por ello que el sistema DNS es necesario. Pero si se realizase una petición DNS por cada nombre de dominio introducido, sería una práctica enormemente ineficiente. Es cierto que la actualización en el caso 2 de la IP de un hosts es algo más que inviable en grandes magnitudes, pero igualmente es cierto que tampoco es algo que suceda constantemente. Si la IP de un hosts se mantiene relativamente “estable” con el tiempo, sería una tontería estar realizando peticiones DNS constantemente para resolver la dirección del hosts. Más aun, cada petición DNS que se realiza, tiene un coste en el ancho de banda y en la sobrecarga de los servidores de resolución DNS (estos los veremos más adelante)

    Por todo ello, no es rara la existencia de una caché a nivel local que almacene las peticiones más realizadas o más recientes. Imaginar por ejemplo que se desea acceder a la web de google.es y que 5 segundos más tarde deseamos realizar otro acceso a la misma web. Esto implicaría dos peticiones DNS. Con una caché de DNS local, con un tiempo de vida limitado evidentemente, sería el equipo local quien respondería la petición DNS de nuestro navegador, sin necesidad de enviar una petición DNS a nuestra puerta de enlace o directamente a nuestros servidores DNS:

    C:\Users\Theliel>ipconfig /displaydns >> dns.txt
    zxlinks.com
    —————————————-
    Nombre de registro . : zxlinks.com
    Tipo de registro . . : 1
    Período de vida . . . : 86400
    Longitud de datos . . : 4
    Sección . . . . . . . : respuesta
    Un registro (host). . : 127.0.0.1

    zxlinks.com
    —————————————-
    No hay registros de tipo AAAA

    arstechnica.com
    —————————————-
    Nombre de registro . : arstechnica.com
    Tipo de registro . . : 1
    Período de vida . . . : 2091
    Longitud de datos . . : 4
    Sección . . . . . . . : respuesta
    Un registro (host). . : 75.102.3.15

    Con ipconfig /displaydns mostramos el contenido de la caché DNS de Windows. En este caso vemos dos entradas en ella, una de ellas apunta a la dirección de Loopback, la otra la IP de dicho hosts. Esto es debido a que Windows introduce los host del archivo hosts en su caché DNS, con un tiempo de vida de 24 horas (86400 seg). Por otro lado registrará cualquier petición DNS reciente que sea realizada, de este modo si el sistema requiere la resolución de otro host en un tiempo en el que la caché aun tenga dicho registro, será esta quien devuelva el resultado en vez de realizar una petición. El lado negativo en cambio es que si un host modifica su IP en el tiempo que nuestro sistema está cacheando la IP, la IP no será actualizada para nuestro sistema, y posiblemente nos toparemos con una URL no disponible. Es decir, el uso de caché aumenta el rendimiento considerablemente, pero de cuando en cuando puede existir un problema de coherencia. Es por ello que casi cualquier sistema permite el vaciado de la caché DNS, en Linux suele ir asociado simplemente a reiniciar el servicio (dependiendo del servicio usado), en Windows se realiza mediante: “ipconfig /flushdns”

    Por encima de esta caché local, podríamos situar un caché aún más cercana al usuario que se resolvería antes que enviar la petición al sistema. Algunos navegadores como Firefox poseen una pequeña caché interna de resolución de DNS que realiza una función igual. Esta caché suele ser más pequeña y suele ser mucho más eficiente, dado que esta caché tan solo es usada para peticiones realizadas mediante el navegador. Esto quiere decir que cualquier otro tipo de peticiones producidas por gestores de correo, clientes FTP, conexiones de juegos/aplicaciones… ninguna de estas estarán registradas en dicha caché. En Firefox, para poder acceder a las opciones de caché de DNS es necesario acceder a la página de configuración avanzada mediante la dirección en la barra de direcciones: about:config, y dentro de esta buscar la clave “network.dnsCacheEntries” y “network.dnsCacheExpiration”, siendo ambos nombres bastante descriptivos sobre su función.

  • Caso 4: Resolución DNS en caché de nuestro router

    Del mismo modo que nuestro sistema cuenta con una pequeña caché para almacenar las peticiones DNS más recientes o más comunes, no es extraño pensar en que un sistema similar podría ser incluido por ejemplo a nivel de nuestro propio router, de modo que el router serviría a todos sus clientes conectados como servidor de DNS. Sería por tanto este quien resolvería por los clientes las peticiones pertinentes y devolvería a estos el resultado. Pero por el mismo motivo, podría mantener una caché interna de DNS con las peticiones no de un solo cliente, sino de todos los clientes conectados. Es decir, si el cliente 1 necesita acceder por vez primera al servidor google.es y segundos más tardes el cliente 2 quiere acceder al mismo servidor, es más que probable que el router no vuelva a realizar una petición DNS para conocer la IP del servidor google.es, sino que ya tendrá almacenada dicha entrada debido a la petición anterior del cliente 1, con lo que todo el sistema se agiliza de forma considerable, optimizando además el ancho de banda. De lo contrario el router tendría que esperar la contestación de los servidores DNS configurados en él, estos a su vez o devolver la petición o realizarla a un servidor superior… y tan solo cuando se obtiene la IP destino devolverla al hosts que la pidió, y una vez el hosts tiene la IP dele servidor poder realizar ahora sí la petición http (por ejemplo) pertinente. Esta función no obstante depende del router en cuestión, y al igual que la resolución de DNS en caché local, posee de pros y contras (en el 90% de las situaciones es una práctica que merece bastante la pena)

    Hay que tener en cuenta y no hay que confundir una caché DNS con un servidor DNS, el cual evidentemente mantiene una caché DNS. Existen routers en la actualidad que poseen funciones de servidor DNS y por tanto cachea las peticiones DNS. Por ejemplo podemos ver esto en las firmware del equipo de DD-WRT.

Resolución DNS por medio de los servidores DNS (caso 5)

Aunque sería el caso 5, vamos a verlo independientemente de los otros 4 casos, dado que es aquí donde se pone en marcha en realidad el sistema DNS. Todos los casos anteriores lo que impiden de un modo u otro es tener que hacer uso de este sistema, no porque sea ineficaz, sino para evitar la sobrecarga en este. Además, es evidente que cualquier petición realizada al exterior consumirá un tiempo superior a cualquier petición respondida de forma local. Veamos algunos tiempos de resolución gracias a la herramienta de resolución DNS Dig, disponible tanto para Linux (suele venir incluida) como para Windows (se debe de descargar):

theliel@Anarchy:~$ dig theliel.es
; <<>> DiG 9.7.0-P1 <<>> theliel.es
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58146
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 2362 IN A 188.121.46.128

;; Query time: 2 msec
;; SERVER: 192.168.3.1#53(192.168.3.1)
;; WHEN: Fri Jun 11 17:34:21 2010
;; MSG SIZE rcvd: 44

theliel@Anarchy:~$ dig @80.58.61.250 theliel.es

; <<>> DiG 9.7.0-P1 <<>> @80.58.61.250 theliel.es
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3856
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 2361 IN A 188.121.46.128

;; Query time: 66 msec
;; SERVER: 80.58.61.250#53(80.58.61.250)

;; WHEN: Fri Jun 11 17:34:22 2010
;; MSG SIZE rcvd: 44

Como podemos ver, la resolución DNS realizada por mi router en este momento es de tan solo 2 msec, es más que probable que tenga en su caché la resolución ya realizada. En cambio, si especifico que la resolución se lleve a cabo por medio de mi ISP, el tiempo se eleva a 66 msec, en este caso es el servidor DNS primario de telefónica España. Esta utilidad puede ser usada también para comprobar que servidores DNS son más óptimos para nuestra red. Por ejemplo, podemos ver el tiempo que tardaría los servidores de DNS de google, y si son mejores que los de nuestro ISP:

theliel@Anarchy:~$ dig @8.8.8.8 theliel.es
; <<>> DiG 9.7.0-P1 <<>> @8.8.8.8 theliel.es
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49868
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;theliel.es. IN A

;; ANSWER SECTION:
theliel.es. 3594 IN A 188.121.46.128

;; Query time: 97 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)

;; WHEN: Fri Jun 11 17:43:00 2010
;; MSG SIZE rcvd: 44

En este caso, el servidor de DNS de Google (8.8.8.8) tiene unos tiempos de resolución peores a los servidores de mi ISP. Esto también tiene su explicación. Por un lado la cercanía de los servidores, por otro lado la necesidad de dichos servidores de recurrir a servidores DNS superiores.

Cuando ningún sistema “local” puede resolvernos un nombre de dominio, es necesario realizar una petición DNS a un servidor DNS para que este nos devuelva la IP del host al que deseamos acceder. Cuanto antes sea respondida dicha petición, antes será alcanzado el hosts. La mejor forma de ilustrar esto es poner dos ejemplos: El mejor de los casos y el peor de los casos. De este modo se puede ver perfectamente el funcionamiento jerárquico de DNS y la importancia última de los servidores DNS raíces.

En el mejor de los casos, el servidor DNS de nuestro ISP tiene directamente la respuesta de nuestra petición. Es decir, imaginar que deseamos conocer la IP del servidor donde está alojado el dominio theliel.es. Si nuestro ISP posee esta entrada directamente en su servidor DNS, este no tendrá que acudir a un servidor de DNS superior y de forma inmediata devolverá la IP de este host. Pero si dicha entrada no se encuentra presente en el servidor de DNS de nuestro ISP, este a su vez debe de realizar una petición DNS a un servidor DNS superior a él, De este modo se realiza lo que se conoce como peticiones DNS recursivas, en la que nuestra petición DNS va saltando entre los diferentes servidores DNS hasta que alguno de estos servidores devuelve la IP deseada. Veamos el peor de los casos de este ejemplo cuando se desea conocer la IP del host earth.google.es:

theliel@Anarchy:~$ dig +trace @80.58.61.250 earth.google.es

; <<>> DiG 9.7.0-P1 <<>> +trace @80.58.61.250 earth.google.es
; (1 server found)
;; global options: +cmd
. 472319 IN NS f.root-servers.net.
. 472319 IN NS g.root-servers.net.
. 472319 IN NS h.root-servers.net.
. 472319 IN NS i.root-servers.net.
. 472319 IN NS j.root-servers.net.
. 472319 IN NS k.root-servers.net.
. 472319 IN NS l.root-servers.net.
. 472319 IN NS m.root-servers.net.
. 472319 IN NS a.root-servers.net.
. 472319 IN NS b.root-servers.net.
. 472319 IN NS c.root-servers.net.
. 472319 IN NS d.root-servers.net.
. 472319 IN NS e.root-servers.net.
;; Received 228 bytes from 80.58.61.250#53(80.58.61.250) in 400 ms

es. 172800 IN NS ns1.crn.nic.es.
es. 172800 IN NS ns1.nic.es.
es. 172800 IN NS ns1.cesca.es.
es. 172800 IN NS ns3.nic.fr.
es. 172800 IN NS sun.rediris.es.
es. 172800 IN NS ns-ext.nic.cl.
es. 172800 IN NS sns-pb.isc.org.
;; Received 376 bytes from 202.12.27.33#53(m.root-servers.net) in 99 ms

google.es. 7200 IN NS ns2.google.com.
google.es. 7200 IN NS ns1.google.com.
;; Received 79 bytes from 130.206.1.2#53(sun.rediris.es) in 66 ms

earth.google.es. 345600 IN CNAME earth.google.com.
earth.google.com. 86400 IN CNAME www3.l.google.com.
www3.l.google.com. 300 IN A 209.85.229.102
www3.l.google.com. 300 IN A 209.85.229.100
www3.l.google.com. 300 IN A 209.85.229.101

;; Received 132 bytes from 216.239.34.10#53(ns2.google.com) in 116 ms

En este caso, el servidor DNS de nuestro ISP (80.58.61.250) es incapaz de resolver la IP del host earth.google.es. Dado que no es capaz de resolver dicha dirección, no tiene otro remedio que realizar una petición DNS a un servidor que pueda conocer algo más de ese host. Aquí es donde cobra gran importancia la jerarquía de los dominios. En el host earth.google.es, el dominio de primer nivel es “es”. El servidor de DNS de telefónica no conoce cuales son los servidores de resolución DNS para los ccTLD .es, pero sí conoce la dirección de los servidores DNS raíces. El servidor DNS de telefónica consulta la lista de los servidores raíces y opta por enviar la petición al servidor raíz m (m.root-servers.net). El servidor raíz m recibe por parte del servidor DNS de telefónica una petición de resolución para el servidor DNS .es. El servidor raíz m SI CONOCE y si tiene en su base de datos la dirección de los servidores DNS que gestionan las direcciones ccTLD .es, y de entre todas ellas escoge el servidor sun.rediris.es, con lo que envía esta IP al servidor DNS de telefónica. Este conoce ya la IP del servidor de DNS que le podrá resolver la IP del dominio google.es, con lo que envía al servidor DNS anteriormente devuelto por el servidor raíz una petición de resolución para el dominio de segundo nivel google.es. El servidor sun.rediris.es recibe la petición por parte del servidor raíz M para resolver la dirección del host google.es (ya dentro del dominio de primer nivel .es). Esta consta en su base de datos, con lo que le responde de nuevo con la IP de la de la resolución del host del servidor de DNS de google, concretamente ns2.google.com. Dado que este es el último servidor de DNS que necesita, el servidor de telefónica que está realizando la recursividad solicita la resolución de earth.google.es a dicho hosts, dicho servidor recibe la petición de resolución para earth (ya dentro del dominio google.es), y dado que la posee envía la contestación al ISP y este a nosotros.

Lo normal es que todo este proceso se realice de forma completamente transparente por parte de nuestro ISP, y nuestro sistema tan solo realice una petición DNS, mientras que nuestro ISP puede realizar la petición recursiva DNS (es quien va enviando las diferentes peticiones según las respuestas que va recibiendo por parte de los servidores DNS) y es él quien al final nos envía a nosotros la dirección IP final. Aquí podemos ver la gran importancia de los servidores raíces, podemos decir que estos son los que poseen acceso directo a los servidores de DNS TLD. Si estos servidores raíces fallan, Internet falla, de ahí a ser objetivo de hackers desde que Internet nació y de ahí a que estén repartidos por todo el mundo y con numerosas réplicas en él.

Esta es la mejor imagen que he encontrado que ilustra todo el proceso: caché del navegador, caché del PC, caché del ISP y de cómo este envía la petición recursiva:


 

Tipo de Registros DNS:

Hasta ahora hemos hablado sobre cómo funciona el sistema DNS, pero está incompleto. Hasta ahora podríamos hacernos la idea de que un servidor DNS es a groso modo un sistema que procesa las peticiones DNS recibidas con una gran base de datos en la que asocia una IP a un nombre de dominio. Pero esto no es cierto. Esta base de datos no está constituida por una asociación IP -> Nombre de dominio, sino por un conjunto de registros asociados a cada dominio. Esto otorga al sistema DNS de funcionalidades mucho más extendidas, que no simplemente el mero hecho de conocer la IP de un host. Estos registros almacenan cierta información sobre el dominio en cuestión, por ejemplo el registro A lo que contiene es precisamente la IP de dicho dominio.

Aun cuando en la actualidad la lista de posibles registros DNS es mucho mayor, la inmensa mayoría de toda la red continúa usando tan solo algunos de los registros DNS que se crearon originalmente, aquellos especificados en el RFC 1035. De este primer abanico de registros, algunos son experimentales como los registros MB o MR, mientras que otros como MD y MF fueron sustituidos por otros más usados y con la misma finalidad. Veamos los registros DNS que podríamos considerar “útiles” de esta primera especificación:

 

  • A: Almacena la IPv4 del host, es decir, el mapeo de nombre de dominio – dirección IP de host.
  • NS: Especifica un servidor DNS para dicho dominio, es decir, el servidor DNS autorizado para dicho host.
  • CNAME: Más comúnmente conocido quizás como un alias. Es decir, especifica el nombre de otro nombre. Podría verse quizás como una redirección a nivel de DNS de un dominio a otro. Por ejemplo una entrada de este tipo: “correo.theliel.es CNAME gl2.gmail.com” significa que cada vez que se debe de resolver la IP para “correo.theliel.es”, se devolverá en su lugar la IP de gl2.gmail.com. En este caso, decimos que correo.theliel.es (o solamente correo, si damos por hecho que estamos en el dominio theliel.es) es un alias del host de google dado. Esto es usado constantemente. Hay que tener en cuenta que por su propia definición no es posible solicitar a un servidor DNS que nos respondan los alias de dicho dominio, pero sí podemos saber si un dominio/subdominio… dado es un alias de otro simplemente haciendo un ping. Veamos la diferencia entre hacer un ping a un alias o hacer ping a un host directamente:

    Ping a un alias:

    C:\Users\Theliel>ping earth.google.com
    Haciendo ping a www3.l.google.com [209.85.227.100] con 32 bytes de datos:

    Ping al host real anterior:

    C:\Users\Theliel>ping www3.l.google.com
    Haciendo ping a www3.l.google.com [209.85.227.139] con 32 bytes de datos:

    Al hacer un ping a un alias, este automáticamente nos “redirige” al host al que apunta el alias. Es decir, en los servidores de nombres de Google en algún lugar existirá una entrada de este tipo: earth.google.com CNAME www3.l.google.com. Para terminar indicar que aunque se puede hacer, no es recomendable anidar alias, es decir, un alias que apunta a otro alias que apunta al host.

  • SOA: Marca el comienzo de una zona DNS, entendiendo por zona DNS algo así como el ámbito de acción de dicha red. Es decir, los servidores DNS de google forman una zona DNS que casi con toda seguridad englobaría todos los servicios de google, todas sus redes, etc… pero es evidente que los servidores DNS de google casi con toda seguridad no poseen registros de otras zonas DNS como las de Yahoo, Microsoft…

    El registro SOA por tanto contiene en primer lugar el servidor DNS principal de la zona, así como datos administrativos: correo del administrador, número de serie, temporizadores de refresco… datos concretos sobre la propia zona DNS.

  • PTR: Puntero a un nombre de dominio. Su función principal es hacer resoluciones DNS inversas, es decir, en vez de obtener la IP por el host obtener el host por la IP. Un ejemplo de esto:

    C:\Users\Theliel>dig -x 74.125.77.104
    ; <<>> DiG 9.7.1rc1 <<>> -x 74.125.77.104
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1981
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;104.77.125.74.in-addr.arpa. IN PTR

    ;; ANSWER SECTION:
    104.77.125.74.in-addr.arpa. 86400 IN PTR ew-in-f104.1e100.net.

    Es decir si realizamos una resolución inversa de la IP 74.125.77.104 nos devuelve que es el host ew-in-f104.1e100.net, host de google.es

  • MX: Registro de intercambio de correo. Este registro es fundamental para el uso del correo electrónico, mapea un dominio a un servidor de correo (o una lista de posibles candidatos). Cada vez que enviamos un correo electrónico a una dirección, es necesario conocer el servidor de correo de dicho dominio. ¿Cómo? A través de la consulta de sus registros MX. Una vez obtenemos el host de dicho servidor podemos conectarnos a él para entregar el correo. En realidad el funcionamiento del correo electrónico es muy simple. Si enviamos desde Gmail por ejemplo (interfaz web) un correo a una dirección @live.com, aunque no sea nuestro navegador quien haga la consulta, el servidor de google por nosotros para poder entregar dicho mensaje primero tiene que conocer la IP o el destino de dicho realm (el realm es el @live.com). Por ciencia infusa Google no puede conocer la IP del host al que debe de entregar el correo. Realizaría algo similar a lo siguiente:

    theliel@Anarchy:~$ dig live.com MX
    .

    ;; QUESTION SECTION:
    ;live.com. IN MX

    ;; ANSWER SECTION:
    live.com. 2426 IN MX 5 mx1.hotmail.com.
    live.com. 2426 IN MX 5 mx2.hotmail.com.
    live.com. 2426 IN MX 5 mx3.hotmail.com.
    live.com. 2426 IN MX 5 mx4.hotmail.com.

    theliel@Anarchy:~$ ncat -C mx1.hotmail.com 25
    Connected to mx1.hotmail.com.
    Escape character is ‘^]’.
    220 col0-mc2-f34.Col0.hotmail.com Sending unsolicited commercial or bulk e-mail (bla bla bla)
    ehlo test
    250-col0-mc2-f34.Col0.hotmail.com (3.10.0.73) Hello [81.34.161.58]
    250-SIZE 29696000
    250-PIPELINING
    250-8bitmime
    250-BINARYMIME
    250-CHUNKING
    250-AUTH LOGIN
    250-AUTH=LOGIN
    250 OK
    mail from: <test@gmail.com>
    550 DY-001 Mail rejected by Windows Live Hotmail for policy reasons. We generally do not accept email from dynamic IP’s as they are not typically used to deliver unauthenticated SMTP e-mail to an Internet mail server. http://www.spamhaus.org maintains lists of dynamic and residential IP addresses. If you are not an email/network admin please contact your E-mail/Internet Service Provider for help. Email/network admins, please visit http://postmaster.live.com for email delivery information and support
    Connection closed by foreign host.

    Es decir, primero hay que conocer el servidor de correo, que es posible gracias a una consulta DNS de su registro MX. Este servidor nos responde con una lista de hosts disponibles, TODAS en esta ocasión con la misma prioridad (el número 5 que las precede, a menor número mayor prioridad a la hora de conectarse a uno u otro). Una vez que disponemos ya del host (mx1.hotmail.com en este caso) podemos conectarnos a él. OJO!! aunque se da ya por sabido en realidad cuando intentamos conectarnos al host citado, nuestro sistema deberá realizar otra petición DNS para conocer la IP del host mx1.hotmail.com, consultando el registro A de dicho dominio. Una vez que se realiza la conexión (en mi caso de ejemplo con ncat) el servidor de Gmail intentaría algo como lo expresado, mail from: <test@gmail.com>. En este caso el servidor de correos de live.com no nos permite continuar dado que detecta que la IP origen es dinámica (cuestiones de seguridad de los servidores de correo). En el caso de Gmail permitiría la conexión. Evidentemente es solo un ejemplo.

  • TXT: Es un registro reservado para cualquier tipo de información que se quiera añadir. A día de hoy se usa para una gran multitud de propósitos, ninguno específico.


No obstante, con el paso de los años se han ido haciendo necesario algunos registros adicionales, y a esta lista inicial deberíamos de añadir algunos más para poder dar la lista como “completa”, aunque evidentemente existan muchos otros registros, aunque también mucho menos usados:

  • AAA: Si el registro A mapeaba hosts a direcciones IPv4, es necesario disponer de un registro DNS que permite devolver del mismo modo direcciones IPv6. Su función es exactamente la misma, salvo que en vez devolver los 32bits de una IPv4 nos devolverá los 128 bits de la dirección IPv6.
  • SRV: Registro de servicios, otorga información sobre ciertos servicios. A día de hoy su uso es fundamental en aplicaciones tipo VoIP o muchos otros servicios modernos que dependen de una forma u otra de servidores más o menos específicos.


Paquete DNS:

Las peticiones DNS a fin de cuentas son datos que se envían, y al igual que una petición HTTP, este tiene su estructura por así decirlo. No obstante, DNS opera en el nivel de aplicación, por tanto hace uso de otros protocolos inferiores como UDP o IP para transmitirse. DNS usa el protocolo UDP para enviarse, usando el puerto 53 para tal efecto:

1 0.000000000 192.168.x.124 192.168.x.1 DNS Standard query A theliel.es
2 0.117633000 192.168.x.1 192.168.x.124 DNS Standard query response A 188.121.46.128


 

Problemas y soluciones a DNS:

Existen ciertas limitaciones en cuanto al sistema DNS. En realidad no son limitaciones en sí, sino problemas que surgen con los años. Para empezar y el más importante quizás es que DNS como tantos otros protocolos no se crearon para ser seguros, sino eficientes. Pensar por ejemplo que cualquiera podría construir un servidor DNS e intentar suplantar unas peticiones por otras malignas. O realizar ataques de envenenamiento DNS (que se verá en otro momento).

A todo esto se añade el problema de los actuales hosting virtuales, que permiten albergar en el mismo host diferentes servidores web funcionando al mismo tiempo. Con esto nos topamos cada día y nadie se pregunta en realidad cómo es posible, dado que un registro A tan solo devolverá la IP de un host, no la web que se quiere acceder a él. Es decir imaginar que deseamos acceder a una web http://ejemplo.com. Para poder realizarse la conexión es necesaria conocer la IP e imaginemos que la IP es 2.2.2.2. Ahora bien, en teoría solo bastaría una conexión a dicha IP por el puerto 80 y mediante el protocolo http para recibir dicha web. El problema aparece cuando en dicho host hay múltiples servidores web funcionando todos en el mismo puerto y al mismo tiempo. Es por eso que si en el navegador intentamos acceder a estos servidores por IP no podremos. Como saben estor servidores que web devolver? Gracias a las cabeceras HTTP que sirven de referencia al servidor para conocer la web que debe de devolver.

Por último y no menos importante son los conocidos como DDNS, o DNS dinámicos. Ya hemos visto la importancia de un dominio, y que los servidores DNS se van actualizando con el tiempo para tener siempre actualizada la IP a la que apuntan dichos nombres de dominio. No obstante la IP de un host no debería de variar demasiado, pero que sucede si tenemos un dominio que queremos que apunte a un host que posee una IP dinámica? Pues bien, existen servicios tanto gratuitos o de pago para sofocar esto. El sistema funciona de forma muy simple:

  1. Se nos otorga un dominio, normalmente un subdominio de segundo nivel, tipo “pepito.dyndns.org”
  2. Dado que nuestra IP puede variar incluso con cada conexión a la red, se crea una aplicación cliente que envía los datos de la nueva conexión cada vez que la conexión se debe de actualizar, y estos datos los envía precisamente a este proveedor de servicios, en este caso dyndns. Esta aplicación cliente enviaría nuestra IP actual, nombre de usuario y contraseña y con esos datos ellos actualizarían sus servidores DNS para actualizar así la IP asociada a dicho dominio.
  3. Nuestro host, aun teniendo una IP dinámica siempre sería accesible por medio del servicio de DDNS proporcionado por dyndns.

Para que esto sea posible SIEMPRE debe de existir una aplicación cliente que sea la que se encargue siempre de enviar los datos de la nueva conexión al servidor del proveedor. Lo que se hace a día de hoy para facilitar esto es añadir soporte en los propios routers para esto, es decir, muchos routers poseen internamente clientes DDNS, de modo que en realidad todo el proceso queda completamente transparente al usuario, este tan solo tiene que configurar el router y una vez realizado, cada vez que la IP cambia el router conecta con el servidor del servicio y actualiza la IP. Como digo es un servicio muy importante a día de hoy, sobre todo para aquellos que necesitan acceder a servicios de su red de forma remota sin importar la IP de esta.

 

 

Protocolos TCP y UDP

En conjunto con el protocolo IP conforman el núcleo principal de prácticamente todas las redes existentes a día de hoy, recordemos que estamos usando el modelo TCP/IP, luego el protocolo TCP seguro que jugará un papel importante.

Estos dos protocolos serán básicamente los dos únicos protocolos a nivel de transporte que vamos a tener. Podríamos añadir en todo caso SCTP usado para streaming, pero vamos… el 99% de todo el tráfico se gestiona por uno de estos dos protocolos. Recordemos que el nivel de transporte será quien establezca una comunicación entre aplicación origen- aplicación destino (en los niveles inferiores en realidad las comunicaciones son entre nodos). La idea es proveer a la comunicación con ciertos mecanismos como el control de flujo, detección de errores y otras cuestiones que iremos viendo.

Como hemos dicho veremos dos protocolos tan solo:

  • UDP (User Datagram Protocol)
  • TCP (Transmission Control Protocol)

Vamos a ver primero UDP por su gran sencillez, sería prácticamente la mínima expresión. A partir de este no obstante es mucho más simple comprender un protocolo bastante más complejo como TCP. Pero antes de entrar en los protocolos en sí hay que hablar de los puntos de accesos a estos, dado que será algo primordial para estos: Los puertos.

 

Puertos:

De cara al modelo TCP/IP o modelo OSI, los puertos serían los SAP del nivel de transporte, los puntos de acceso. Visto de forma más práctica los puertos permiten conexiones múltiples simultáneas entre distintos o iguales hosts sin que ninguna conexión interfiera en la otra. Visto de un modo más simple aun, los puertos serían las diferentes entradas/salidas en las comunicaciones.

Cuando un host desea enviar un mensaje a otro por medio de TCP o UDP primero debe de solicitar al OS un puerto de salida por el cual poder realizar la comunicación. Del mismo modo que necesita de un puerto de salida, dicho mensaje deberá de especificar ya no solo el destino (la IP o el nombre de host), sino el puerto al que quiere acceder en dicho host e informar al destino de puerto de salida que está usando para la comunicación, a fin de que el destino pueda contactar del mismo modo con el emisor. La necesidad del puerto de salida es clara, por algún lado tiene que salir el mensaje. ¿Pero y el puerto de entrada? En realidad es igualmente importante, ya que tanto puertos de entrada/salida se asocian generalmente a servicios/aplicaciones concretas. Es decir, gracias a estos puertos ya no solo debemos de especificar un host destino, sino que dentro de este, a que servicio o aplicación deseamos enviarle el mensaje.

Estos puertos se identifican como un número entero sin signo de 16 bits, es decir, un número comprendido entre el 0 y el 65535. Estos números hacen de ID de puerto por así decirlo. Estos puertos no son compartidos es decir, existirán por tanto 65536 puertos para TCP enumerados de 0 a 65535 y otros tantos para UDP enumerados exactamente igual, es por ello que el número del puerto no especifica si es UDP o TCP, esto es importante.

Como he dicho el 99% de todas las comunicaciones que hacemos se basan en este concepto, aun cuando no lo sepamos porque el proceso sea transparente a nosotros. El mejor ejemplo de esto es por ejemplo la navegación web. Hemos hablado de la necesidad de la IP o de las DNS, pero nadie ha visto en ningún momento nada parecido a un puerto o a un número que no sea la IP y que podamos imaginar que es un puerto. Pero esto es porque los navegadores lo hacen de forma implícita. Cuando en un navegador especificas por ejemplo “http://” estás especificando el protocolo http que por defecto (no significa que no pueda ser otro) se le asocia el puerto 80. Es decir, si en el navegador accedemos a la web http://www.google.es se realizará una petición al host www.google.es por el puerto 80 TCP, y con puerto no me refiero al puerto de salida de nuestro host, sino el puerto destino del host remoto.

Esto de que el puerto 80 esté asociado a los servidores web es así porque la IANA estableció que el puerto 80 sería el puerto “conocido” para el servicio web. En realidad la IANA mantiene un extenso listado con todos los puertos “conocidos”, así como los puertos registrados. Pero esto no quiere decir que los servicios de dicha lista se deban de asociar a dichos puertos, dado que un administrador de sistemas tiene siempre la última palabra sobre qué puerto asociar a que servicio. De todos modos esto tiene su lógica. Si se establece que el puerto para web será el 80, cualquier aplicación estará configurada para ello y no será necesario conocer en cada ocasión el puerto, lo mismo sucede con infinidad de puertos. Otras veces en cambio lo deseable puede ser exactamente lo contrario, y por motivos de seguridad no queremos asociar un servicio a su puerto preestablecido.

Se podría decir que generalmente tan solo los puertos de destino suelen tener un servicio asociado, pero esto sería incorrecto dado que un puerto de entrada se convierte en puerto de salida cuando tiene que enviar un mensaje. Así que podríamos matizar diciendo que generalmente los puertos de salida al iniciar la comunicación no suelen estar asociados. Por ejemplo, si realizamos una petición http al servidor web de google, sabemos que debemos de enviarla al puerto 80 TCP, ¿pero por qué puerto saldrá el mensaje de nuestro equipo? podríamos pensar en primer lugar que por el mismo puerto, que por el 80, pero esto no es así, el puerto 80 lo usaríamos para enviar datos (lo normal claro) tan solo de tener instalado un servidor web. Luego… ¿qué puerto se usará de salida? En este caso lo normal es que el navegador solicite una conexión de salida al OS, y sea el propio sistema quien le asigne un puerto que en ese momento no esté en uso para realizar dicha conexión, posiblemente entre un rango de puertos ya preestablecidos. Es decir, cada comunicación que hagamos incluso para navegar, el puerto de salida de nuestro mensaje será diferente casi el 100% de las veces. Es más, ahora mismo por ejemplo mi navegador Firefox mantienen de forma simultanea 5 conexiones activas, usando los puertos de salida 44384, 44385, 44387, 44388 y 44389, pero esto es en este mismo instante!! en cuanto la conexión TCP finalice y se abra una conexión TCP nueva, se le asignará un nuevo puerto de salida, y así el navegador quedará mientras dure la conexión “a la escucha” de dicho puerto preparado para recibir cualquier información que entre por él, que es de suponer que el mismo navegador estará esperando. Evidentemente los puertos que ya no están en uso se reutilizan sin problema alguno.

Podemos decir también que un puerto tiene 2 estados fundamentales, Abierto y Cerrado. Para que un puerto pueda enviar/recibir información, debe de estar abierto, es decir, algún servicio o programa asociado a él. Cuando en el ejemplo anterior nuestro navegador tiene que comunicarse con el puerto 80 TCP de un servidor web, antes de poder realizar la conexión el OS asocia a dicha aplicación (Firefox) el puerto temporal para la comunicación, digamos que el puerto queda abierto. Al otro lado en cambio, el puerto 80 del servidor web estará permanentemente abierto a la espera de cualquier comunicación externa entrante, el puerto 80 en este caso estará asociado a por ejemplo un servidor web Apache o IIS. En cambio, el puerto temporal abierto por el OS para Firefox para dicha conexión estará abierto tan solo el tiempo que dure la comunicación, cuando esta finalice, el puerto se cerrará. Esto es muy importante de cara a la seguridad como se verá en otro momento.



UDP:

Es un protocolo no orientado a la conexión, es decir, no provee ningún mecanismo de control de flujo, ni tampoco implementa ningún sistema propio de detección de errores o de pérdida de mensajes/datagramas (en nivel 4 no se puede hablar ya de paquetes, que es propio del nivel 3). Aunque en realidad el término “orientado a conexión” hace referencia a que no es necesario una negociación previa entre los dos dispositivos para comenzar la comunicación. Cuando tratamos con UDP debemos de tener claro por tanto que a este protocolo no le importa si se pierden datos en el camino, es más, el destino puede incluso estar saturado o colgado y UDP no tendrá constancia de ello, como si el puerto de comunicación está abierto o simplemente no es válido.

Esto parece tener muchos inconvenientes, pero en cambio todo depende de la aplicación que necesite enviar los datos o qué tipo de datos sean. Por ejemplo, la corrección de errores o el control de flujo puede implementarse a nivel de aplicación, o simplemente la pérdida de datagramas podría no ser importante, cosa muy habitual por ejemplo en aplicaciones en tiempo real como juegos online, Streaming, VoIP… ¿Pasa algo si 1 de cada 1000 datagramas se pierde en una videoconferencia? Pues la verdad es que prácticamente no afecta absolutamente en nada, a lo mejor vemos en ese momento un punto de otro color en la imagen recibida de la webcam del otro usuario, o puede que la conversación tenga un poco de más ruido de fondo, pero para nosotros es mucho más importante la fluidez de la conversación a la calidad de esta. Puede que UDP tenga muchos puntos negativos, pero no hay que verlo como negativos, sino como características, que dependiendo de la situación son mucho más deseables que otras. ¿Cuál es el objetivo por tanto de UDP? es fácil, la transmisión rápida de datos, la sencillez de la comunicación, en que prácticamente no hay que ocuparse de nada.

Hay que tener en cuenta que cuanto más complejo es un protocolo más sobrecargado está, y esto tiene un impacto notable en el uso de las redes. Imaginar que solo quiero enviar la palabra “Casa” a otro host. Con UDP me vasta dos datos y medio y lo envío. En TCP como ya veremos tendríamos que negociar la conexión, enviar los datos, cerrar la conexión… y todo ello además con cabeceras mucho más grandes en fin.. que a lo mejor en vez de enviar 20 bytes tendríamos que enviar 200 bytes para la misma tarea.

Como hemos dicho UDP no requiere del establecimiento de una conexión previa, de ningún sistema de acuerdo entre los dos hosts. Si un host quiere enviar un mensaje UDP a otro, tan solo tiene que (a nivel de transporte claro está) rellenar la cabecera UDP y adjuntar los datos que quiera:

Puerto de Origen

Puerto de Destino

Longitud

Checksum

  • Puerto de Origen/Puerto de Destino (16 bits cada uno): Especifica el puerto de origen y el puerto de destino del mensaje UDP. Al ser un número de 16 bits se infiere que tendremos un máximo de 65536 puertos posibles
  • Longitud (16 bits): Es un registro ya típico, en este caso especifica la longitud en bytes de todo el mensaje UDP, incluyendo tanto cabecera como el SDU del nivel superior, es decir, los datos realmente. Hay que recordar que cada nivel normalmente añade/elimina su propia cabecera a los datos recibidos y los envía hacia abajo o hacia arriba en el modelo TCP/IP. Dado que la cabecera tiene un tamaño fijo de 64 bits, la longitud mínima para un mensaje UDP sería 8 Bytes, es decir, un mensaje UDP vacío. Por la misma razón, la máxima cantidad de datos que se pueden enviar por un mensaje UDP sería 64K menos 8 Bytes.
  • CheckSum (16 bits): La detección de errores en este caso es un poco peculiar, y además, en IPv4 es opcional (obligatoria en IPv6, recordemos que IPv6 NO tenía comprobación de checksum a nivel de protocolo IP). El algoritmo que usa es exactamente el mismo que el que se realiza en IP, se realiza el complemento a uno a la suma en complemento a uno resultante de cada palabra, pero en este caso no se hace sobre la cabecera de UDP, sino sobre la llamada pseudo cabecera UDP. Esta cabecera en realidad no existe, tan solo es una composición que se crea para crear el checksum. Esta cabecera está compuesta por la IP de origen, la IP destino, un byte de ceros, un registro que especifica el protocolo y otro registro que especifica la longitud del mensaje UDP, es decir, esta cabecera virtual toma algunos elementos de la cabecera IP. Pero repito, tan solo se “construye” esta cabecera para calcular el checksum, esta cabecera como tal no existe, no se transmite.

Eso es todo. Es la mínima expresión, una cabecera con lo mínimo, en que lo más “complejo” puede ser el checksum y que ni siquiera es obligado en IPv4. Después de la cabecera evidentemente se adjuntarían los datos del nivel superior, el SDU, que junto a la cabecera conformarían el 4PDU, el mensaje UDP completo que pasaría al nivel de red (en caso de que se esté enviando).

¿Cuál es el mejor ejemplo de mensaje UDP? Los mensajes DNS, DNS se transmite por medio de mensajes UDP. Qué pasa si se pierde un mensaje DNS? Pues posiblemente que si el navegador o el host tenga un tiempo de espera predeterminado para la petición DNS, si no recibe la respuesta casi de inmediato, enviará casi seguro una segunda o una tercera petición. Pero no es algo que requiera una integridad especial o una complejidad enorme. Además, son mensajes que se están retransmitiendo constantemente. Usar TCP para mensajes tan cortos sería hacer un uso enorme de la red tan solo para las peticiones DNS. Con UDP funcionan el 99% perfectamente, y hacen un uso muchísimo más optimizado de la red. Además, cuanto más pequeños sean los mensajes, menor probabilidad de errores existirá en su retransmisión.


TCP:

Es todo lo contrario a UDP. Para empezar, es un protocolo orientado a conexión, es decir, requiere del establecimiento previo de una conexión antes de poder comenzar a retransmitir datos. Es infinitamente más complejo que UDP, pero por otro lado TCP hace posible comunicaciones fiables, tolerantes a fallos, con una buena gestión del control de flujo… aunque todo ello requiere por ende un protocolo más complejo, una cabecera más grande y una menor cadencia a la hora de transmitir datos en definitiva.

Al igual que le pasara a UDP, no se puede ver esto como algo negativo, sino como algo necesario para poder tener una comunicación fiable para aplicaciones que así lo requieren. Posiblemente el caso más ilustrativo sería la navegación web por ejemplo. Una web puede pesar considerablemente, desde unos KBs a MBs de datos. Que importa en este caso gastar unos KBs de más si nos garantizamos que el navegador recogerá correctamente la información del servidor opuesto. Pensar cuando enviamos un formulario (al margen de que se pueda enviar o no por protocolos seguros como TLS/SSL), no podemos permitirnos en modo alguno que al servidor no le llegue un mensaje TCP correcto, dado que ese mensaje podría ser desde un número diferente en el DNI, en el nombre o en cualquier otro lugar. Recordar que protocolos como UDP no tienen siquiera ningún mecanismo para saber si los datos han llegado o no, mucho menos si lo hicieron correctamente. En la mayoría de las comunicaciones necesitamos saber que los datos se han enviado correctamente o se han recibido sin errores.

Existen pues muchas aplicaciones que hacen uso de ambos protocolos, por ejemplo la mayoría de programas P2P o juegos online. ¿Por qué? Habilitan por ejemplo un puerto UDP para maximizar el envío/recepción de datos, y se usa la misma aplicación para controlar que estos lleguen en buen estado. Pero a la par se usa un puerto TCP para aquellas cuestiones que si requieran precisión, normalmente pequeños mensajes, pero que sí necesitamos conocer que han llegado y en buen estado:

 

Puerto de Origen

Puerto de Destino

Número de Secuencia

Número de ACK

Offset

Reservado

U

A

P

R

S

F

Ventana

CheckSum

Puntero “Urgente”

Opciones

Padding

 

  • Puerto de Origen/Destino (16 Bits cada uno): Tiene exactamente el mismo uso que el citado en el protocolo UDP, especifica mediante un entero sin signo el puerto de origen que usará el mensaje TCP, así como el puerto destino al que va dirigido.
  • Número de Secuencia (32 bits): Recordemos que TCP posee funciones de control de flujo, esto significa que de algún modo cada mensaje enviado tiene que ser claramente identificable de otro. Esto quiere decir que si dos mensajes TCP llegan al destino de forma desordenada, el host receptor podría ordenarlos perfectamente dado el número de secuencia. Del mismo modo si se recibe un mensaje cuyo número de secuencia no concuerda con el esperado, el mensaje podría descartarse por interpretar que dicho mensaje es ajeno a la comunicación actual entre los dos hosts, por ejemplo un mensaje inyectado desde un tercer host que intentase manipular la conversación entre ambos. Si el flag Syn (S) no está especificado, será el número de secuencia del primer octeto (byte) de datos adjuntos en dicho mensaje (después de toda la cabecera). En cambio, si el flag Syn está habilitado, el primer octeto adjunto en dicho mensaje será el número de secuencia + 1.
  • Número de ACK (32 bits): La gran mayoría de las veces, para nosotros un ACK será un mensaje o paquete de confirmación. Este tipo de mensajes son muy comunes en gran multitud de protocolos, son como pequeñas señales de respuesta para indicar que se ha recibido la información. Gracias a estos mensajes también solucionamos el problema de conocer si un mensaje llega correctamente o no a su destino, dado que si llega, el destinatario nos responderá con un ACK (ACK proviene de Acknowledgment). Por ello, si el flag ACK (A) está activado, el número de ACK corresponderá al próximo número de secuencia del mensaje que espera recibir por parte del emisor. Es decir, en el caso de que la comunicación sea correcta, si un host envía un ACK con número de ACK “200″, significará que está esperando que el otro host le envíe un mensaje (del tipo que sea) con un número de secuencia de 200.
  • Offset (4 bits): El número de bloques de 32 bits que ocupará la cabecera, por tanto indica cuando empiezan los datos (el SDU). Como ya se viese en el protocolo IP, para que este tipo de registros sean posible es necesario que la cabecera siempre sea múltiplo de 32 bits, lo cual se hace con un padding, puesto que existen campos en la cabecera de longitud variable.
  • Reservado (6 bits): bits reservados, se deben de establecer a cero.
  • Flags (1 bit cada una): Los flag o banderas son bits que básicamente dicen cuando un flag está activado o no. Cada uno de esos bits especifican algo concreto:

    URG (U): Usado conjuntamente con el campo “Puntero Urgente” para especificar que existe un dato en el mensaje que debe de ser procesado con anterioridad.
    ACK (A): Usado conjuntamente con el número de ACK para indicar una contestación, como ya se ha explicado.
    PSH (P): Esta señal está relacionada directamente con la ventana del protocolo TCP que se verá a continuación. Si el flag PSH es especificado, el mensaje por pequeño que sea será enviado.
    RST (R): Básicamente es una bandera que de habilitarse indica al otro host que reinicie la comunicación, algo así como un reset de la sesión.
    Syn (S): Formalmente realiza la sincronización del número de secuencia. El primer mensaje enviado por cada una de las partes al otro tendrá activada el flag Syn, es decir, al inicio de la comunicación.
    FIN (F): Se usa para comenzar o forzar el cierre de la sesión. Técnica significa que no serán enviados más datos por parte del emisor.


  • Ventana (16 bits): Especifica en Bytes el tamaño de la ventana de recepción. Es decir, el tamaño máximo (comenzando desde el número de secuencia de ACK) de datos que puede recibirse en una comunicación TCP, antes de contestar con un ACK. En realidad esta ventana no es más que un buffer, cuyo tamaño queda especificado por este campo. Cuanto mayor sea el tamaño de ventana se obtendrá una mayor cadencia en los datos (el término exacto es throughput, pero creo que no existe un equivalente exacto en español). En contra partida, una ventana grande es perjudicial cuando la calidad de la red no es demasiado buena, puesto que en caso de error (por pequeño que sea), se requerirá enviar de nuevo toda la ventana completa, repercutiendo negativamente en el rendimiento. No es lo mismo a fin de cuenta enviar un mensaje de 1 byte en un byte, teniendo en cuenta que entre byte y byte hay que responder con un ACK, que enviar un mensaje en bloques de hasta 64KB, lo cual es muchísimo más eficiente… aunque menos seguro y menos fiable.

    A día de hoy cada vez se está optando por incrementar casi al máximo las ventanas de recepción, o en caso de Windows por ejemplo permitir al propio OS establecer de forma dinámica el tamaño de esta en función de la calidad de la comunicación y otros factores.


  • CheckSum (16 bits): El sistema de comprobación de errores de TCP es el mismo que el que se explicó en UDP.
  • Puntero Urgente (16 bits): Especifica un desplazamiento de Bytes (comenzando desde el número de secuencia) en el que se encuentra el primer byte que se ha tipificado como “mensaje urgente”
  • Opciones y Padding (Variable): Especifica una serie de opciones que pueden añadirse antes del SDU. Dado que se debe de conservar la divisibilidad entre 32 Bits, se usará un padding rellenando de ceros para cubrir siempre cualquier pico que pudiese existir en dichas opciones.

Es evidente que la complejidad aquí es mucho mayor que en UDP. Describir el funcionamiento de todo el protocolo sería algo inviable, y para eso están las especificaciones oficiales en el RFC 793. No obstante, aunque no se explique cada uno delos posibles casos pueden darse en una comunicación TCP, si es interesante ver a groso modo como se llevaría a cabo una comunicación modelo, sin entrar en demasiados detalles, en lo que sería el establecimiento y cierre de la comunicación. Como digo esto es tan solo una pequeña parte de todo el protocolo TCP, se pueden presentar un millón de posibilidades y de comportamientos anómalos en la conexión y la respuesta de cada host a dicho comportamiento está en algunos casos especificados y en otros no. De todos modos, esto se podrá ver en otros temas, como por ejemplo en los escáneres de puertos, donde es muy importante conocer el funcionamiento de estos protocolos:

 

Sabiendo los registros de la cabecera, se puede más o menos inferir las características de TCP. Por ejemplo, la fiabilidad en los datos enviados/recibidos queda asegurada gracias a los números de secuencia, por los cuales es posible conocer el orden incluso en el que deben de llegar los mensajes, o en caso de que un mensaje no sea recibido el host emisor puede ser informado sobre ello para reenviar de nuevo el mensaje perdido. El número de secuencia de ACK tiene un cometido similar, dado que si el emisor no recibe el ACK de un mensaje que ha enviado, puede interpretar que el mensaje no ha sido recibido y podría enviarlo de forma automática de nuevo, mientras que de cara al receptor si le llegan dos mensajes con el mismo número de secuencia (por ejemplo porque el emisor ha reenviado el mensaje y el primero no llegó por una latencia excesiva de la red) ignoraría simplemente el segundo, siempre y cuando el número de secuencia fuese correcto, si recibe un número de secuencia erroneo simplemente descartaría el mensaje.

Por otro lado, el uso de una ventana (buffer) también garantiza un correcto control de flujo, mientras que técnicas como los algoritmos de congestión de red hacen posible que la comunicación sea todo lo fluida que se pueda cuando la intensidad del tráfico amenaza la comunicaicón. Estos algoritmos se basan simplemente en los mismos flags de las conexiones TCP para ajustar ciertos parámetros como la ventana de recepción, el tamaño máximo del mensaje (especificado en las extensiones de la cabecera TCP) o la gestión de ACKs. Por ejemplo, el algoritmo de congestión que puede usar Windows Vista/7 se llama Compound TCP. Este algoritmo posee dos ventanas, las cuales aumentan en tamaño o disminuyen en función del retraso en las comunicaciones. De forma similar actáa por ejemplo el protocolo de congestión por defecto de Linux: TCP Cubic. A la par que las comunicaciones son más rápidas y fiables, es normal que los algortimos de congestión usados vayan cambiando con el tiempo, dado que el que es bueno ahora no lo será mañana.

 

 

Protocolo Ethernet y ARP

Llegados a este punto sería conveniente hablar de Ethernet, aunque sin entrar en mucho detalle sobre este. Ethernet es un protocolo… una tecnología para redes locales. Al ser un protocolo de nivel 1 y 2, tiene más componentes físicas que informáticas. Por ejemplo, Ethernet tiene sus propios estándares para cables que pueden usarse, conectores, hardware… cuestiones que podrían ser interesantes ver, pero que se escapan al alcance de este capítulo. Ahora veremos Ethernet como el protocolo de nivel más bajo que tendremos dentro del modelo TCP/IP o modelo OSI, y será la misma tecnología Ethernet y sus protocolos los que convertirán al final los datos en meras señales eléctricas que serán transmitidas por un cable.

Desde el punto de vista físico, para nosotros tan solo nos interesa conocer cuestiones como la velocidad, modo de funcionamiento y tipo de medio. Desde el punto de vista lógico nos interesa no obstante conocer la estructura de un frame ethernet.

Físicamente para nosotros podemos diferenciar 3 estándares atendiendo a la velocidad de enlace de Ethernet: Ethernet, Fast Ethernet y Gigabit Ethernet, La diferencia de ellos es por tanto el ancho de banda posible. ASí, Ethernet tiene una capacidad máxima de transmisión de datos de 10Mb/sec (ojo!! Megabits, no MegaBytes), Fast Ethernet 100Mb/s y GigaEthernet una capacidad de 1000Mb/s. Actualmente existen estándares menos usados domésticamente como 10 GigaEthernet o 100 GigaEthernet, cuyos nombres son completamente descriptivos.

De cara al medio, estamos acostumbrados a ver Ethernet siempre usado sobre el famoso cable “Categoría 5e” y conectores RJ45. Este cables son a groso modo 4 parejas de hilos trenzados. Pero esto es solo una de las especificaciones de Ethernet, ya que en realidad Ethernet puede ser usado no solo sobre estas parejas de hilos trenzadas, sino por ejemplo sobre fibra óptica también. Lo que sucede es que los cables de hilos trenzados son infinitamente más baratos que otras infraestructuras como pueda ser la de fibra óptica, por no hablar de la facilidad de crimpar (añadir un conector a un extremo de un cable) a un cable de hilos trenzados a uno de fibra, o la flexibilidad de uno y de otro. Actualmente sobre hilos de cobre trenzados es posible llegar hasta 10GigaEthernet, mientras que sobre fibra hasta los 100GigaEthernet. De todos modos, lo más común, barato y cómodo para un usuario doméstico son los estándares 100BaseT y 1000BaseT, es decir, Fast Ethernet y Giga Ethernet sobre cables de cobre trenzados. En el caso de 100BaseT se usarán 4 hilos en total de un cable de pares trenzados Categoría 5 como mínimo, mientras que en redes GigaEthernet requeriremos de los 4 pares de hilos de un cable Categoría 5e o Categoria 6. En ambos casos, el estándar asegura una longitud máxima de cable entre nodos de 100 metros, a partir de los cuales sería necesario regenerar la señal. Como nota personal, en entornos especialmente ruidosos o cuando dichos cables serán usados externamente, recomendaría que los cables fuesen apantallados para aislar mejor las interferencias, aunque esto es tan solo opcional.

Desde el punto de vista del modo de funcionamiento, tan solo decir que Ethernet puede funcionar tanto en Half-Duplex como en Full-Duplex. Esto se verá más en detalle en otro capítulo cuando se vean Hubs y Switchs.

Desde un punto de vista lógico tenemos que ver como es un frame Ethernet, y teniendo en cuenta los diferentes protocolos que hemos visto hasta ahora, Ethernet no supondrá mayor problema. Un frame Ethernet II (los frames usados a día de hoy) no poseen otra cosa que la dirección MAC origen y destino, el protocolo superior que lo usará, los datos que portará y un checksum:

Cuando se trató el protocolo IP se mencionó MTU como unidad máxima de transmisión, que es una limitación de la red y no del mismo protocolo IP, ya que el protocolo IP podía incluir paquetes de hasta 64KB. Pues bien, ese MTU proviene de los niveles inferiores, en caso de usar redes Ethernet dicha limitación procede de aquí. ¿Por qué dijimos que lo normal para conexiones ADSL es un MTU de 1492 Bytes? El 99% de las redes locales domésticas son redes Ethernet. Como podemos apreciar perfectament en la imagen superior, los frame Ethernet tienen un tamaño mínimo de 64 bytes y un tamaño máximo de 1512 Bytes. De esos 1512 Bytes, 1500 son los reservados para los datos adjuntos. Dado que nuestros equipos se comunican principalmente por cable a nuestros routers, estos enlaces son Ethernet con un MTU de 1500. Pero por otro lado, la mayoría de nuestras conexiones ADSL están apoyadas por el protocolo PPPoE (Punto a Punto sobre Ethernet), el cual (el protocolo) tiene una cabecera de 8 Bytes. Es decir, el tamaño máximo de los datos que pueden enviarse por medio de una conexión ADSL mediante PPPoE debería de ser exactamente 1492, dado que PPPoE usa frames Ethernet. Ahora bien, esto no quiere decir que un MTU de 1942 para conexiones ADSL PPPoE sea el óptimo, pero explicar esto implicaría de nuevo salirnos del ámbito de este capítulo.

Hay que tener bien presente que estos frames existen tan solo para nosotros, para nuestra red local Ethernet, y en el caso específico de las conexiones ADSL PPPoE. Siempre que usemos un Sniffer para ver que tipos de frames nos están llegando hay que comprender bien esto, dado que podemos ver solo lo que llega a nuestros equipos, no como dichos datos son transportados desde un punto del planeta a otro, hablamos por tanto en este caso de un protocolo de puertas para dentro.

De la cabecera Ethernet II anterior, EtherType especifica el protocolo inmediato contenido en los datos adjuntos. Así por ejemplo, para un paquete IPv4, EtherType tendrá un valor de 0×0800, 0x86DD para IPv6, 0×8863 y 0×8864 para PPPoE, o un valor de 0×0806 si es el protocolo ARP. Para quien quiera una lista completa puede verla en el estándar de la IEEE de los tipos de redes Ethernet


Una dirección IP es una dirección lógica asociada a un host, mientras que una dirección MAC es una dirección “física”. Quizás el término dirección física no sea realmente correcto, pero sí podemos decir que una dirección MAC especifica inequívocamente una interfaz NIC (o al menos debería). Tal y como se plantea toda la red de Internet, así como los protocolos TCP/IP y DNS, parecerá innecesario un protocolo como ARP, pero sin embargo es un protocolo crucial, sobre todo dentro de redes locales como las redes Ethernet (casi todas las redes locales).

Gracias al protocolo IP podemos encontrar en el globo un host simplemente conociendo su dirección IP. Pero esta dirección no es más que una dirección lógica. En IPv6 esto es diferente dado que la asociación IP-NIC es casi estructural, pero en IPv4 esto no es así ni mucho menos. Volviendo al tema principal, puede que una dirección IP especifique un host en internet, pero… ¿Como saben los equipos o los routers a que interfaz de red enviar dichos paquetes? Es importante conocer siempre lo que pueda ser la parte física de una comunicación a la parte lógica. Podemos pensar en la parte física aquello que podemos tocar o ver: Cables, Routers, Switchs, Bridges, Interfaces de Red (NIC)… hardware a fin de cuenta. En cambio, en la parte “lógica” tendríamos fundamentalmente los protocolos de comunicación que funcionan sobre esa parte física, y en última instancia bits de datos que circulan de un lado a otro. Pues bien, en algún punto por tanto es necesario unir esa parte física con esa parte lógica, y el protocolo ARP se encarga de ello, al menos en cuanto a conocer el origen/destino de un paquete IP.

El protocolo ARP será el encargado por tanto de conocer el host físico emisor/receptor de un paquete por medio de su IP, dicho de otro modo, el protocolo ARP se encargará de saber las direcciones MAC de las NIC. El protocolo IP trabaja en el nivel 3 del modelo OSI (nivel de red), TCP/UDP son protocolos del nivel 4 (de transporte), mientras el protocolo DNS es un mensaje concreto UDP (luego es un protocolo a nivel de aplicación). ¿A que nivel pertenece por tanto ARP?

El problema del ámbito de ARP no es nuevo. En teoría es un protocolo a nivel de enlace de datos (nivel 2), pero no obstante para que ARP pueda trabajar correctamente necesita tener acceso al nivel 3 para conocer la IP. Si vemos esto desde un modelo OSI estricto, ARP quedaría fuera de este, dado que requeriría acceder a ambos niveles, lo cual violaría los principios del modelo OSI. Pero por un lado el modelo usado actualmente es TCP/IP, y por otro podríamos ver el modelo OSI como algo más flexible. Otros expertos concluyen que aun cuando el modelo OSI fuese completamente fijo e inflexible, ARP no violaría el modelo, dado que su función es meramente de nivel de red, con la única salvedad de que porta datos pertenecientes a IP, y que por tanto ARP es un protocolo de nivel 2. Personalmente creo que las dos opciones son correctas. No se puede ver el modelo TCP/IP u OSI como algo completamente rígido, y tampoco podemos pensar en que un frame solo puede contener datos propios. Quizás el ejemplo más significativo estaría en el protocolo ICMP. Sin entrar en detalle a explicar este protocolo, ICMP depende y se apoya sobre IP, con lo que debería de ser un protocolo superior a IP, pero en realidad no presta ningún servicio de transporte o de nivel superior. ICMP es un protocolo puramente de nivel 3, aunque necesite o se apoye en IP. Bueno, de forma similar podríamos ver ARP. Para mi por tanto ARP es un protocolo de nivel de enlace de datos (nivel 2), pero quizás sería correcto decir que es un protocolo tanto de nivel 2 como de nivel 3.

 

¿El problema?

La finalidad de ARP queda clara. Un protocolo que permita extraer de algún modo de la dirección física MAC de un host. ¿Por qué es esto estrictamente necesario? La mejor forma de ver esto es intentar componer la red TCP/IP más sencilla que pueda existir, para evitar pensar en routers, hubs u otros elementos de red: Dos hosts conectados uno a otro por un cable Ethernet. Imaginar por tanto que disponemos de dos host configurados manualmente y conectados por un cable de red, formando entre ambos equipos una red muy simple. El host A se configura para tener una dirección IP 192.168.0.1 y el host B para tener la dirección 192.168.0.2. Si lo vemos de una forma completamente lógica, decimos simplemente que el host A se comunica con el host B enviando los paquetes IP a la dirección 192.168.0.2. ¿Pero como sabe el host A quien es el host B? Visto desde un punto de vista completamente físico, la tarjeta de red del host A tan solo sabe que ella tiene una dirección física por ejemplo de 00:00:00:00:00:01, a la cual hay conectada un cable por el cual enviar o recibir datos, y lo mismo para el host B, 00:00:00:00:00:02. Los adaptadores de red no tienen por qué entender de IP, recordemos que Ethernet es un protocolo de nivel 2. En última instancia, el adaptador de red simplemente pone los datos que sean en las lineas de transmisión del cable y listo. En este caso es simple, dado que tan solo hay un equipo conectado al otro extremo, los datos enviados por A llegarán siempre al equipo B. El host B cuando recibe lo que sea por su interfaz de red podría simplemente tomarlo por bueno y tomar cualquier dato que llegue por él como válido y procesarlo. En este caso no haría falta siquiera conocer direcciones físicas. Pero que sucede si creamos una red en vez de dos equipos de tres?

Imaginar que a los dos equipos antes mencionados incluimos un Host C con dirección física 00:00:00:00:00:03. ¿Como? En el caso más simple de todos esto se haría con un dispositivo de red conocido como Hub. Básicamente los Hub conectan todos los diferentes hosts conectados a él entre sí de una forma muy simple. Un cable/interfaz Ethernet o Fast-Ethernet tiene dos lineas para transmitir datos y dos para recibir, pues el hub lo que hace es conectar internamente las dos líneas de transmisión de datos de cada cable con las dos de recepción de los otros. Es decir, cuando el host A envíe un paquete, este será recibido tanto en B como en C, y exactamente lo mismo para cualquier paquete enviado por B o por C. El problema es evidente, ante esta situación ya no basta simplemente con poner el dato en el cable y dejar que los hosts tomen por bueno y procesen el dato. Por otro lado cada host puede tener una IP diferente sí, pero como hemos dicho los adaptadores de red no tiene por qué saber nada de IP, y por otro lado las aplicaciones no entienden de direcciones MAC, solo de paquetes IP.

 

¿La solución?

Si al enviar el dato que sea desde A especificamos la dirección MAC destino (es decir, el adaptador de red a quien está destinado dicho frame), esta dirección o ID si puede ser comprobada/verificada por el adaptador de red. En este caso del Hub, tanto B y C recibirán un frame de A, pero el frame de A especificará que el destino será 00:00:00:00:00:02, con lo que el host C simplemente ignorará el frame, puesto que la dirección MAC no es la suya. Con esto podría parecer que el uso de IP es innecesario, pero recordemos que la función de un protocolo de nivel de red es completamente diferente a un protocolo de nivel de enlace de datos. IP hablará con todos los protocolos superiores, mientras que Ethernet es un protocolo de bajo nivel. Visto esto vemos la necesidad de las direcciones MAC, pero no del protocolo ARP. Pues bien, se ha dado por echo que el host A conoce la dirección MAC del host B, lo cual puede ser que la conozca o puede ser que no la conozca. Si arrancamos en frió todos los dispositivos, la única forma que el host A conozca la dirección MAC de los otros host y viceversa es manteniendo un archivo local en cada equipo que especifique dichas direcciones. Esto ya vimos en DNS que no aceptable en ningún modo, hace falta un protocolo que se encargue de dicha tarea.

Cuando un host no posea la dirección mac de otro, necesitará realizar una petición ARP para conocer dicha dirección. ARP tiene tan solo dos métodos de funcionamiento: Enviar peticiones y Enviar respuestas. El procedimiento base es muy simple, si necesita conocer la MAC del host B (del cual evidentemente conoce la IP, dado que el mismo paquete IP especifica dicha IP), enviará una petición a la dirección física de broadcast de la red con la solicitud. Todos los host recibirán Y ATENDERÁN la petición puesto que la dirección física a la cual está destinado el frame son TODOS los host, pero tan solo el host B contestará a ella, dado que dicha petición especifica la IP del host B. La respuesta de B por otro lado será dirigida directamente a A, dado que en la misma solicitud se incluye la dirección MAC del host A. La respuesta llegará a todos los host (estamos usando un hub), pero estos no la procesaran porque la dirección MAC especificada en el frame será la de A. A recibirá la contestación por parte de B con un frame que contendrá la dirección física de B, y el host A podrá actualizar su caché ARP, donde almacenará la asociación IP host B -> MAC host B.

Lo primero será por tanto conocer la estructura de este frame un tanto especial, ya se ha dicho que aun siendo (a mi juicio) un protocolo de nivel 2, lleva consigo una IP:

 

Tipo de Hardware
Tipo de Protocolo
Long. Dirección HardwareLong. Dirección del Protocolo
Operación
Dirección Hardware del Origen
Dirección del Protocolo del Origen
Dirección Hardware del Destino
Dirección del Protocolo del Destino

Hay que tener en cuenta que ARP depende de dos protocolos, el superior y el inferior. Para nosotros, ARP será usado extensamente en redes IPv4 sobre Ethernet, pero esto no quiere decir que son los únicos protocolos con los que podría funcionar ARP.

  • Tipo de Hardware (16 bits): Especifica el hardware del nivel inferior que será usado. En caso de redes Ethernet, el valor de dicho campo será un 0×0001
  • Tipo de Protocolo (16 bits): Especifica el protocolo superior al que referenciará, en caso del protocolo IP el valor de dicho campo será de 0×0800
  • Long. Dirección Hardware (8 bits): Especifica el tamaño en bytes que ocupará una dirección del tipo hardware especificado en el campo “Tipo Hardware”. En caso de redes Ethernet, las direcciones MAC tienen un tamaño de 48 bits, luego este campo estará fijo en 48/8 = 6 Bytes -> 0×06
  • Long. Dirección del Protocolo (8 bits): Especifica el tamaño de la Dirección del protocolo de nivel superior, en nuestro caso una dirección IPv4 tiene una longitud de 32 bits -> 32/8 = 4 Bytes -> 0×04
  • Operación (16 bits): Especifica el modo de operación del protocolo ARP. Ya se dijo que ARP actúa o realizando una petición (Request, un valor de 1 en dicho campo) o respondiendo a una (Reply, con un valor de 2 en dicho campo)
  • Dirección Hardware/Protocolo Origen/Destino (variable): Dado que el hardware y el protocolo sobre los cuales ARP va a funcionar puede ser diferente, estos campos no tienen una longitud fija, de echo estos campos son fijados en los registros anteriores. En estos campos se almacenará la dirección MAC de origen y la dirección MAC destino en caso de los registros Dirección Hardware y la dirección IP de origen y destino en el caso de los campos de Dirección del Protocolo.


En realidad es un frame muy simple, no lleva mayores complicaciones ni sobrecargas en el protocolo. Vamos a ver un ejemplo de frame tipo ARP IP sobre Ethernet capturado por un Sniffer:

+Frame 1: 60 bytes on wire (480 bits), 60 bytes captured (480 bits)
-Ethernet II, Src: Cisco-Li_xx:xx:xx (00:xx:xx:xx:xx:xx), Dst: AsustekC_xx:xx:x (00:xx:xx:xx:xx:xx)
Destination: AsustekC_xx:xx:x (00:xx:xx:xx:xx:xx)
Source: Cisco-Li_xx:xx:xx (00:xx:xx:xx:xx:xx)
Type: ARP (0×0806)
Trailer: 00000000000000000000000000004fe127ba

-Address Resolution Protocol (request)
Hardware type: Ethernet (0×0001)
Protocol type: IP (0×0800)
Hardware size: 6
Protocol size: 4
Opcode: request (0×0001)
Is gratuitous: False
Sender MAC address: Cisco-Li_4c:fc:8a (00:25:9c:4c:fc:8a)
Sender IP address: 192.168.x.1 (192.168.x.1)
Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00)
Target IP address: 192.168.X.2 (192.168.x.2)

El primer bloque pertenecería al protocolo Ethernet. Tan solo se especifica como ya se dijo la dirección MAC origen y destino, el tipo de protocolo (en este caso ARP) y el trailer. El trailer es el fin de la trama (frame), lo cual hay que explicarlo. Como hemos visto un frame Ethernet termina con una secuencia de 4 Bytes que es el checksum. No obstante por regla general no será posible acceder a estos datos del frame por un sniffe, dado que el checksum se calcula de forma automática en el propio adaptador, y para tener acceso a ello sería necesario drivers específicos que realmente no merece la pena molestarse por ello.Es decir, el trailer NO ES el checksum en modo alguno, sino un padding necesario. ¿Por qué? Un frame Ethernet debe de tener un tamaño mínimo de 64 bytes. En este caso podemos comprobar que el Frame capturado tiene curiosamente 64 Bytes (60 Bytes + 4 Bytes del Checksum que se omiten), pero se obtiene un valor exacto de 64 Bytes gracias al trailer, sin este el frame ethernet tendría un tamaño inferior. Es por ello que la propia interfaz de red añade un padding después de los datos para rellenar ese tamaño mínimo de 64 bytes (60 si no contamos el checksum), o lo que es lomismo, un tamaño mínimo de datos de 46 Bytes.

El segundo bloque corresponde al protocolo ARP. La captura muestra exactamente cada uno de los campos de este protoclo, el tipo de Hardware (Ethernet), el tipo de protocolo de red (IP), el tamaño en Bytes de las direcciones, el modo de operación y las direcciones MAC e IP. Aparece no obstante un campo llamado “Is gratuitous”. En el protocolo ARP se denomina un frame gratuito a un auto anunciamiento. Es decir, imaginar que el frame anterior ARP en vez de tener como emisor la MAC y la IP del router tuviese la MAC e IP de él mismo, pero el destino fuese igualmente la dirección indeterminada: 00:00:00:00:00:00. En este caso, es evidente que nadie contestaría al frame ARP, pero este mensaje SI actualizaría probablemente las tablas ARP locales de cada equipo.

El frame completo ARP del ejemplo lo que realmente significa es que pregunta a toda la red por la dirección MAC de la IP 192.168.x.2. ¿Como es posible? porque el frame no está siendo enviado a una dirección MAC concreta, sino a la dirección indefinida 00:00:00:00:00:00, dado que no se conoce cual es. Esto hace que todos los host en la red escuchen tal frame. Cabe esperar que inmediatamente de lanzar el route dicha peticion ARP, el host del cual se desea conocer la dirección MAC responda con un frame ARP reply a dicha petición.

¿Que sucede cuando una petición ARP se contesta?

Al igual que las caché DNS, todos los equipos poseen una caché generalmente dinámica ARP que almacena las asociaciones MAC/IP, lo que evita el uso continuo de realizar peticiones ARP para conocer dichas direcciones MAC. Estas tablas se actualizarán a medida que sean necesaria, pero al contrario de lo qeu se piense, generalmente son actualizadas al recibir cualquier ARP reply de la red, sea legítimo o no, y esto será tratado en profundidad en otro capítulo de este tema. Dado que existe esta tabla/caché ARP, es posible tanto eliminar entradas de esta como añadir entradas manualmente, como listar la tabla ARP.

En windows:

C:\Users\Theliel>arp -a

Interfaz: 192.168.x.3
Dirección de Internet Dirección física Tipo
192.168.x.1 00-xx-xx-xx-xx-xx dinámico
192.168.x.255 ff-ff-ff-ff-ff-ff estático
224.0.0.22 01-00-5e-00-00-16 estático
224.0.0.252 01-00-5e-00-00-fc estático
239.255.255.250 01-00-5e-7f-ff-fa estático
255.255.255.255 ff-ff-ff-ff-ff-ff estático

Interfaz: 192.168.x.2
Dirección de Internet Dirección física Tipo
192.168.x.1 00-xx-xx-xx-xx-xx dinámico
192.168.x.6 00-xx-xx-xx-xx-xx dinámico
192.168.x.8 00-xx-xx-xx-xx-xx dinámico
192.168.x.13 00-xx-xx-xx-xx-xx dinámico
192.168.x.255 ff-ff-ff-ff-ff-ff estático
224.0.0.22 01-00-5e-00-00-16 estático
224.0.0.252 01-00-5e-00-00-fc estático
239.255.255.250 01-00-5e-7f-ff-fa estático
255.255.255.255 ff-ff-ff-ff-ff-ff estático

En Linux:

Anarchy:/# arp -n
Address HWtype HWaddress Flags Mask Iface
192.168.x.1 ether 00:xx:xx:xx:xx:xx C eth0
192.168.x.2 ether 00:xx:xx:xx:xx:xx C eth0
192.168x.25 ether 00:xx:xx:xx:xx:xx C eth0


El protocolo ARP es simple y altamente efectivo, no obstante no está libre de problemas de seguridad. Cuanto más simples es un protocolo más efectivo es, pero también es intrínsecamente más inseguro la mayoría de las veces. Recordar que Internet no se pensó como una fortaleza en la que todo estuviese medido, sino todo lo contrario, un sistema lo más simple posible y efectivo. Y viendo los protocolos que la hacen posible, tengo que decir que lo lograron, y a día de hoy es sin duda alguna la red de redes.

Proyecto: Adrianne I

Antes de comenzar, citar posiblemente a quien me inspiró a ello, y en cierto modo me ayudó a comprender algunos conceptos y me enseñó por donde buscar, por así decirlo: Bilalt, aunque desgraciadamente no conozco su nombre real y hace ya años que “desapareció”.

Voy a ir intentando completar este “reto personal”. Entre otras cosas, siempre me sentí atriado por los gráficos 3D, aunque no quiero decir con esto los juegos, sino el diseño 3D, como crear esos mundos increibles que tanto estamos acostumbrados a ver.

Por otro lado debo de decir que no me puedo consuderar ni mucho menos un gurú en la programación. Lo suficiente quizás para ser capaz de crear el programa que sea con algo de tiempo, pero dudo mucho que este pudiese estar a la altura de un verdadero programador como los que hay, auténticos genios en su campo. Pero por el lado positivo, la informática me ha enseñado que todos los campos dentro de ella de alguna u otra forma están relacionados, lo que quiere decir es que para mi es más facil que para la gran mayoría enfrentarme a un problema concreto (claro está, informáticamente hablando), sea de programación, de diseño… hasta el punto que aunque un genio de la programación sea capaz de hacer lo mismo mucho más eficientemente y más rapido que yo (sin duda alguna), yo tengo ideas o caigo en una serie de cosas que para otro normalmente serían muy complejas o siquiera las tendría en cuenta.

Todo esto me ha ayudado a la hora de poner en marcha Adrianne. A todo esto… quien es Adrianne? Esta es Adrianne:

Con cada serie de nuevas tarjetas gráficas, nVidia ordena crear una Demo especialmente diseñada para ella, intentando poner al máximo sus prestaciones. Hace unos años, con el lanzamiento de la serie 8 de nVidia, nos deleitaba con esta Demo. Se trata de Adrianne Curry si no recuerdo mal, creo que era una PlayMate que se prestó para tal exhibición.

Evidentemente no pretendo obtener un resultado similar. Mi idea es ser capaz al menos de renderizar el cuerpo entero de ella poligonalmente con un mínimo de iluminación, y como un “imposible” dejaría abierta la posibilidad de texturizar el modelo.

En realidad el reto que me propuse pasaba simplemente por ser capaz de realizar un parser para los arcihvos nmb, que son archivos propietarios de nVidia en los que se encuentra toda la geometría de los diseños 3D de estos. Es decir, en el caso de Adrianne, el archivo “geo_model.nmb”contiene toda la información sobre el modelo 3D Adrianne. Al ser un archivo propietario, a menos que llame a la puerta de nVidia y les pida por favor la estructura interna de este, el trabajo a mano a realizar es increiblemente grande. Hay que tener en cuenta que para mis ojos, tan solo es un archivo binario de 64MB, sin aparente información usable en su interior. Luego antes de ser capaz de renderizar nada, lo que tengo q hacer es ir interpretando poco a poco cada bloque hexadecimal de tan ingente archivo. Mi proyecto principal no fue con Adrianne, sino con Dawn, una Demo más antigua. Pero a fin de cuenta la estructura de ambos es muy similar, la diferencia es que ADrianne está en 64MB, y Dawn en tan solo 13MB. Es mas, tan solo la cabeza de Adrianne es más compleja que todo el modelo de Dawn.

Antes de poder hacer nada, la primera etapa es por tanto crear un pequeño Engine gráfico, la creación de un pequeño espacio tridimensional en el que poder representar puntos, polígonos… esto no es algo complicado, sobre todo con la cantidad de información que tenemos en internet. El problema claro está es comprender los ejemplos, el código, cada instrucción… y adaptarlo todo de la mejor forma a nuestro proyecto.

En mi caso he usado OpenGL como render, y GLUT para facilitarme el jugar con las coordenadas espaciales y la perspectiva.

Una vez la plantilla principal del engine está creada, el paso siguiente es verificar si dicho archivo, “geo_model.nmb” realmente contiene la información geométrica de Adrianne, y por supuesto verificar si el engine gráfico funciona. Aquí es donde tenemos que poner a funcionar el cerebro.

Lo más simple de todo, como no tenemos idea de la estructura interna del archivo de nVidia, es intentar renderizar todo el archivo como si fuese todo él un array de puntos. Pensar en un polígono. Su esencia última es el triángulo. Un triangulo se representa por 3 vértices. En cualquier archivo de geometría, lo que más debe de abundar con diferencia son vértices. Los vertices posicionarán los polígonos (triángulos) en el espacio tridimensional, los vértices de las normales serán los que indiquen el vector normal, usado para conocer la cara poligonal que recive la luz o por ejemplo también los vertices de los vectores tangenciales. Con esto quiero decir que de dicho archivo, de ser cierto, el 90% deberían de ser coordenadas espaciales.

Un vértice en un espacio de tres dimensiones se representa por 3 coordenadas x, y z. Si es un espacio bidimensional, usado por ejemplo en el mapeo de las texturas hacen falta tan solo 2 coordenadas u, v. Pero volviendo al tema principal, mi primer parser podría consistir simplemente en leer todo el archivo e interpretarlo como he dicho como un array de vértices. Un vertice normalmente se considera un numero de tipo float (numeros en coma flotante), un tipo de representación numérica, que es usada muy comúnmente cuando se necesita una resolución muy grande o muy pequeña. Un float se representa por medio de 32bits, es decir 4 bytes. Dicho esto, la primera aproximación a realizar es interpretar todo el archivo como una hilera de bloques de 32bytes, en el que se repetirá constantemente el patrón: X, Y, Z. Es decir, los primeros 4*3bytes del archivo serían el vértice 1: la componente X la componente Y y la componente Z. Los 3 floats siguientes se interpretarían como el vértice 2 con sus tres componentes… así sucesivamente.

Renderizar esto es facil, tan solo tenemos que cargar el archivo en memoria y desde nuestro engine hacer q se se representen en pantalla los vértices contenidos en nuestro buffer o la estructura creada. En mi caso he usado una estructura de este tipo:

Typedef Struct {

float x, y,z;
}vertices;

vertices *buffer;

Es decir, creo un array buffer de tipo vértices.Una vez todo está preparado, en el mismo engine tan solo tengo que llamar a este buffer y representar todos los puntos con un bucle simple for, que recorra todo el array. Previamente se ha calculado el número de vértices que tendría el archivo. Esto es facil, si he interpretado que todo el archivo en sí es un conjunto de vértitces, tan solo tengo que conocer por medio de ifstream el tamaño del archivo. Una vez conocido el tamaño del archivo en bytes, dividirlo entre 4 bytes (1 float = 4bytes) y después dividirlo por 3 (cada vértice tiene 3 componentes). El número resultante son los vértices. Por medio de new creo un array dinámicamente.

Cuando todo ello está terminado, con un for recorro todo el array, representando en cada momento el supuesto vértice:

glVertex3f (buffer.x, buffer.y, buffer.z);

Pero para poder lograr tener más información de todo ello, hago que dependiendo del puntero de nuestro buffer (la posición de este) me represente cada punto de un color u otro. Para ello divido el numero de vértices en 4, y el resultado será la umbral de cada trozo. De esta forma si el punto representado se encuentra en el primer cuarto del archivo, se representará de color rojo, si corresponde al segundo verde. Blanco si es al tercero y azul si es al cuarto. Esto es simple con una instrucción if y glColor3f.

Por último queda pensar en algo… de funciona, hemos presupuesto que el primer vértice comienza en la posición del archivo 0, y todos los consiguientes en saltos de 4 bytes. Imaginemos por un momento que tenemos realmente un archivo tan solo con vértices, pero que el primer byte del archivo es un identificador. Quiere decir que de representarlo como digo, no tendría nada!! puesto que mi matrón se extiende por todo el archivo, y jamás tendría un solo vértice representado correctamente. Pero esto mismo sucedería no solo si los vertices comenzasen en el primer byte, sino tb con el segundo y con el tercero. Las posibilidades por tanto sería un desplazamiento de 0, 1, 2 y 3 bytes. 4 no haría falta, dado que son bloques de 4 Bytes cada float, si desplazase 4 sería igual que no desplazar. Hablo de localidad dentro del mismo archivo. Con lo que si quiero representar el archivo a pelo, tengo que hacer en realidad 4 representaciones, cada una variando el desplazamiento 1 byte.

Como si de magia se tratase, con un desplazamiento de 0, y con todo lo comentado, esto es lo que obtengo:

Si no me falla la vista, eso parece ser el bañador de Adrianne? Evidentemente no quiere decir que todo lo que vemos sea parte de la geometría, ni mucho menos. Tan solo hemos pasado a nuestro engine un buffer de 64MB interpretado todo ello como vértices y obtenemos eso. Cláramente el bañador en azul, si está en azul quire decir que el bañador se encontraría en el último cuarto del archivo.

Para un desplazamiento de 1 Byte:

Vaya… en este caso hemos acertado en la cabeza de lleno, una pierna, medio cuerpo, un brazo, el ojo izquierdo, un pendiente… La cabeza en Verde nos dice que está en el segundo cuarto.

Para un desplazamiento de 2:

Otra pierna, en azul a la derecha y girado parece que podría ser el collar y un posible ojo? Tener en cuenta que las posiciones no tiene porqué corresponderse, al menos por ahora.

Y por último para un offset de 3:

Por último tenemos otro brazo, collar, cuerpo…

Creo que la mayoría de toda la geometría queda al descubierto.

Como segundo paso se podría acotar aun más la búsqueda de cada malla (parte del cuerpo) por separado, para conocer la ubicación concreta de cada una de las partes. Una vez realizado podríamos comenzar visualizando el archivo en un editor hexadecimal y ver si podemos extraer información directamente de él, teniendo en cuenta lo qye ya tenemos.

Pero ei… de momento el engine funciona, y se ve claramente un voceto muy primitivo de Adrianne diseccionada, en forma de puntos de colores.

Proyectos Actuales

Bueno… supongo que a este ritmo tendré que cambiar el nombre del blog por alguno que sea más fidedigno a mi blog. Estos son los proyectos en los que estoy “trabajando” cuando estoy “aburrido”, por supuesto estoy abierto a sugerencias, siempre y cuando sea algo que me interese y tenga ganas de desmarañar:

1º. Engine Gráfico

a) Crear motor gráfico. Completado (Muy rústico, pero funciona)
b) Crear un parser para renderizar los objetos .nmb de nVidia, por ejemplo Adrianne (una Demo de nVidia). Completado 20%
c) Renderizar aunq sea de forma muy primitiva Adrianne de forma completa. 5%
d) Publicar.

2º. Web

a) Crear una Web “decente” y suprimir completamente el blog, de modo que toda la información esté mucho más estructurada, secciones para cada cosa… y también eliminar del todo cualquier dependencia a Google. 0% Completado

2º. Proyecto SonyEricsson C905

a) Modificación del sistema de archivos. Completado (Por medio de a2tool)
b) Archivos importantes. Completado
c) Creación/Modificación de Drivers para Pantalla, Cámara… Completado 80%
d) Artículos sobre actualización/liberación? 0%
e) Otras modificaciones posibles: Temas, ajustes, personalizaciones… 80%

3º. Proyecto ElBruto

a) Compresión del sistema de juego. Completado
b) Desensamblado de la creación de personajes y otros procesos importantes. Completado
c) Modificación “al vuelo” del formulario de envío de datos. Completado
d) Script en Bash (Linux/Cywing) para creación infinita de alumnos. 40% Completado
e) Uso simples de un Bot para la creación de Alumnos. 0% Completado
f) Un “programa” para implementar todo los cheats posibles por hacer. 0% Completado
g) Publicar.

4º. Repositorio Cydia

a) Preparación. Completado
b) Debian, Toolchain… Completado
c) Compilación, creación de scripts y publicación. 0%

Agosto + Sevilla = Mucho calor. ¿Que hago?

Aunque no es que deje de tener interes en nuestros dispositivos, no puedo olvidar otros tantos proyectos que tengo en la cabeza y en verano que suelo tener mucho más tiempo reabro algunos de ellos.

Pero no signifique que no estoy aquí. De cuando en cuando miro aquí y allí pero la verdad no es que vea muy util publicar noticias cada dos por tres por alguna aplicación que Apple saque en el Store.

Y como es bueno mantenerse ocupado, he retomado simplemente a mejorar un poco mi SE C905, modificado los drivers de la cámara, pantalla, cambiar algunos aspectos del software, eliminar lo que sobra…

Si os dais cuenta, es siempre lo mismo. Da igual que lo que tienes en las manos sea una PDA, un movil, un PC… una vez saltadas las medidas de protección, el resto es código, y como código, se puede modificar y adaptar a las necesidades de cada uno. En este caso concreto no estaba conforme con las modificaciones de drivers que hay publicadas por otros lugares. Además soy de la vieja escuela, me fio más de lo que hago yo, y además estará completamente ajustado a mis necesidades.

En otro orden de cosas el verano tampoco me ha dado demasiadas malas noticias. Mi nuevo PC empieza a funcionar como tiene que funcionar y pronto tendré que actualizar la guia de codificación de video, dado al incremento exponencial en cuanto a calidad/velocidad que se estan haciendo en x264, hasta tal punto que la primera guia empieza a estar fráncamente obsoleta.

Por otro lado está el proyecto de “El bruto”, que no está abandonado, está “terminado”. Espero que no se quede en el cajón y tenga “ganas” de dedicar una entrada.

Y para acabar y más importante que todo eso, queda mi vida personal, fuera de mis hobby y mi trabajo, amén de un libro que algún día posiblemente se publique, y no, no es de informática, ni de iPod ni de nada por el estilo, es más… una novela. No todo tienen que ser números, siempre hay que dejar un hueco… el más grande, para el romanticismo, el amor y otras palabras aun más profundas.

Para mis amigos del sur que lo viven como yo… a 40 grados a las 20.00, paciencia… duchas frías, leer en la piscina o un masaje de la chica en la playa. Que posiblemente pocas mejores cosas se han inventado

Un saludo y espero que esteis pasando un bonito verano.

Proyecto: Después del éxito de Hammerfest, Brutus!!. Invirtiendo el tiempo en vacaciones

En vacaciones solemos tener siempre los mismos problemas… nunca hay noticias interesantes y sin embargo si nos lo montamos bien algo más de tiempo libre. Voy a seguir ausente unos días debido a que tengo que terminar de portar todo mi sistema al PC nuevo y posiblemente espere para terminarlo todo a la RTM de Windows 7 que debería de estar para esta semana que entra, por ello es que aun no he actualizado tampoco mi archivo de publicidad para Cydia y esas cosillas… lo siento…

Bueno vamos a dar un adelanto… en realidad esta idea no surgió de mí, dado que nunca me había interesado por este juego que por lo que parece ahora está de moda entre algunos aficionados.

Todo ocurrió hace ya unas semanas cuando un amigo me preguntó si sería posible lograr algo con este juego. Me explicó el funcionamiento del juego a grandes rasgos. Por lo visto lo que se intenta lograr es tener el mayor número de discípulos creo. Bueno, en cuanto termine la migración y otros menesteres explicaré y publicaré un código fuente para que cualquiera pueda compilarlo (tb lo daré compilado, o quizás no de el código… ya veré que hago) para digamos… disparar los discípulos a un nunmero indeterminado de ellos.

¿Gracioso verdad?

Proyecto: Eliminando publicidad en Cydia y Safari II (Actualizado 19/09/09)

Bueno, por ahora han aparecido dos problemas:

SBSettings chequea por si tenemos añadido en nuestro archivo host bloqueadores de Ads. Esto lo he solucionado a lo facil, redirigiendo el archivo del que se tomará de entrada en vez de “hosts” a “hostt”. El archivo no existe, luego la comprobación no es negativa, con lo que sbsettings funciona bien.

Categories usa el mismo sistema. Ahora mismo no tengo categories instalado, pero lo publicaré dentro de poco tambien.

Para poder corregir esto, volver a descargar el archivo de mi repositorio, en el que incluiré una/s versiones modificadas de sbsetting (ya lista) y categorie (aun no incluida) para solucionar esto. Simplemente hay que sustituir los archivos tal y como sustituimos el archivo de host.

SBSettings se encuentra en -> “/Applications/SBSettings/SBSettings”. De todos modos intentaré conservar la estructura dentro de mi propio 7z. Siento que no exista un modo mejor de hacerlo… y me temo que deberé de actualizar los parches a medida que actualicen los programas… pero por suerte tampoco existen apenas programas con este problema, por ahora tan solo son dos.

Quien no use estos programas, simplemente que no sustituya dichos archivos.

En realidad esto sería mucho más simple hacerlo a través de Cydia, pero mientras que logro poner el repositorio en linea y mientras no.

Os dejo como quedaría SBSettings, como podeis ver, adios a la publi, y en este caso sí que arranca ahora.

Proyecto: Eliminando publicidad en Cydia y Safari (Actualizado)

Esto me ha creado un pequeño dilema moral/ético. Llevaba ya un tiempo pensando en si es correcto filtrar la publicidad que aparece por ejemplo en Cydia en cada repositorio, o cuando queremos acceder a la información de una aplicación de Cydia en concreto o… la verdad es que algunas son realmente molestas y consumen un ancho de banda brutal en comparación de lo que consume simplemente lo que es el repositorio o la información util.

Pero claro… por otro lado las aplicaciones de Cydia son en su mayoría gratuitas y los repositorios se hospedan gratuitamente, siendo la publicidad algo de ingresos para ellos, cosa que me parece bien también.

Al final me he decantado por crear el proyecto, y espero que ningún desarrollador de Cydia se moleste. La idea es ir erradicando poco a poco cualquier publicidad no deseada en Cydia e ir extendiendo esto a Safari. En realidad filtrar contenidos es algo muy simple y efectivo, es usado en multitud de programas. Por ejemplo en Firefox tenemos la extensión Adblock plus con la cual nos suscribimso a listas para bloquear los molestos Ads q cada vez más invaden la red. La solución simple para nosotros sin tener que acudir a ningún programa es usar el archivo “hosts”.

Esto es algo que he explicado en alguna que otra entrada ya, pero lo comento de nuevo. El archivo “hosts” que existe virtualmente en cualquier OS, es un listado de hosts preconfigurados que usa el sistema operativo para fijar hosts, es decir, mapea nombres de host a direcciones IP. Esto tiene multitud de aplicaciones, luego explicaremos alguna. Su formato es muy simple, una entrada que corresponde a una IP se le asocia un nombre de host. ¿Que significa esto? que cuando cualqueir recurso del sistema tenga que acceder a dicho host, se envía directamente a la IP configurada. En realidad es como un sistema DNS.

Esto tiene una cantidad increible de usos:

-Acelerar la navegacion web añadiendo de forma estática las IPs de los host, con lo que las peticiones DNS no son necesarias para dichos Host, ahorrando ancho de banda y ganando velocidad

-Asignar estáticamente nodos de nuestra propia red, de forma que podamos alcanzar cualquier nodo de nuestra red con un nombre de host.

-Redirigir peticiones de una web (un host) a otra, por ejemplo para empresas o por pura comodidad. Aunque un virus podría dar buena cuenta de ello tambien y usarlo maléficamente. Tu quieres visitar hotmail.com y a todos los efectos estas en dicha página… solo que la iP es diferente y es un sitio Pishing.

-Bloquear contenido. Esta es la opción que le vamos a dar nosotros. Dado que el archivo de hosts hace de tradcutor, podemos hacer que se rediriga cada host a la ip que queramos. ¿Pero que sucede si redirigimos un host a la ip 127.0.0.1?

127.0.0.1 es la direccion de loopback, es decir, es la IP que identifica a tu propio PC en tu PC. Es decir si un programa envia un paquete a dicha dirección IP, lo envía a la interfaz de si mismo. Que sucede si tenemos Apache instalado (un servidor web) y tecleamos en nuestro navegador http://127.0.0.1? Pues que accederemos a la web index.html por defecto de apache, puesto que estaremos accediendo a nuetro mismo PC. Y si no tenemos apache instalado? nos devolverá un error el explorador pq no tenemos ningun servidor corriendo.

Luego si mapeamos un dominio cualquiera a 127.0.0.1, salvamos y accedemos desde el navegador a dicho host, nuestro navegador de firma mágica nos dirá que el host no existe. Que sucede si hacemos un listado de hosts de publicidad mapeados todos a 127.0.0.1? pues que la publicidad de dichos dominios no aparecerá, ni siquiera se solicitará al exterior puesto que internamente la buscará en nuestro propio PC. No hay consumo de ancho de banda de nuestra linea y nos quitamos los molestos ads.

Mi primer objetivo es eliminar la publicidad que pueda de Cydia con este método. Ya podeis descargar el archivo “hotst” que iré poco a poco modificando. Lo teneis a la derecha, en mi blog. Lo descargais, descomprimir y lo copiais y sustituis en el iPod/iPhone, en la ruta:

/private/etc -> Permisos 0644, archivo copiado como root.

No hace falta siquiera reiniciar. Por ahora croe que está eliminada toda la publicidad de todos los repositorios que vienen por defecto en Cydia menos el de iSpazio, debido a que no usan un host propio para ello, y si lo bloquease por este método, bloquearía el acceso tb al repositorio.

El archivo host especifica que hosts bloqueados estan en cada repositorio, aunque no es del todo exacto. Por ejemplo se bloquean los Ads de Google, y es algo que no es exclusivo del repositorio de BigBoss. Todos los ads bloqueados no solo corresponden Cydia, sino que safari o cualquier otra aplicación tendrá acceso a ellos.

Esto quiere decir que espero la colaboración de el resto para que si usando mi archivo de Host encuentra alguna publicidad en Cydia (que no sea la de iSpazio) que me lo deje en lso comentarios que repositorio fue y q me indique información sobre ella.

He dejado por motivos obios los logotipos de cada repositorio, no los considero publicidad, y además sería problemático bloquearlos

Con el tiempo iré creciendo el archivo y bloqueando mas y más ads de safari, por ahora tan solo los que afectan directamente a Cydia, aunque indirectamente los bloquea tb en safari. En safari empezaré por los más usuales.

sé que existen archivos hosts para descargar con listados interminables de adss, pero esa no es mi idea. Para empezar pq esos listados puden ocupar hasta cantidades de 1MB!! lo que haría el procesado de dicho archivo bastante pesado, y además nuestro dispositivo no es que ande muy sobrado de RAM. Así que por ahora me limitaré a ir filtrando poco a poco lo que sea más habitual. Repito, quien tenga interes por eliminar la publicidad de algunos sitios web comunes que lo diga que los añado.

Iba a poner algunas imágenes mostrando Cydia, pero os lo vais a tener que imaginar, otro día

Nada más por hoy… y posiblemente hasta el martes, que un servidor tiene que disfrutar del sol y el mar.

Actualizado: Nota!! la aplicación Categorie de Cydia usa banners de publicidad molestos que están bloqueados por mi version de archivo host. El problema es que la aplicación chequea si el archivo host está bloqueando dichas entradas, y de encontrarla simplemente reusa a ejecutar Categories. Es un método para obligar a tener los Spam aun cuando se use mi sistema. no obstente posiblemente o doy con una solución a esto, o parcheo categories para que no compruebe esto. Odio este tipo de sistemas.

Proyecto: Hammerfest II: CWS2FWS/Flasm, Apache… modificando lo que se desee

ATENCIÓN!! Como siempre, no me hago responsable del uso que se le puedan dar a las palabras… letras que aquí expongo. De principio a fin, y como sabéis todos siempre me he limitado a dar información y escribir conocimientos. Mi objetivo no persigue en modo alguno utilizar nada de forma inmoral ni por supuesto ilegal. Tanto Hammerfest como MotionTwin son marcas registradas, si hago un mal uso por error de cualquiera de su contenido, invito a los que tengan derecho sobre ello que me lo comuniquen y en paz. No soy un Jurista ni pretendo serlo, ni tampoco estoy de acuerdo con los Cheats (trampas).

Introducción:

Antes de comenzar… para quien sea capaz de leerse todo, tendrá desde luego con eso mi gran admiración… comprendo que es algo largo, pero creo que merece la pena.

Y para quien quiera esta entrada en formato PDF:

AQUI (descomprimir y listo)

Creo que no tiene ningún sentido que nos pongamos a discutir ahora sobre la intencionalidad o no de esta entrada, así como si debo publicar contenidos de este tipo o no debo de hacerlo. Todo ello creo que quedó completamente claro en mi primera entrada al respecto y sobradamente en los comentarios de esta. Posiblemente aparezcan de nuevo detractores y defensores… así que supongo que mejor evitar lo mismo, pero como he dicho siempre cada cual es libre de dar su opinión.

Al igual que hiciese con anterioridad, voy a intentar copiar el formato de la entrada anterior, intentando mantener los mismos puntos y seguir un orden. En este caso nos vamos a topar con el problema de los derechos de autor, los creadores del juego. Por razones claras, no puedo publicar nada que crea que pueda estar protegido por ellos, con lo que si llega el caso, no os podré poner literales, y quien quiera saber más tendrá que seguir estas letras a la par que va aprendiendo. De todos modos espero que sea lo menos posible.

Que es lo que vamos a aprender aquí? de que vamos a hablar? Bueno… en este caso vamos a aprender cómo se puede estudiar un juego/app flash a fondo, la cantidad de información que podemos obtener de este y de cómo podemos usarla!! Una vez que entendemos esto, veremos cómo podemos “engañar” servidores externos, como podemos descompilar y volver a compilar un objeto flash, como se manejan los archivos temporales del navegador, como se interactúa con contenidos flash…. etc etc etc. Y para quien se dedique o se quiera dedicar a la creación de contenidos de este tipo, pautas para mejorar la seguridad, entre otras cosas. Pondremos de ejemplos en este caso no solo a editar unos puntos, sino ser capaces de modificar virtualmente lo que deseemos de Hammerfest o de cualquier aplicación/juego flash que deseemos. Por simplicidad empezaremos a ver cómo podríamos modificar la rareza de algunos objetos, y podríamos acabar haciendo para que apareciese literalmente el objeto que deseásemos. Si tenemos tiempo, o quizás en otra entrada, veremos lo fácil que resultaría teletransportarse entre niveles

Como se aborda un problema II

En la primera parte nos hacíamos una serie de preguntas a las que fuimos contestando más o menos. Aprendimos a grandes rasgos como funciona internet, que información recibimos, que información enviamos… así como se tratan los contenidos interactivos de estos. Siempre tomamos la misma premisa, que cualquier contenido con el que interactuamos de forma activa desde nuestro PC, de un modo u otro está en nuestro PC, y por ello podemos modificarlo a voluntad si sabemos el qué, el cómo y el dónde. Pero a diferencia de lo que hicimos en primer lugar en el que modificábamos al vuelo el juego, en el que modificábamos (por así decirlo) el comportamiento de este, en este caso no es lo que vamos a hacer.

Es posiblemente una idea que se ha podido plantear alguno… como hemos dicho aquí lo importante no es saber hacer algo o no saber hacerlo, eso se aprende, se piensa se estudia… lo importante es preguntarse el cómo, pensar una medida de “ataque”. Y en esta ocasión, según aprendimos en la primera parte, vamos a hacernos otro razonamiento:

Sabemos que podemos modificar lo que sea que se encuentre en nuestro PC. Sabemos que el juego se ejecuta en nuestro PC y por ello pudimos modificar el comportamiento de este. Pero… si el juego se ejecuta en nuestro PC, significa que antes de que se ejecute en nuestro navegador (por así decirlo) se encuentra ya en este, y si esto es así… ¿podría modificarlo ANTES de que este se ejecute?

Todo tiene ventajas e inconvenientes, claro está. Una modificación “al vuelo” de cualquier juego/programa explicada en la primera parte suele ser algo mucho más fácil de hacer. Esto tiene sentido, un programa en ejecución se encuentra en memoria sí o sí como hemos dicho ya, para que el procesador pueda ir ejecutando instrucción a instrucción. Conocer las instrucciones que se están ejecutando es muy fácil, tan solo hay que saber ensamblador e interpretarlas o mirar un simple listado en inet de ellas. Aunque se suelen implementar todo tipo de medidas de protección para que una persona curiosa le dé por mirar en la memoria, como ya hicimos, se suelen poner muchísimas más medidas en el programa que aun no se está ejecutando. Nosotros en la primera parte simplemente con lógica logramos sortear la escasa “seguridad” que tenía MT en el juego una vez que este se ejecutaba. Es cierto que usaba algún que otro método de protección, pero poco más, con paciencia y buen tino es suficiente.

La modificación en disco es algo que suele ser más complejo, y en nuestro caso el problema se complicará por razones que veremos más adelante. Modificar es más fácil, pero no lo es interpretar lo que se está modificando. Algo que está en memoria suele estar ya “limpio”, desencriptado, descomprimido… casi con una secuencia lógica, listo para ser ejecutado el código por el procesador. En cambio cuando algo está en disco, lo normal es que esté “empaquetado”, encriptado, ensamblado… y solo una vez realizado el proceso inverso se podrá “atacar” el código directamente. La ventaja es que es más fácil obtener un control mucho más amplio de lo que se desea hacer.

Nuestro punto de partida por lo tanto será, como alguno habrá adivinado ya, la edición directa en disco. Pero para poder hacer esto tendremos q ir sorteando una a una las protecciones o las complicaciones que nos podamos ir encontrando. Nos centraremos en cada una de ellas a lo largo de esta lectura. Lo primero que necesitamos saber como hicimos la primera vez será el Dónde, ya que tenemos el Cómo lo vamos a hacer. Y al igual que nos ocurrió antes, nos toparemos con caminos que no nos llevan a ninguna parte y que tendremos que replantearnos de nuevo para llegar al fin.

¿Dónde?

Podemos localizar a grandes rasgos tres problemas fundamentales. El primero es que información es la que debemos editar, donde se encuentra. El segundo, como interpretar dicha información. Y por último como hacer que dicha información pase por legítima, por así decirlo. Luego en este punto vamos a tratar de resolver el primer problema. Que queremos modificar, como localizarlo, donde se encuentra… para poder pasar más adelante al cómo interpretar dichos datos, cómo modificarlos y para terminar cómo “montarlos”

En la primera parte, el planteamiento que nos hacíamos era que al estar en ejecución cualquier aplicación flash, esta debía de estar ejecutándose en algún lugar de nuestro PC. Aquí el planteamiento es el mismo, si se está ejecutando en nuestro PC es que antes ha tenido que pasar por nuestro HDD (Disco Duro) casi con toda probabilidad. Bueno… podría haber pasado directamente a memoria, pero esto no es así, y ahora vamos a explicar por qué, y vamos a hacer un paréntesis para explicar cómo funciona otro rasgo importante de cualquier navegador: El Caché. Pero aun cuando pasase a memoria directamente, explicaremos además como se podría aun así interceptar dichos datos. A fin de cuenta ahora mismo no nos estamos planteando como editar, que interpretar o que… ahora mismo tan solo nos interesa echarle el guante a la aplicación flash en cuestión, ya nos preocuparemos del resto más adelante.

¿Que es el caché?

El caché en los navegadores es un espacio reservado del HDD de cada uno que se encarga de mantener los datos más visitados, más recientes, más importantes… con la idea de que si se vuelve a solicitar una web que estuviese íntegramente en caché, se cargaría al instante. Evidentemente serían datos no actualizados, dado que los datos mostrados vendrían desde nuestro HDD, y no desde el servidor remoto. Normalmente no se guarda una página entera ni muchísimo menos, a veces son solo imágenes, otras veces código.. Cada navegador implementa el caché de forma diferente, y también depende de los ajustes de cada persona. Dado que normalmente la navegación se realiza por los mismos sitios, si mantenemos en caché imágenes que son estáticas con el tiempo y contenidos similares, nuestro navegador no tendrá que ir descargando una y otra vez el mismo contenido cada vez que se visita, y a lo mejor tan solo descargará de nuevo aquel contenido que podamos definir como “dinámico”. Por ejemplo, un contenido estático sería el logotipo de una empresa, que al visitar una web siempre fuera el mismo en el mismo sitio incluso con el paso de meses y años. Ese tipo de imágenes mantenidas en el caché harían que esa imagen no se descargase frecuentemente, siempre usaría la misma desde el HDD del PC, ahorrando el tiempo de carga de la misma y ancho de banda. Por el contrario un ejemplo de contenido dinámico sería una web en la que retransmiten un partido de futbol, y que se actualiza a lo mejor cada 30 segundos. Ese contenido no tiene cabida en el caché, dado que el contenido que deseamos es siempre nuevo!! Y si usásemos caché para este tipo de contenido lo que se nos mostraría en el navegador sería siempre datos no actualizados.

¿Qué importancia tiene esto en los objetos flash? Muchísima!! y la mayoría de todos vosotros alguna vez en algún momento se ha planteado esto aunque sin darse cuenta con los videos de YouTube u otros, que son videos flv, usando el mismo principio que aquí mencionamos. Imaginar que accedemos a YouTube y visionamos un video cualquiera. Lo reproducimos y cuando terminamos de verlo deseamos volverlo a ver. ¿Creéis que el video se volverá a tener que descargar de los servidores de YouTube? Sería una tontería!! Por el contrario podemos reproducirlo mil y una veces, posicionarnos al instante a cualquier punto del video… ¿por qué? porque está ya en nuestro PC. Incluso si cerramos el explorador (dependiendo de la configuración del navegador) y volvemos a visitar el mismo video, posiblemente la carga sea inmediata. Uno de los trucos para poder guardar estos Videos en el PC es lo mismo que estamos explicando aquí, dado que está almacenado en el caché, tan solo tendremos que recuperarlo.

Un objeto flash funciona del mismo modo. El navegador lanzará una petición para recuperar dicho objeto flash (del mismo modo que en YouTube se hace una petición para obtener un video) y el servidor remoto comenzará la transmisión del objeto flash. El objeto flash se irá almacenando en los temporales de Windows y casi con toda seguridad antes o después acabe en el caché del explorador. Al finalizar la transmisión de datos, el objeto estará en nuestro PC!! Da igual que no sepamos donde se encuentra exactamente, pero podremos afirmar con rotundidez que está en nuestro PC. De hecho, sin pensar demasiado, creo ahora mismo que el único o casi el único contenido que no pasa directamente por nuestro PC sino que pasa a la aplicación que sea directamente son los contenidos tipo Streaming, por ejemplo videos en Streaming, en los que se transmite un flujo constante de datos hacia la aplicación que los solicita, y al acabar la transmisión se corta la conexión y listo, si se requiere de nuevo los datos se deben de solicitar todos de nuevo. E incluso en este caso, también es simple interceptar estos datos y almacenarlos (El bueno de VLC siempre ayuda)

¿Alguien se ha perdido? Vamos a ver que tenemos por ahora. Lo que estoy diciendo es que si accedemos a cualquier web en la que se cargue un objeto flash, ya sea una aplicación ya sea un juego ya sea lo que sea, este contenido casi con toda seguridad pasará a formar, por el tiempo que sea, parte del caché del navegador, y si sabemos cómo localizar este caché y dicho objeto en el caché, tendremos el Dónde. Por la misma razón que existen contenidos dinámicos y estáticos, existen métodos por los cuales decir al navegador que el contenido que va a recibir no se almacene en caché, o se puede usar esto también para intentar evitar que el contenido pueda ser accedido en el caché. Pero a nosotros por ahora esto no nos importa (aunque más adelante será un problema con el que nos vamos a topar), lo que nos importa es que en el caché está nuestro objetivo.

¿Donde está el caché? ¿Cómo se encuentran estos archivos temporales del caché?

Bueno esto es más complicado. Cada navegador usa un sistema diferente. En mi caso uso y usaré para todo Firefox, con lo que todo lo que diga a partir de ahora irá orientado a él. Esto no quiere decir que no se haga de modo muy similar con Internet Explorer, Ópera o cualquier otro navegador.

En Firefox hay unos archivos de control que podríamos decir que se encarga de establecer toda la estructura del caché. A grandes rasgos, dado que la arquitectura de la caché en Firefox podría ser tratada en una entrada solo para ella, podemos decir que los archivos independientes que suelen ocupar en tamaño un espacio no despreciable, se almacenan en el caché de forma inalterada, es decir, si es una imagen jpg se creará en el caché la imagen nativa jpg. En el caso de tamaños de archivos despreciables (en comparación con objetos “pesados”) como páginas HTML, pequeñas imágenes, páginas de formato CSS… este tipo de contenido se suele almacenar no de forma independiente, sino en bloques dentro de otros archivos. Las peticiones web se almacenan también en este tipo de archivos (Ya explicaremos que son estas peticiones web).

Luego quiere decir que si accedemos a la web X, cargamos la aplicación/juego, accedemos a la carpeta del caché de Firefox, existirá un archivo de nombre indeterminado que es precisamente el juego/aplicación que estamos ejecutando además en dicho momento en RAM, y que es posible que al cerrar el navegador y dejar de ejecutarlo, permanezca aun así en dicha carpeta. Pero… ¿cual es el archivo?

Por cierto, no he dicho la ruta aun del caché de Firefox, pero es algo que no es un secreto ni misterio, una simple búsqueda en google nos quitaría el problema:

Windows Vista:

“C:\Users\[Usuario]\AppData\Local\Mozilla\Firefox\Profiles\aleatorio.default\Cache”

Windows XP:

“C:\Documents and Settings\[Usuario]\Local Settings\Application Data\Mozilla\Firefox\Profiles\aleatorio.default\Cache”

Donde [usuario] es el nombre del usuario de sesión y aleatorio es un nombre generado de forma aleatoria (en realidad no es aleatorio, pero nos da igual). Pues en dicha carpeta se encuentra. Tener en cuenta que la carpeta AppData/Local Settings y posiblemente otras estén ocultas, así que Herramientas de carpetas y ver Archivos/Carpetas ocultas.

Otro modo más simple y rápido de saber cual es nuestra carpeta de caché en Firefox es teclear en la barra de direcciones de este lo siguiente:

about:cache

Evidentemente sin las comillas. Ello nos abrirá una pestaña o en la misma, y nos saldrá información acerca de nuestro caché, entre otras cosas donde se guarda de manera local:

Disk cache device

Number of entries:

2842

Maximum storage size:

51200 KiB

Storage in use:

51190 KiB

Cache Directory:

C:\Users\[Usuario]\AppData\Local\Mozilla\Firefox\Profiles\xxx.default\Cache

Luego está claro a que carpeta debemos acudir. Pero incluso en la misma pestaña abierta, podremos darle a un botón que se llama: List Cache Entries que os listará todos los objetos almacenados en el caché, entre ellos debería de estar nuestro objeto flash o nuestro video de YouTube…

El problema es identificar el objeto. Si le damos a List Caché Entries es muy fácil saber si nuestro objeto está o no está dado que hace referencia directa a la URL de origen de dicho objeto. Pero cuando accedamos a la carpeta Caché veremos que los nombres no son nada descriptivos, que parece que son tan solo nombres aleatorios. Ante esto podemos hacer varias cosas para identificar lo que estamos buscando:

a) Aunque no necesario, si limpiamos el caché del navegador ANTES de acceder a la aplicación/juego, tendremos un caché prácticamente vacío, lo que hará encontrar el archivo en cuestión casi al instante. No voy a explicar ahora como se limpia el caché del navegador. Pero el proceso sería Limpiar caché, cerrar navegador y visitar la web de la aplicación/juego flash para que este se cargue, evidentemente hay que hacer que se cargue la aplicación/juego.

b) Con un caché vacío o casi vacío, lo normal sería ordenar los archivos de la carpeta caché por tamaño o por fecha. Por fecha para eliminar posibles entradas que el caché contenga (en caso de no limpiar el caché). Por tamaño porque es lo más identificativo de cara a diferenciar el objeto flash entre cualquier otro objeto, y esto mismo se puede aplicar para videos de YouTube u otros. Es lógico pensar que el contenido flash va a ser de un tamaño considerable en comparación con otros contenidos que se hayan podido descargar. A fin de cuentas las imágenes, código HTML… no ocupa demasiado en comparación con lo que puede ocupar una aplicación/juego flash, que pueden ocupar desde 1MB a 10MB a lo que sea. O lo mismo para un video, que puedes ir buscando tamaños a partir de 3MB por ejemplo. Dado que vamos a suponer que el caché está limpio, posiblemente el archivo de más peso sea precisamente lo que andamos buscando. OJO! los archivos que comienzan por “_CACHE_” son archivos de bloques que NO SON LOS QUE BUSCAMOS, estos los ignoramos, ocupen más o ocupen menos, hay 4 de estos archivos si no recuerdo mal.

c) Una vez que tengamos claro o casi seguros que archivo es el que estamos buscando, deberíamos de comprobarlo de algún modo. Lo primero será copiar dicho archivo al escritorio de Windows para tenerlo más accesible y evitar además que se elimine del caché por algún método ya explicado. Una vez en el escritorio tenemos varias formas de verificar si tal archivo es o no es el que necesitamos:

Opción A: Dado que es un contenido flash, nuestro navegador debería ser capaz de abrirlo directamente. Para hacer esto tan solo tendríamos que renombrar el archivo con la extensión de objeto flash: “swf” y arrastrarlo a nuestro navegador. Posiblemente el navegador cargaría el objeto flash sin problema alguno… pero quien lo haga, se dará cuenta en el caso de aplicaciones como Hammerfest que, o se le bloquea el navegador o no aparece absolutamente nada… no, no es un error, es debido a que muchas aplicaciones/juegos flash se componen en realidad de dos partes, sobre todo cuando es una aplicación/juego que interacciona con un servidor y en la que la aplicación/juego interacciona de algún modo con la sesión de cada jugador. Estas partes podríamos categorizarlas como el programa cargador y el programa aplicación. El cargador se encargaría de asociar por así decirlo una cuenta, una sesión, un… a la aplicación principal, además de encargarse de asuntos de seguridad, control de cuentas, intermediario en la transmisión de datos… dejando la aplicación tan solo para eso, para la aplicación en sí, sin preocuparse esta de si ha existido errores en la transmisión de datos, si todo es correcto… etc etc. Esto es u esquema muy común en este tipo de contenidos. Debido a esto, la aplicación “sola” no puede ser ejecutada en un navegador, puesto que depende del cargador que es quien le pasará los parámetros necesarios para hacerla ejecutar correctamente.

Opción B: A estas alturas supongo que el que más o el que menos tendrán un editor hexadecimal en su PC, y si no es así… ya está tardando. Yo recomiendo WinHex, pero cada cual que use su favorito. La opción A es rápida y simple, aunque no garantiza al 100% que sea lo que andamos buscando. Lo que nos interesa con esto es saber si la cabecera del archivo coincidiría con la cabecera de un objeto flash swf. La cabecera de un objeto flash, los primeros 3 bytes del archivo, corresponden con “SWF”, 46 57 53 en hexadecimal ó a “CWS” 43 57 53, como podemos ver en estas dos capturas de un tema flash para mi móvil que estoy creando:

http://2.bp.blogspot.com/_vjJp6vqpe7U/SiQKAiJpaUI/AAAAAAAAAxk/YbFOXQRFN6I/s400/Captura.PNGhttp://4.bp.blogspot.com/_vjJp6vqpe7U/SiQJh9aafQI/AAAAAAAAAxc/KhSfqT2cRtU/s400/Captura2.PNG
Con dichas cabeceras sé que aunque el navegador no quiera abrir dicho contenido, son objetos flash. Si tenemos en cuenta el tamaño, la fecha y el navegador vacío… está claro.

Hay herramientas que hacen de todo esto mucho más fácil, y simplemente interceptan la petición flash y permiten almacenarla en disco directamente. Pero me gusta hacer las cosas a la vieja, sin depender de ningún programa en la medida que pueda.

Aunque nadie se lo plantee, en las dos imágenes posteadas aparece lo que será una de las cuestiones claves en el siguiente capítulo, pero como estoy diciendo, será cosa del siguiente capítulo.

El otro modo del que hablaba, pasaría por interceptar la petición al servidor web que hace nuestro navegador y descargar el objeto flash directamente con cualquier gestor de descargas o desde nuestro propio navegador si deshabilitamos los complementos que hagan que el contenido flash se “ejecute”, permitiéndonos descargar dicho contenido.

¿Como interceptar estas peticiones?

Hay muchas soluciones. Desde mirar el código fuente de la web que abre la aplicación/juego en cuestión, algún complemento de Firefox para mirar cabeceras, un servidor proxy… o evidentemente mi favorito, un Sniffer. Un Sniffer no solo nos va a servir para esto, sino que nos puede dar siempre una información valiosísima y muy útil. Un Sniffer, entre otras muchas cosas captura perfectamente cualquier petición realizada, con lo que nos es muy simple conocer la ruta exacta del objeto flash, así como si existe alguna dependencia o el nombre mismo real del archivo en el servidor.

A continuación os dejo una petición (y su contestación) de un objeto flash, vista desde WireShark, precisamente el mismo tema flash que estoy creando:

http://1.bp.blogspot.com/_vjJp6vqpe7U/SiQYiUqNmiI/AAAAAAAAAxs/tXJHjpD-q28/s400/Captura.PNG
Hacer clic para ver más grande.

Como se puede observar en la imagen, la parte superior roja hace referencia a la petición que realiza nuestro navegador, mientras que la parte azul hace referencia a la contestación por parte del servidor.

Si os fijáis, las dos primeras líneas son:

“GET /Desktop.swf HTTP/1.1
Host: www.theliel.es”

La primera dice que quiere obtener el archivo /Desktop.swf que hace referencia a dos cosas. La primera al nombre del archivo y la segunda a la dirección en el host donde se encuentra, en este caso en “raíz”.

La segunda línea lo dice ella misma, es el host. Luego quiere decir que el archivo flash que desearíamos descargar se encontraría en la dirección “www.theliel.es/Desktop.swf”. Luego con cualquier gestor de descargas o modificando el comportamiento de nuestro navegador, podríamos tener de forma clara también cualquier objeto flash en nuestro escritorio.

Usar WireShark es fácil, aunque requiere quizás de algo de práctica para ver las cosas con claridad. Para quien prefiera algo más facilito pero al estilo de WireShark podría probar también con un programa gratuito llamado Paros, que es un pequeño proxy que intercepta cualquier petición y muestra de forma estructurada las peticiones realizadas a cada host, de modo que si lo activamos y abrimos cualquier web con cualquier contenido, en Paros nos irá apareciendo toda la estructura de archivos de dicha web, incluyendo objetos flash, con sus nombres reales y rutas, siendo idóneo para los menos acostumbrados. Configurar Paros es muy fácil, pero requiere de un pequeño cambio, dado que Paros actúa de proxy, y tenemos que hacer que el contenido pase por él. Tan solo debemos de acceder a las opciones de red de Firefox:

Opciones/Avanzadas/Redes/Configuración. Estableceremos servidor proxy manual a la dirección de loopback de nuestro PC: 127.0.0.1 y el puerto el que servirá Paros, que por defecto es el 8080. Una vez modificado esto y con paros funcionando, podremos ver que funciona perfectamente, cualquier página visitada quedará registrada íntegramente en Paros:

http://2.bp.blogspot.com/_vjJp6vqpe7U/SiQcxFWz0dI/AAAAAAAAAx0/TssxHkmE1P0/s400/Captura.PNG

Como podemos ver es un poco lo mismo. En Request tendremos las peticiones y en Response la contestación. En el ejemplo, simplemente abrí la web de mi blog, y vemos parte del árbol que se ha generado a partir de ello (no está completo). Por ejemplo podemos ver cosas curiosas, como que se hace una petición a YouTube de un video!! Claro, en mi blog tengo un enlace a mi video de iPod Touch, y aparece aquí, aunque en otro dominio y no es el video en sí, sino el reproductor de YouTube que implementa Bloggers. Y aun así, si os fijáis, aparece la ruta exacta a dicho reproductor (que no deja de ser u objeto flash). Con Paros, para quien no esté acostumbrado, podrá crear un árbol completo sobre la web que quiera estudiar y ver las dependencias de archivos, los dominios, los nombre de los archivos… datos que a la larga nos harán falta de un modo u otro. Luego ya sea pro WireShark, ya sea por Paros… recomiendo usar un sistema similar. De momento cada cual puede conformarse con la captura de caché, pero ya veremos los problemas que aparecerán más tarde.

Descargar Paros Proxy

Notas: Hace falta tener instalado el JRE desde la web oficial de Sun, que se puede obtener desde AQUI (y seleccionar la plataforma). Después de usar Paros recordar volver a deshabilitar proxy en las opciones de Firefox o no os funcionará el navegador con Paros cerrado.

Bueno, creo que queda claro suficientemente el Dónde, quien haya terminado de leer este capítulo, debería de ser capaz de saber capturar cualquier contenido desde caché o desde un proxy como Paros o WireShark. Así que ahora de todo esto nos olvidamos y simplemente vamos a suponer que tenemos en el escritorio un archivo llamado: Test.swf (por ejemplo) que será la aplicación/juego que queramos estudiar, ya la saquemos desde Paros y conservando el nombre original que extraída del caché con un nombre raro y renombrado. No importa.

Interpretando, Jugando con los editores hexadecimales

De acuerdo Theliel, tienes en el escritorio un archivo swf que ocupa lo suficiente como para volvernos locos buscando algo de interés. ¿Qué podemos hacer ahora con esto? Bueno, es interesante pensar en las alternativas, en diferentes planteamientos posibles. Se me ocurren muchas alternativas, algunas de las cuales sé de buena tinta que ya han sido usadas por más de uno, pero siempre corre el mismo riesgo, no implica que toda idea pueda acabar en un éxito. Muchas nos llevarán de nuevo a callejones sin salidas, otras veces no seremos capaces de continuar y es posible a lo mejor que no encontremos salida!! Pero vamos a intentarlo. Así que antes de ver las diferentes técnicas o sistemas que podemos aplicar, tenemos que conocer antes algo de flash, sería poco prudente por nuestra parte intentar abalanzarnos así como así contra un objeto flash, sería temerario igualmente cruzar un pantano lleno de serpientes venenosas con los ojos cerrados.

Así que vamos por el principio: ¿Que es flash?

Si acudimos a la Wiki nos vamos a topar con buena información al respecto, pero creo que es mejor que cada uno se haga su propia idea. Yo veo flash como un objeto, una caja. Una caja en la que dentro podemos encontrar por ejemplo pistas de video y de audio, podemos encontrar gráficos vectoriales que pueden ser animados o lo más importante para el caso que nos ocupa, un lenguaje de Script de “programación”, llamado ActionScript. Este lenguaje maneja imágenes, videos, vectores… etc etc etc, todo ello objetos que se encuentran dentro de nuestro objeto flash. Al ser Flash un lenguaje en sí mismo (ActionScript) es necesario que alguien haga de intérprete de dicho lenguaje!! Y efectivamente nos topamos con que Flash actúa como una máquina virtual. Esto no es raro, dado que para que podamos visualizar contenido Flash en nuestros navegadores necesitamos instalar previamente dicha Máquina virtual, llamada para tal efecto el reproductor “adobe flash player”. Pero no deja de ser una máquina virtual. ¿Qué significa esto?

Cuando creamos un contenido Flash, añadimos a este los objetos que necesitamos, todo el contenido estático que luego será usado por nuestro código en ActionScript para manejarlo. Así por ejemplo añadiremos nuestras imágenes que formarán nuestro monigote, los sonidos del paisaje, las fotos de fondo… lo que sea. Y por otro lado tendremos que escribir un código (o se generará este en parte) para hacer que nuestro monigote (que a lo mejor no es más que una sucesión de 4 imágenes estáticas) ande, corra, salte, vuelve, beba agua, vaya al servicio… o lo que sea. Digamos que ActionScript hace todo, es la programación de la aplicación/juego Flash. Os imagináis poder echarle el guante a este código? Simplemente nos bastaría con saber programación en ActionScript para desentrañar todos los misterios de cualquier aplicación/juego del que tuviésemos dicho código!!

Una vez acabada la aplicación/juego, se compila y comprime (o no) y se genera el archivo swf final que será colgado de cualquier servidor con las instrucciones dadas para que sea ejecutado en los exploradores de medio mundo. Ese código en ActionScript se compila como sucede con cualquier código de PC, y pasa a código máquina. Dado que Flash actúa en un modelo de máquina virtual, este código compilado no es interpretado para nuestro PC, pero sí por el reproductor que tiene ya instalado nuestro navegador, Flash Player. Este es capaz de abrir el archivo flash, saber que es una imagen, que es un sonido… y traduce a instrucciones de PC los códigos en ensamblador flash leídos por la aplicación/juegos en ejecución. Lo vemos mejor ilustrado en un ejemplo:

En ActionScript -> A=B * C
ActionScript Compilado ->

“constants “A”, “B”
push”A”, “B”
getVariable
push “b”
getVariable
multiply
SetVariable”

Que no son más que instrucciones ensamblador para Flash. Cuando se compila tan silo se genera el código hexadecimal correspondiente a cada instrucción. Sí, la dificultad de interpretar Flash en ensamblador es que Flash es un lenguaje de pila. Pero eso lo dejaremos para otro día.

De todos modos con esto podemos tener una idea bastante clara de lo que es la tecnología flash y de cómo funciona, y tendremos algunas ideas nuevas de cómo podríamos abordar el problema.

a) La opción más normal y lógica a seguir pasaría por descompilar la aplicación/juego flash e intentar de este modo tener acceso al código ActionScript. Esto suena más fácil de lo que parece, dudo que exista a día de hoy algún desensamblador en condiciones para Flash. Aun así sería una opción más que posible, y seguramente nos funcionaría al 100%. Pero esto implicaría primero que nuestro desensamblador hiciese su trabajo en condiciones, saber nosotros ActionScript y ser capaces de manejar un código considerable que ni siquiera hemos escrito, y para colmo ser capaces de recompilar de nuevo TODO el objeto flash para que los cambios realizados pudieran ser útiles. Es una posibilidad, y la trataremos en su debido tiempo… tiene sus pros y sus contras.

b) La opción a es buena, pero para quien no tenga conocimientos puede ser un camino más que bloqueado. Muchas veces en cambio podemos optar por métodos más sutiles que no siempre serán válidos pero que a veces nos podrán funcionar y muy bien. Sí, con muchas limitaciones la mayoría de las veces, pero lo suficientemente efectivos para no meternos en otros berenjenales. Vamos a centrarnos primero en esta opción, y dejaremos la opción A para más adelante.

Hemos dicho que tenemos el objeto flash en el PC y también que dentro de él seguro que encontraríamos código en ActionScript, imágenes, sonidos… Pero no deja de ser un contenedor nuestro objeto Flash. Antes de continuar vamos a hacer un símil con el formato de Audio/Video MP4. MP4 no es más que un contenedor en el que podemos encontrar Audio, Video, pistas de subtítulos, pistas de capítulos… etc. Si el contenedor no estuviese muy protegido o encriptado o comprimido… sería muy fácil abrir con un programa o incluso un editor hexadecimal y buscar el principio y fin de la pista de subtítulos por ejemplo, o de la pista de audio. El mismo concepto podríamos aplicar a u objeto Flash.

¿Que queremos decir con esto? que antes de intentar descompilaciones extrañas, sistemas rebuscados… vamos a intentar ir a lo fácil. ¿Qué pasa si dicho objeto flash lo abro directamente con mi editor hexadecimal? ¿Podré encontrar información de interés o tan solo símbolos extraños y valores sin sentido?

Pues señores, esto es una lección práctica así que a probar!! Yo continuaré con mi ejemplo basado en mi tema para mi móvil, para que después digan los amigos de MT que no tengo consideración con ellos!! Pero cada cual puede seguirme con el objeto flash que más les guste. (Dije que no pondría ningún material que pudiese atentar con los derechos de autor de Hammerfest, pero nunca dije que pudiese descompilar o modificar o jugar con un archivo creado por mí mismo. Las cosas de la vida)

A lo que íbamos. Vamos a ver qué sucede cuando abrimos directamente el objeto flash en nuestro editor hexadecimal (es la misma imagen que la anterior):

http://4.bp.blogspot.com/_vjJp6vqpe7U/SiQJh9aafQI/AAAAAAAAAxc/KhSfqT2cRtU/s400/Captura2.PNG

Sin embargo, después de recorrer todo el archivo no he encontrado nada que me pueda servir. Quizás no sea una buena idea después de todo… ¿o sí? Ahora entra el conocimiento puro y duro que hayamos podido aprender de Flash. Hemos hablado de las cabeceras de los archivos flash… ¿pero nadie se ha preguntado por qué existen dos cabeceras diferentes? Tenemos una cabecera CWS y otra FWS. Dije hace un buen rato que cuando se compila un objeto flash para generar como paso final el archivo .swf, entre otras opciones, podemos optar por la compresión de dicho objeto. El objetivo de la compresión es obvio, hacer que dicho objeto flash ocupe menos, aunque tiene una segunda función igual de interesante… ocultar contenido potencialmente accesible sin más. Actualmente, para cualquier creador de contenidos flash ya sea por ahorrar espacio como para ocultar rastros, la compresión es bien necesitada. Si no hay nada que ocultar a veces la compresión no obstante no es recomendada, el dispositivo final tendría que descomprimir antes y a lo mejor el espacio ahorrado podría ser mínimo o inexistente, dependiendo del contenido de dicho objeto flash.

Como podemos saber si el contenido del objeto flash se encuentra comprimido o sin comprimir? es fácil, mirando la cabecera. Precisamente la C de CWS significa “Compressed”, mientras que los archivos flash con cabecera FWS no se encuentran comprimidos. En las dos imágenes que posteé en su momento pertenecen al mismo archivo, compilado igual, uno comprimido y otro sin comprimir. En mi caso el tamaño de archivo es prácticamente el mismo, pero podemos encontrar sorpresas en la versión no comprimida:

http://2.bp.blogspot.com/_vjJp6vqpe7U/SiQKAiJpaUI/AAAAAAAAAxk/YbFOXQRFN6I/s400/Captura.PNG
Si comparáis las dos imágenes, está claro que los datos son dispares, pero tampoco hay nada legible. No obstante, si en mi editor hexadecimal me desplazo a lo largo del archivo swf (no comprimido) al igual que hice anteriormente con el comprimido, me encuentro por ejemplo cosas de este tipo:

http://4.bp.blogspot.com/_vjJp6vqpe7U/SiQ1hX9IPxI/AAAAAAAAAx8/k-JmTrdHbbs/s400/Captura.PNG

Interesante… muy interesante. Esto está un poco mejor… parece código de alguna clase. No digo que en este caso pueda servirnos para algo, o puede que sí… quien sabe… pero es un punto de partida. Para empezar porque si lo mostrado sí tuviese sentido claro para nosotros, podríamos simplemente modificar un valor y guardar. Con suerte sería suficiente, si obviamos posibles problemas por checksum y otros.

Normalmente, la mayoría de contenidos Flash contienen datos de interés de este tipo, y cuanto mayor sea la aplicación/juego, más uso intensivo se le da a este tipo de contenido. ¿Pero por qué? Tiene su lógica:

Pensar en una aplicación empresarial, por ejemplo la gestión de parques naturales de España. Imaginar que desde dicha aplicación se controla todo:

- Gestión
- Mantenimiento
- Visitas
- Animales
- Personal
- Facturación
- etc

Está claro que por muy sofisticada que sea la aplicación, un peso muy importante e imprescindible no recae sobre la aplicación en sí, sino en la base de datos que tendrá detrás de él suministrando todos esos datos. Vale, la aplicación es una maravilla, pero hace faltan los datos del personal, los datos de los animales, los datos de cada parque, los datos de cada visitante, las… todo ello no se implementa evidentemente en la misma aplicación, en realidad no tendría mucho sentido, más que nada pq estos datos pueden crecer o decrecer rápidamente, son dinámicos, están en continuo cambio.

Pero claro… en un entorno empresarial a día de hoy hay servidores que se encargan de administrar dicha base de datos, de dar acceso… pero en una aplicación flash esto como que no, todo debe de ir en el mismo caso. Si grandes tablas o bases de datos se tuviesen que implementar en una aplicación/juego flash, evidentemente no se haría en ActionScript, no sería una forma eficiente ni de implementar ni de corregir. Imaginaros que por lo que sea, se introdujo mal un dato en la aplicación servida, en una app flash que gestiona lo dicho, parques de España y supongamos que no hay una base de datos externa. El programador debería de abrir el entorno de programación, abrir todo el proyecto, ir al punto exacto, modificar el dato por el nuevo, guardar los cambios, recompilarlo todo… mucho trabajo a lo mejor para simplemente modificar un dato. En cambio, si tienes un entorno que sepa por ejemplo simplemente abrir y cerrar un objeto flash correctamente y permite modificar un objeto existente en él, como una tabla, una BD… automáticamente el proceso se simplificaría al máximo. El programador tardaría a lo mejor de 10 minutos (compilar un proyecto flash en condiciones tarda) y cientos de pasos a cuanto… 1 minuto?.

El caso de Hammerfest por ejemplo. Está claro que es lo que usa, principalmente porque se vio en CheatEngine en el capítulo eliminado (Temporalmente). Y segundo porque simplemente es lógico. Hammerfest es un juego/aplicación que se basa principalmente en objetos con propiedades como el valor, como la rareza, como las familias existentes… etc etc que todos sabemos. Os imagináis que los amigos de MT tuviesen a lo mejor que recompilar toda la aplicación Flash simplemente para modificar el valor de un objeto? Hombre, que a lo mejor se puede hacer y compensa!! Pero al menos desde mi punto de vista es algo muy poco efectivo y a la larga una pérdida de tiempo descomunal.

Siguiendo el mismo razonamiento, no sería extraño presuponer que los amigos de MT implementaron este tipo de soluciones. El problema que tienen es que de ser así, los datos podrían ser accedidos de forma simple, y modificarlos también. Evidentemente si fuese el caso de una compresión, esto evitaría poder verlo, con lo que la compresión sería además un método de “protección” adicional para este tipo de datos, con lo que simplemente realizando una descompresión del objeto flash, podría darnos una cantidad de información increíble, e incluso información lista para modificar sin necesidad de recompilar nada ni usar ingeniería inversa, ni saltarse ninguna protección, ni “parchear” en el sentido real de hacer una modificación consistente. Tan solo sería necesario un editor hexadecimal, localizar el punto a modificar y listo.

Por razones de seguridad esta vez no me voy a pillar los dedos y ante la duda esta vez tan solo doy información al respecto que no esté sujeta a ninguna posible ley de propiedad intelectual, de este modo si se repite de nuevo lo sucedido asegurarme que quien realice la petición a Google le salga el tiro por la culata y termine pagando por ello, como fue el caso de un caso en el que la empresa acabó pagando 100.000$ por costas y otros, quien se vea interesado puede leerlo AQUI

Pero nosotros a lo que nos interesa…

¿En mi caso concreto? Un poco lo mismo, mi objeto flash (el tema) se apoya en archivos de texto plano para especificar algunas propiedades que no son especificadas en otros puntos de todo el objeto flash.

En el caso de Hammerfest, casi con toda posibilidad exista algo muy similar, y cualquier propiedad pueda ser editada sin complicación alguna y sin conocimientos de ningún tipo, como pueda ser la rareza de cada objeto, el valor, la familia a la que pertenezca, redirecciones de portales de las paralelas… Quien haya llegado hasta aquí y haya querido experimentar con ello ya se habrá percatado de ello.

Pero claro… aun no hemos desvelado como vamos hacer para descomprimir un contenido flash. A fin de cuenta no estamos hablando de descompilar nada, simplemente de descomprimir. Un objeto flash puede comprimirse usando el algoritmo zlib. Normalmente este proceso se realiza como paso último a la compilación del objeto flash swf. A efectos de nuestro navegador, le da igual que se trate de un contenido flash comprimido o no comprimido. Si está comprimido tardará algo más en ejecutarse puesto que se debe de descomprimir en memoria, si está descomprimido el proceso será más rápido pero el tamaño será mayor, con lo que la descarga será más larga. Todo tiene sus pros y sus contras. A nosotros nos puede dar lo mismo, ya estamos trabajando en local, y si en un futuro necesitásemos comprimirlo de nuevo por el motivo que fuese ya nos preocuparíamos de hacerlo. Esto no es descabellado, yo si creara contenido de este tipo, usaría como medida adicional un Loader (cargador) que especificase un hash del contenido que se ejecuta y que se reenviase al final de la ejecución, con idea de que de alterarse el servidor rechazara la conexión. Aunque es solo un ejemplo, se me ocurren muchos otros, igual como otras posible medidas para también saltarse estas propuestas, como podría ser entonces descompilar el Loader y editarlo con mis datos… pero es como todo… no existe un sistema infalible, pero se pueden poner complicadas las cosas.

A lo que íbamos… Zlib. Como se aplica Zlib a un objeto Flash?? Hombre, es evidente que no se aplica íntegramente a todo el contenido, cualquiera para saber esto podría crear un simple ejemplo flash y compilarlo con diferentes opciones de compresión. Para ahorrar trabajo os lo digo yo, la compresión no se aplica por ejemplo a la cabecera. Pero quitando la cabecera del archivo se aplica íntegramente a todo el archivo. Aquí se abre un nuevo abanico de posibilidades para convertir un archivo flash comprimido -> CWS a un archivo flash no comprimido -> FWS:

a) Podríamos en un editor hexadecimal cortar la cabecera del archivo y lo que quedase aplicarle el algoritmo zlib (para descomprimir) usando alguna herramienta que encontremos (lo cual es complicado), y una vez descomprimido el contenido restituirle la cabecera cortada y modificar CWS por FWS

b) Podríamos buscar alguna herramienta que hiciese el trabajo por nosotros… y os ahorro el trabajo, no es fácil encontrar algo así, aunque por suerte para muchos existe, pero la usaremos en otro apartado que explique más detalladamente cómo se podría descompilar un objeto flash o “reconstruirlo”. Además queremos aprender no hacer trampas por hacer trampas, y lo mejor siempre es hacerlo todo a mano.

c) Con suerte hace tiempo encontré un código publicado por “Alex Beregszaszi” de dominio público, es decir, no está atado a ninguna licencia con lo cual su uso es libre. Dicho código hace precisamente eso, convertir directamente un archivo CWS en otro FWS. Yo creo que es el mejor punto de partida, además todo el mundo puede desde compilarlo para la plataforma que desee como proponer mejoras como ver que no es nada malicioso. Os dejo el código subido en un archivo, no quiero extender aun más esta entrada :P :

Código CWS2FWS

Y para quien no quiera complicaciones y lo quiera ya compilado

Programa CWS2FWS

Si alguien quiere compilarlo, creo que la versión que he puesto es la buena, creo que realicé una pequeña modificación dado que el código original tenía un par de errores. En cualquier caso se ejecuta por línea de comandos evidentemente y la sintaxis es simple:

cws2fws. exe [flash CWS] [flash FWS]

Con ese pequeño código podremos convertir cualquier objeto flash comprimido a un objeto flash sin comprimir, y así poder investigar cualquier posible dato “oculto” que existiese. Una vez el objeto flash descomprimido, un simple vistazo por el editor hexadecimal debería de descubrir cualquier texto propenso a ser editable de forma simple. Dado que es un objeto flash estándar sin comprimir, en teoría se podría usar sin problema por nuestro navegador el nuevo objeto flash. Eso sí, aviso, una cosa es modificar un byte y otra cosa es añadir o eliminar datos a la estructura ya creada. Imaginar que nos encontramos en la aplicación de parques naturales lo siguiente:

Original:

“Pagar
-Pedro: 150″

Modificado 1:

“Pagar
-Pedro: 100″

Modificado 2:

“Pagar
-Pedro: 50″

Según lo que estoy explicando, sería muy tentativo modificar Pedro a cero o 5 o algo muy bajo, como en el caso de la modificación 2, en el que se podría estar modificando la longitud del archivo El problema es que de ser así, a la estructura le estaríamos restando a lo mejor un byte. En cambio la modificación 1 podría pasar por buena, dado que no modificaría la longitud, aunque si el valor. Este tipo de medidas son constantemente usadas por cualquier programador. Para poder modificar a libertad se requeriría posiblemente reconstruir el objeto Flash, una “recompilación” pequeña, ya que posiblemente la misma tecnología flash tenga métodos de control de este tipo para impedir archivos dañados, mala transmisión de datos y otras historias.

Llegados a este punto podríamos decir que hemos terminado el cómo interpretar los datos y como modificarlos. Hemos aprendido a obtener un objeto flash cualquiera, copiarlo en el escritorio, descomprimirlo y con suerte al hacerlo tener acceso a datos legibles y modificables de manera simple, tan fácil como editarlo de forma hexadecimal, modificar y guardar. Claro que aun tenemos ciertas restricciones, como una manipulación más exhaustiva, y evidentemente tampoco hemos logrado de forma práctica nada!! tan solo estamos jugando en local con el objeto flash.

Antes de abordar el cómo hacer para que pasemos del estudio a la práctica, vamos a explicar el método a que ya dije hace muchas líneas: Descompilar.

Descompilar tiene el problema de la interpretación. Descompilar el código ActionScript de un objeto flash a ensamblador flash es “fácil”. Evidentemente interpretar dicho código ya no es tan fácil. Hay multitud de programas tanto de pago como gratuitos para descompilación flash, claro que cada programa puede hacer una interpretación muy diferente del código flash en ensamblador que recupera el proceso de descompilar. Un programa ideal sería capaz de reconstruir el código tal y como fue escrito por el programador a partir del código en ensamblador. Esto en la práctica es imposible, dado que diferentes códigos pueden producir el mismo código en ensamblador. Podemos obtener aproximaciones que nos sirvan a lo mejor para guiarnos un poco… pero poco más, aunque como he dicho todo depende del decompilador.

No me gusta la decompilación aunque hay veces que no hay otro camino. Tampoco voy a recomendar ningún programa para ello. Lo único que voy a usar es un programa completamente gratuito que permite descompilar y reconstruir, así como descomprimir y comprimir objetos flash de forma simple y rápida. Eso sí, el código decompilado tan solo pertenecerá a texto plano que pueda existir y código ActionScript (que para nuestro caso perfecto) y no se incluirá ni se tratará de abrir el objeto flash y extraer los diferentes subobjetos, como imágenes y otros. Decir que tampoco generará un código “legible”, tan solo el código en ensamblador, con lo que quien quiera manipular en mayor medida tendrá que aprender algo de ensamblador Flash, que tampoco es que sea complicado una vez que se comprende. Pero la principal característica estrella de este programa es que nos va a permitir por ejemplo descompilar un objeto flas, modificarlo y reconstruir un nuevo objeto flash igual que el anterior!! pero modificado los cambios que modificásemos, es decir, corrigiendo cualquier incremento o decremento del tamaño de los archivos, checksum… etc etc. Una vez decompilado el código de este modo podremos modificar lo que queramos como queramos, reconstruirlo y funcionando al 100%, sin ninguna limitación.

El programa?

Flasm

podéis encontrar información detallada sobre ensamblador en flash y otros, y lo podéis descargar desde:

AQUI

Aunque existen también versiones para Linux y MAC OS. Y sí, es una herramienta de línea de comandos. El funcionamiento es muy simple, tan solo voy a poner los comandos que puedan ser útiles mayoritariamente:

flasm -d Desktop.swf > Desktop.flm
flasm -a Desktop.flm
flasm -x Desktop_Com.swf
flasm -z Desktop_Dec.swf

La primera decompila el objeto flash Desktop.swf y genera la decompilación en un archivo llamado Desktop.flm (que se puede abrir con cualquier editor de texto)
La segunda compila el archivo (presumiblemente modificado) Desktop.flm dentro de su original Desktop.swf
La tercera descomprime el archivo
Desktop_Com.swf, convirtiendo este en un archivo FWS
La cuarta el proceso contrario. el archivo Desctop_Dec se comprime convirtiéndose en CWS

Como vemos la herramienta podría sustituirnos la pequeña aplicación antes expuesta. Pero esto es para aprender, y mejor aprender con la anterior, a menos que se deseen hacer cambios sustanciales en el objeto flash y haga falta recompilarlo. Esto es parte de mi archivo decompilado por Flasm, y la sorpresa como verán la mayoría es de mayúsculas, de lo que parecía en WinHex un tanto caótico y algo de información visible, aquí paso a tener una estructura con muchísima más información, y además nos va a servir para explicar, por último en este capítulo, un par de conceptos más. Dos trozos copiados directamente de mi archivo Desktop.flm, dos sitios diferentes del código, la primera el inicio, la segunda a mediados:

Inicio:

“movie ‘Desktop.swf’ compressed // flash 7, total frames: 2, frame rate: 20 fps, 240×320 px
protect ‘xxxxxxxxxxxxxxxxxx’
scriptLimits recursion 256 timeout 5

defineMovieClip 21 // total frames: 1
end // of defineMovieClip 21
defineMovieClip 22 // total frames: 11
frame 0
stop
end // of frame 0
end // of defineMovieClip 22
defineMovieClip 29 // total frames: 12
end // of defineMovieClip 29″

En esta parte tenemos información como que el archivo original decompilado estaba comprimido, es decir, de tipo CWS. Por otro lado aparece la etiqueta Protect, que quiere decir que el contenido supuestamente está protegido para que no pueda ser abierto en algún IDE, lo cual tampoco es mucha seguridad dado que igual que está esa línea, podría eliminarla directamente desde el archivo y eliminaría con ella la seguridad. Lo que aparece como XXX es la clave en hash MD5, que evidentemente por motivos de seguridad he editado. Lo he puesto para que veáis que esas protecciones pueden eliminarse tan fácil como eliminando dicha línea. Interesante verdad? Y más adelante tan solo vemos lo que parecen son definiciones de clips y también algunos frames y el número de estos… información información!! la información por absurda que parezca siempre es útil. Imaginar cambiar un frame por otro!! a lo mejor en un juego flash esto no sirve para nada, si modifico un frame por otro en mi tema, creerme que el resultado será completamente diferente. En flash normalmente el código se ejecuta sobre “frames” concretos, son como partes. Recordar que Flash nació como contenido dinámico, sobre todo para gráficos en movimiento y ese tipo de cosas, con lo que se conserva siempre el estilo de “frames”, y por encima de estos clips.

Más adelante tengo más información interesante. Aparece anteriormente el frame 0… pero es que más adelante tengo el código en ensamblador que se ejecutará en el frame 0!!:

frame 0
constants ‘elements’, ‘Array’… ‘Contacts’, ‘App8_IconName’, ‘App8_Text’, ‘walkman’…
push ‘elements’, 0.0, ‘Array’
new
varEquals
push ‘App0_IconName’, ‘PREPLAY_DESKTOP_ICN’
setVariable
push ‘App0_Text’, ‘PlayNow’
setVariable
push ‘App1_IconName’, ‘DESKTOP_WAP_ICN’
setVariable
push ‘App1_Text’, ‘Internet’
setVariable
….

Esto tiene mejor pinta. Es decir, simplemente por lo que veo y sin ser un genio interpreto que si modifico la línea que pone: push “‘App1_Text’, ‘Internet’” por “push ‘App1_Text’, ‘TusMuelas’”, sin ser propietario de dicho archivo, sin ser mío el objeto flash… cuando meta el tema a mi dispositivo el icono de Internet ya no se llamará “Internet”, sino se llamará “TusMuelas”. (En realidad tendría que modificar tb el texto que sale un pelín más arriba y que no aparece pq lo he abreviado, que era largo).

Después de aplicar todos los cambios y guardar el archivo flm, tan solo tendría que recompilar el código con: Flashm -a Desktop.flm y terminaríamos finalmente un archivo Desktop.swf que al meterlo a mi móvil tendría el efecto deseado. Tan fácil como eso. Y esto se extrapola a cualquier aplicación/juego en flash! Incluso los cambios realizados en este ejemplo son sobre código en ensamblador que todo el mundo comprendería, en el caso de encontrarnos texto en plano pues más simple aun, como el que apareció en la primera imagen, que si bien no era en este caso identificativos, en otro si puede serlo.

Hemos acabado otro capítulo. Si todo ha ido bien, y hemos aprendido bien la lección, a este punto deberíamos ser capaces de Localizar un objeto flash en el caché de Firefox o descargarlo directamente, copiarlo al escritorio, descomprimirlo y modificarlo sutilmente ó decompilarlo -> modificarlo -> reconstruirlo, todo gracias a Flasm.

Nos queda el último paso, y por ser el último no es el menos importante, sino quizás el más importante, puesto que hasta ahora hemos logrado realizar modificaciones, sí. Hemos logrado hacer pasar nuestro objeto flash como bueno, sí. Y en caso del tema de mi móvil sería suficiente, dado que tan solo me quedaría enviarlo a mi móvil y listo. Pero en caso de una aplicación/juego flash, no podemos enviarlo de vuelta al servidor de ellos ;) , así que intentaremos darle una vuelta de tuerca e intentar jugar o interactuar con una aplicación/juego modificado por nosotros.

Aplicando lo aprendido

Por lo que tengo entendido muchos han logrado llegar al punto en el que nos encontramos, pero no han sido capaces de llegar más allá. Vamos a intentar explicar diversas posibles técnicas que podrían permitirnos hacer que pasásemos como cualquier otra persona.

En la primera parte de todo esto, hace ya unas semanas, explicábamos que la edición al vuelo simplemente consistía en la modificación in situ de nuestra propia RAM y que quitando eso todo lo demás funcionaba perfectamente. Ahora vamos a intentar pensar cómo podríamos “inyectar” por así decirlo un objeto flash modificado en nuestro PC por otro. Si pensamos se nos pueden ocurrir diferentes buenas ideas, lo cual es bueno, cuantas más ideas tengamos mayor margen de acierto podremos tener, quizás un camino no, pero quizás otro sí. Voy a poner soluciones que se me ocurren, aunque puede haber más:

- Si el Caché contiene un archivo temporal que se reutiliza cuando se vuelve a visitar una web, sustituir el archivo del caché por el modificado sería una buena opción. Al volver a visitar la web el archivo a usar sería el modificado en el caché, con lo que estaría todo hecho.
- En memoria se tiene que descomprimir como dijimos el objeto flash. Podría “inyectar” el nuevo objeto en memoria y sustituir el cargado en el momento de comentar
- Montarme en algún servidor gratuito una aplicación/juego completo en el que subiese los archivos necesarios modificados, dirigir el navegador hacia él, con lo que se cargaría el nuevo objeto y no el “oficial”.
- Trabajar siempre que se pueda en Local

Seguro que hay más alternativas pero creo que por ahora nos vamos a quedar con estas y vamos a explicar en qué consiste cada una de ellas, sin entrar en demasiado detalle, que si no leer esto será peor que leer el quijote. Intentaremos que al menos una de todas ellas nos dé resultado. Yo os recomiendo a quien le guste esto es que personalmente vaya explorando otras posibles soluciones o probando las que aquí se exponen, es la mejor forma de aprender.

Vamos a ir desglosando cada una de las posibilidades que se nos plantean:

a) Usar el Caché:

En principio sería la opción más lógica. Si podemos recuperar del caché el archivo que hemos modificado, podremos sustituir el caché con el archivo modificado para que al visitar de nuevo la web se cargue el nuevo objeto modificado y no el viejo. Por extraño que parezca esto es muy complicado. Primero porque es una técnica que es completamente dependiente del navegador a usar, como hemos dicho cada navegador gestiona el caché de modo diferente. Por otro lado los sistemas de caché que implementan los navegadores suelen estar incluso más protegidos que los propios objetos flash que estamos intentando modificar. Jugar con el caché de Firefox es un infierno, sustituir un archivo por otro en el caché con el mismo nombre o mismo tipo no sirve absolutamente para nada. Esto sucede porque existen archivos de control que especifican el tamaño de cada archivo por un hash, más un tamaño especificado en las peticiones de archivo que Firefox almacena, sin contar con que el servidor podría obligar a recargar dichas peticiones con lo que si se modificase en un byte el archivo la carga estaría corrupta.

Sí, es completamente posible hacerlo de este modo, pero creerme que no tengo tiempo para explicaros como manejar el cache de Firefox, teniendo en cuenta además la poca documentación al respecto que hay y lo “engorroso” que resultaría realizar cualquier modificación adicional. Si cada vez que deseo modificar algo tengo que perder 20 minutos en reconstruir el caché de Firefox para que cuele, sin contar en posibles medidas de seguridad por parte del otro servidor…

Pero funciona!!

Eso sí, quien se quiera entretener puede probarlo con cualquier archivo del caché, que para el caso es lo mismo. Si no existiese un método mejor os lo explicaría, pero como tenemos un método mejor y que se aprende también bastante, este método lo descartamos… de momento, pero ei, podemos dejarlo pendiente como un nuevo OffTopic

b) Inyectar en Memoria:

La verdad es que a priori puede parecer lógico, pero si lo pensamos detenidamente va perdiendo fuerza… estaríamos dando mucho por supuesto, como por ejemplo que la inyección se puede realizar después de la carga del objeto flash sin que este haya llegado a empezar a ejecutarse, o tendríamos que encontrar un modo de interceptar la carga y poner nuestro objeto en medio. Y no, tampoco es que sea algo fácil de hacer.

Técnicamente es posible interceptar al vuelo la carga del objeto desde caché a RAM y modificar el acceso para cargar el archivo modificado, esto se suele denominar hook, un gancho, una petición a caché a dicho archivo hace bloquear el caché y suministrar a RAM el objeto modificado. Se podría crear una pequeña aplicación que realizara lo citado, monitorizar el acceso a caché y montar el nuevo objeto.

Nos vale como solución? Pues sinceramente no lo sé, porque personalmente no la he puesto en ejecución nunca. No podría decir ni sí ni no hasta que no lo intentase por todos los medios. Supongo que es posible, pero a lo mejor al hacerlo me toparía con algún problema nuevo que a lo mejor podría superar o no… a fin de cuentas es todo lo que hemos hecho hasta ahora, probar caminos, estudiar posibilidades e intentar avanzar. Aunque a veces tengamos que dar la vuelta y probar otro camino

c) Montar un sitio clónico

También parece una buena idea. Con cualquier programa tipo Spider podría descargar en el PC la web de la aplicación/juego y editando lo que fuese necesario y evidentemente sustituyendo el objeto flash por el modificado, volver a montar la aplicación/juego en un servidor propio y probar suerte.

Al igual que la solución de caché es más dependiente del navegador, esta solución es más dependiente de la aplicación/juego flash que sea en cuestión. Como hemos dicho, normalmente se usan aplicaciones tipo Loaders (cargadores) que entre otras cosas monitorizan este tipo de prácticas, para que no puedan llevarse a cabo. Por ejemplo lo más trivial sería enviar en algún momento y de alguna forma la URL en la que se aloja supuestamente dicho contenido y si no coincide con la original rechazando la conexión. De todos modos, fuese cual fuese la medida de protección, esta podría ser eludida si releemos todas estas letras. A fin de cuentas hemos dicho que podemos modificar cualquier objeto flash… ¿cierto?, podríamos modificar el objeto flash original para lograr el efecto que deseásemos y modificar también el objeto flash que nos estuviese bloqueando, de forma que no realizase comprobaciones claves de protección, comprobaciones de hash… y posiblemente también lo lograríamos.

¿Pros? Este método parece más simple y más cómodo, ya que podríamos realizar cualquier modificación relativamente rápidas una vez sorteadas a base de modificación de los objetos flash implicados las protecciones que pudiesen existir.

¿Contras? El código a modificar podría ser mucho, y dependería prácticamente del conocimiento en ensamblador o tener algún desensamblador que fuese realmente eficaz para saber que parte de código eliminar o añadir o modificar para hacer que el nuevo objeto flash se comportase como nosotros deseamos. Por otro lado cualquier modificación se debería reenviar a nuestro servidor y si es algo pesado tardaría. Y para acabar, trabajar de este modo implicaría conocer más o menos la estructura de la web que deseamos clonar, aunque como hemos visto, con Paros esto es muy fácil. De hecho creo que tiene opciones de Spider.

d) Trabajar en Local

Esta es la opción que recomiendo, todo son ventajas una vez se comprende el funcionamiento, aunque no deja de tener algún que otro contra, pero es la menos dependiente y con mucha diferencia la más rápida. Vamos a ver en que se basa.

Hemos dicho que en una petición Web se añade evidentemente el origen del archivo. En nuestro caso vamos a denominar este origen como “tema.theliel.es” y el archivo será desktop.swf, y lo que me gustaría sería modificar dicho archivo por el mío en una nueva pestaña sin que nadie se cosque del cambio. Imaginar que tengo montado en mi blog un enlace hacia dicho archivo, de forma que cuando hace quien sea clic en dicho enlace, se abre en su navegador otra pestaña con el contenido de dicha ubicación. Su navegador realizará la petición a “tema.theliel.es” del archivo en cuestión, y el servidor tema.theliel.es responderá con el envió de dicho archivo. Así es como funcionan las cosas. Veremos si podemos colocar el nuestro.

Podría modificar con un proxy (como paros por ejemplo) esta petición al vuelo y especificar un nuevo host? Sí, pero el problema sería el mismo, si la aplicación/juego devolviese en algún momento dicha URL estaría cazado. Vale, no puedo interceptar la URL… pero me queda algún AS en la manga? Sí.

¿Qué pasa si monto en mi PC, en Local, un servidor Web propio y hago una especie de página clon en local? Hombre, en principio debería de tener los mismos problemas que cuando lo monto en remoto… pero veremos que no es así, y que además nos ahorramos el tener que subir archivos a remoto. El problema que vamos a tener, el único contra, es que necesitaremos por lo tanto no solo los objetos flash, sino posiblemente más cosas… ya lo veremos.

¿Cómo se monta un servidor Web? Es muy simple, opción rápida, eficiente y fácil? Apache. Apache es un servidor Web completamente gratuito. Lo podemos obtener de:

AQUI (sin soporte para SSL)

La instalación es simple, podemos especificar todo por defecto en la instalación, cuando se nos pregunte por el dominio de red y el nombre del servidor pondremos: “localhost” y dejaremos el resto tal y como está, puerto 80 para todos los usuarios. El correo hace falta ponerlo, inventaros uno si lo deseáis, no importa. Instalación Típica, siguiente, siguiente…

Si todo ha ido bien, una vez terminado de instalar, si abrimos un explorador web y tecleamos en dirección: “localhost” debería de aparecer una página en blanco que ponga:

It works!

Si aparece dicho mensaje, implica que nuestro servidor web está en funcionamiento. Ya podremos colgar lo que deseemos de él. Para no complicarnos, tan solo deberemos de colocar lo que deseemos en la carpeta:

“C:\Program Files\Apache Software Fundación\Apache2.2\htdocs” -> En caso de instalación por defecto.

En la carpeta htdocs se almacenará el contenido web. Eso significa que si creo una página html llamada index.html en dicha localidad y accedo a “localhost/index.html” accederé a dicha web.

Pero hasta que punto esto es útil? A fin de cuentas tener que montar toda la web es lo mismo que lo que hacíamos antes en remoto. No, con esto ganaos dos cosas:

a) No necesidad de replicar una web completa, tan solo aquello que sea esencialmente necesario
b) trabajar en local siempre es mucho más cómodo

Aun así no hemos terminado de explicar el punto A. Vale, tenemos el servidor web Apache funcionando, en dicha carpeta tenemos el objeto flash modificado (!!OJO!! deberá tener el nombre original!! para ello lo ideal sería usar paros o cualquier otro sistema), en mi caso Desktop.swf. Y ahora qué? Si accedo a Tema.theliel.es me continúa cargando en la pestaña el archivo original, no el modificado. Lo que necesito es que cuando se solicite dicha petición se cargue el mío, y que no sea una modificación al vuelo, que podría detectarse por la misma aplicación o por un cargador. Existe algo para hacer esto? Si, se llama “Host”

En todos los sistemas operativos que conozco existe un archivo llamado “Host”. Este archivo se encarga de traducir host por otros host. Es decir, es como un redireccionador automático. Este archivo se puede usar de forma inteligente en mil aspectos diferentes!! por ejemplo podríamos hacer que cada vez que solicitásemos la web de google se cargase la web de Orange, o un hacker podría modificar el archivo host de sus víctimas y modificar la web mail.live.com (Hotmail) por un Scam en otro servidor, sin que el usuario se diese cuenta, dado que la redirección se hace de forma completamente transparente, y para todos los efectos la dirección real es la real.

Cual es el secreto de esto? Que yo podría añadir una entrada en mi archivo host que redirigiese las peticiones realizadas a tema.theliel.es a localhost.

El archivo se encuentra en:

“C:\Windows\System32\Drivers\etc\” y se puede abrir con cualquier editor de texto.

la entrada sería exactamente esta:

tema.theliel.es 127.0.0.1

Es decir, todas las peticiones realizadas a tema.theliel.es equivalen de forma interna a una petición a la dirección ip 127.0.0.1, que es la dirección local, dirección de loopback. De ahí la importancia a que se mantenga el mismo nombre de archivo:

El navegador solicita el archivo desktop.swf del servidor tema.theliel.es, pero el PC reenvía en la petición en vez de a tema.theliel.es a 127.0.0.1 sin que nadie se dé cuenta, sin nada que muestre lo contrario. nuestro servidor apache recogerá la petición y devolverá el archivo solicitado, que sí está modificado. En la pestaña del navegador se abrirá el archivo swf modificado bajo la dirección de tema.theliel.es/desktop.swf e internamente para el objeto flash, se encontrará en dicha ubicación, eludiendo cualquier tipo de protección que pudiese existir.

El único problema que tiene como digo es que este proceso redirección TODAS las peticiones, es decir, para el PC cualquier referencia a dicho host la modificará por la otra (de forma interna y sin afectar de manera externa). Luego cualquier archivo que se solicitase de dicho host se debería de servir igualmente desde nuestro servidor web en local, dependiendo de cómo sea el servidor original, esto implicaría tener más o menos archivos que servir.

Si por ejemplo en vez de hacer clic en el enlace que va a desktop.swf fuese un index.html en www.theliel.es/index.html y en dicho index.html se cargase mi archivo “tema.theliel.es/desktop.swf” y otro adicional, “tema.theliel.es/background.bmp” y un montón de imágenes y cosillas cuya ubicación fuese www.thelie.es, lo que tendría que crear en mi carpeta htdocs de apache serían los archivos “background.bmp” (una copia del original) y por supuesto el archivo “desktop.swf” (modificando el original). Luego tampoco tendría que recrear la web completa. Lo mejor para saber que archivos deberíamos o no tener en local, sería usar herramientas como Paros, que ya expliqué con anterioridad. A través de él es fácil ver las dependencias por dominios, y tan solo tendríamos que tener una copia en local de los archivos descargados de dicho dominio en el que se encuentra nuestro objeto flash a modificar.

Claro que también se depende en cierta medida del servidor origen.

Y señores, hemos acabado!! Pero vamos a hacer un rápido repaso, y en conclusiones lo que puede significar todo lo que hemos explicado hasta ahora y si es cierto que se pueden realizar todas las cosas que se dijeron en un principio:

1º. Interceptar el archivo flash original, ya sea por el caché, por descarga directa.
2º. Asegurarnos de que el archivo capturado se corresponde con el objeto flash buscado
3º. Tener información acerca de dicho objeto. Está comprimido? Sin comprimir?
4º. Descomprimir el objeto flash si es un objeto flash comprimido ó desensamblarlo si se prefiere directamente
5º. Abrir dicho objeto ya descomprimido, empezando por un editor hexadecimal (recomendado) e intentando ver si es posible modificar (y sacar provecho) de lo que podamos ver a simple vista, intentando primero sin realizar grandes cambios, cambiar un 2 por un 3, un 3 por un 4…
6º. Si los cambios no son suficientes, descompilar, interpretar el código y buscar algo más claro. Después de la modificación recompilar.
7º. Montar un servidor Web con Apache
8º. Modificar el archivo Host de Windows para redireccionar el contenido deseado a nuestro propio PC como se ha indicado.
9º. Disfrutar con los cambios realizados, y si no se está confirme, volver a editar el objeto flash, volver salgarlo y volver a probar los cambios.
10º. Preguntar las dudas existentes al bueno de Theliel.

Conclusiones

Bueno, esto ya se acaba. Sí, soy consciente de que no he sido tan explícito quizás, pero en realidad la idea tanto de mí primer entrada al respecto como la segunda continua siendo lo mismo, aprender con ejemplos reales. Por tonterías de algunos pues hago las pruebas con contenido propio, pero cada cual es dueño de hacer lo que sea. Si, el título es referente a Hammerfest, lo sé, y no deja de ser una gran segunda parte para continuar aprendiendo y enseñando. Con los procedimientos que he explicado aquí, cualquiera que quisiese tendría conocimientos para modificar cualquier aspecto de HF, algunos de forma trivial quizás como el valor, la rareza… y otros a lo mejor no tan triviales en una primera lectura, pero igual de fáciles, como podría ser el enrutado de portales entre niveles o cualquier cosa que podáis imaginar. Simplemente es acudir al código del objeto flash, interpretarlo y modificarlo según nuestras necesidades.

Lo ideal sería hacerse, como me hice en mi tiempo y como publiqué en el foro oficial hace tiempo, una BD con el identificador de cada objeto, el nombre del objeto, la familia a la que pertenece, el valor, la rareza… etc etc etc. Sé que en muchas páginas encontramos información al respecto, aunque la mayoría no son del todo correctas. Todo esto haría mucho más rápido y comprensible cualquier cambio que se quisiese realizar, es normal… cuanto mejor conoces un sistema, más puedes manejarlo.

Aun así, nos vemos en los comentarios o en el Messenger, para resolver dudas, preguntas o simplemente el cabezoneo de algún bloguero, en el caso de que en investigaciones propias os quedéis atrapados o bloqueados, a fin de cuenta este mundo es un poco así, antes o después te vas a chocar con una puerta que te costará abrir.

Espero que de todo esto se aprenda algo nuevo, y con que tan solo una persona se haya quedado con algo, es suficiente y me doy por bien pagado.

Aun posiblemente tenga material para una tercera parte en la que podríamos explicar más acerca de los navegadores, flash, servidores, hash, seguridad… o incluso reescribir todas estas letras para intentar hacer la lectura más amigable… quien sabe… pero es que por increíble que parezca, uno tiene su propia vida privada, sus trabajos sus estudios… y precisamente no es que sean las mejores fechas para investigar y escribir la biblia.

Mis amigos fieles a iPod Touch e iPhone… espero no marearos demasiado con este tipo de contenido, comprendo que se sale de lo “normal”. Y para el resto un saludo y para la próxima.

Proyecto: Hammerfest I: Temporalmente eliminado

He recibido una carta de Bloggers que me insta temporalmente a suprimir el contenido hasta que digamo… el caso sea resuelto. No tengo ningún tipo de problemas en suprimirlo ;) , y mientras que espero terminaré la segunda parte, aun más interesante ;) . Supongo que a los chicos de MT no les ha sentado muy bien mi publicación sobre las vulnerabilidades de Hammerfest ;) . Que digo yo… creo que deberían de preocuparse más por programar mejor que a quejarse al guardia de turno, pero ei… quien soy yo para decir nada.

Aun así, cualquiera que quiera recuperar la primera parte (mientras que dure el papeleo), tan solo tiene que escribirme un correo a la dirección del msn que aparece en el margen derecho:

theliel (at) live (dot) com //Sí, el (at) equivale a una @ y el (dot) a un punto “.”

Que le enviaré sin problema alguno la entrada en formato word o pdf, eso si, para ahorrar trabajo que ponga en el asunto algo ilustratibo, como “entrada hammerfest eliminada” o algo similar, para evitar el Spam. Tambien dentro de pocos minutos publicaré en el foro oficial de CheatEngine a groso modo lo mismo que puse aquí, para que sirva a otros de allí.

Os recuerdo que en la primera parte habíamos aprendido a usar CheatEngine para modificar los puntos de la partida, haciendo uso de edición en RAM de nuestro propio PC, y teniendo en cuenta algunas premisas. Esto será importante para la segunda parte.

La segunda parte prometo será mejor que la primera. Se centrará en como modificar prácticamente cualquier aspecto del juego de manera muy simple, una vez se comprenda que se está haciendo y como claro está. Esto será de gran utilidad para cualquiera que quiera aprender sobre tecnologías Flash y otros. En serio, os lo recomiendo. Y para evitar más notificaciones al respecto o por si las moscas, eliminaré cualquier imagen si es necesario, o cualquier literal. Puedo explicar todo perfectamente sin necesidad de demostrarlo o poner el ejemplo real. Ya veré que se me ocurre.

En parte comprendo a los chicos de MT, y así intenten evitar posibles cheaters. Supongo que ellos tienen sus derechos… al igual que yo.

Un saludo a todos.

Proyecto: Activación de nuevas funciones de Maps en Touch

Antes de comenzar, y para no repetir a lo largo de estas líneas, siempre que se modifiquen archivos, por precaución guardar copias de seguridad de estos. No voy a decir en cada momento eso de: Recordar realizar una copia de seguridad…. Estais avisados amigos

Por otro lado, esto tan solo es válido para la firmware 2.2 y el iPod Touch Viejo. Evidentemente, puesto que para el nuevo no hay JB.

Como sabemos ya, en la versión firmware 2.2 Apple ha introducido en ella nuevas opciones en la aplicación Maps:

-StreetView para ver imágenes a pie de calle
-Cálculo de rutas a Pie, en coche o en Bus
-Localización de lugares de interés cercanos

Pero como es común en Apple y su ansia de ganar dinero y de hacer las cosas exclusivas, por una razón absurda que nadie conoce decidió deshabilitar dichas opciones para los iPod Touch, tanto el nuevo como el viejo. Seguro que se le olvidó ;)

Yo me considero una persona de bien, así que no he podido sino refrescarle la memoria a Apple para poder reactivar unas funciones que YA tiene de por sí nuestro dispositivo.

Estos dias han salido en numerosos lugares como habilitar estas funciones. Pues bien, al igual que Apple hiciese con la famosa actualización de enero, Apple protege la aplicación según si esta identifica que estamos ante un iPod o un iPhone. La opción definitiva pasa evidentemente por parchear el arcihvo implicado y listo. Pero encontrar el punto exacto y el archivo concreto no es a veces tan simple. Debido a esto salen soluciones que funcionan perfectamente pero con efectos colaterales:

Ya hace tiempo demostramos que lo que diferencia a un iPhone de un Touch a nivel del OS son los archivos de configuración que se cargan en uno y en otro al iniciarse. Los más claros y que más efectos tienen sobre nuestro dispositivo son:

N45AP.plist -> Ajustes de sistema iPod Touch Viejo
N72AP.plist -> Ajustes de sistema iPod Touch Nuevo
M68AP.plist -> Ajustes de sistema iPhone
N82AP.plist -> Ajustes de sistema iPhone 3G (Solo presentes en firmware de iPhone 3G)

Settings-iPod.plist -> Ajustes que se cargarán desde la aplicación preferencias para iPod
Settings-iPhone.plist -> Ajustes que se cargarán desde la aplicación preferencias para iPhone

Lo gracioso es que quitando el archivo N82AP.plist del iphone 3G, todos los demás se encuentran en todas las firmwares.

Es decir, cada dispositivo carga un archivo u otro según el q sea. Pero que pasa si yo le pongo el nombre de N45AP.plist al archivo M68AP.plist? y N45AP.plist lo elimino (por seguridad lo renombro)?. Al reiniciar el iPod se creerá que es un iPhone y cargará toda la configuración de este. Evidentemente no tiene el hardware del iPhone, pero a todos los demás efectos será un iphone. Esto evidentemente no nos compensa. Si es un iphone tendremos mensajes de error de conexión a la red y otros. Pero si hacemos el cambio que he citado, las preferencias que se cargarán serán las del archivo Settings-iPhone.plist, con lo que nuestras preferencias tb serán diferentes.

Bueno visto esta pequeña introducción vamos a explicar el proceso:

0º. Preparación

Se requierere poco, pero sí es cierto que un mínimo de conocimientos de SSH, Cydia y otros. Antes de empezar necesitaremos instalar las siguientes herramientas en el iPod, en el caso de no tenerlas instaladas ya, y algunas de ellas en el PC:

-Cydia (evidentemente)
-OpenSSH (Putty, WinSCP como clientes para el PC)
-Erica Utilities

Cydia para instalar el resto, OpenSSH para tener acceso por SFTP y SSH para tener una shell, y Erica Utilities para poder usar la utilidad Plutil.

Todas estas herramientas ya se han hablado en este blog con anterioridad, explicado como funcionan con más o menos detalle y otros. Quien quiera saber más de ello solo tiene que investigar por el blog. Lo que me recuerda que tengo que añadir algún buscador de información en él.

Suponiendo que tenemos todo listo podemos seguir.

1º. Engaño

Apple dice que si tienes un iphone puedes disfrutar de esas prestaciones, pero si tienes un iPod no. Luego si hacemos pasar el iPod por un iphone tendremos todas las funciones operativas.

Como se hace est0? Siguiendo el principio comentado con anterioridad.
¿Cual es el archivo que hará creer al sistema que tenemos un iphone? los archivos mágicos son:

N45AP.plist
M68AP.plist

Ambos archivos internamente no son tan diferentes, tan solo sucede que cambian algunos parámetros en uno o en otro. Una opción podría ser usar directamente el archivo de iPhone “M68AP.plist” en sustitución del archivo de iPod “N45AP.plist”. Pero hacerlo así provocaría más efectos colaterales, dado que se aplicarían un mayor número de ajustes propios al iphone, y lo que queremos es tan solo activar las opciones nuevas de Maps. Lo que se plantea por tanto es modificar tan solo el archivo de ipod “N45AP.plist” con el ajuste mínimo y suficiente para que se crea que somos un iphone. Esta clave, comando… como querais llamarlo, se llama “telephony”. Con esta simple instrucción, se carga o no se cargan los ajustes de teléfono (por así decirlo, luego con los efectos colaterales veremos esto un poco más en detalle). Esto no decimos que sea eso porque sí, sino que si abrimos el archivo de iphone “M68AP.plist” podemos más o menos ver claramente las diferencias de los dos archivos y para que sirven cada una de las claves.

Bueno, parece facil, tan solo tenemos que añadir unas líneas a nuestro archivo “N45AP.plist” y problema resuelto. Y en realidad es así de fácil… al menos a priori.

Manos a la obra.

a) Lo primero es saber la ubicación de dicho archivo dento de nuestro dispositivo:

/System/Library/CoreServices/SpringBoard.app

b) La mayoría de los archivos de Apple de este tipo están codificados para ahorrar espacio y tener un grado superior de protección. No pueden leerse directamente, por lo que hay que convertirlos. Para eso hablamos de “Erica Utilities” y Plutil. La conversión será primero para convertir dicho archivo a “legible” y después de nuevo, despues de la modificación, a “ilegible”.

El proceso en realidad es muy facil. Accedemos por SSH con cualquier cliente SSH (linea de comandos) como root al iPod (yo uso Putty) y ejecutaremos:

“plutil -c xml1 /System/Library/CoreServices/SpringBoard.app/N45AP.plist”
(sin las comillas)

Con esa simple sentencia se convertirá el archivo a un formato plano de texto.

c) Por medio de cualquier cliente para acceso a SFTP (yo uso WinSCP) iremos a dicha ubicación y editaremos el archivo citado. Aquí depende de cada uno. Unos prefieren copiar el archivo al PC y editarlo desde ahí y otros clientes de SFTP permiten la edición “directa”. Da igual. El caso es modificar el archivo que está dentro. Lo primero es abrirlo, y tendremos un archivo de texto bastante comprensible. Tan solo voy a pegar el trozo que nos conscierne:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<dict>
<key>bundles</key>
<array/>
<key>capabilities</key>
<dict>
<key>deviceName</key>
<string>iPod</string>
<key>editableUserData</key>
<true/>
<key>piezo-clicker</key>
<true/>
<key>standAloneContacts</key>
<true/>

Se trata tan solo de añadir justo debajo:

<key>telephony</key>
<dict>
<key>maximumGeneration</key>
<real>2.5</real>
</dict>

Evidentemente después de estas líneas, abrá más cosas en el archivo, todo ello sin modificar. Tan solo es un trozo que hay que añadir en el sitio concreto citado. Una vez terminamos guardamos y listo

d) Recordar que el archivo tiene que quedar como estaba. Es decir, con permisos 0644 (en caso de que se modificasen, y reconvertirlo a binario. Si usamos Plutil anteriormente para la conversión, ahora haremos lo mismo, pero con una sentencia un pelín diferente

““plutil -c binary1 /System/Library/CoreServices/SpringBoard.app/N45AP.plist”

Con esto hemos terminado el engaño. Si reiniciamos el iPod completamente veremos que no solo tenemos activadas todas las funciones de Maps nuevas, sino que hemos incluido efectos colaterales no deseados:

-Los ajustes de Preferencias serán diferentes, se cargarán los de iPhone
-Mensajes de error tipo popup que nos dice que no tenemos servicio, o fuera de covertura…
-La etiqueta “iPod” de arriba a la derecha se cambiará a otra de “No hay servicio” ó “Fuera de servicio”. No recuerdo sinceramente cual
-Posiblemente otros cambios.

Todo ello tan solo por añadir unas 4 líneas? 5? Quitando eso todo funcionará perfectamente. Podeis abrir la aplicación Maps y comprobar que teneis acceso a todas las nuevas prestaciones. Apartir de aquí pasaremos a solucionar cada uno de los efectos colaterales

2º. Colateral 1: Preferencias cambiadas

Esto es fácil. Anteriormente hemos comentado cuales son los archivos que guardan las diferentes configuraciones que tendrá la aplicación Preferencias. Estos archivos son:

Settings-iPod.plist
Settings-iPhone.plist

En este caso no nos hace falta ni siquiera convertirlos. El problema es que al detectar el “teléfono” puesto antes en el paso 1º, nos carga el archivo “Settings-iPhone.plist” que es diferente al archivo “Settings-iPod.plist”. Pero esto tiene muy facil solución. Tan solo tenemos que eliminar el archivo “Settings-iPhone.plist”, duplicar el archivo “Settings-iPod.plist” y renombrar uno de ellos a “Settings-iPhone.plist”. De este modo se cargará igualmente el mismo archivo, pero los ajustes de este serán los de iPod, no de iPhone.

a) Ubicación de los archivos:

/Applications/Preferences.app

b) El modo de renombrar, copiar, duplicar… creo que es trivial, cada uno lo haga como mejor sepa.

Al terminar, si accedemos a Ajustes, veremos como las opciones que tenemos son las de toda la vida.

2º. Colateral 2: Popups de error aleatorios

El iPhone cuando está sin covertura o hay un problema de red, avisa con ciertos mensajes sobre estos. Estos mensajes son enormemente molestos para nosotros, ya que evidentemente nunca tendremos covertura y siempre trabajaremos fuera de servicio. Estos mensajes de error se ejecutarán aleatoriamente cada X segundos, minutos… es decir, que podemos estar trabajando con el iPod y tener un molesto mensaje de golpe.

No he encontrado en ningún foro, blog… ninguna solución al problema. Los otros efectos colaterales son simples de corregir, como hemos visto (hay más que trataremos después), pero ninguna para este.

La solución la encontré en realidad por casualidad sin casualidad. Tengo la mala (o buena, según se vea) de no tener nunca nada en ejecución que no sea necesario. Al igual que un PC, los procesos en ejecución consumen rendimiento y potencia (critico en un portatil o dispositivo de mano), consumen memoria y se hace el sistema más vulnerable.

Desde hace tiempo tengo un archivo en mi PC con posibles “Tweaks” (trucos, ajustes…) para maximzar el rendimiento de mi iPod. En él tengo un listado de procesos a deshabilitar, demonios a eliminar… etc. En que me baso? es simple. Un proceso debe de tener una finalidad. Si esa finalidad no será usada para mí… proceso que me ahorro. Esto se extrapola a cualquier sistema. Está claro que existen procesos de sistema, pero existen otros que uno puede prescindir.

Existe un demonio en ejecución constante, en el iPod, llamado “CommCenter”. Lo absurdo de todo ello es que este demonio (un demonio es como un servicio en Windows, para entendernos) se usa tan solo para gestionar asuntos del teléfono. Es absurdo pq a día de hoy no he encontrado ni un solo uso que pueda tener nuestro iPod Touch de este demonio. Lo dejó Apple olvidado para ¿iPod Touch? A saber. Lo que es cierto es que este demonio se encuentra activo en todos los iPod Touch viejos, posiblemente en el nuevo también.

Este es uno de los “Tweaks” aplicados a mi iPod. La supresión de este demonio, de modo que cuando mi iPod se inicia jamás se carga este servicio. Para que tener activo un proceso que tan solo se encarga de interactuar con el teléfono si mi iPod no tiene teléfono. Es un poco de cajón. Podríamos pensar que se encarga de algo más… Sí, es posible… pero por ahora como digo no ha aparecido ese “algo más” y todo funciona como el primer día, sin errores alguno.

¿Quien decía que los sistemas de Apple son mejores y más seguros?

Esto enlaza con el efecto colateral que nos atañe. Esos popups los tiene que lanzar alguien… y da la casualidad además que dichos popups los lanza este proceso. Vamos a matar dos pájaros de un tiro!!. Por un lado vamos a suprimir un proceso que teníamos siempre en ejecución, con el consumo de RAM consecuente, y por otro lado vamos a hacer desaparecer de un plumazo cualquier popups.

La mejor forma de hacerlo es con una simple sentencia por SSH, con la cual se detendrá el servicio y se marcará para que no vuelva a ejecutarse en futuros reinicios.

a) Deshabilitación del Daemon CommCenter:

“launchctl unload -w /System/Library/LaunchDaemons/com.apple.CommCenter.plist”
(sin las comillas)

unload hace que el servicio se detenga, y el comando -w hace que el Daemon se marque para que no se ejecute más al iniciar el sistema. Es decir, se deshabilita del todo el Daemon.

Con esa simple sentencia, se acabaron los popups molestos y ganamos algo de RAM adicional. Posiblemente ganemos incluso en algo de batería.

Después de efectuar los cambios, un reinicio siempre ayuda a aplicar mejor los cambios y ver que todo está correcto


3º. Colateral 3: Etiquetas que sustituyen a “iPod”

Por último, al entrar en modo teléfono nos desaparecerá la etiqueta de “iPod” que nos aparece arriba a la izquierda (o cualquiera que tengamos puesta con MIM) por otra que pondrá “Sin Servicio”. Esto aparece en los iPhone cuando se encuentran sin covertura. Aquí tenemos dos opciones.

Si solucionamos el Colateral 2, en vez de “Sin servicio” aparecerá un: “Buscando…”. Si no solucionamos el Colateral 2 aparecerá un “Sin servicio”. En ambos casos se soluciona exactamente igual, tan solo tendremos que editar una etiqueta o la otra.

Aquí vamos a tener que volver a la edición de archivos plist. El proceso es exactamente el mismo que hiciésemos anteriormente. Primero los convertiremos a xml con plutil (texto plano), modificaremos lo que tengamos que modificar y convertiremos de vuelta el archivo a binario.

Tan solo se trata de un truco.

a) Localización del archivo a modificar: “SpringBoard.strings”

/System/Library/CoreServices/SpringBoard.app/Spanish.lproj

En caso de que tengamos nuestro iPod en español

/System/Library/CoreServices/SpringBoard.app/English.lproj

En caso de que lo tengamos en inglés

Evidentemente a buen entendedor pocas palabras bastan, cada idioma en su carpeta. De todos modos el archivo es exactamente el mismo.

b) Conversión a texto plano:

“plutil -c xml1 /System/Library/CoreServices/SpringBoard.app/Spanish.lproj/SpringBoard.strings”

c) Edición:

En este caso no hay que añadir nada, tan solo editar una etiqueta. Que tenemos un “Sin Servicio”? Buscamos por dicho texto en el archivo, y sustituimos el “Sin Servicio” por lo que deseemos. Que tenemos un “Buscando…”? lo mismo. En el caso de Buscando, creo que los puntos suspensivos se codificaban de otro modo, así que buscar mejor por “Busca”. Cuando sustituyamos las entradas deseadas, guardamos y listo

d) Conversión a binario:

“plutil -c binary1 /System/Library/CoreServices/SpringBoard.app/Spanish.lproj/SpringBoard.strings”

Una vez terminado, un respring o un reboot y como nuevo.

———————————
———————————

Llegados a este punto, todo debería funcionar correctamente, con TODAS las funciones de Maps activadas y sin ninguna contraindicación asociada:

Volver a arriba

Sobre Mí

 
Creative Commons License
Alma Oscura por Theliel is licensed under a Creative Commons Reconocimiento-No comercial-Sin obras derivadas 3.0 Unported License.
Basado en el trabajo de blog.theliel.es.
Para otros permisos que puedan exceder el ámbito de esta licencia, contactar en blog.theliel.es/about.