Bastionado, seguridad en sistemas: Introducción a la creación de preprocesadores Snort (III) pre { background:#eeeeee; border:1px solid #A6B0BF; font-size:120%; line-height:100%; overflow:auto; padding:10px; color:#000000 } pre:hover { border:1px solid #efefef; } code { font-size:120%; text-align:left; margin:0;padding:0; color: #000000;} .clear { clear:both; overflow:hidden; }

Bienvenido al blog

Bienvenidos al blog de seguridad en sistemas

sábado, 20 de agosto de 2011

Introducción a la creación de preprocesadores Snort (III)

Hola de nuevo, esta es la tercera entrada de introducción a la implementación de un preprocesador dinámico, donde veremos las funciones principales de un preprocesador dinámico, su función y el orden de llamadas de éstas.

Como hemos visto a lo largo de las entradas pasadas éste tiene como mínimo dos ficheros:

  • sf_preproc_info.h: este nombre no se debe cambiar. Es donde se declara el preprocesador, su nombre, su número de registro y donde indica la función de inicialización para empezar la carga del preprocesador. Esta función se encuentra implementada en el fichero "nombrePreprocesador.c".
  • nombrePreprocesador.c: es el fichero donde se encuentra la implementación del preprocesador, en nuestro caso se llama "blog.c".

El funcionamiento básico de ambos ficheros se explica en el siguiente diagrama resumido:

Fichero sf_preproc_info.h:
  ...
  extern void BlogSetup();
  ...

Fichero blog.c:
  -> extern DynamicPreprocessorData _dpd;

  -> void BlogSetup(){ ...  _dpd.registerPreproc("Blog", BlogInit); ...}

      -> BlogInit(char * args)
      { ...
      "DeclaracionEstructuas" ,
      "Declaracion de politicas" , 
      "Lectura del parametro 'args' que contiene la configuración de snort.conf",
      "Declaramos la funcion que se ejecuta para cada paquete en el lado del preprocesado:
          _dpd.addPreproc(hacerEnPreproc,opc2,...);",
      "Para cada paquete leido que hacemos en el motor de reglas
          _dpd.preprocOptRegister("tag regla", leerReglaFichero,hacerEnRegla,...);"
       
        ... }

             -> void hacerEnPreproc(el_paquete, ...) { ... acciones ... }

             -> static int leerReglaFichero(nombreRegla,valoresRegla, GuardamosDatos)           
            -> static int hacerEnRegla(paquete, ..., LoGuardado) { ... acciones ... }

Veamos paso a paso que es exactamente lo que está ocurriendo:


1º) En el fichero "sf_preproc_info.h" se indica la función del fichero "nombrePreprocesador.c" que inicializa el preprocesador. En nuestro caso la función es "BlogSetup" la cual fue declarado en el fichero "sf_preproc_info.h" como "extern void BlogSetup();".

Por tanto una vez se carga la función "BlogSetup" todo el resto de la implementación que veremos a continuación estará en el fichero "nombrePreprocesador.c", es decir "blog.c".

2º) La función "BlogSetup()" es la encargada de registrar el preprocesador mediante "registerPreproc" de la estructura "DynamicPreprocessorData",  indicando como segundo argumento el nombre de la función que se encargara de empezar la carga del preprocesador; a esta función la llamaremos "BlogInit" y se declararía de la siguiente forma: "_dpd.registerPreproc("Blog", BlogInit)".

Dentro de esta función, dependiendo de si se hace un "Start" o un "Reload" del servicio Snort se cargara una u otra función de inicialización. Para que se entiende forma sencilla, si yo ejecuto Snort en modo start se carga la función "_dpd.registerPreproc("Blog", BlogInit);", si en cambio es un reload de un Snort ya en ejecución haremos  un "_dpd.registerPreproc("Blog", BlogInit, BlogReload, BlogReloadSwap, BlogReloadSwapFree);", tal como se muestra a continuación:

void BlogSetup(void)
{
    #ifndef SNORT_RELOAD
        _dpd.registerPreproc("Blog", BlogInit);
    #else
        _dpd.registerPreproc("Blog", BlogInit, BlogReload, BlogReloadSwap, BlogReloadSwapFree);
    #endif
}

Para estas entradas solo trataremos el caso de inicialización pero es importante entender que las funciones reload son obligatorias para el arranque del Snort por tanto se dejaran tal cual están las del ejemplo que proporciona Snort.

3º) La función "BlogInit" carga los datos necesarios para el preprocesador durante el arranque del Snort, por ejemplo, la creación de estructuras necesarias, lectura de ficheros, lectura de los parametros de configuración del preprocesador indicados en el fichero de configuración de Snort (/etc/snort/snort.conf) y declarar las políticas del preprocesador. También se registran las funciones que se van a ejecutaran en el módulo del preprocesado y en módulo del motor de reglas al leer un paquete de red. El primero se crea mediante la función "addPreproc" y el segundo mediante la función "preprocOptRegister", ambas pertenecientes a la estructura "DynamicPreprocessorData".

Para asegurar que se ha entendido el funcionamiento de cada una de las funciones vamos a repasarlo mediante un pequeño diagrama hecho con DIA (siendo esta forma más visual), ya que, entender el funcionamiento del core de un preprocesador dinámico es la base de la implementación de éstos:


     
Con esto ya disponemos de las nociones básicas del funcionamiento de un preprocesador.

Para finalizar vamos a mostrar dos pequeñas funciones de la estructura "DynamicPreprocessorData" (entre muchas comillas por que ya os habréis dado cuenta que no es realmente una estructura) que permite mostrar texto en la implementación de forma que podamos seguir la traza del preprocesador. Éstas son "logMsg" y "fatalMsg". Ambas muestran por pantalla texto y el valor de las variables, pero "fatalMsg" adicionalmente finaliza la ejecución de Snort, por ejemplo, al detectar un fallo:

Si no hay error:
    _dpd.logMsg("La IP mostrada es %s\n",IPPROC);
sino
      _dpd.fatalMsg("Fallo en la aplicación, no puedo continuar\n");

Estas funciones son importantes porque las usaremos mucho durante la implementación de Snort.

Con esto ya hemos explicado las funciones principales de un preprocesador y como son llamadas unas a otras para realizar una cierta tarea. En la siguiente entrada, y última, se expondrá el código de un procesador "chorra" que sirva de ejemplo de como se implementa. Nos leemos.


No hay comentarios:

Publicar un comentario