Android不像iOS那么简单,没有Bonjour的等价物。
Android 4.0,冰激凌三明治,引入了Wi-Fi Direct点对点网络。起初我希望它能够被扫描以便像你所想的那样使用,但它可以帮助Android设备在没有访问点的情况下进行通信,因此它们并不真正“在您的网络上”。此外,ICS仅运行在部分Android设备上。
与其采用主动netscan方法,不如采用被动监视方法。如果您的网络是安全的,则可能会嗅探加密数据包,但这很麻烦。您需要:
如果您想实际操作,
Wireshark 支持
WPA 解密。
一旦您能够查看 Wi-Fi 流量,您会注意到 Android 设备倾向于与某些 Google 服务器通信,并且它们的 HTTP 连接具有
可识别的用户代理字符串。这是可行被动解决方案的基础。
Tenable Network Security 提供的产品似乎采取了这种方法。
另一个想法
@Michelle Cannon提到了Libelium的Meshlium Xtreme,其方法不会让您完全达成目标(没有好的最新MAC地址范围表就不行)。但它可以成为达成较小目标的一部分。
您可以:
- 检测所有无线设备
- 使用MAC的组织唯一标识符(OUI)消除苹果设备
- 通过监测信号强度来确定它是否移动,以此判断它是移动设备(移动设备会出现并消失)
- 您可以使用MAC OUI作为它是Android的提示
- 您可以使用MAC OUI作为它不是Android(而是笔记本电脑或无线网卡等)的提示。
如果你愿意检测那些可能是Android的设备,这可能可行。
DHCP指纹识别
@Michelle Cannon建议使用DHCP指纹识别。起初我不确定,但我必须感谢他提出了看起来最简单的被动扫描方案。作为一个警示,我想解释一下我为什么迟到了。
有些事情我们知道,有些事情我们不知道,还有些事情我们认为我们知道但是错了。
在许多方面,Android使用Linux内核是有好处的。但是如果您想在网络上发现Android设备,则不是很好。因为Android的TCP/IP堆栈是Linux的,所以Android设备看起来像Linux设备,或者一开始我是这么认为的。但后来我意识到,Linux有很多构建配置参数,因此在网络上看到Android时可能会有一些特别之处,但是是什么呢?
DHCP指纹识别使用设备请求的确切DHCP选项加上时间。要使其工作,通常需要最新的指纹数据库来进行匹配。起初看起来
fingerbank正在众包收集这些数据,但然后我注意到他们的文件已经没有更新了将近一年。考虑到所有不同类型的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通常使用dhclient作为他们的DHCP客户端,但Android使用dhcpcd。 Android强烈倾向于在可能的情况下使用BSD风格的软件许可证,而dhcpcd使用BSD许可证。看起来dhcpvendorcode可以用作移动设备正在运行Android的强有力指示。
DHCP监视
客户端在加入网络时使用DHCP获取IP地址,因此它开始时没有IP地址。它通过使用UDP广播进行初始交换来解决这个问题。在Wi-Fi上,即使使用WPA,广播流量也不会被加密。因此,您只需监听UDP端口67以获取客户端到服务器的流量,并监听68以获取反向流量。您甚至无需将网络接口置于混杂模式中。您可以使用协议分析器(如Wireshark)轻松监视此流量。
我更喜欢编写代码来监视流量,并决定使用Python。我选择了pydhcplib来处理DHCP的细节。我的使用经验并不顺畅。我需要手动下载并放置IN.py和TYPES.py支持文件。他们的数据包转换成字符串时留下了dhcpvendorcode为空。它确实正确解析了DHCP数据包,所以我只是写了自己的打印代码。
以下是监视客户端到服务器的DHCP流量的代码:
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']):
for option in options:
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)
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的一个缺点是它可能会被更改。设备制造商或运营商很容易更改host_name(尽管经过搜索,我未能找到任何证据表明他们曾经这样做)。有
apps to change host name,但它们需要root权限,因此只是个例外情况。
最后,目前有629个星标的
Android Issue 6111: Allow a hostname to be specified是开放的。在将来的某个时候,可能很快就会在Android设置中看到可配置的host_name。因此,如果您开始依赖host_name来识别Android设备,请意识到它可能会在您面前被撤回。
如果您正在进行实时跟踪,则使用反向DNS查找的另一个潜在问题是您必须决定扫描频率。 (当然,如果您只是进行一次性快照,则这不是问题。)频繁扫描会消耗网络资源,而不频繁则会导致数据过时。以下是如何添加DHCP监视可以帮助解决此问题:
- 启动时使用反向DNS查找来查找设备
- ping设备以查看它们是否仍然活动
- 监视DHCP流量以立即检测新设备
- 偶尔重新运行DNS查找以查找可能遗漏的设备
- 如果您需要注意设备离开,请在所需时间分辨率下ping设备
虽然这并不容易(也不是100%准确),但有几种技术使得在网络上发现Android设备成为可能。
192.168.1.104
是你的 Android 设备在 WiFi 上的 IP 地址,而192.168.1.1
是你的 WiFi 路由器的 IP 地址?还是关于其他服务器,我使用不正确?谢谢。 - AlexAndro