web-dev-qa-db-fra.com

un moyen de découvrir les appareils Android sur votre réseau?

Je souhaite être en mesure de découvrir des périphériques Android sur mon réseau et éventuellement de récupérer des informations sur les périphériques les concernant. C'est très facile avec les appareils Apple, car ils exécutent les services Bonjour. Cependant, je ne trouve pas de service similaire fonctionnant sous Android. 

Cela doit fonctionner sans modifier le périphérique Android, installer un service ou ouvrir un port. Il est conçu pour fonctionner avec les appareils Android Vanilla de la manière dont Bonjour vous aide à trouver les appareils Apple Vanilla. Même être capable de vérifier que l'appareil fonctionne sous Android serait suffisant.


Réponse choisie : Bien que ce ne soit pas la réponse la mieux notée (pour le moment), jetez un œil à la réponse de Luis. Comme il le mentionne, vous pouvez utiliser une recherche DNS (à l'aide de votre serveur DNS local) pour découvrir les appareils Android. J'ai constaté que le taux de réussite était de 100%, car Android oblige les appareils à utiliser un nom d'hôte Android -_ ____ . C'est apparemment difficile à changer au téléphone, même s'il est enraciné. Donc, je pense que c'est une méthode assez précise. Merci 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.

Exemple de code: Si vous souhaitez implémenter cela en Java (par exemple, pour s'exécuter sur Android), vous ne pouvez pas utiliser facilement getHostName () car il utilise les serveurs DNS externes. Vous souhaitez utiliser le serveur DNS local sur votre routeur, par exemple. Luis mentionne ci-dessous que vous pouvez modifier les serveurs DNS de la connexion Wifi, mais que cela pourrait éventuellement casser d'autres choses. Au lieu de cela, j'ai trouvé la bibliothèque dnsjava extrêmement utile pour envoyer des requêtes DNS ciblées. Voici un exemple de code utilisant la bibliothèque:

        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);
    }

Cela me donne la sortie:

DNS Record: Android-711c129e251f14cf.\001.

Bingo.

53
gnychis

Il existe une approche très simple qui m'a donné des résultats positifs dans peu de dispositifs différents.

Lorsqu'un périphérique se connecte à votre routeur, il reçoit une adresse IP (c'est-à-dire DHCP) et enregistre un nom dans DNS. Le nom enregistré semble toujours être au format Android_nnnnnnnn.

Bien sûr, vous pouvez nommer n’importe quel ordinateur avec la même approche et tromper la vérification, ce qui entraîne des faux positifs ...

De plus, je ne peux pas garantir que tous les fournisseurs de périphériques suivent la même approche, mais je constate que cela fonctionne correctement sur quelques périphériques de marques différentes (y compris différents niveaux de SDK) que j'ai testés.

--ÉDITÉ--

Comment faire

Cela dépend de l'endroit où vous exécuteriez le code pour découvrir les périphériques Android. En supposant que vous exécutiez le code sur un périphérique Android:

  1. Commencez par découvrir les périphériques répondant à Ping sur votre réseau. Vous pouvez utiliser le code dans ma réponse à ce message: execComd () pour exécuter une commande ping.
  2. Obtenez le nom des périphériques qui répondent en utilisant le code:

    InetAddress inetAddress = InetAddress.getByName (string_with_ip_addr);

    Nom de chaîne = inetAddress.getCanonicalHostName ();

--EDIT 2--

Preuve de concept

La méthode ci-dessous est juste un prof de concept pour ce que j'ai écrit ci-dessus.

J'utilise la méthode isReachable() pour générer la demande ICMP, ce qui est indiqué dans de nombreuses publications ne fonctionnant qu'avec des périphériques enracinés, ce qui est le cas du périphérique utilisé pour le tester. Cependant, je n’ai pas donné d’autorisations root pour l’application qui exécute ce code; j’estime donc qu’elle ne pouvait pas définir le bit SIUD, ce qui explique pourquoi certaines méthodes de cette méthode échouent. J'aimerais que quelqu'un le teste sur un périphérique non rooté.

Pour appeler, utilisez:

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

Elle retourne dans la liste hostsa les noms des périphériques répondant à une requête 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;
}

Cordialement.

31
Luis

Android ne va pas être aussi simple que iOS. Il n'y a pas d'équivalent Bonjour.

Android 4.0, Sandwich à la crème glacée, introduit Wi-Fi Direct Réseau entre pairs. Au début, j'espérais pouvoir analyser votre façon de penser, mais cela aide les appareils Android à communiquer sans point d'accès, ils ne sont donc pas vraiment "sur votre réseau". En outre, ICS ne fonctionne que sur une fraction des appareils Android.

Plutôt qu'une approche active de netscan, vous vous retrouvez avec une approche de surveillance passive. Si votre réseau est sécurisé, la détection du paquet chiffré est possible, mais peu pratique. Tu devras 

  • mettez votre interface réseau en mode moniteur
  • capturer la poignée de main à 4 voies
  • déchiffrez-le à l'aide de la clé pré-partagée du réseau
  • cela vous donnera la clé dont vous avez besoin pour déchiffrer le trafic

Si vous voulez voir cela en action, Wireshark prend en charge WPA le déchiffrement .

Une fois que vous êtes en mesure de visualiser le trafic Wi-Fi, vous remarquerez que les appareils Android ont tendance à communiquer avec certains serveurs de Google et que leurs connexions HTTP comportent des chaînes Agent utilisateur pouvant être identifiées . une solution passive réalisable.

Tenable Network Security propose des produits qui semblent adopter ce type d’approche.

Une autre idée

@Michelle Cannon a mentionné le Meshlium Xtreme de Libelium, dont l'approche ne vous mènera pas jusqu'au bout (pas sans de bonnes tables de plages d'adresses MAC actualisées à ce jour). Mais cela pourrait faire partie d'un objectif moins ambitieux. Vous pouvez:

  • Détecter tous les appareils sans fil
  • Éliminer les périphériques Apple à l'aide de l'identificateur d'organisation unique (OUI) du MAC
  • Dites que c'est un appareil mobile en surveillant la force du signal pour déterminer s'il est en mouvement (et les appareils mobiles auront tendance à apparaître et à s'en aller)
  • Vous pourrez peut-être utiliser le MAC OUI comme indice, c'est Android
  • Vous pourrez peut-être utiliser le MAC OUI en guise d'indice qu'il ne s'agit pas d'Android (mais d'un ordinateur portable ou d'une carte sans fil, etc.).

Cela peut fonctionner si vous êtes prêt à détecter les appareils qui sont probablement Android.

Empreintes digitales DHCP

@ Michelle Cannon a suggéré d'empreintes digitales DHCP. Je n'étais pas sûr au début, mais je dois le remercier pour avoir suggéré ce qui semblait être le meilleur choix pour un balayage passif simple. En guise de mise en garde, j'aimerais expliquer pourquoi j'étais en retard à la fête.

Il y a des choses que nous savons, des pensées que nous ne savons pas et des choses que nous pensons connaître mais qui ne vont pas.

À bien des égards, il est bon qu'Android utilise le noyau Linux. Mais ce n'est pas bon si vous voulez découvrir des appareils Android sur votre réseau. La pile TCP/IP d'Android est celle de Linux. Par conséquent, les appareils Android ressemblent à ceux de Linux ou c'est ce que je pensais au début. Mais ensuite, j'ai réalisé que Linux avait beaucoup de paramètres de configuration pour construire, de sorte qu'il pourrait y avoir quelque chose de particulier à propos d'Android vu sur un réseau, mais quoi?

Les empreintes digitales DHCP utilisent les options DHCP exactes demandées par le périphérique, ainsi que le minutage. Pour que cela fonctionne, vous devez généralement disposer d'une base de données d'empreintes digitales à jour. Au début, il semblait que fingerbank était sollicité pour la recherche de ces données, mais j’ai remarqué par la suite que leurs fichiers n’avaient pas été mis à jour depuis presque un an. Avec tous les types d'appareils Android, je ne pense pas qu'il soit pratique de conserver des empreintes digitales mises à jour pour un seul projet.

Mais ensuite, j'ai regardé les signatures DHCP réelles pour Android et j'ai remarqué ceci:

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 utilise normalement dhclient comme client DHCP, mais Android utilise dhcpcd. Android a une préférence marquée pour l'utilisation de logiciels sous licence de style BSD, dans la mesure du possible, et dhcpcd utilise une licence BSD. Il semblerait que dhcpvendorcode pourrait être utilisé comme un indicateur fort de l’application d’un appareil mobile sous Android.

Surveillance DHCP

Un client utilise DHCP pour obtenir une adresse IP lors de la connexion à un réseau, c'est-à-dire qu'il démarre sans adresse IP. Il contourne ce problème en utilisant des émissions UDP pour l’échange initial. Sur le Wi-Fi, même avec WPA, le trafic de diffusion n'est pas crypté. Vous pouvez donc simplement écouter sur le port UDP 67 le trafic client-serveur et 68 à l’inverse. Vous n'avez même pas besoin de mettre votre interface réseau en mode promiscuous. Vous pouvez facilement surveiller ce trafic en utilisant un analyseur de protocole comme Wireshark.

J'ai préféré écrire du code pour surveiller le trafic et j'ai décidé d'utiliser Python. J'ai sélectionné pydhcplib pour gérer les détails de DHCP. Mon expérience avec cette bibliothèque n'était pas lisse. Je devais télécharger et placer manuellement les fichiers de support IN.py et TYPES.py. Et leur conversion de paquet en chaîne laissait le dhcpvendorcode vide. Il a correctement analysé les paquets DHCP, alors je viens d'écrire mon propre code d'impression.

Voici le code qui surveille le trafic DHCP du client au serveur:

#!/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()

Ce code est basé sur l'exemple de serveur pydhcplib car il écoute les demandes des clients, comme un serveur.Lorsque ma tablette Nexus 7 Android 4.2 se connecte, cette information intéressante est capturée (expurgée):.

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

Recherche DNS inversée .

@Luis a publié une excellente solution qui montre à quel point la simplicité est meilleure. Même après avoir vu que le client DHCP d'Android configurait Host_name sur Android-5c1b97cdffffffff, je n'ai pas pensé à demander au routeur sa liste de noms à l'aide de recherches DNS inversées. Le routeur ajoute le nom d'hôte à son serveur DNS afin que vous puissiez toujours accéder au périphérique si son adresse IP change.

Le nom_hôte doit rester répertorié dans le DNS pour la durée du bail DHCP. Vous pouvez vérifier si le périphérique est toujours présent en pinging it.

En fonction du nom d’hôte, l’un des inconvénients est qu’il peut être modifié de différentes manières. Il est facile pour le fabricant ou le transporteur de l’appareil de changer le nom de l’hôte (bien que, après une recherche, j’ai été incapable de trouver des preuves qu’ils aient jamais eues). Il y a des applications pour changer le nom d'hôte , mais elles requièrent un utilisateur root, ce qui est tout au plus un cas Edge.

Enfin, il y a un open Problème Android 6111: Permet de spécifier un nom d’hôte qui a actuellement 629 étoiles. Il ne serait pas surprenant de voir un nom d’hôte configurable dans les paramètres d’Android à un moment donné, peut-être bientôt. Donc, si vous commencez à vous fier à Host_name pour identifier les appareils Android, réalisez que cela pourrait vous être arraché.

Si vous effectuez un suivi en direct, un autre problème potentiel avec la recherche DNS inversée est que vous devez décider de la fréquence d'analyse. (Bien sûr, ce n'est pas un problème si vous prenez juste un instantané.) Un balayage fréquent consomme des ressources réseau, rarement vous laisse avec des données obsolètes. Voici comment l'ajout de la surveillance DHCP peut aider:.

  • Ping dispositifs pour voir s'ils sont toujours actifs
  • Surveiller le trafic DHCP pour détecter les nouveaux périphériques instantanément
  • Relancez occasionnellement Lookup DNS pour rechercher les périphériques que vous avez peut-être manqués.
  • Si vous devez remarquer que des périphériques partent, envoyez une requête ping aux périphériques à la résolution de minutage souhaitée
  • Bien que ce ne soit pas facile (ni précis à 100%), il existe plusieurs techniques qui permettent possible de découvrir des appareils Android sur votre réseau.

While it's not easy (nor 100% accurate), there are several techniques that make it possible to discover Android devices on your network.

21
jimhark

Autant que je sache, le système Android ne fournit aucun zeroconf app/service sur sa pile système/application intégrée. Pour activer la découverte automatique sur le périphérique connecté au réseau local, vous devez installer une application tierce zeroconf ou développer votre propre application/service, puis l'installer sur le périphérique. Certaines options de l'API sont les suivantes:

  • JmDNS (pour le protocole bonjour d'Apple)
  • Cling (pour le protocole UPnP de Microsoft)
  • Android NSD API (introduit depuis Android 4.1)

Je ne suis pas très clair sur vos exigences. Si vous voulez quelque chose de similaire (découverte et connexion automatiques) sur les appareils Android Vanilla, vous pouvez probablement utiliser Wi-Fi direct qui est maintenant disponible sur un appareil plus récent fonctionnant sous Android 4.0 Cependant, il faut que les deux appareils prennent en charge Wi-Fi Direct et créent uniquement une connexion P2P ad-hoc avec Wi-Fi désactivé, un peu comme une connexion Bluetooth avec une portée plus longue:

enter image description here

Pour la prise en charge de l'API Wi-Fi Direct, consultez le guide officiel - Connexion de périphériques sans fil .

5
yorkw

Je regarde cela une pensée

http://www.libelium.com/smartphones_iphone_Android_detection

payer une note spéciale à cette

Les utilisateurs doivent-ils avoir une application spécifique installée ou interagir d'une manière ou d'une autre pour être détectés?

Non, l'analyse est effectuée silencieusement, Meshlium détecte simplement les "images de balise" générées par les radios Wifi et Bluetooth intégrées dans les Smartphones. Les utilisateurs doivent simplement avoir au moins une des deux interfaces sans fil activée.

Il y a longtemps que j'utilisais une application appelée Stumbler sur mon Mac pour trouver des réseaux wifi, je pense que c'est similaire

Autres idées

Eh bien, si je dois déterminer les téléphones Android sur un réseau local, comment pourrais-je le faire? En l'absence d'un service DNS en cours d'exécution, je n'ai que deux possibilités

Le SSID si sa diffusion est en cours - ne peut rien me dire. L'adresse IP - Android vous permet de contrôler beaucoup le nommage des hôtes. Je suppose que vous pouvez définir une plage d'adresses IP spécifique pour vos appareils Android. -pas utile.

Alternativement, disons que je vois un périphérique inconnu sur le réseau, si Bluetooth est activé, je diffuse une signature de périphérique Bluetooth SDPP que je peux utiliser pour déduire mon type de périphérique.

Si j'utilisais un service prenant en charge Android et que je voulais découvrir des appareils Android spécifiques sur mon réseau, je pourrais simplement enregistrer les adresses mac de ces appareils et les surveiller sur le réseau.

Autre que cela, vous devrez exécuter un bonjour (dns-sd) ou upnpp dameon sur le périphérique.

2
Michelle Cannon

J'apprends beaucoup de ce sujet. 

dhcp fingerprinting existe également. Apparemment, différents périphériques agissent différemment du type de numérisation réseau dont nous avons discuté, comme ceux qui utilisent NMAP comme scanner Linux. Des cartes du comportement de ces sondes sont disponibles sur 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/

1
Michelle Cannon

Réponse mise à jour

Désolé, je n'ai pas bien compris la question initiale. Seul votre commentaire m'a clairement fait comprendre que vous ne souhaitiez pas installer rien sur les appareils cibles, mais que vous souhaitiez simplement un moyen de détecter des téléphones aléatoires sur votre réseau.

Je ne sais pas si cela serait vraiment possible comme vous le souhaitez. Sans aucun service de découverte de réseau sous Android, vous ne trouverez pas l'appareil en premier lieu. Bien sûr, vous pouvez utiliser certains protocoles réseau de bas niveau, mais cela ne vous donnerait qu'un indice qu'il existe quelque chose mais pas ce que c'est (être un appareil Android, un PC, etc.).

L'approche la plus prometteuse serait de rechercher des applications préinstallées dotées d'une fonctionnalité réseau quelconque. Par exemple. Les appareils Samsung ont Kies Air (si l'utilisateur le permet), Motorola utilise UPnP pour son serveur multimédia et HTC possède aussi quelque chose de propre, si je me souviens bien. Cependant, aucune application n'est installée sur tous les appareils Android de tous les fournisseurs et opérateurs. Par conséquent, vous ne pouvez pas compter uniquement sur l'un d'entre eux, mais vous devrez rechercher différents services à l'aide de leurs protocoles et comportements spécifiques afin d'obtenir des informations supplémentaires sur le périphérique. Et, bien sûr, l'utilisateur devrait activer la fonctionnalité pour pouvoir l'utiliser.

Ancienne réponse

Une alternative supplémentaire à la liste de yorkw est AllJoyn by Qualcomm. Il s'agit d'un cadre de découverte multiplate-forme à code source ouvert et d'un cadre de communication entre homologues que je utilisais déjà par le passé. 

Bien que Qualcomm soit un gros sponsor d’AllJoyn, cela ne signifie pas pour autant que vous ayez besoin d’un chipset Qualcomm. En fait, AllJoyn fonctionne sur tous les chipsets, y compris Intel et nVidia. Il ne nécessite pas de téléphones enracinés ni aucune autre modification du framework Android et fonctionne simplement "out of the box" en utilisant le Wi-Fi et/ou Bluetooth comme méthodes d'appariement.

1
André

Voici une ligne qui envoie une requête ping à toutes les machines de votre réseau (en supposant que votre réseau s'appelle 192.168.1.x) et effectue une recherche inversée de leurs noms:

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 

Requiert GNU en parallèle pour fonctionner. Vous pouvez l'installer sur OSX avec "brew install parallel"

À partir de là, vous pouvez simplement regarder les périphériques nommés Android-c40a2b8027d663dd.home. ou peu importe.

Vous pouvez ensuite essayer d’exécuter nmap -O sur un périphérique pour voir ce que vous pouvez encore découvrir:

Sudo nmap -O Android-297e7f9fccaa5b5f.home.

Mais ce n'est pas vraiment fructueux.

0
Will Schenk