scapy之ap信息收集
1
以上文章由作者【syaber】有赏投稿,也欢迎广大朋友继续投稿,详情可点击OSRC重金征集文稿!!!了解~~。
前言
对于无线攻击的第一步,通常是信息搜集,我们可以直接使用aircrack套件中的airodump-ng工具进行信息收集,但本文不介绍airodump-ng的使用方法,而是从较为底层的方式去实现信息搜集这一目的,从而能更好地理解对于无线信息搜集的原理,由于目的是掌握原理,所以一些地方讲得比较基础,但也不是面面俱到,小白向,望大佬轻喷。本文主要针对2.4GHz频段,不涉及5GHz。
环境/工具
kali或ubuntu16.04/18.4系统(作者使用的是ubuntu18.04,由于windows,mac系统对无线攻击的支持不完善,不建议使用windows/mac系统进行无线攻击)一张外置无线网卡
Scapy
scapy是python的一个库,主要用于各种协议的数据包发送或嗅探,也可以自己构造一个协议。由于kali自带的scapy版本过老,如果使用kali,需要更新下scapy库。安装scapy:
pip install https://github.com/secdev/scapy/archive/master.zip
手动信息收集
我们先手动对ap进行信息搜集,从而了解信息搜集的原理。
在开始信息搜集之前,先大致了解下802.11协议的一些理论知识,这里主要介绍下Beacon帧。
对于ap的信息搜集主要来源便是Beacon帧,Beacon帧又称信标帧,在很多协议中都有Beacon帧这一概念,在802.11协议中,Beacon帧主要用于宣告ap的存在。Beacon帧中携带许多重要的信息,比如说ap的mac地址、ssid、信道、加密方式等等。
用手机打开wifi开关后,在wifi列表中便可以看到存在的ap,这个过程可以理解为手机不断切换信道去接收各个信道上的Beacon帧,实际上也是一个信息搜集的过程。
为了在wireshark中分析Beacon帧,我们先把网卡设置为监听模式:
sudo airmon-ng start wlx70f11c1f9108
激活网卡:
sudo ifconfig wlan0mon up
(网卡名称通过iwconfig命令查看)
Beacon帧属于管理帧,type为0,子帧类型subtype为8,在wireshark中可以用
wlan.fc.type_subtype==8
或者
wlan.fc.type==0 and wlan.fc.subtype==8
来过滤Beacon帧:

Beacon帧头:

在Beacon帧头部可以看到Beacon的目的地址(Destination address)为:
ff:ff:ff:ff:ff:ff
即广播地址,Beacon帧的源地址(Source address)为:
68:a0:3e:**:**:**
即ap的mac地址
802.11协议帧通过信息元素(IE)来携带一些信息,802.11协议的信息元素架构为:

信息元素由ID来标识,如ID=0,即代表此信息元素为SSID,Length表示信息元素的长度,范围为0~0xff字节,每个信息元素携带的信息则放在Info中。
wireshark中的Beacon帧:

前面的固定参数:Timestamp,Beacon Interval,Cap info分别表示ap的存活时间,Beacon帧的发送间隔以及一些flag标志位。
我们主要注意下面的信息元素。
SSID:

学名服务集标识,通俗讲就是wifi的名字。约定俗称ssid的长度最多为32字节,但802.11协议规定信息元素的长度最多为255字节,这里曾经出现过ssid长度溢出漏洞,后来被默默修复了。
Channel:
用来表示当前ap的信道。2.4Ghz主要使用1至14信道。
RSN:

802.11i新引入的信息元素,表示一些关于安全的信息,比如加密方式,认证方式。
加密方式的对应关系为:
'0':'Use group cipher suite''1':'WEP-40''2':'TKIP''3':'Reserved''4':'CCMP''5':'WEP-104'
认证方式的对应关系为:
'0':'reversed''1':'IEEE 802.1X / PMKSA caching''2':'PSK'
802.1x主要用于企业wifi认证,我们平时用的wifi主要是PSK认证。
到目前为止,我们用人工的方式进行了信息搜集,显然是个比较繁琐的过程,而且不能批量信息搜集,对于别的信道的ap,还需要更改网卡信道,下面我们使用scapy来代替人工操作。
使用Scapy进行信息收集
这里我们主要使用scapy的嗅探功能。
先贴上最简单的脚本:
from scapy.all import *class sniffer():def __init__(self,iface):self.iface=ifaceself.cipher_suites={'x00':'Use group cipher suite','x01':'WEP-40','x02':'TKIP','x03':'Reserved','x04':'CCMP','x05':'WEP-104'}self.akm_suites={'x00':'reversed','x01':'802.1X','x02':'PSK'}self.run()def PacketHandler(self,pkt):ap_mac=pkt[Dot11].addr3if ap_mac not in self.ap:self.ap.append(ap_mac)print "%s | beacon"%ap_macpkt.show()def run(self):sniff(iface=self.iface,prn=self.PacketHandler,filter="type mgt subtype beacon")if __name__ == "__main__":sniffer('wlan0mon')
参数填入网卡接口的名称即可。
scapy嗅探函数sniff底层调用的是tcpdump,所以sniff的过滤规则和tcpdump一致(参考https://www.tcpdump.org/manpages/pcap-filter.7.html)
filter="type mgt subtype beacon"
表示过滤管理帧,并且子帧类型为beacon。
sniff函数的prn参数可以将嗅探到的数据包交给prn参数进行处理。
def PacketHandler(self,pkt):ap_mac=pkt[Dot11].addr3if ap_mac not in self.ap:self.ap.append(ap_mac)print "%s | beacon"%ap_macpkt.show()
PacketHandler用来处理嗅探到的Beacon帧,scapy会解析Beacon帧,可以使用pkt.show()查看Beacon的各个layer,运行此脚本:

在Dot11层可以看到Beacon帧头的一部分信息,其中addr3即为Beacon帧的源地址。
如果不熟悉scapy的layer命名,可以用下面定义的函数查看:
def expand(x):yield xwhile x.payload:x = x.payloadyield xprint list(expand(pkt))
我们需要从scapy解析的帧中将mac地址,ssid,信道,加密方式,认证方式提取出来。
但由于scapy的信息元素的layer全都是Dot11Elt,想要遍历所有的Dot11Elt,可以在读取第一个Dot11Elt后将其舍弃,从而自顶向下遍历:
elt=pkt[Dot11Elt]while elt.payload:......elt=elt.payload
获取ssid:
if elt.ID==0: #ssidssid=elt.info
获取信道:
elif elt.ID==3: #channelch=ord(elt.info)
解析RSN有些复杂:
pkt.show()

虽然scapy已经解析出加密以及认证方式,但我们取出仍是字节,取出pairwise_cipher_suites以及akm_suites的最后一个字节,再到字典比对:
elif elt.ID==48: #ciper and authcipher_type=str(elt[Dot11EltRSN].pairwise_cipher_suites[0])[-1:]akm_type=str(elt[Dot11EltRSN].akm_suites[0])[-1:]cipher=self.cipher_suites[cipher_type]auth=self.akm_suites[akm_type]
当前脚本:
from scapy.all import *class sniffer():def __init__(self,iface):self.iface=ifaceself.ap=[]self.cipher_suites={'x00':'Use group cipher suite','x01':'WEP-40','x02':'TKIP','x03':'Reserved','x04':'CCMP','x05':'WEP-104'}self.akm_suites={'x00':'reversed','x01':'802.1X','x02':'PSK'}self.run()def promt(self,arg1,arg2,arg3,arg4,arg5):return "%17s%30s%10s%10s%10s"%(arg1,arg2,arg3,arg4,arg5)def PacketHandler(self,pkt):ap_mac=pkt[Dot11].addr3if ap_mac not in self.ap:ssid=Nonech=Nonecipher=Noneauth=Noneself.ap.append(ap_mac)elt=pkt[Dot11Elt]while elt.payload:if elt.ID==0: #ssidssid=elt.infoelif elt.ID==3: #channelch=ord(elt.info)elif elt.ID==48: #ciper and authcipher_type=str(elt[Dot11EltRSN].pairwise_cipher_suites[0])[-1:]akm_type=str(elt[Dot11EltRSN].akm_suites[0])[-1:]cipher=self.cipher_suites[cipher_type]auth=self.akm_suites[akm_type]elt=elt.payloadprint self.promt(ap_mac,ssid,ch,cipher,auth)def run(self):print self.promt('mac','ssid','channel','cipher','auth')sniff(iface=self.iface,prn=self.PacketHandler,filter="type mgt subtype beacon")if __name__ == "__main__":sniffer('wlan0mon')
运行结果:

(最后一个是隐藏wifi)
这时我们发现嗅探到的都是一信道的ap,因为我们的网卡在第一信道,扫描全信道需要不断更改网卡信道,我们使用多线程每0.5秒切换下信道,最终脚本:
from scapy.all import *from threading import Threadimport osimport timedef change_ch(iface):ch=0while 1:ch+=1cmd="sudo iwconfig {iface} channel {channel}".format(iface=iface,channel=(ch%14+1))os.system(cmd)time.sleep(0.5)class sniffer():def __init__(self,iface):self.iface=ifaceself.ap=[]self.cipher_suites={'x00':'Use group cipher suite','x01':'WEP-40','x02':'TKIP','x03':'Reserved','x04':'CCMP','x05':'WEP-104'}self.akm_suites={'x00':'reversed','x01':'802.1X','x02':'PSK'}self.run()def promt(self,arg1,arg2,arg3,arg4,arg5):return "%17s%30s%10s%10s%10s"%(arg1,arg2,arg3,arg4,arg5)def PacketHandler(self,pkt):ap_mac=pkt[Dot11].addr3if ap_mac not in self.ap:ssid=Nonech=Nonecipher=Noneauth=Noneself.ap.append(ap_mac)elt=pkt[Dot11Elt]while elt.payload:if elt.ID==0: #ssidssid=elt.infoelif elt.ID==3: #channelch=ord(elt.info)elif elt.ID==48: #ciper and authcipher_type=str(elt[Dot11EltRSN].pairwise_cipher_suites[0])[-1:]akm_type=str(elt[Dot11EltRSN].akm_suites[0])[-1:]cipher=self.cipher_suites[cipher_type]auth=self.akm_suites[akm_type]elt=elt.payloadprint self.promt(ap_mac,ssid,ch,cipher,auth)def run(self):print self.promt('mac','ssid','channel','cipher','auth')sniff(iface=self.iface,prn=self.PacketHandler,filter="type mgt subtype beacon")if __name__=="__main__":t1=Thread(target=change_ch,args=('wlan0mon',))t1.daemon=Truet1.start()t2=Thread(target=sniffer,args=('wlan0mon',))t2.start()t2.join()
最终结果:


关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平同马克龙交流互动的经典瞬间 7904050
- 2 黑龙江水库冰面下现13匹冰冻马 7809153
- 3 微信表情包戒烟再度翻红 7713181
- 4 2025你的消费习惯“更新”了吗 7617974
- 5 三星堆与秦始皇帝陵竟有联系 7522434
- 6 为啥今年流感如此厉害 7428425
- 7 劲酒如何成了年轻女性的神仙水 7333238
- 8 首次!台湾浅滩海域搜救应急演练举行 7237452
- 9 你以为的进口尖货 其实早已国产了 7140534
- 10 中疾控流感防治七问七答 7041465







OPPO安全应急响应中心
