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=iface
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 PacketHandler(self,pkt):
ap_mac=pkt[Dot11].addr3
if ap_mac not in self.ap:
self.ap.append(ap_mac)
print "%s | beacon"%ap_mac
pkt.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].addr3
if ap_mac not in self.ap:
self.ap.append(ap_mac)
print "%s | beacon"%ap_mac
pkt.show()
PacketHandler用来处理嗅探到的Beacon帧,scapy会解析Beacon帧,可以使用pkt.show()查看Beacon的各个layer,运行此脚本:
在Dot11层可以看到Beacon帧头的一部分信息,其中addr3即为Beacon帧的源地址。
如果不熟悉scapy的layer命名,可以用下面定义的函数查看:
def expand(x):
yield x
while x.payload:
x = x.payload
yield x
print 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: #ssid
ssid=elt.info
获取信道:
elif elt.ID==3: #channel
ch=ord(elt.info)
解析RSN有些复杂:
pkt.show()
虽然scapy已经解析出加密以及认证方式,但我们取出仍是字节,取出pairwise_cipher_suites以及akm_suites的最后一个字节,再到字典比对:
elif elt.ID==48: #ciper and auth
cipher_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=iface
self.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].addr3
if ap_mac not in self.ap:
ssid=None
ch=None
cipher=None
auth=None
self.ap.append(ap_mac)
elt=pkt[Dot11Elt]
while elt.payload:
if elt.ID==0: #ssid
ssid=elt.info
elif elt.ID==3: #channel
ch=ord(elt.info)
elif elt.ID==48: #ciper and auth
cipher_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.payload
print 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 Thread
import os
import time
def change_ch(iface):
ch=0
while 1:
ch+=1
cmd="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=iface
self.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].addr3
if ap_mac not in self.ap:
ssid=None
ch=None
cipher=None
auth=None
self.ap.append(ap_mac)
elt=pkt[Dot11Elt]
while elt.payload:
if elt.ID==0: #ssid
ssid=elt.info
elif elt.ID==3: #channel
ch=ord(elt.info)
elif elt.ID==48: #ciper and auth
cipher_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.payload
print 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=True
t1.start()
t2=Thread(target=sniffer,args=('wlan0mon',))
t2.start()
t2.join()
最终结果:
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 澳门是伟大祖国的一方宝地 7930557
- 2 日本火山喷发灰柱高达3400米 7961372
- 3 女子穿和服在南京景区拍照遭怒怼 7895730
- 4 2024 向上的中国 7711150
- 5 肖战新片射雕英雄传郭靖造型曝光 7659183
- 6 大三女生练咏春一起手眼神骤变 7516775
- 7 胡锡进与你聊聊2024 7454115
- 8 男子钓上一条自带“赎金”的鱼 7386292
- 9 赵丽颖带儿子探班 7276735
- 10 高考601分女生为何选择殡葬专业 7109483