De Nairobi a Rusia. Eso sí, pasando por mi PC.

Buenas de nuevo.

Hace un par de días, recibí en mi correo personal un correo de esos que traen sorpresas adjuntas. Esta vez, tocaba un documento Word escaneado en una fotocopiadora supuestamente de mi empresa y enviado por correo desde una cuenta de mi propio dominio.

Como esa noche no tenía ningún “proyecto Manhattan” pendiente, me propuse investigar un poco a ver qué podía sacar del citado documento. No pretende ser un “forense” en toda regla ni pretendo estar a la altura de grandes profesionales con los que me gusta comentar las jugadas por Twitter. Solamente pretendo explicar la información que he podido sacar del documento y como la he obtenido.

Vamos al lío.

Lo primero que hice fue ver el código fuente del correo electrónico (os lo resumo a las primeras líneas que es donde está lo importante).

Encabezado del correo

Return-Path: <copier@aratech.es>
Received: from llsb960-a02.servidoresdns.net (llsb960-a02.servidoresdns.net [82.223.190.170])
by llce663-z.servidoresdns.net with LMTPA;
Mon, 01 Feb 2016 12:32:01 +0100
X-Sieve: CMU Sieve 2.3
Received: from 41.215.43.150.accesskenya.com (unknown [41.215.43.150])
by llsb960-a02.servidoresdns.net (Postfix) with ESMTP id 5B99A1CD0
for <onavarrete@aratech.es>; Mon, 1 Feb 2016 12:31:57 +0100 (CET)
Date: Mon, 01 Feb 2016 14:31:56 +0300
To: <onavarrete@aratech.es>
From: “copier@” <copier@aratech.es>
Sender: <copier@aratech.es>
Reply-To: <copier@aratech.es>
Subject: Scanned image from copier@aratech.es
Message-ID: <2016020184903.38E7.COPIER@aratech.es>
X-Mailer: Network Scanner System
Content-Type: multipart/mixed; boundary=”SmTP-MULTIPART-BOUNDARY-C46B1868″
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0

Lo primero que hice fue comprobar la dirección IP y el dominio para ver si podía extraer alguna información de ellos.

WhoIs dirección IP

inetnum: 41.215.43.148 – 41.215.43.151
netname: KE-COMMSOL
descr: Ultimate Tracking Solutions
country: KE
admin-c: NPS2007-AFRINIC
tech-c: RM1760-AFRINIC
status: ASSIGNED PA
mnt-by: ACCESSKENYA-MNT
source: AFRINIC # Filtered
parent: 41.215.0.0 – 41.215.127.255

person: AccessKenya IP Administrators
nic-hdl: NPS2007-AFRINIC
address: 4th Floor,
address: Purshottam Place
address: Westlands Road
address: Nairobi
address: Kenya
phone: +254 020 3600000
source: AFRINIC # Filtered

person: Raymond Macharia
address: Site Estate,Athi River
phone: +254 722556969
nic-hdl: RM1760-AFRINIC
remarks: data has been transferred from RIPE Whois Database 20050221
source: AFRINIC # Filtered

WhoIS dominio accesskenya.com

Domain Name: accesskenya.com
Registry Domain ID: 28899305_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.srsplus.com
Registrar URL: http://srsplus.com
Updated Date: 2014-12-09T12:50:11Z
Creation Date: 2000-06-09T10:20:29Z
Registrar Registration Expiration Date: 2016-06-09T10:20:29Z
Registrar: TLDS LLC. d/b/a SRSPlus
Registrar IANA ID: 320
Registrar Abuse Contact Email: @web.com
Registrar Abuse Contact Phone: +1.8773812449
Reseller:
Domain Status: clientTransferProhibited http://icann.org/epp#clientTransferProhibited
Registry Registrant ID:
Registrant Name: Domain Manager
Registrant Organization: AccessKenya Group
Registrant Street: P O Box 43588
Registrant City: Nairobi
Registrant State/Province: NONE
Registrant Postal Code: 100
Registrant Country: KE
Registrant Phone: +254.203600000
Registrant Phone Ext.:
Registrant Fax:
Registrant Fax Ext.:
Registrant Email: @accesskenya.com
Registry Admin ID:
Admin Name: Domain Manager
Admin Organization: AccessKenya Group
Admin Street: P O Box 43588
Admin City: Nairobi
Admin State/Province: NONE
Admin Postal Code: 100
Admin Country: KE
Admin Phone: +254.203600000
Admin Phone Ext.:
Admin Fax:
Admin Fax Ext.:
Admin Email: @accesskenya.com
Registry Tech ID:
Tech Name: Domain Manager
Tech Organization: AccessKenya Group
Tech Street: P O Box 43588
Tech City: Nairobi
Tech State/Province: NONE
Tech Postal Code: 100
Tech Country: KE
Tech Phone: +254.203600000
Tech Phone Ext.:
Tech Fax:
Tech Fax Ext.:
Tech Email: @accesskenya.com
Name Server: ns0.accesskenya.com
Name Server: ukns1.accesskenya.com
DNSSEC: Unsigned

Como se puede apreciar por los datos de la dirección IP y del dominio, los tiros vienen desde Nairobi (Kenia), y por el momento no tengo fotocopiadoras con mis cuentas de correo tan lejos.

Lo siguiente que hice fue descargar el documento Word en un entorno controlado (punto a tener en cuenta) y empezar a probar lo que se me iba ocurriendo.

Lo primero, pasar el documento por VirusTotal.com. El resultado ya va dejando ver el contenido del documento: 25/53 detecciones y una buena lista de “alias” conocidos.

Lo siguiente, extraer información con la herramienta OfficeMalScanner. Para el que no la conozca, es una herramienta por línea de comandos que nos da información del documento, extrae macros si las tiene, intenta desencriptarlo si va cifrado, etc…

officemalscanner

Como podemos observar, el documento tiene macros (Module1, Module2, UserForm1 y ThisDocument) que se extraen por defecto en un directorio con el mismo nombre del archivo escaneado.

Volvemos a ejecutar OfficeMalScanner de nuevo, ahora con los parámetros “scan brute“, para buscar ficheros OLE embebidos e intentar fuerza bruta contra archivos PE encriptados. En esta ejecución no encuentra nada extra (nos quedamos sólo con las macros).

Mi siguiente paso fue abrir las macros con el bloc de notas para ver el código que ejecuta. Veo mucho código que intenta simular un software para mostrar datos de “sondas” en el documento, gráficas y demás tontadas variadas, pero intercalados hay unos cuantos “goto” que hace que la ejecución salte todo ese código de relleno y sólo ejecute unas cuantas funciones, las necesarias para descargar el ejecutable necesario para infectar el pc.

Lo siguiente que hice fue ejecutar las macros añadiendo inspecciones a las variables para ver los datos que podía extraer, como las URL, nombres de archivos y demás datos que utiliza la macro para cumplir su cometido.

Cuando ejecutamos las macro, deja un archivo en el mismo directorio con nombre “[путь к файлу” que realmente no le he encontrado “finalidad”. He probado varias cosas con él, pero no he sacado nada en claro. Lo único que he podido “adivinar” es que tiene un encabezado “BM” cuando lo abro en hexadecimal y podría apuntar a un trozo de archivo de imágen, pero realmente no le he encontrado la finalidad (se aceptan sugerencias).

Simultáneamente, abrí WireShark y lo dejé capturando tráfico para detectar las conexiones que se hacen al ejecutar la macro.

ejecucionmacros

Volviendo a lo que nos ocupa, vemos por los datos de la inspección que se está preparando un stream de datos desde internet, con intención de guardarlo en disco en un directorio temporal.

De los datos de la inspección de variables, realmente aprovechable sólo está la URL de donde se descargará el archivo malicioso “.exe”.

URL

Con el bucle “For” que se aprecia en la imagen, ha ido componiendo letra a letra la URL de donde se descargará el archivo. En este caso, la URL será:

“http://www.peopleond-clan.de/u56gf2d/k76j5hg.exe”

Lo podemos confirmar gracias a WireShark que estaba capturando paquetes, y nos refleja dicha conexión (El paquete marcado GET).

WhireShark

El archivo se descarga en la ruta “c:\users\oscarnavarrete\appdata\local\temp” y se modifica el nombre quedando como:

“c:\users\oscarnavarrete\appdata\local\temp\perdoma.exe”

Gracias a WireShark, sabemos también que el archivo realiza conexiones a la ip “185.24.92.236”, la cual pertenece a una página de “jóvenes soldados sovieticos”… De ahí el título de la entrada. Supongo que en algún sitio tiene que entregar los datos que recabe en el equipo.

URL_destino

WhoIs de la IP “soviética”

inetnum:        185.24.92.0 - 185.24.93.255
netname:        SP-NET1
descr:          System Projects, LLC
country:        RU
admin-c:        MS32000-RIPE
tech-c:         MS32000-RIPE
status:         ASSIGNED PA
mnt-by:         SYSTEMPROJECTS-MNT
created:        2013-04-19T01:39:09Z
last-modified:  2013-04-19T01:39:09Z
source:         RIPE # Filtered

person:         Mikhail Svetlov
address:        Russia
phone:          +7 391 2054546
nic-hdl:        MS32000-RIPE
mnt-by:         SYSTEMPROJECTS-MNT
created:        2013-03-19T11:53:29Z
last-modified:  2013-04-23T10:02:47Z
source:         RIPE # Filtered

% Information related to '185.24.92.0/24AS60879'

route:          185.24.92.0/24
descr:          System Projects, LLC
origin:         AS60879
mnt-by:         SYSTEMPROJECTS-MNT
created:        2013-04-19T13:06:37Z
last-modified:  2013-04-19T13:06:37Z
source:         RIPE # Filtered

Lo siguiente fue pasar el archivo ejecutable por RDG Packer Detector para ver si me aportaba algún dato interesante (compilador, empacado o no…) El resultado fue que está compilado con Microsoft C++ y está protegido con aPLib.

Siendo ya las 04:00 de la madrugada y sin más fuerzas para continuar (teniendo en cuenta que a las 08:00 tocan diana), sólo me dio para abrirlo en hexadecimal y ver si veía algo interesante a simple vista.

Aparecieron unas cuantas cosas que pueden ser interesantes.

Datos de versión del archivo:

Copyright ©.PassMark Software All rights reserved.

Product OverpaidConnectionstring

Original name OverpaidConnectionstring.exe
File version 7.8.21.4
Description Brace Inventions Lost Looping Graphs
Comments Brace Inventions Lost Looping Graphs
El tal “overpaidconnectionstring.exe” es bastante conocido en VirusTotal y páginas del ramo, así que no da mucha confianza de primeras.

Por otra parte, parece que lleva un instalador de “oovoo”, que por lo que he leído, es un programa para hacer videoconferencia de hasta 12 personas simultáneamente, lo que me hace pensar que pueda ser un malware que utilice la cam y el micro del portátil para capturar imágenes y audio fraudulentamente.

Parece ser que se inyecta, o lo intenta en “explorer.exe”.

En este punto, tal y como he comentado hoy con mi amigo Jesús Angosto (@jdangosto), es donde me quedé. 04:00 de la madrugada y teniendo que ir a trabajar al día siguiente… no me daba para más. Jesús siempre se anima a echar una mano y a estar para lo que necesites, cosa que le agradezco enormemente. ¡Gracias!

Sé que me he dejado cosas en el tintero y que a muchos de vosotros se os ocurrirá muchas más cosas para hacerle al archivo en cuestión. Para eso estamos aquí. Compartid lo que queráis y así aprendemos todos.

Un saludo y hasta la próxima.

Backup automatizado de switches HP ProCurve con Python

Buenos días.

Hoy os traigo otro nuevo avance en mi empeño por hacer cosas con Python.

En la empresa vamos ya por 42 switches gestionables en nuestra red (sólo en la localización de mi oficina y sólo los gestionables…), y no paramos de crecer y ampliarla. Ésto está muy bien y es divertido para los que nos gusta jugar con redes cableadas, inalámbricas y de fibra óptica, pero acaba dando algún que otro susto cuando se te olvida hacer backup de la configuración de alguno de ellos después de haber modificado esa vlan que era tan importante.

Como no tenemos mucho tiempo para realizar esas tareas y, la mitad de las veces se nos va el santo al cielo con la siguiente urgencia y no nos acordamos de hacerlo, decidí crear un script en Python (aprovechando que me cambié el ordenador de la oficina de Windows Server 2008 R2 a Ubuntu 14.04) que realizase la tarea por mí periódicamente.

La entrada hace referencia a switches “HP ProCurve” en concreto, ya que los 42 que tengo son de la misma familia, aunque es fácilmente modificable para aplicarlo a cualquier tipo de switch o dispositivo que sea accesible por telnet u otro protocolo similar vía consola.

Al final, ha quedado una cosa bastante curiosa que me gustaría compartir con vosotros (aunque ya sé que mi código no es el más depurado).

El script lo que hace básicamente es:

1.- Crea una carpeta nueva “Backup_Switches_DDMMYY” en la carpeta de Backups.

2.- Se va conectando por telnet a una lista de switches configurados en un archivo a tal efecto y va copiando el resultado del comando “show run”.

3.- Tiene en cuenta si el switch no tiene contraseña, si tiene contraseña, si hay que pulsar Intro o no hay que pulsarlo para acceder a la configuración. Funciona con todas las combinaciones posibles (entre tantos modelos tengo todas las variantes…). Ésto es porque hay switches que acceden directamente a la pantalla de “user” y “password”, en otros pone “Pulse Intro para continuar” y al pulsarlo es cuando te pregunta “user” y “password”… los que no piden contraseña y acceden directamente al prompt, los que no piden contraseña pero hay que pulsar Intro para acceder al prompt…

4.- Vuelca el contenido de la configuración en un archivo “Backup_IP_DDMMYY_HHMM.txt” dentro de dicha carpeta y lo modifica un poco (eliminando la primera y última líneas del archivo por ejemplo, que traen texto innecesario).

5.- Una vez se han tratado todos los switches de la lista, comprime la carpeta en formato “.zip” y elimina la carpeta con los archivos de configuración, dejando sólo el archivo comprimido.

6.- Si observáis el script, tengo comentada la librería y las líneas de código para hacer que suba los archivos a un TFTP, ya que es como lo ejecutaba al principio. Desde un qemu emulando una Raspberry a un TFTP que tenía en mi ordenador. Se puede hacer que lo suba a un TFTP, FTP, Mega, Dropbox, Drive… o lo que se os ocurra y se pueda programar en Python (vamos, casi todo…).

7.- Se puede programar con cron para que se ejecute cada día, semana, mes…

Pantalla de ejecución del script (conexión a los 2 primeros switches):

ejecucion_switches

Carpeta con la fecha para ir guardando los archivos individuales:

carpeta_switches

Detalle de los archivos de backup (los mismos 2 primeros switches):

archivos_switches

Lo único que necesita el script para trabajar es un archivo en el mismo directorio llamado “lista”, que contiene los datos necesarios para conectarse y obtener la configuración de los switches.

Se configura un switch por línea, y sólo es necesario 4 parámetros por switch (mínimo 2 obligatorios, máximo 4).

Los parámetros son: IP, hostname, [usuario, password]

En el siguiente ejemplo, el primer switch tiene como usuario “usuario” y como contraseña “password”, y el segundo no tiene usuario ni contraseña (nótese que tiene que estar la coma igualmente).

Archivo “lista”

192.168.46.181,HP ProCurve Switch 5308xl,usuario,password
192.168.38.182,SALANUEVA,,

Archivo “Backup_Switches.py”

#!/usr/bin/python

import telnetlib
import datetime
import time
import os
import sys
import subprocess
import zipfile
#import tftpy

now=datetime.datetime.now()

os.mkdir("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y"))

listado=[]
respuesta=""
index=-1

with open("lista","r") as origen:
	for line in origen:
		listado.append(line[:-1])

for elemento in listado:

	datos=elemento.split(",")

	host = datos[0]
	tn=telnetlib.Telnet(host)
	print "Conectado a " + host + " (" + datos[1] + ")"
	time.sleep(2)
	respuesta=tn.read_very_eager()
	index=respuesta.find("Username:")
	if index!=-1:
		tn.write(datos[2] + "\n")
		time.sleep(2)
		tn.read_until("Password:")
		tn.write(datos[3] + "\n")
		time.sleep(2)
	else:
		tn.write("\n")
		time.sleep(2)
		if datos[2]!="":
			tn.read_until("Username:")
			tn.write(datos[2] + "\n")
			time.sleep(2)
			tn.read_until("Password:")
			tn.write(datos[3] + "\n")
			time.sleep(2)
	tn.read_until(str(datos[1]) + "#")
	tn.write("terminal length 1000\n")
	tn.write("show run\n")
	time.sleep(2)
	tn.write("exit\n")
	time.sleep(2)
	tn.write("exit\n")
	time.sleep(2)
	tn.write("y")
	output = tn.read_all()
	tn.close()
	filename = "tmp"
	fp=open(filename,"w")
	fp.write(output + "\n")
	fp.close()
	with open("tmp") as myfile:
		suma = sum(1 for line in myfile)
	myfile.close()
	contador = 1
	with open("tmp","r") as input:
		with open("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y") + "/backup_" + datos[0] + "_" + now.strftime("%d%m%Y") + "_" + now.strftime("%H%M") + ".txt","wb") as output:
			for line in input:
				if contador!=1 and contador!=suma and contador!=suma-1:
					output.write(line)
				contador=contador+1
	input.close()
	output.close()	
	os.remove("tmp")

zf=zipfile.ZipFile("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y") + ".zip", "w")
for dirname, subdirs, files in os.walk("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y")):
	zf.write(dirname)
	for filename in files:
		zf.write(os.path.join(dirname,filename))
zf.close()

for root, dirs, files in os.walk("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y"), topdown=False):
	for name in files:
        	os.remove(os.path.join(root,name))
	for name in dirs:
                os.rmdir(os.path.join(root, name))
os.rmdir("/media/oscar/ALMACEN/Backups_Switches/Backup_Switches_" + now.strftime("%d%m%Y"))

origen.close()
sys.exit()

#client = tftpy.TftpClient("192.168.46.45",69)
#client.upload("backup_" + datos[0] + "_" + now.strftime("%d%m%Y") + "_" + now.strftime("%H%M") + ".txt","/home/pi/SAVE/backup")
#subprocess.call(["rm","backup"])

Espero vuestros comentarios así como las mejoras que se os ocurran (así las puedo implementar en producción yo también ;-D).

Un saludo y hasta la próxima.

Detectando “bordes”

Buenas tardes.

Sé que habéis llegado hasta aquí pensando en detectar otro tipo de “bordes”, pero esos que pensáis no hace falta detectarlos de ninguna manera ya que se dejan ver por si solos.

Hoy os voy a hablar de otro tipo de “bordes”. El título podría ser “detección de bordes” o “detección de contornos”.

Evidentemente hay miles de herramientas con miles de filtros que realizan ésta tarea muchísimo mejor de lo que yo lo voy a hacer aquí, pero ya sabéis que ésto trata de “lo entendí, y fui capaz de hacerlo por mí mismo, que sabe mucho mejor…” Al final del artículo tenéis tanto el código fuente como el link para descargar el ejecutable.

Por trabajo, me tocó investigar sobre detección de contornos en una imagen para ver cómo se podría realizar un reconocimiento de caracteres o cosas similares, pero autónomamente. Es decir, sin depender de un software de tercero con el que aplicar los filtros y tratar las imágenes, si no desarrollar un software que aplicase los filtros necesarios y extrajese la información necesaria de la imagen por si sólo.

Buscando información en Internet, encontraréis que si filtros laplacianos, que si matriz de Sobel vertical, matriz de Sobel horizontal… y unas explicaciones con fórmulas matemáticas, gráficos y demás parafernalia que al final no es tan complicada de entender.

Para mis pruebas yo me decidí por la matriz de Sobel. Lo que hace básicamente es tener en cuenta los 8 píxeles que rodean al píxel que estamos analizando en cada momento para determinar un “gradiente” y, dependiendo del umbral que le hayamos marcado, decidir si lo marca como “contorno” o no. Al final, lo que tendremos será una imágen en la que tendremos píxeles a blanco y píxeles a negro donde esté el contorno o borde y de la que eliminaremos el resto de la información.

Dependiendo del “umbral” que marquemos, la imagen tendrá unos contornos finos y definidos o gruesos y más difuminados. El resultado final dependerá de dicho umbral que decidamos aplicar.

He realizado una aplicación en visual basic (visual studio 2010) para demostrar el funcionamiento de dicha matriz.

El funcionamiento es sencillo:

  1. Con el botón “abrir imagen” seleccionamos la imagen de la que deseamos extraer los contornos.
  2. Seleccionamos un umbral con el trackbar (entre 0 y 255 que son las intensidades que podemos encontrar para un pixel).
  3. Por último pulsamos sobre “aplicar Sobel” y veremos aparecer el resultado en la ventana adjunta.
  4. Podremos guardar la imagen resultante pulsando sobre “Guardar”.

Aquí os presento la diferencia entre aplicar un umbral bajo o uno alto a una matrícula, por ejemplo.

Umbral Bajo:

filtro_bajo

Umbral Alto:

filtro_alto

Como se puede apreciar, con un umbral alto se obtienen unos contornos muy claros y definidos (también se debe al alto contraste entre los caracteres de la matrícula y el fondo).

Os dejo otro ejemplo más aplicado sobre la imagen de un coche.

coche_sobel

Os dejo el código fuente del programa para que veáis lo sencillo que puede ser crear nuestro propio filtro detector de contornos o bordes.

Imports System.drawing

Public Class Form1

    Dim contador
    Dim horizontal()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        OpenFileDialog1.ShowDialog()
        If OpenFileDialog1.FileName <> "" Then
            PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
            ListBox1.Items.Clear()
        End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        ListBox1.Items.Clear()
        Dim vectorx(,) = {{1, 0, -1}, {2, 0, -2}, {1, 0, -1}}
        Dim vectory(,) = {{1, 2, 1}, {0, 0, 0}, {-1, -2, -1}}
        Dim img1 As Bitmap
        img1 = New Bitmap(PictureBox1.Image)
        Dim img2 As New Bitmap(img1.Width, img1.Height, Imaging.PixelFormat.Format32bppArgb)
        ReDim horizontal(img2.Width - 1)
        For i As Integer = 0 To UBound(horizontal) - 1
            horizontal(i) = 0
        Next

        For y As Integer = 0 To img1.Height - 1
            contador = 0
            For x As Integer = 0 To img1.Width - 1
                Dim gradX As Single = 0
                Dim gradY As Single = 0
                Dim grad As Single = 0

                If x = 0 Or y = 0 Or x = img1.Width - 1 Or y = img1.Height - 1 Then
                    grad = 0
                Else
                    For i As Integer = -1 To 1
                        For j As Integer = -1 To 1
                            Dim p As Color = img1.GetPixel(x + i, y + j)
                            Dim intensity As Single = 0.333F * (CInt(p.R) + p.G + p.B)
                            gradX += intensity * vectorx(i + 1, j + 1)
                            gradY += intensity * vectory(i + 1, j + 1)
                        Next
                    Next

                    grad = (Math.Abs(gradX) + Math.Abs(gradY))
                End If

                grad = Math.Max(0, grad)

                grad = Math.Min(255, grad)

                If grad >= TrackBar1.Value Then
                    img2.SetPixel(x, y, Color.Black)
                    contador += 1
                    horizontal(x) = horizontal(x) + 1
                End If
            Next
            PictureBox2.Image = img2
            PictureBox2.Refresh()
            ListBox1.Items.Add(contador)
        Next
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        SaveFileDialog1.ShowDialog()
        If SaveFileDialog1.FileName <> "" Then
            PictureBox2.Image.Save(SaveFileDialog1.FileName)
        End If
    End Sub

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        TrackBar1.Value = 122
    End Sub

End Class

Aquí el enlace al ejecutable.

Saludos y hasta la próxima.

Detectando NICs en Modo Promiscuo

tdred

Buenas noches.

De todos los que nos solemos “encontrar” por Twitter son conocidos los #Ciberretos de @CiberpoliES.

El domingo pasado a las 12 de la mañana, que ninguno de los dos teníamos mucho que hacer por lo visto, recibí un mensaje directo de @CiberpoliES diciéndome que llevaba un rato enredando intentando descubrir tarjetas de red en modo monitor y que estaría bien que me currase un script que las detectara… Para ser exactos, el mensaje fue “A ver si se te ocurre algún script para detectar la presencia de tarjetas de red en modo monitor

Como las noches las solemos aprovechar para “investigar” a parte de leer vuestros mensajes de twitter, empecé a hacer pruebas para ver si se podía detectar con un script una tarjeta en modo promiscuo, más que nada porque una vez que alguien nos espeta algo como eso, no podemos dormir hasta que encontramos solución, y como yo creo que el resto de vosotros (también me preguntó un lector que para qué servía “enviar archivos mediante ping“… en fin)

Así que ni corto ni perezoso, raspberry por un lado y portátil con windows 10 y kali virtualizado por otro, manos a la obra a ver si podemos dar gusto a @CiberpoliES.

A las 4 de la madrugada del Lunes, ya tenía un script funcionando pero me faltaba que @CiberpoliES lo probase también, por aquello de comprobar que no sólo funciona en nuestro “laboratorio” y en “condiciones ideales” (y os aseguro que el entorno de @CiberpoliES no es el entorno ideal después de que tuviese que probar con 2 portátiles, la raspberry y no sé cuantas antenas porque a cada uno le falla algo jejejeje ;-D) Una vez probado y visto que funciona, aquí os lo presento (teniendo en cuenta los falsos positivos que comento en la nota informativa más adelante)

Pero… vayamos por partes. ¿Cómo se puede detectar una tarjeta en modo promiscuo en nuestra red? Primero veamos algo de teoría…

Las tarjetas de red en modo “normal” responden a 3 tipos de mensajes. El primer tipo son los mensajes que van dirigidos expresamente para ella (con su dirección mac), el segundo tipo son mensajes multicast para todos los dispositivos de la red o para el grupo de la tarjeta de red y el tercer tipo son los mensajes de Broadcast como por ejemplo ARP para solicitar la dirección mac de un equipo del que no se conoce (dirección FF:FF:FF:FF:FF:FF en la capa Ethernet y 00:00:00:00:00:00 en la capa ARP).

Es decir, la tarjeta de red en modo normal, sólo pasa paquetes al sistema operativo que cumplan una de esas tres condiciones: que sea para ella (su mac) o que sea multicast o broadcast y cumpla la condición del paquete (como tener su dirección ip en un paquete ARP solicitando su mac).

Por otra parte, analizando los distintos sistemas operativos y buscando información sobre el comportamiento de dichos sistemas ante este tipo de paquetes sabemos lo siguiente (es decir, cómo responde el sistema operativo al paquete, y no la tarjeta de red):

1.- La dirección multicast de todos los equipos de la red (01:00:5E:00:00:01) pasa la tarjeta de red en modo normal y promiscuo y es respondida por el sistema operativo tanto en Windows como en Linux.

2.- La direccion 0 multicast (01:00:5E:00:00:00) sólo pasa la tarjeta de red en modo promiscuo y sólo es respondida por Linux, no por Windows.

3.- La dirección multicast sólo con el bit de grupo activado (01:00:00:00:00:00) sólo pasa la tarjeta de red en modo promiscuo y sólo es respondida por Linux, no por Windows.

4.- La dirección de “falso” broadcast de 8 bits (FF:00:00:00:00:00) sólo pasa la tarjeta de red en modo promiscuo y es respondida por el sistema operativo en Windows 9X/ME y Linux.

5.- La direccion de “falso” broadcast de 16 bits (FF:FF:00:00:00:00) sólo pasa la tarjeta de red en modo promiscuo y es respondida por todos las versiones de Windows y Linux.

6.- La dirección de “falso” broadcast FF:FF:FF:FF:FF:FE sólo pasa la tarjeta de red en modo promiscuo y es respondida también por todas las versiones de Windows y Linux.

7.- La dirección de broadcast (verdadero broadcast) FF:FF:FF:FF:FF:FF pasa la tarjeta de red tanto en modo normal como modo promiscuo y es respondida por todos los sistemas operativos tanto Windows como Linux.

Es decir, tenemos que encontrar un paquete que enviado a los equipos sólo nos responda cuando esté en modo promiscuo, y que me permita aplicarlo a la mayoría de sistemas operativos.

Como podemos observar, el paquete idóneo es con la dirección de falso broadcast “FF:FF:FF:FF:FF:FE”, ya que si la tarjeta está en modo normal, será rechazado por no ser multicast, no ser broadcast “puro” ni ser la mac de la tarjeta, pero que si está en modo monitor será pasado al sistema operativo y nos responderá tanto Windows como Linux.

Manos a la obra. Os muestro 2 scripts.

El primero es la versión “rápida” de demostración. Sólo envío el paquete a toda la red con Scapy y pinto la mac e ip de los equipos que responden.

El segundo, es la versión completa. Permite elegir la interface de red a utilizar y detecta la red para hacer el bucle automáticamente a todos los equipos de dicha red, la puerta de enlace para descartar el router (ahora explico por qué), añadiendo el parámetro “-v” nos permite ver el paquete que va a enviar Scapy, etc…

Nota informativa: los script ejecutados en red cableada funcionan 100%, ya que todos los equipos que detectan están en modo monitor y el router es descartado por el script (ya que el “linux” que tiene dentro contesta también a ese tipo de paquetes dando un falso positivo). Si los ejecutamos en una red inalámbrica, aparecerán falsos positivos, como los teléfonos android que también contestan a todos los paquetes con el linux que llevan dentro…

Todavía no he encontrado una solución “fácil” para descartar los teléfonos android (ya he pensado en fabricante por la mac, fingerprints de so con p0f (igual que lo hace nmap), etc…) así que se aceptan sugerencias, teniendo en cuenta que no me gustaría usar más “aplicaciones de terceros” y no me gustaría salirme de módulos de python a poder ser…

Y dicho ésto, aquí están los script. No seáis malos con mi python, que ya sabéis que soy principiante en dicho lenguaje.

Sois libres de copiar, usar, modificar, distribuir… sólo me gustaría ir sabiendo las mejoras que le vais introduciendo al script.

Un saludo y hasta la próxima.

rapido.py

import sys
from scapy.all import *

conf.verb=0
ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:fe")/ARP(pdst="192.168.1.0/24"),timeout=2)

for snd,rcv in ans:
	print rcv.sprintf(r"%Ether.src% & %ARP.psrc%\\")

completo.py

import sys
from scapy.all import *

def get_mac_address(interf):
	my_macs = [get_if_hwaddr(interf)]
	for mac in my_macs:
		if(mac != "00:00:00:00:00:00"):
			return mac

def get_ip_address(interf):
	my_ips = [get_if_addr(interf)]
	for ip in my_ips:
		if(ip != "0.0.0.0"):
			return ip

def get_def_route(interf):
	data = os.popen("/sbin/route -n ").readlines()
	for line in data:
		if line.startswith("0.0.0.0") and (interf in line):
			return line.split()[1]

Timeout=2

if len(sys.argv)<2 or len(sys.argv)>3:
	print "Uso: prueba.py interface [-v]"
	sys.exit(1)
elif len(sys.argv)==3 and sys.argv[2]!="-v":
	print "Uso: prueba.py interface [-v]"
	sys.exit(1)
else:
	print "Interface seleccionado: " + sys.argv[1]
	my_mac = get_mac_address(sys.argv[1])
	my_ip = get_ip_address(sys.argv[1])
	octetos = my_ip.split(".")
	my_net = octetos[0] + "." + octetos[1] + "." + octetos[2] + ".0/24"
	my_gw = get_def_route(sys.argv[1])

if not my_mac:
	print "Error obteniendo MAC"
	sys.exit(1)
else:
	print "MAC Interface " + sys.argv[1] + ": " + my_mac

if not my_ip:
	print "Error obteniendo IP"
	sys.exit(1)
else:
	print "IP Interface " + sys.argv[1] + ": " + my_ip
	print "Red a Escanear: " + my_net
	print "Default Gateway para interface " + sys.argv[1] + ": " + my_gw

conf.verb=0

packet = Ether(dst="FF:FF:FF:FF:FF:FE",src=my_mac)/ARP(op=1,hwdst="00:00:00:00:00:00",hwsrc=my_mac,psrc=my_ip,pdst=my_net)

if len(sys.argv)==3 and sys.argv[2]=="-v":
	print "Mostrando Composicion del Paquete:"
	packet.show()

ans,unans=srp(packet,timeout=2)

print ""
print "Mostrando POSIBLES Modo Monitor en la Red:"
print ""

for snd,rcv in ans:
	if rcv.psrc!=my_gw:
		print rcv.sprintf(r"%Ether.src% & %ARP.psrc%")

WordPress 4.4 y Latch

Buenas noches.

Tras actualizar WordPress a la última versión (4.4) y si tenéis instalado Latch como medida de seguridad en vuestro blog, os habréis encontrado con un bonito error 500 como yo.

También puede ser que os aparezca el error por cualquier otro plugin que no sea compatible con la nueva versión.

No hay que asustarse.

1.- Conectamos por ssh al servidor o el método que prefiráis.

2.- Accedemos a la carpeta de WordPress “wp-content” y renombramos la carpeta “plugins” a otro nombre.

3.- Accedemos a WordPress y comprobamos que todo vuelve a la normalidad.

4.- Volvemos a renombrar la carpeta como “plugins” y desde el panel de administración veremos todos los plugins como desactivados.

5.- Vamos activando uno a uno los plugins comprobando cada vez que activamos uno que el sitio sigue funcionando.

6.- Así localizamos el que ha dado el error (en mi caso Latch).

7.- Lo dejamos desactivado a la espera de la actualización pertinente.

Un saludo.

Soluciones Tecnológicas

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR