61

ネットワーク上のAndroidデバイスを検出し、それらに関するデバイス情報を取得できるようにしたいと考えています。AppleデバイスはBonjourサービスを実行しているため、これは非常に簡単です。ただし、Androidで実行されている同様のサービスは見つからないようです。

これは、Androidデバイスを変更したり、サービスをインストールしたり、ポートを開いたりしなくても機能する必要があります。Bonjourがバニラアップルデバイスを見つけるのに役立つ方法で、バニラAndroidデバイスと連携することを目的としています。デバイスがAndroidを実行していることを確認できれば十分です。


選ばれた回答:(まだ)最高評価の回答ではありませんが、ルイスの回答をご覧ください。彼が言及しているように、(ローカルDNSサーバーを使用して)DNSルックアップを使用してAndroidデバイスを検出できます。Androidはデバイスにandroid -_____のホスト名を使用するように強制するため、これは100%の成功率であることがわかりまし。これは、たとえそれが根付いているとしても、電話で変更するのは明らかに難しいです。ですから、これはかなり正確な方法だと思います。ありがとう、ルイス!

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.

サンプルコード:これをJavaで実装する場合(たとえば、Androidで実行する場合)、getHostName()は外部DNSサーバーを使用するため、簡単に使用することはできません。たとえば、ルーターでローカルDNSサーバーを使用するとします。ルイスは、Wifi接続のDNSサーバーを変更できるが、他のことを壊す可能性があると以下に述べています。代わりに、dnsjavaターゲットを絞ったDNS要求を送信するのにライブラリが非常に役立つことがわかりました。ライブラリを使用したサンプルコードは次のとおりです。

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

これにより、次の出力が得られます。

DNS Record: android-711c129e251f14cf.\001.

ビンゴ。

4

7 に答える 7

34

いくつかの異なるデバイスでポジティブな結果をもたらした非常に単純なアプローチがあります。

デバイスがルーターに接続すると、IP(DHCPなど)を受信し、DNSに名前を登録します。登録されている名前は常にの形になっているようandroid_nnnnnnnnです。

もちろん、同じアプローチで任意のコンピューターに名前を付けてチェックを騙し、誤検知を引き起こす可能性があります...

また、すべてのデバイスサプライヤが同じアプローチに従っていることを確認することはできませんが、テストしたさまざまなブランド(さまざまなSDKレベルを含む)のいくつかのデバイスで正しく機能することがわかりました。

-編集済み--

どうやってするの

これは、Androidデバイスを検出するためにコードを実行する場所によって異なります。Androidデバイスでコードを実行すると仮定します。

  1. まず、ネットワークで応答しているデバイスを見つけますping。この投稿に対する私の回答のコードexecComd()を使用して、pingコマンドを実行できます。

  2. コードを使用して、応答するデバイスの名前を取得します。

    InetAddress inetAddress = InetAddress.getByName(string_with_ip_addr);

    文字列名=inetAddress.getCanonicalHostName();

--編集2--

コンセプトの証明

以下の方法は、私が上で書いたことの概念実証にすぎません。

私はisReachable()メソッドを使用してICMPリクエストを生成しています。これは、多くの投稿でルート化されたデバイスでのみ機能すると言われています。これは、テストに使用されるデバイスの場合です。ただし、このコードを実行しているアプリケーションにroot権限を付与しなかったため、SIUDビットを設定できなかったと考えられます。これが、このメソッドが失敗したと主張する理由です。ルート権限を取得していないデバイスで誰かがテストするという観点から、ここでそれを実行したいと思います。

使用を呼び出すには:

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

hostsping要求に応答するデバイスの名前のリストを返します。

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

よろしく。

于 2012-11-23T21:43:21.843 に答える
21

AndroidはiOSほど簡単ではありません。Bonjourに相当するものはありません。

Android 4.0、Ice Cream Sandwichは、Wi-Fi Direct PeertoPeerネットワーキングを導入しました。最初は、あなたの考えどおりにスキャンできることを望んでいましたが、Androidデバイスがアクセスポイントなしで通信するのに役立つため、実際には「ネットワーク上」にはありません。さらに、ICSはAndroidデバイスのごく一部でのみ実行されます。

アクティブなネットスキャンアプローチではなく、パッシブモニタリングアプローチが残されています。ネットワークが安全であれば、暗号化されたパケットをスニッフィングすることは可能ですが、不便です。あなたがしなければならないでしょう

これが実際に動作していることを確認したい場合は、WiresharkがWPA復号化をサポートしています。

Wi-Fiトラフィックを表示できるようになると、Androidデバイスは特定のGoogleサーバーと通信する傾向があり、そのHTTP接続には識別可能なユーザーエージェント文字列が含まれていることがわかります。これは、実行可能なパッシブソリューションの基礎です。

Tenable Network Securityは、このタイプのアプローチを採用しているように見える製品を提供しています。

別のアイデア

@Michelle Cannonは、LibeliumのMeshlium Xtremeについて言及しました。そのアプローチでは、そこまで到達することはできません(最新のMACアドレス範囲テーブルがないわけではありません)。しかし、それはより小さな目標を達成することの一部である可能性があります。あなたはできる:

  • すべてのワイヤレスデバイスを検出する
  • MACのOrganizationallyUniqueIdentifier(OUI)を使用してAppleデバイスを排除する
  • 信号強度を監視して移動していることを確認することで、モバイルデバイスであることを伝えます(モバイルデバイスは表示されて消える傾向があります)
  • あなたはそれがAndroidであるというヒントとしてMACOUIを使うことができるかもしれません
  • MAC OUIは、Androidではない(ラップトップやワイヤレスカードなど)ヒントとして使用できる場合があります。

これは、おそらくAndroidであるデバイスを検出する意思がある場合に機能する可能性があります。

DHCPフィンガープリント

@Michelle Cannonは、DHCPフィンガープリントを提案しました。最初はわかりませんでしたが、単純なパッシブスキャンの最善策のように見えるものを提案してくれた彼に感謝しなければなりません。注意点として、なぜパーティーに遅れたのかを説明したいと思います。

私たちが知っていること、知らないと思うこと、知っていると思うが間違っていることがあります。

多くの点で、AndroidがLinuxカーネルを使用するのは良いことです。ただし、ネットワーク上でAndroidデバイスを検出する場合は適切ではありません。AndroidのTCP/IPスタックはLinuxであるため、AndroidデバイスはLinuxデバイスのように見えるので、最初は考えました。しかし、Linuxには多くのビルド構成パラメーターがあるので、ネットワーク上で見たときにAndroidに特有の何かがある可能性があることに気付きましたが、どうでしょうか。

DHCPフィンガープリントは、デバイスとタイミングによって要求された正確なDHCPオプションを使用します。これが機能するためには、通常、照合するための最新の指紋データベースが必要です。最初は、 fingerbankがこのデータを調達するために混雑しているように見えましたが、その後、ファイルがほぼ1年間更新されていないことに気付きました。すべての異なるAndroidデバイスタイプで、単一のプロジェクトの更新されたフィンガープリントを保持することは実用的ではないと思います。

しかし、Androidの実際のDHCP署名を調べたところ、次のことに気づきました。

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は通常DHCPクライアントとしてdhclientを使用しますが、Androidはdhcpcdを使用しています。Androidは、可能な場合はBSDスタイルでライセンスされたソフトウェアを使用することを強く好み、dhcpcdはBSDライセンスを使用します。dhcpvendorcodeは、モバイルデバイスがAndroidを実行していることを示す強力な指標として使用できるように思われます。

DHCP監視

クライアントは、ネットワークに参加するときにDHCPを使用してIPアドレスを取得するため、IPアドレスなしで開始します。最初の交換にUDPブロードキャストを使用することで、この問題を回避します。Wi-Fiでは、WPAを使用しても、ブロードキャストトラフィックは暗号化されません。したがって、UDPポート67でクライアントからサーバーへのトラフィックをリッスンし、68でその逆をリッスンできます。ネットワークインターフェイスを無差別モードにする必要はありません。Wiresharkなどのプロトコルアナライザを使用して、このトラフィックを簡単に監視できます。

私はトラフィックを監視するコードを書くことを好み、Pythonを使用することにしました。DHCPの詳細を処理するためにpydhcplibを選択しました。このライブラリでの私の経験はスムーズではありませんでした。IN.pyおよびTYPES.pyサポートファイルを手動でダウンロードして配置する必要がありました。そして、彼らのパケットから文字列への変換は、dhcpvendorcodeを空白のままにしていました。DHCPパケットを正しく解析したので、自分で印刷コードを記述しました。

クライアントからサーバーへのDHCPトラフィックを監視するコードは次のとおりです。

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

このコードは、サーバーのようにクライアント要求をリッスンするため、pydhcplibのサーバーの例に基づいています。

Nexus 7 Android 4.2タブレットが接続すると、この興味深い情報がキャプチャ(編集)されます。

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

ホスト名は固定形式のようで、簡単に解析できます。IPアドレスが必要な場合は、サーバーからクライアントへのトラフィックを監視できます。注:新しいクライアントがIPアドレスなしで最初に表示されたときの最初の交換のみがブロードキャストされます。将来のリース延長等は放送されません。

DNS逆引きルックアップ

@Luisは、シンプルな方が優れていることを示す優れたソリューションを投稿しました。AndroidのDHCPクライアントがhost_nameをandroid-5c1b97cdffffffffに設定しているのを見た後でも、DNS逆引き参照を使用してルーターに名前のリストを要求することは考えていませんでした。ルーターはhost_nameをDNSサーバーに追加するため、IPアドレスが変更されてもデバイスにアクセスできます。

host_nameは、DHCPリースの期間中、DNSにリストされたままになると予想されます。pingを実行することで、デバイスがまだ存在するかどうかを確認できます。

host_nameに依存することの1つの欠点は、これを変更できる方法があることです。デバイスの製造元または通信事業者がhost_nameを変更するのは簡単です(ただし、検索した後、彼らが持っている証拠を見つけることができませんでした)。ホスト名を変更するアプリはありますが、rootが必要なので、せいぜいエッジケースです。

最後に、未解決のAndroid Issue6111があります。現在629個の星が付いているホスト名を指定できるようにします。将来のある時点で、おそらくすぐに、Android設定で構成可能なhost_nameが表示されるのは当然のことです。したがって、Androidデバイスを識別するためにhost_nameに依存し始める場合は、それがあなたの下からヤンクアウトされる可能性があることに注意してください。

ライブトラッキングを実行している場合、逆引きDNSルックアップのもう1つの潜在的な問題は、スキャンの頻度を決定する必要があることです。(もちろん、これは1回限りのスナップショットを作成する場合は問題になりません。)頻繁にスキャンするとネットワークリソースが消費され、まれに古いデータが残ります。DHCP監視を追加すると次のようになります。

  • 起動時に逆引きDNSルックアップを使用してデバイスを検索します
  • デバイスにpingを実行して、デバイスがまだアクティブかどうかを確認します
  • DHCPトラフィックを監視して、新しいデバイスを即座に検出します
  • ときどきDNSルックアップを再実行して、見逃した可能性のあるデバイスを見つけます
  • デバイスが離れていることに気付く必要がある場合は、希望のタイミング解像度でデバイスにpingを実行します

簡単ではありませんが(100%正確でもありません)、ネットワーク上のAndroidデバイスを検出できるようにするいくつかの手法があります。

于 2012-11-21T17:36:56.107 に答える
5

ちなみに、Androidシステムは、組み込みのシステムアプリ/サービススタックにzeroconfアプリ/サービスを提供していません。ローカルネットワークに接続されている実際のデバイスで自動検出を有効にするには、サードパーティのzeroconfアプリをインストールするか、独自のアプリ/サービスを開発して実際のデバイスにインストールする必要があります。いくつかのAPIオプションは次のとおりです。

要件についてはよくわかりません。バニラAndroidデバイスで同様の機能(自動検出と接続)が必要な場合は、Android 4.0を実行している後のデバイスで利用できるようになったWi-FiDirectを使用できますが、どちらのデバイスもWi-FiDirectをサポートしており、Wi-FiをオフにしたアドホックP2P接続のみを作成します。これは、より長い範囲のBluetooth接続とよく似ています。

ここに画像の説明を入力してください

Wi-Fi Direct APIのサポートについては、公式ガイド-デバイスのワイヤレス接続をご覧ください。

于 2012-11-18T04:49:34.567 に答える
2

私はこれを考えています

http://www.libelium.com/smartphones_iphone_android_detection

これに特別な注意を払う

ユーザーが検出されるためには、特定のアプリをインストールする必要がありますか、それとも何らかの方法で対話する必要がありますか?

いいえ、スキャンはサイレントに実行されます。Meshliumは、スマートフォンに統合されたWifiおよびBluetooth無線によって発生した「ビーコンフレーム」を検出するだけです。ユーザーは、2つのワイヤレスインターフェイスの少なくとも1つをオンにする必要があります。

昔、私は自分のMacでstumblerというアプリを使ってwifiネットワークを見つけていましたが、これは似ていると思います

その他のアイデア

ローカルネットワーク上のAndroidスマートフォンを特定する必要がある場合は、どうすればよいでしょうか。実行中のDNSサービスがない場合、私にはいくつかの可能性しかありません

SSIDがブロードキャストされている場合-何も教えてくれませんIPアドレス-androidを使用すると、ホストの命名を細かく制御できるため、Androidデバイスに特定のIP範囲を定義できると思います。-役に立たない。

または、ネットワーク上に不明なデバイスが表示されているとしましょう。Bluetoothがオンになっている場合は、デバイスタイプを推測するために使用できるBluetoothデバイスシグネチャSDPPをブロードキャストしています。

Androidをサポートするサービスを実行していて、ネットワーク上で特定のAndroidデバイスを検出したい場合は、それらのデバイスのMACアドレスを登録して、ネットワーク上で監視することができます。

それ以外の場合は、デバイスでbonjour(dns-sd)またはupnppdameonのいずれかを実行する必要があります。

于 2012-11-21T20:20:48.467 に答える
1

更新された応答

申し訳ありませんが、元の質問を正しく理解していません。あなたのコメントだけが、ターゲットデバイスに何もインストールする必要はなく、ネットワーク内のランダムな電話を検出する方法が必要であることを私にはっきりと示しました。

これがあなたが望む方法で本当に可能かどうかはわかりません。Androidでネットワーク検出サービスを実行しないと、そもそもデバイスを見つけることができません。もちろん、いくつかの低レベルのネットワークプロトコルを使用することはできますが、それは何かがあることを示すだけであり、それが何であるか(Androidデバイス、PC、その他)を示すものではありません。

最も有望なアプローチは、ある種のネットワーク機能を備えたプレインストールされたアプリをチェックすることです。たとえば、SamsungデバイスにはKies Airがあり(ユーザーが有効にしている場合)、MotorolaはメディアサーバーにUPnPを使用しており、私が正しく覚えていれば、HTCにも独自のものがあります。ただし、すべてのベンダーと携帯通信会社のすべてのAndroidデバイスにインストールされているアプリはありません。したがって、これらの1つだけに依存することはできませんが、デバイスに関する追加情報を取得するには、特定のプロトコルと動作を使用してさまざまなサービスをチェックする必要があります。そしてもちろん、あなたがそれを使用するためには、ユーザーはその機能を有効にする必要があります。

古い応答

yorkwのリストに代わる追加の方法は、QualcommのAllJoynです。これは、私が過去にすでに使用したオープンソースのクロスプラットフォーム検出およびピアツーピア通信フレームワークです。

QualcommはAllJoynの大きなスポンサーですが、これは、定義にQualcommチップセットが必要であることを意味するものではありません。実際、AllJoynはIntelやnVidiaを含むすべてのチップセットで動作します。ルート権限を取得された電話やAndroidフレームワークへのその他の変更は必要なく、ペアリング方法としてWi-FiやBluetoothを使用して「箱から出して」機能します。

于 2012-11-18T16:14:45.443 に答える
1

私はこのトピックから多くを学んでいます。

dhcpフィンガープリントと呼ばれるものもあります。明らかに、LinuxスキャナーのNMAPを使用するデバイスなど、これまでに説明した種類のネットワークスキャンとは異なるデバイスの動作が異なります。これらのプローブからの動作のマップは、インターネットで入手できます。

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/

于 2012-11-22T00:09:04.860 に答える
-1

これは、ネットワーク上のすべてのマシンにpingを実行し(ネットワークがである192.168.1.xと想定)、それらの名前を逆引きする1つのライナーです。

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 

動作するにはGNUパラレルが必要です。「brewinstallparallel」を使用してOSXにインストールできます

これから、名前が付けられたデバイスなどを見ることができますandroid-c40a2b8027d663dd.home.

次に、デバイスでnmap -Oを実行して、他に何がわかるかを確認できます。

sudo nmap -O android-297e7f9fccaa5b5f.home.

しかし、それはそれほど実り多いものではありません。

于 2014-12-01T17:53:40.977 に答える