Hacking de Redes UPnP - Parte III

Hacking de Redes UPnP - Universal Plug-N-Play

=======================
Hacking de Redes UPnP - Parte I
Hacking de Redes UPnP - Parte II
Hacking de Redes UPnP - Parte III
=======================

Continúa desde “Hacking de Redes UPnP - Parte II

Una Introducción a Miranda

Miranda es una herramienta de administración de UPnP escrita en Python. Lleva consigo una línea de comandos que soporta autocompletado e historial de comandos, y provee la habilidad de guardar tu trabajo en un archivo que puede ser recargado para su posterior análisis. También puedes alterar las configuraciones del programa sobre la marcha, y registrar todos tus comandos en un archivo log, de manera que puedas saber exactamente lo que ejecutaste y cuando lo ejecutaste.

Miranda puede descubrir hosts UPnP tanto activamente como pasivamente, y con un simple comando pueden ser enumerados todos los tipos de dispositivos, servicios, acciones y variables. Las variables de estado del servicio pueden ser automáticamente correlacionadas con sus acciones asociadas, e identificadas tanto sus variables de salida y/o entrada para cada acción. Miranda almacena la información de todos los hosts en una estructura única de datos y te permite desplegar directamente toda la información y ver su contenido.

Finalmente, puedes ejecutar cualquier acción soportada por el host UPnP; si la acción requiere algún valor de entrada, se te informará su nombre y su tipo (string, 4 byte entero, 2 byte entero, etc), así como los valores permitidos o rangos de valores que el host UPnP ha suplido, y se le pedirá que ingrese el valor.

Descubriendo hosts UPnP con Miranda

Cuando inicias Miranda por primer vez, te llevará a una shell interactiva con un prompt 'upnp>' a la espera de ejecución de comandos. La primera cosa que probablemente quieras hacer es descubrir si hay algún host UPnP en tu red; esto puede ser realizado con los comandos 'pcap' o 'msearch'. Cuando es ejecutado el comando 'pcap', Miranda se pondrá en escucha (modo pasivo) buscando mensajes SSDP NOTIFY, mientras que el comando 'msearch' consultará los dispositivos UPnP usando un mensaje M-SEARCH. Por defecto, 'msearch' buscará todos los dispositivos UPnP, pero también se le puede especificar que busque un determinado tipo de dispositivo o servicio si así se desea. En este ejemplo, simplemente buscaremos algún dispositivo:

Código:
upnp> msearch

Entering discovery mode for 'upnp:rootdevice', Ctl+C to stop...

****************************************************************
SSDP reply message from 192.168.0.1:5678
XML file is located at http://192.168.0.1:5678/igd.xml
Device is running Embedded UPnP/1.0
***************************************************************

Discover mode halted...

Aquí podemos ver que hay un host UPnP en la red, el cual resulta ser un router DI-524. También podemos ver que es reportado el tipo de servidor UPnP ('Embedded UPnP/1.0¿), y la ubicación del archivo XML raíz.

Ejecutando el comando 'host list' nos muestra la lista de todos los hosts UPnP descubiertos y el número índice de cada uno (el número índice es usado en comandos subsecuentes para hacer referencia a un host específico):

Código:
upnp> host list

       [0] 192.168.0.1:5678

Hemos descubierto un host UPnP, ahora necesitamos enumerar sus capacidades. Ejecutando el comando 'host get 0' obtendremos toda la información UPnP del host con el índice 0:

Código:
upnp> host get 0

Requesting device and service info for 192.168.0.1:5678 (this could take a few seconds)...

Host data enumeration complete!

Ahora buscamos en todos los datos que hemos recogido de este host usando el comando 'host info'. Este comando nos permite desplegar los datos del host interno de Miranda y ver la información que este almacena. Observa también que todos estos comandos se autocompletaran automáticamente, de manera que no tendrás que escribirlos por completo:

Código:
upnp> host info 0

xmlFile : http://192.168.0.1:5678/igd.xml
name : 192.168.0.1:5678
proto : http://
serverType : Embedded HTTP Server 3.23
upnpServer : Embedded UPnP/1.0
dataComplete : True
deviceList : {}
Código:
upnp> host info 0 deviceList

InternetGatewayDevice : {}
WANDevice : {}
WANConnectionDevice : {}
Código:
upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection actions

AddPortMapping : {}
GetNATRSIPStatus : {}
GetGenericPortMappingEntry : {}
GetSpecificPortMappingEntry : {}
ForceTermination : {}
GetExternalIPAddress : {}
GetConnectionTypeInfo : {}
GetStatusInfo : {}
SetConnectionType : {}
DeletePortMapping : {}
RequestConnection : {}

Dependiendo del host, puede haber muchos datos en esta estructura, así que si quieres ver el resumen de los datos para un host particular, ejecuta el comando 'host summary':

Código:
upnp> host summary 0

Host: 192.168.0.1:5678
XML File: http://192.168.0.1:5678/igd.xml
InternetGatewayDevice
     manufacturerURL: http://www.dlink.com
     modelName: D-Link Router
     UPC: 123456789001
     modelNumber: None
     presentationURL: http://192.168.0.1:80
     friendlyName: D-Link Router
     fullName: urn:schemas-upnp-org:device:InternetGatewayDevice:1
     modelDescription: Internet Access Router
     UDN: uuid:upnp-InternetGatewayDevice-1_0-12345678900001
     modelURL: None
     manufacturer: D-Link
WANDevice
     manufacturerURL: http://www.dlink.com
     modelName: D-Link Router
     UPC: 123456789001
     modelNumber: 1
     presentationURL: None
     friendlyName: WANDevice
     fullName: urn:schemas-upnp-org:device:WANDevice:1
     modelDescription: Internet Access Router
     UDN: uuid:upnp-WANDevice-1_0-12345678900001
     modelURL: http://support.dlink.com
     manufacturer: D-Link
WANConnectionDevice
     manufacturerURL: http://www.dlink.com
     modelName: D-Link Router
     UPC: 123456789001
     modelNumber: 1
     presentationURL: None
     friendlyName: WAN Connection Device
     fullName: urn:schemas-upnp-org:device:WANConnectionDevice:1
     modelDescription: Internet Access Router
     UDN: uuid:upnp-WANConnectionDevice-1_0-12345678900001
     modelURL: http://support.dlink.com
     manufacturer: D-Link

El comando de resumen nos muestra todos los tipos de dispositivos que este host reporta, así como algún dato adicional relacionado con cada tipo de dispositivo. Si quieres ver toda la información que miranda almacena sobre un host en particular, lo puedes hacer con el comando 'host details 0'. Sin embargo, la información arrojada por este comando es por lo general bastante larga, probablemente quieras guardarla en un archivo y verla en un editor de texto; esto puede ser hecho con el comando 'save info 0':

Código:
upnp> save info 0 dl524

Host info for '192.168.0.1:5678' saved to 'info_dl524.mir'

El argumento 'dl524' es opcional; si ninguna cadena es pasada como argumento, se usará entonces el número índice en su lugar. Mientras que estemos en la sesión, también podemos guardar los datos que Miranda ha almacenado sobre todos los hosts que han sido descubiertos, de modo que después podamos cargarlos de nuevo e iniciar una nueva sesión:

Código:
upnp> save data session1

Host data saved to 'struct_session1.mir'

Enviado comandos UPnP con Miranda

Ahora vamos a explorar algunas de las acciones que podemos ejecutar en este dispositivo. Anteriormente cuando ejecutamos el comando 'host info', listamos todas las acciones disponibles para el servicio WANIPConnection que está asociado con el dispositivo WANConnectionDevice; veámoslas de nuevo:

Código:
upnp> host info 0 deviceList WANConnectionDevice services WANIPConnection actions

AddPortMapping : {}
GetNATRSIPStatus : {}
GetGenericPortMappingEntry : {}
GetSpecificPortMappingEntry : {}
ForceTermination : {}
GetExternalIPAddress : {}
GetConnectionTypeInfo : {}
GetStatusInfo : {}
SetConnectionType : {}
DeletePortMapping : {}
RequestConnection : {}

Como puedes ver, este servicio es el que soporta las acciones AddPortMapping y DeletePortMapping, así como algunas otras que parecen interesantes. Primero intentaremos ejecutar la acción GetExternalIPAddress; esto se puede hacer con el comando 'host send'. Para ejecutar un comando, debes indicar el número índice del host, el nombre del tipo de dispositivo que soporta el servicio, el nombre del servicio que soporta la acción, y el nombre de la acción que quieras ejecutar (de nuevo, todos estos campos se autocompletan, no es mas que escribir mientras se va mirando)

Código:
upnp> host send 0 WANConnectionDevice WANIPConnection GetExternalIPAddress

NewExternalIPAddress : 68.12.34.56

'NewExternalIPAddres' es el nombre de la variable asociada con esta acción, y '68.12.34.56' es el valor devuelto para esa variable por el IGD. Algunas acciónes tienen varias variables asociadas con ellas; estas variables pueden ser tanto de entrada (valores que le pasamos al IGS) o de salida (valores devueltos por el IGD). En el caso de la acción GetExternalIPAddress, solo hay una variable de salida. Sin embargo, si hay alguna variable de entrada disponible para una acción, Mirando nos pedirá que introduzcamos estos valores antes de enviar la acción. Toda la información de la variable puede ser enumerada/vista usando los comandos 'host info' o 'host details. No tenemos que tener ningún conocimiento sobre estas variables antes de ejecutar las acciones UPnP.

Intentemos mapeando el puerto 8080 en la WAN para abrir la interfaz administrativa que está en el puerto 80 del IGD (192.168.0.1):

Código:
upnp> host send 0 WANConnectionDevice WANIPConnection AddPortMapping

Required argument:
     Argument Name:  NewPortMappingDescription
     Data Type:      string
     Allowed Values: []
     Set NewPortMappingDescription value to: All your ports are belong to us

Required argument:
     Argument Name:  NewLeaseDuration
     Data Type:      ui4
     Allowed Values: []
     Set NewLeaseDuration value to: 0

Required argument:
     Argument Name:  NewInternalClient
     Data Type:      string
     Allowed Values: []
     Set NewInternalClient value to: 192.168.0.1

Required argument:
     Argument Name:  NewEnabled
     Data Type:      boolean
     Allowed Values: []
     Set NewEnabled value to: 1

Required argument:
     Argument Name:  NewExternalPort
     Data Type:      ui2
     Allowed Values: []
     Set NewExternalPort value to: 8080

Required argument:
     Argument Name:  NewRemoteHost
     Data Type:      string
     Allowed Values: []
     Set NewRemoteHost value to:

Required argument:
     Argument Name:  NewProtocol
     Data Type:      string
     Allowed Values: ['TCP', 'UDP']
     Set NewProtocol value to: TCP

Required argument:
     Argument Name:  NewInternalPort
     Data Type:      ui2
     Allowed Values: []
     Set NewInternalPort value to: 80

La acción AddPortMapping recibe varios valores, pero hay unos puntos importantes que deben ser mencionados:

1. Los valores Booleanos son '1' (verdadero) o '0' (falso)
2. El argumento NewProtocol solo permite dos valores, 'TCP' o 'UDP'
3. No especificamos ningún valor para la variable NewRemoteHost, la cual permite que todos los hosts remotos coincidan con esta asignación de puertos.

No recibimos ningún dato porque la acción AddPortMapping no tiene ninguna variable de salida definida (de nuevo, toda esta información es almacenada en la estructura de datos, si tienes curiosidad). Sin embargo, podemos verificar que la acción fue ejecutada exitosamente lanzando la acción GetSpecificPortMappingEntry:

Código:
upnp> host send 0 WANConnectionDevice WANIPConnection GetSpecificPortMappingEntry

Required argument:
     Argument Name:  NewExternalPort
     Data Type:      ui2
     Allowed Values: []
      Set NewExternalPort value to: 8080

Required argument:
     Argument Name:  NewRemoteHost
     Data Type:      string
     Allowed Values: []
     Set NewRemoteHost value to:

Required argument:
     Argument Name:  NewProtocol
     Data Type:      string
     Allowed Values: ['TCP', 'UDP']
     Set NewProtocol value to: TCP

NewPortMappingDescription : All your ports are belong to us
NewLeaseDuration : 0
NewInternalClient : 192.168.0.1
NewEnabled : 1
NewInternalPort : 80

AHora podemos borrar el puerto mapeado con la acción DeletePortMapping. Igual que AddPortMapping, la acción DeletePortMapping no devuelve ningún dato a menos que haya ocurrido un error:

Código:
upnp> host send 0 WANConnectionDevice WANIPConnection DeletePortMapping

Required argument:
     Argument Name:  NewProtocol
     Data Type:      string
     Allowed Values: ['TCP', 'UDP']
     Set NewProtocol value to: TCP

Required argument:
     Argument Name:  NewExternalPort
     Data Type:      ui2
     Allowed Values: []
     Set NewExternalPort value to: 8080

Required argument:
     Argument Name:  NewRemoteHost
     Data Type:      string
     Allowed Values: []
     Set NewRemoteHost value to:

Hay una gran multitud de otras acciones interesantes, como por ejemplo ForceTermination, la cual provoca la caída de la conexión WAN del router. Vale la pena explorar los varios servicios y acciones para cada dispositivo que estés auditando.

Conclusión

Si bien, UPnP es un protocolo que pocos entienden, está activo en una vasta mayoría de redes caseras, e incluso también en algunas redes corporativas. Muchos dispositivos soportan UPnP en orden de facilitar el uso para los consumidores, sin embargo, a menudo soportan acciones que ningún servicio debería de estar posibilitado de ejecutar automáticamente, y especialmente sin ninguna autorización. Peor aún, la implementación del protocolo en sí rara vez es construido con una mentalidad prioritaria en la seguridad, dejándolo abierto a futuros ataques.

La mejor defensa contra los ataques UPnP tanto locales como remotos es simplemente deshabilitarlo en algunos/todos los dispositivos de la red. Sin embargo, considerando que este protocolo y otros protocolos "auto-magicos" son diseñados para ayudar a Joe, quien probablemente esté inadvertido de los peligros de tales protocolos, la única verdadera solución es que los vendedores sean mas atentos en sus diseños, y sus implementaciones, mas seguras.

=======================
Hacking de Redes UPnP - Parte I
Hacking de Redes UPnP - Parte II
Hacking de Redes UPnP - Parte III
=======================

Tercera y Ultima parte del articulo Plug-N-Play Network Hacking traducido por Cortex en nuestra seccion Traducción de Artículos de La Comunidad.

Subir