studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones android discovery service-discovery

programacion - ¿Alguna forma de descubrir dispositivos Android en tu red?



manual de programacion android pdf (7)

Quiero poder descubrir dispositivos Android en mi red y, posiblemente, recuperar información del dispositivo sobre ellos. Esto es muy fácil con los dispositivos de Apple, ya que ejecutan los servicios de Bonjour. Sin embargo, parece que no puedo encontrar ningún servicio similar ejecutándose en Android.

Esto debe funcionar sin modificar el dispositivo Android, instalar algún servicio o abrir algún puerto. Está pensado para funcionar con dispositivos Android de vainilla de la manera en que Bonjour lo ayuda a encontrar dispositivos Apple de vainilla. Incluso poder solo verificar que el dispositivo funciona con Android sería suficiente.

Respuesta elegida : aunque no es la respuesta mejor calificada (todavía), por favor, eche un vistazo a la respuesta de Luis. Como él menciona, puede usar una búsqueda de DNS (usando su servidor DNS local) para descubrir dispositivos Android. Descubrí que esto tiene una tasa de éxito del 100%, ya que Android obliga a los dispositivos a usar un nombre de host de Android _ ____ . Aparentemente, esto es difícil de cambiar en el teléfono, incluso si está rooteado. Así que creo que este es un método bastante preciso. Gracias luis

Example: $ nslookup 192.168.1.104 192.168.1.1 Server: 192.168.1.1 Address: 192.168.1.1#53 104.1.168.192.in-addr.arpa name = android-711c129e251f14cf./001.

Código de muestra: si desea implementar esto en Java (por ejemplo, para ejecutar en Android), no puede usar fácilmente GetHostName () porque usa los servidores DNS externos. Desea utilizar el servidor DNS local en su enrutador, por ejemplo. Luis menciona a continuación que podría modificar los servidores DNS de la conexión Wifi, pero eso podría romper otras cosas. En cambio, he encontrado que la biblioteca dnsjava es extremadamente útil para enviar solicitudes de DNS dirigidas. Aquí hay un código de ejemplo usando la biblioteca:

String ipAddress = "104.1.168.192"; String dnsblDomain = "in-addr.arpa"; Record[] records; Lookup lookup = new Lookup(ipAddress + "." + dnsblDomain, Type.PTR); SimpleResolver resolver = new SimpleResolver(); resolver.setAddress(InetAddress.getByName("192.168.1.1")); lookup.setResolver(resolver); records = lookup.run(); if(lookup.getResult() == Lookup.SUCCESSFUL) { for (int i = 0; i < records.length; i++) { if(records[i] instanceof PTRRecord) { PTRRecord ptr = (PTRRecord) records[i]; System.out.println("DNS Record: " + records[0].rdataToString()); } } } else { System.out.println("Failed lookup"); } } catch(Exception e) { System.out.println("Exception: " + e); }

Esto me da la salida:

DNS Record: android-711c129e251f14cf./001.

Bingo.


AFAIK, el sistema Android no proporciona ninguna aplicación / servicio zeroconf en su pila integrada de aplicaciones / servicios del sistema. Para habilitar la detección automática en el dispositivo real conectado a la red local, necesita instalar alguna aplicación zeroconf de terceros o desarrollar su propia aplicación / servicio e instalarla en el dispositivo real, algunas opciones de API son:

  • JmDNS (para el protocolo bonjour de Apple)
  • Cling (para el protocolo UPnP de Microsoft)
  • Android NSD API (introducido desde Android 4.1)

No tengo muy claro cuáles son sus requisitos. Si desea algo similar (es decir, auto descubrimiento y conexión) en los dispositivos Android de vainilla, probablemente pueda usar el Wi-Fi directo, que ahora está disponible en algún dispositivo posterior con Android 4.0, sin embargo, requiere ambos dispositivos son compatibles con Wi-Fi Direct y solo crean una conexión P2P ad-hoc con Wi-Fi apagado, como una conexión Bluetooth con un alcance más largo:

Para obtener soporte de la API de Wi-Fi Direct, consulte la guía oficial - Conexión de dispositivos de forma inalámbrica .


Android no va a ser tan fácil como iOS. No hay un equivalente de Bonjour.

Android 4.0, Ice Cream Sandwich, introdujo redes Wi-Fi Direct Peer to Peer. Al principio, esperaba que pudiera ser escaneado de la manera que piensa, pero ayuda a que los dispositivos Android se comuniquen sin un punto de acceso, por lo que realmente no están "en su red". Además, ICS se ejecuta en solo una fracción de los dispositivos Android.

En lugar de un enfoque de netscan activo, te queda un enfoque de monitoreo pasivo. Si su red es segura, es posible, pero inconveniente, detectar el paquete cifrado. Tendrás que

  • ponga su interfaz de red en modo monitor
  • capturar el apretón de manos de 4 vías
  • descifrarlo usando la clave precompartida de la red
  • Esto te dará la clave que necesitas para descifrar el tráfico.

Si desea ver esto en acción, Wireshark admite el descifrado WPA .

Una vez que pueda ver el tráfico de Wi-Fi, notará que los dispositivos Android tienden a comunicarse con ciertos servidores de Google y sus conexiones HTTP tienen cadenas de agente de usuario que pueden identificarse . Esta es la base para una solución pasiva viable.

Tenable Network Security ofrece productos que parecen adoptar este tipo de enfoque.

Otra idea

@Michelle Cannon mencionó el Meshlium Xtreme de Libelium, cuyo enfoque no lo llevará hasta el final (no sin las buenas tablas de rango de direcciones MAC actualizadas). Pero podría ser parte de alcanzar una meta menor. Usted puede:

  • Detecta todos los dispositivos inalámbricos.
  • Elimine los dispositivos de Apple utilizando el identificador único organizacional (OUI) de MAC
  • Diga que es un dispositivo móvil al monitorear la intensidad de la señal para determinar si se está moviendo (y los dispositivos móviles tenderán a aparecer y desaparecer)
  • Es posible que pueda usar el OUI de MAC como una sugerencia de que es Android
  • Es posible que pueda usar el MAC OUI como una indicación de que no es Android (sino una computadora portátil o una tarjeta inalámbrica, etc.).

Esto puede ser viable si está dispuesto a detectar dispositivos que probablemente sean Android.

Huella dactilar DHCP

@Michelle Cannon sugirió la toma de huellas dactilares DHCP. Al principio no estaba seguro, pero tengo que agradecerle por sugerir lo que parece ser la mejor apuesta para un simple escaneo pasivo. Como una cola de advertencia, me gustaría explicar por qué llegué tarde a la fiesta.

Hay cosas que sabemos, pensamos que no sabemos y cosas que creemos que sabemos pero estamos mal.

En muchos sentidos, es bueno que Android use el kernel de Linux. Pero no es bueno si quieres descubrir dispositivos Android en tu red. La pila TCP / IP de Android es la de Linux, por lo que los dispositivos con Android se verán como dispositivos Linux o eso pensé al principio. Pero luego me di cuenta de que Linux tiene muchos parámetros de configuración de construcción, por lo que podría haber algo distintivo en Android cuando se ve en una red, ¿pero qué?

La toma de huellas dactilares de DHCP utiliza las opciones exactas de DHCP solicitadas por el dispositivo más el tiempo. Para que esto funcione, generalmente se necesita una base de datos actualizada de huellas dactilares para comparar. Al principio, parecía que el fingerbank estaba fingerbank esta información, pero luego noté que sus archivos no se habían actualizado durante casi un año. Con todos los diferentes tipos de dispositivos Android, no creo que sea práctico mantener las huellas digitales actualizadas para un solo proyecto.

Pero luego miré las firmas DHCP reales para Android y noté esto:

Android 1.0: dhcpvendorcode=dhcpcd 4.0.0-beta9 Android 1.5-2.1: dhcpvendorcode=dhcpcd 4.0.1 Android 2.2: dhcpvendorcode=dhcpcd 4.0.15 Android 3.0: dhcpvendorcode=dhcpcd-5.2.10

Linux normalmente usa dhclient como su cliente DHCP, pero Android está usando dhcpcd. Android tiene una fuerte preferencia por usar software con licencia del estilo BSD siempre que sea posible y dhcpcd usa una licencia BSD. Parece que dhcpvendorcode podría usarse como un indicador sólido de que un dispositivo móvil está ejecutando Android.

Monitoreo DHCP

Un cliente utiliza DHCP para obtener una dirección IP cuando se une a una red, por lo que se inicia sin una dirección IP. Resuelve este problema utilizando difusiones UDP para el intercambio inicial. En Wi-Fi, incluso con WPA, el tráfico de transmisión no está cifrado. Así que solo puede escuchar en el puerto UDP 67 para el tráfico de cliente a servidor y 68 para el reverso. Ni siquiera necesita poner su interfaz de red en modo promiscuo. Puede controlar fácilmente este tráfico utilizando un analizador de protocolo como Wireshark.

Preferí escribir código para monitorear el tráfico y decidí usar Python. Seleccioné pydhcplib para manejar los detalles de DHCP. Mi experiencia con esta biblioteca no fue fluida. Necesitaba descargar y colocar manualmente los archivos de soporte IN.py y TYPES.py. Y su conversión de paquete a cadena estaba dejando el dhcpvendorcode en blanco. Analizó correctamente los paquetes DHCP, así que escribí mi propio código de impresión.

Aquí hay un código que monitorea el tráfico DHCP de cliente a servidor:

#!/usr/bin/python from pydhcplib.dhcp_packet import * from pydhcplib.dhcp_network import * from pydhcplib.dhcp_constants import * netopt = { ''client_listen_port'':"68", ''server_listen_port'':"67", ''listen_address'':"0.0.0.0" } class Server(DhcpServer): def __init__(self, options): DhcpServer.__init__( self,options["listen_address"], options["client_listen_port"], options["server_listen_port"]) def PrintOptions(self, packet, options=[''vendor_class'', ''host_name'', ''chaddr'']): # uncomment next line to print full details # print packet.str() for option in options: # chaddr is not really and option, it''s in the fixed header if option == ''chaddr'': begin = DhcpFields[option][0] end = begin+6 opdata = packet.packet_data[begin:end] hex = [''0'',''1'',''2'',''3'',''4'',''5'',''6'',''7'',''8'',''9'',''a'',''b'',''c'',''d'',''e'',''f''] print option+'':'', '':''.join([(hex[i/16]+hex[i%16]) for i in opdata]) else: opdata = packet.options_data.get(option) if opdata: print option+'':'', ''''.join([chr(i) for i in opdata if i != 0]) print def HandleDhcpDiscover(self, packet): print "DHCP DISCOVER" self.PrintOptions(packet) def HandleDhcpRequest(self, packet): print "DHCP REQUEST" self.PrintOptions(packet) ## def HandleDhcpDecline(self, packet): ## self.PrintOptions(packet) ## def HandleDhcpRelease(self, packet): ## self.PrintOptions(packet) ## def HandleDhcpInform(self, packet): ## self.PrintOptions(packet) server = Server(netopt) while True : server.GetNextDhcpPacket()

Este código se basa en el ejemplo del servidor de pydhcplib porque escucha las solicitudes de los clientes, como un servidor.

Cuando mi tableta Nexus 7 Android 4.2 se conecta, esta interesante información se captura (elimina):

DHCP REQUEST vendor_class: dhcpcd-5.5.6 host_name: android-5c1b97cdffffffff chaddr: 10:bf:48:ff:ff:ff DHCP DISCOVER vendor_class: dhcpcd-5.5.6 host_name: android-5c1b97cdffffffff chaddr: 10:bf:48:ff:ff:ff

El nombre del host parece tener un formato fijo y se puede analizar fácilmente. Si necesita la dirección IP, puede supervisar el servidor al tráfico del cliente. Nota: solo se transmite el intercambio inicial, cuando un nuevo cliente aparece por primera vez sin una dirección IP. Las futuras extensiones de arrendamiento, etc., no se transmiten.

Búsqueda de DNS inversa

@Luis publicó una gran solución que demuestra cuán simple es mejor. Incluso después de ver que el cliente DHCP de Android estaba configurando host_name para android-5c1b97cdffffffff, no pensé en preguntarle al enrutador por su lista de nombres usando búsquedas DNS inversas. El enrutador agrega el nombre de host a su servidor DNS para que aún pueda acceder al dispositivo si cambia su dirección IP.

Se espera que el nombre de host permanezca listado en el DNS durante la duración de la concesión DHCP. Puede verificar si el dispositivo todavía está presente haciendo pinging mismo.

Un inconveniente para depender de host_name es que hay formas en que esto podría cambiarse. Es fácil para el fabricante del dispositivo o el proveedor cambiar el nombre de host (aunque después de buscar, no he podido encontrar ninguna evidencia que tengan). Hay aplicaciones para cambiar el nombre del host , pero requieren root, por lo que es, a lo sumo, un caso de ventaja.

Finalmente, hay un problema abierto de code.google.com/p/android/issues/detail?id=6111 que actualmente tiene 629 estrellas. No sería sorprendente ver el nombre de host configurable en la configuración de Android en algún momento en el futuro, tal vez pronto. Entonces, si empiezas a depender de host_name para identificar los dispositivos Android, te darás cuenta de que podría ser eliminado de debajo de ti.

Si está realizando un seguimiento en vivo, otro problema potencial con la búsqueda inversa de DNS es que debe decidir con qué frecuencia escanear. (Por supuesto, esto no es un problema si solo está tomando una instantánea por única vez). El escaneo frecuente consume recursos de la red, lo que no es frecuente lo deja con datos obsoletos. Aquí es cómo puede ayudar agregar monitoreo DHCP:

  • En el inicio, use la búsqueda inversa de DNS para encontrar dispositivos
  • Haga ping a los dispositivos para ver si todavía están activos.
  • Monitorea el tráfico DHCP para detectar nuevos dispositivos al instante
  • Ocasionalmente, vuelva a ejecutar la Búsqueda de DNS para encontrar dispositivos que pueda haber perdido
  • Si necesita notar que los dispositivos se están yendo, haga ping a los dispositivos a la resolución de tiempo deseada

Si bien no es fácil (ni es 100% preciso), existen varias técnicas que permiten descubrir dispositivos Android en su red.


Aquí hay una línea que hace ping a todas las máquinas en su red (asumiendo que su red es 192.168.1.x ) y realiza una búsqueda inversa de sus nombres:

for i in {1..255}; do echo ping -t 4 192.168.1.${i} ; done | parallel -j 0 --no-notice 2> /dev/null | awk ''/ttl/ { print $4 }'' | sort | uniq | sed ''s/://'' | xargs -n 1 host

Requiere GNU paralelo para trabajar. Puedes instalarlo en OSX usando "brew install parallel"

De esto solo puede mirar los dispositivos llamados android-c40a2b8027d663dd.home. o lo que sea.

Luego puede intentar ejecutar nmap -O en un dispositivo para ver qué más puede averiguar:

sudo nmap -O android-297e7f9fccaa5b5f.home.

Pero no es realmente tan fructífera.


Estoy aprendiendo mucho de este tema.

También hay algo que se llama dhcp fingerprinting, aparentemente, diferentes dispositivos actúan de manera diferente al tipo de escaneo de red que hemos estado analizando, como los que usan NMAP en un escáner de Linux. Los mapas del comportamiento de estas sondas están disponibles en Internet.

http://www.enterasys.com/company/literature/device-profiling-sab.pdf

https://media.defcon.org/dc-19/presentations/Bilodeau/DEFCON-19-Bilodeau-FingerBank.pdf

http://community.arubanetworks.com/t5/ArubaOS-and-Mobility-Controllers/COTD-DHCP-Fingerprinting-how-to-ArubaOS-6-0-1-0-and-above/td-p/11164

http://myweb.cableone.net/xnih/


Estoy mirando esto un pensamiento

http://www.libelium.com/smartphones_iphone_android_detection

prestar especial atención a esto

¿Los usuarios necesitan tener una aplicación específica instalada o interactuar de alguna manera para ser detectados?

No, el escaneo se realiza de manera silenciosa, Meshlium solo detecta los "marcos de baliza" originados por las radios Wifi y Bluetooth integradas en los teléfonos inteligentes. Los usuarios solo necesitan tener activada al menos una de las dos interfaces inalámbricas.

Hace mucho tiempo solía usar una aplicación llamada stumbler en mi mac para encontrar redes wifi, creo que esto es similar

Otras ideas

Bueno, si tengo que determinar los teléfonos Android en una red local, ¿cómo lo haría? A falta de un servicio de dns en ejecución solo tengo un par de posibilidades

El SSID si se está transmitiendo, no puede decirme nada. La dirección ip - android le permite tener un gran control sobre los nombres de host, así que supongo que podría definir un rango de ip específico para sus dispositivos Android. -no muy útil.

Alternativamente, digamos que veo un dispositivo desconocido en la red, si el Bluetooth está activado, entonces estoy transmitiendo un SDPP con la firma del dispositivo Bluetooth que puedo usar para deducir mi tipo de dispositivo.

Si estuviera ejecutando un servicio compatible con Android y quisiera descubrir dispositivos Android específicos en mi red, podría registrar las direcciones mac de esos dispositivos y observarlos en la red.

Aparte de eso, deberías ejecutar un bonjour (dns-sd) o upnpp dameon en el dispositivo.


Hay un enfoque muy simple que me dio resultados positivos en pocos dispositivos diferentes.

Cuando un dispositivo se conecta a su enrutador, recibe una IP (es decir, DHCP) y registra un nombre en el DNS. El nombre que se registra parece estar siempre en la forma android_nnnnnnnn .

Por supuesto, puede nombrar cualquier computadora con el mismo enfoque y realizar el chequeo, dando como resultado falsos positivos ...

Además, no puedo asegurar que todos los proveedores de dispositivos sigan el mismo enfoque, pero he encontrado que funciona correctamente en algunos dispositivos de diferentes marcas (incluidos diferentes niveles de SDK) que he probado.

--EDITADO--

Cómo hacerlo

Depende de dónde esté ejecutando el código para descubrir los dispositivos Android. Suponiendo que estaría ejecutando el código en un dispositivo Android:

  1. Primero descubre los dispositivos que responden a Ping en tu red. Puede usar el código en mi respuesta a esta publicación: execComd() para ejecutar un comando ping.
  2. Obtenga el nombre de los dispositivos que respondieron usando el código:

    InetAddress inetAddress = InetAddress.getByName (string_with_ip_addr);

    Nombre de cadena = inetAddress.getCanonicalHostName ();

--EDIT 2--

Prueba de concepto

El método a continuación es solo un concepto de lo que he escrito anteriormente.

Estoy usando el método isReachable() para generar la solicitud ICMP, que se dice en muchas publicaciones que solo funcionan con dispositivos rooteados, como es el caso del dispositivo utilizado para probarlo. Sin embargo, no le di permisos de root a la aplicación que ejecuta este código, por lo que creo que no pudo establecer el bit SIUD, que es la razón por la que algunos dicen que este método falla. Me gustaría que alguien lo probara en un dispositivo no rooteado.

Para llamar a utilizar:

ArrayList<String> hosts = scanSubNet("192.168.1.");

Devuelve en los hosts una lista de nombres para los dispositivos que responden a la solicitud de ping.

private ArrayList<String> scanSubNet(String subnet){ ArrayList<String> hosts = new ArrayList<String>(); InetAddress inetAddress = null; for(int i=1; i<10; i++){ Log.d(TAG, "Trying: " + subnet + String.valueOf(i)); try { inetAddress = InetAddress.getByName(subnet + String.valueOf(i)); if(inetAddress.isReachable(1000)){ hosts.add(inetAddress.getHostName()); Log.d(TAG, inetAddress.getHostName()); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return hosts; }

Saludos.


Respuesta actualizada

Lo siento, no he entendido la pregunta original correctamente. Solo su comentario me dejó muy claro que no desea tener que instalar nada en los dispositivos de destino, sino que solo desea una forma de descubrir teléfonos aleatorios en su red.

No estoy seguro de si esto sería realmente posible de la manera que lo deseas. Sin tener ningún servicio de detección de redes ejecutándose en Android, no encontrará el dispositivo en primer lugar. Por supuesto, puedes usar algunos protocolos de red de bajo nivel, pero eso solo te daría un indicador de que hay algo, pero no lo que es (ser un dispositivo Android, una PC o cualquier otra cosa).

El enfoque más prometedor sería verificar si hay aplicaciones preinstaladas que tengan alguna funcionalidad de red. Por ejemplo, los dispositivos Samsung tienen Kies Air (si el usuario lo habilita), Motorola está usando UPnP para su Servidor de Medios y HTC también tiene algo propio, si recuerdo bien. Sin embargo, no hay ninguna aplicación que esté instalada en todos los dispositivos Android de todos los proveedores y operadores. Por lo tanto, no puede confiar únicamente en uno de ellos, pero tendrá que verificar varios servicios diferentes utilizando sus protocolos y comportamientos específicos para obtener información adicional sobre el dispositivo. Y, por supuesto, el usuario tendría que habilitar la funcionalidad para que usted la use.

Antigua respuesta

Una alternativa adicional a la lista de yorkw es AllJoyn by Qualcomm. Es un marco de descubrimiento multiplataforma de código abierto y comunicación de igual a igual que ya he usado en el pasado.

Aunque Qualcomm es un gran patrocinador de AllJoyn, esto no significa que necesite un chipset de Qualcomm en su definición. De hecho, AllJoyn funciona en cualquier conjunto de chips, incluidos Intel y nVidia. No requiere teléfonos rooteados ni ninguna otra modificación en el marco de Android y simplemente funciona de forma inmediata utilizando Wi-Fi y / o Bluetooth como métodos de emparejamiento.