martes, 20 de enero de 2015

Seguridad de una infraestructura de Red


Siguiendo el esquema de capas del modelo OSI se podría hablar de seguridad de la Red a nivel de varias capas, nos enfocaremos en solo en 4 de ellas:

  • Seguridad a nivel de Capa de Enlace (intranet)
  • Seguridad a nivel de Capa de Red (intranet)
  • Seguridad a nivel de Capa de Transporte (LAN o WAN)
  • Seguridad a nivel de Capa de Aplicaciones

En cada una de estas capas existen todo un conjunto de protocolos especificados para trabajar dentro de cada una de ellas. Estos protocolos muchas veces presentan ciertos defectos o vulnerabilidades, inherente a la propia especificación de los mismos o las limitaciones físicas que hay en el mundo real para implementarlos, por ejemplo: el ancho de banda o los recursos de la máquina. Por otra parte están las vulnerabilidades de las aplicaciones que trabajan con dichos protocolos. No hay que confundir las dos cosas, una cosa son los vulnerabilidades de los protocolos y otra la de las aplicaciones. En ocasiones existen tecnologías o configuraciones de red que permiten corregir o apaliar los riesgos de un determinado protocolo, en otras no, o bien los inconvenientes o costos son tales que hacen imposible cualquier implementación. Finalmente están las vulnerabilidades ocasionadas por errores humanos en cuanto a la configuración de un servicio o la infraestructura de red.

Hay protocolos de bajo nivel que suelen ser implementados directamente en el kernel del sistema operativo (por ejemplo ICMP). También hay protocolos se ejecutan en aplicaciones que tienen un nivel de privilegio alto, sea root, administrador o system. Debe tenerse en consideración cuáles son los parámetros de configuración óptimos, cuando eso se puede manipular, que permitirían minimizar los riegos de la infraestructura de red, para los protocolos implementados a nivel de kernel. Por ejemplo la deshabilitación de las respuestas a los mensajes de ping, en el caso de que sea pertinente. También debería tenerse muy en cuenta cuáles son las aplicaciones potencialmente peligrosas que se ejecutan con un alto nivel de privilegio y que medidas se pueden tomar para minimizar los riegos.

La tarea del administrador de red en el caso de las aplicaciones que tienen bugs o errores se reduce simple y llanamente a actualizar dichas aplicaciones con los parches respectivos. Hay aplicaciones y sistemas que se actualizan automáticamente mientras que hay otras que no. También existen vulnerabilidades de Zero-day para las que no existen parches conocidos o para las que hay que buscar parches de 3ra partes, en muchos casos de dudosa confiabilidad. Debe evaluarse si en esos casos conviene o no deshabilitar o sustituir los servicios asociados con esas vulnerabilidades.

Una cuestión importante es cómo identificar mediante la monitorización del tráfico de la Red cualquier ataque o fallo en la misma. Evidentemente esto requiere del uso de sniffers y el dominio de técnicas para usarlos. En cuanto al tráfico, en algunos casos, como los mensajes de broadcast o multicast, es posible identificar un tráfico irregular desde cualquier puerto de un switch o ubicación de red. Hay un tráfico de red que solo es visible dentro de los puertos de un switch, hay un tráfico de Intranet y hay un tráfico de Internet . Hay técnicas de hacking como el ARP Spoofing para visualizar el tráfico de un determinado nodo en un Switch.

El responsable de la seguridad de una red deberá tener presente los riesgos que hay a nivel de las distintas capas de la red, cuáles son los protocolos y aplicaciones trabajando en ellas de forma activa en el IBE y la localización física de los nodos o dispositivos asociados. Las aplicaciones afectadas pueden ser el propio sistema operativo. 

jueves, 4 de septiembre de 2014

ora2pg: Migrando Funciones y Procedures de Oracle a PostgreSQL desde un archivo


Estos son dos ejemplos sencillos:

 Funciones:
ora2pg -p -t FUNCTION -i acctbalance.sql -o acctbalance_pg.sql


Procedures:
ora2pg -p -t PROCEDURE -i acctbalance.sql -o acctbalance_pg.sql


Problema 1004. Sightseeing Trip (Ruta Turística) de acm.timus.ru

  1004. Sightseeing Trip

Este problema lo resolví utilizando un algoritmo de recorrido de un grafo, que represento por medio de una matriz y varios vectores. El grafo lo recorro por medio de una rutina que utiliza backtraking.  Debe compilarse con g++


// Compilar con g++

#include <stdio.h>
#include <string.h>


int no_se_ha_escogido_el_nodo(int vertic, int lim );
void guarda_vector(int vert_i, int lim);
void recorrido_minimo(int nivel, int distancia_recorrida) ;

int calcula_distancia (int lim, int indi);
int ind_vector(int vector, int lim);


int vert[100][10000];     // matriz que enlaza un vertice con otro
int cam[100][100];      // matriz que indica la distancia entre cada camino
int ind[100], i;    // matriz que indica el indice de los caminos que parten de un vertice
int vertices[100];     // matriz que indica el vertice que se esta recorriendo para un determinado nivel de profundidad
int vect_guardado[100]; // matriz en donde se guarda el recorrido de la solucion
int orden[100];        // matriz que indica el orden en el que se dieron los vertices o nodos
int se_dio[101];
int lim_vector_guardado;     // el tamaño del vector que se guardo
int vertice_i;



int distancia_minima = 0x7fffffff;
int N, M;

int main (void) {
  int i;
  int ni; int nk; int distancia;

  int distancia_min, distancia_recorrida;
 




  do {
    memset(vert, 0, sizeof(int)*1000000);
    memset(cam, 0, sizeof(int)*10000);
    memset(ind, 0, sizeof(int)*100);
    memset(orden, 0, sizeof(int)*100);
    memset(se_dio, 0, sizeof(int)*101);

    scanf("%d", &N);  // toma vertices
    if(N==-1) break;
    scanf("%d", &M);  // toma el numero de caminos
    int j=0;
    for(i=0; i < M; i++) {
   
      scanf("%d%d%d", &ni, &nk, &distancia);
      if(cam[ni-1][nk-1] == 0) {
        vert[ni-1][ind[ni-1]] = nk;
        vert[nk-1][ind[nk-1]] = ni;

        if(se_dio[ni-1]== 0 ) {

          se_dio[ni-1]=1;
          orden[j] = ni;j++; 
        } 
        if(se_dio[nk-1] ==0) {
          se_dio[nk-1]=1;    
          orden[j] = nk;j++;        
        }

        ind[ni-1]++;
        ind[nk-1]++;
        cam[ni-1][nk-1] = distancia;
        cam[nk-1][ni-1] = distancia;   
      }
      else if(cam[ni-1][nk-1] > distancia) {
        cam[ni-1][nk-1] = distancia;
        cam[nk-1][ni-1] = distancia;   

      }
     

    }

    // debido a que el grafo puede ser inconexo se chequean todos los vertices utilizando la matriz orden[k]... saltando de 2 en dos porque basta con
    // chequear uno de la pareja de cada camino dado
    //vertice_i=orden[0];
   

    for(int k=0; k < N; k+=2) {
      vertice_i = orden[k];
      recorrido_minimo(0, 0);

    }


    if(distancia_minima != 0x7fffffff) {
      for(i=0; i < lim_vector_guardado-1; i++) {
        printf("%d ", vect_guardado[i]);
      }

      printf("%d\n", vect_guardado[lim_vector_guardado-1]);
      distancia_minima = 0x7fffffff;
    }

    else {
      printf("No solution.\n");
    }

  } while(1);



}


void recorrido_minimo(int nivel, int distancia_recorrida) {
   int j, distancia;

  
   if(distancia_recorrida >= distancia_minima) return;
   if(nivel==0) {
     vertices[nivel] = vertice_i;

     recorrido_minimo(1, distancia_recorrida);
   }

   else {

     j=0;

    
     while(vert[vertices[nivel-1]  -1 ][j]!=0  )  {
       distancia = no_se_ha_escogido_el_nodo(vert[vertices[nivel-1] -  1][j] , nivel );   
      
       if(!distancia) {
        
         vertices[nivel] = vert[vertices[nivel-1] -1 ][j];

         recorrido_minimo(nivel+1, distancia_recorrida + cam[vertices[nivel-1] -1 ][vertices[nivel] - 1]);  

       }  
       else if(nivel - ind_vector(vert[vertices[nivel-1] -  1][j], nivel) > 2){

      if(distancia < distancia_minima) {

            distancia_minima = distancia;
            guarda_vector(vert[vertices[nivel-1] -  1][j], nivel);
          }

       }
       j++;


     }



   }
    


}

int ind_vector(int vector, int lim) {
  int i;
  for(i=0; i < lim; i++ ) {
    if(vector == vertices[i]) {  
      return i;
    }    

  }
}

int no_se_ha_escogido_el_nodo(int vertic, int lim ) {
  int i;
  for(i=0; i < lim; i++ ) {
    if(vertic == vertices[i]) {       
      return calcula_distancia (lim, i);
    }

  }

  return 0;
}


void guarda_vector(int vert_i, int lim) {
  int i;
  for(i=0; i < lim; i++){
     if(vertices[i] == vert_i)  {
       for(int j=i; j < lim; j++) {
         vect_guardado[j-i] = vertices[j] ;


       }
       break;
     }

  }
  lim_vector_guardado = lim - i;

}

int calcula_distancia (int lim, int indi) {
  int distancia=0;
  for(int i=indi+1; i < lim; i++) {
    distancia = distancia + cam[vertices[i-1] -1 ][vertices[i] - 1];
  }
  distancia = distancia + cam[vertices[indi] -1 ][vertices[lim-1] - 1];
  return distancia;

}

viernes, 7 de marzo de 2014

Cómo pasar los nombres de archivos que contengan espacios a una tubería


Al utilizar el comando find de esta forma:

find . -iname "*.htm*" | xargs -n1 grep -H -i "palabra"

los nombres de archivos que contengan espacios se pasaran de forma fragmentada en la tubería, de forma tal que un nombre de archivo como "Fulano de tal.htm",  pasado a grep con la tuberia (pipe en inglés: '|') lo vera como 3 archivos distintos: "Fulano", "de", "tal.hm", debido a que toma el carácter de espacio " ", como un delimitador. Para evitar dicho problema debe corregirse la instrucción anterior de esta forma:

find . -iname "*.htm" -print0 | xargs -0 -n1 grep -H -i "palabra"

sábado, 4 de enero de 2014

Hacer un md5sum de todos los archivos del sistema


Hacer un md5sum de todo el sistema de archivos. Ejemplo:

find /media/pto_montaje -iname "*" -type f -print0  | xargs -0 -n1 md5sum  > md5sum_sistema_archivo.txt

martes, 26 de abril de 2011

Recuperar el arranque de Windows luego de instalar Debian

¡Todavía pasan esas cosas!

solo son 3 líneas:

sudo grub-mkconfig
sudo grub-install /dev/sda 
sudo update-grub

podría ser también que en lugar /dev/sda fuese /dev/hdX...

lunes, 10 de enero de 2011

Buscar he encontrar la ubicación de un controlador en linux

No me interesa de cuanto interés sea esto o no.

Es un ejemplo de cómo saber el nombre del módulo de un controlador y saber donde esta ubicado. En eso nos toparemos con varios comandos que seria de interés conocer.

Supongase que queremos saber el nombre del controlador wireless. El primer comando a utilizar seria este:

primero buscar en los dispositivos pci

lspci -k | grep -i -B 2 -C 2 -E "wireless"

lspci: muestra todos los dispositivos pci

con el parametro -k de "lspci" se muestran los controladores asociados en el kernel con cada dispositivo pci.

el parámetro -i de grep indica que no se hará distinción entre mayúsculas y minúsculas -B 2, indica que se mostraran las  2 lineas que estén antes de  palabra "wireless" y -C 2 indica que se mostraran las dos líneas después. Esto es porque tal vez no este toda la información en la misma línea.

sin embargo tal vez el dispositivo no sea pci sino usb. En ese caso el comando a utilizar seria este:

lsusb | grep -i -E "wireless

podría mostrar una línea como esta:

Bus 001 Device 002: ID 0bda:8187 Realtek Semiconductor Corp. RTL8187 Wireless Adapter

RTL8187 seria el nombre del controlador.

Para confirmarlo se utiliza modinfo:

modinfo rtl8187

en la linea filename aparece la ubicación del controlador:

filename:       /lib/modules/2.6.32-27-generic/kernel/drivers/net/wireless/rtl818x/rtl8187.ko
finalmente si se quiere saber a qué paquete corresponde ese archivo se utiliza dpkg:


dpkg -S /lib/modules/2.6.32-27-generic/kernel/drivers/net/wireless/rtl818x/rtl8187.ko

mostraría algo como esto:

linux-image-2.6.32-27-generic: /lib/modules/2.6.32-27-generic/kernel/drivers/net/wireless/rtl818x/rtl8187.ko

donde linux-image-2.6.32-27-generic es el nombre del paquete.