Skip to main content

Desarrollo rápido de aplicaciones de red: Apache Mina (II) - Nociones básicas

En el artículo anterior explicaba como preparar el entorno de trabajo necesario para desarrollar aplicaciones de red utilizando los framework J2EE, Eclipse y Apache MINA. Un buen punto de partida es como siempre la "Quick start guide" del proyecto, en ella se explican los pasos básicos para la construcción de una aplicación con MINA, en este caso a través del ejemplo del servidor de hora probado con anterioridad, no tiene sentido explicar ese mismo ejemplo así que me centraré en el servidor reverser que es muy similar. No entraré en los parámetros de los métodos de las clases, para eso tenemos la API, ni en el funcionamiento interno del framework, en la guía de usuario que aunque no está completa todavía, sí aborda algo el tema en el apartado 2. Como comenté en la entrada anterior solo daré algunas nociones que puedan ayudar a alguien intentando que esto sea un complemento a la documentación oficial del proyecto ya que solo se explica el código de algún ejemplo y no existe demasiado en castellano sobre MINA.


El paquete del reverser(org.apache.mina.example.reverser) tiene 2 clases y una archivo .html con la descripción del mismo. La clase Main.java es la principal del proyecto como su nombre indica y ReverserProtocolHandler.java tampoco es muy difícil de suponer que va a ser el manejador de los eventos que producen las conexiones entrantes.
Comenzamos la inspección del código por la clase Main.java:



Esta clase es prácticamente igual que en el caso del servidor de hora del ejemplo de la documentación, solo cambia la línea 4 que ahora comentaremos:

1 - La clase NioSocketAcceptor.java es el objeto que se encarga de escuchar las conexiones entrantes.
2 y 3 - Los filtros funcionan como muestra la siguiente imagen enlazada desde éste artículo de la documentación oficial donde se explica todo esto en profundidad. La idea se resume en que el mensaje lo recibe la aplicación por el acceptor y va "subiendo" desde el nivel más bajo de la cadena de responsabilidad a medida que se le van aplicando filtros de la cadena(ioFilterChain) definida sobre ese aceptor cuya misión es tratar las tramas de bits recibidos. Como podemos deducir de lo anterior el orden en que se le aplican es importante ya que, como acabo de decir, la trama recibida se trata secuencialmente.


En nuestro ejemplo se aplican dos filtros(se pueden aplicar todos los que se necesiten en función de nuestras necesidades):
- logger: Crea logs sobre las conexiones, aquí tenemos más información sobre el sistema de logs de MINA.
- codec: Define como se codifican/descodifican las tramas enviadas/recibidas, por ejemplo en el caso de las tramas recibidas dice como debe de interpretar los bytes la aplicación para poder utilizarlos. En este caso utiliza un codec que incorpora MINA para las tramas de texto que son las que necesita este servidor reverser, al igual que pasaba con el servidor de tiempo. Este sistema modular nos permite que la aplicación soporte nuevos protocolos siendo necesario solamente definir un nuevo codec.
4 - Establece en manejador para los eventos producidos por nuestro aceptor(conexiones entrantes), es el que contendrá la lógica de negocio de la aplicación y por lo tanto es donde centraremos nuestro desarrollo.
5 - Hace el bind del socket con el puerto.

Nos queda definir la lógica de negocio en el manejador de nuestra aplicación, en el ejemplo ésta reside en la clase ReverseProtocolHandler.java.




De aquí nos interesa el método messageReceived(), el propio framework nos ofrece en el parámetro message la trama de bits recibida y en el parámetro session la sesión TCP para poder responderle, el desarrollador no tiene que preocuparse de nada más. La lógica de negocio en este caso es convertir la trama a tipo String y darle la vuelta a los caracteres. A continuación se escribe en la sesión, en este caso en forma de tipo String por tener definido el codec para texto como se explicó mientras hablábamos de los filtros. Si no se hubiera definido niguno habría que enviar los bytes usando para ello algún método del objeto a enviar para obtenerlos(.getBytes() normalmente). Para hacer una pequeña prueba podemos crear una cadena nueva y enviarla añadiendo esta línea al final y vemos que ahora el reverser es más simpático... :) :
String probing = ":)"; session.write(probing);

(Nota: El telnet de Windows hace cosas un poco raras, desconozco el porqué pero para nuestras pruebas es suficiente, en el artículo anterior las pruebas eran con un Debian y funciona perfectamente.)




El método messageReceived() lo invoca el framework cuando se produce un evento(llegada de un mensaje) pero podemos añadir comportamiento a la aplicación definiendo otros, ¿cuales defino? Si miramos el código de ReverseProtocolHandler.java vemos que extiende a la clase IoHandlerAdapter.java redefiniendo sus métodos, así que nos vamos a la API y encontramos que además tiene los siguientes métodos: exceptionCaught(), messageSent(), sessionClosed(), sessionCreated(), sessionIdle() y sessionOpened(). Los nombres son lo suficientemente explicativos así que para terminar vamos a hacer otra pequeña prueba para comprender un poco mejor el funcionamiento y de paso hacer nuestro servidor un poco más educado y conseguimos que nos salude al conectarnos. Redefinimos el método sessionOpened() añadiendo el siguiente trozo de código antes del método messageReceived() y listo :) .


@Override
public void sessionOpened(final IoSession session){
String probing = "Hi!, how are you?";
session.write(probing);
}



Intentaré escribir alguna entrada más tratando más en profundidad temas como la gestión de logs, conexiones asíncornas o la creación de codecs nuevos.


Jesús Pérez

Popular posts from this blog

ISO 27001: Inventario de los activos de información

Uno de los primeros pasos que debe seguir la entidad para adaptarse a la norma ISO 27001 es realizar el inventario de activos que contendrá todos aquellos activos de información que tienen algún valor para la organización y que quedan dentro del alcance del SGSI . En un principio puede parecer un poco abrumador para un principiante(como yo) por la enorme cantidad de activos que se te van ocurriendo por eso decidí empezar por clasificarlos de alguna forma, de entre las múltiples maneras que me encontré elijo la definida por los expertos del foro ISO27k ya que me parece la más completa, mostrando ejemplos de cada tipo y es válida para entidades de muy distinta naturaleza. Éste podría ser un buen punto para comenzar siempre teniendo en cuenta lo que nos aconsejan también en ese foro: "Debido a que los activos son algo cambiante, incluso si pudieras cubrir absolutamente todo lo que hay hoy, mañana la situación sería un poco diferente y más en unas semanas, meses o años. Así que

SIP INVITE attack with Metasploit

Some days ago my friend  @pepeluxx  wrote  another post  about INVITE attacks. He spoke about a  @sinologic   project  which allows to everybody passing some security tests to SIP servers. Furthermore he also published a perl script to do the same task. So I implemented it on Metasploit because I think It could be really useful during a pentesting. It’s interesting because these attacks are really dangerous, normally, attackers try to call to expensive locations. This target numbers often have special charges and they make money with this. Here there are two well known examples: http://blog.sipvicious.org/2010/12/11-million-euro-loss-in-voip-fraud-and.html http://snapvoip.blogspot.com.es/2009/02/calls-to-cuba-and-voip-attacks.html I’m not going to deep in this vector because of being a well known (and old!!) one. Basically the attacker tries to make a call using a misconfigured PBX. This is allowed because  SIP RFC  says that an extension has not to be registered to be abl

Another simple Metasploit module: ICMP Flooder

Hi again!, I said I was going to develope VoIP related Metasploit modules but I was reading PacketFu documentation and I found that wrinting an ICMP flooder couldn´t be too complicated at this point. So I share this code too, I decided to include SHOST and SIZE options too trying to get a more flexible module able to make different flavors of this attack as Ping flood , Smurf or Ping of death . Next pictures show the module in  the same way of last post. Code: ------------------------------------------------------------------------- require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Dos include Msf::Exploit::Capture def initialize super( 'Name' => 'ICMP Flooder', 'Description' => 'A simple ICMP flooder', 'Author' => 'Jesus Perez', 'License'     => MSF_LICENSE, 'Version' => '$Revision: 0 $' ) register_opt