使用 scapy 和 python 将 MAC 地址记录到 csv
Logging MAC addresses into a csv using scapy and python
好的,所以我正在尝试创建一个 csv 文件,其中包含所有已看到的 mac 地址和 SSID 的列表。这是我到目前为止得到的代码,其中大部分来自:http://edwardkeeble.com/2014/02/passive-wifi-tracking/ 我正在使用 python 2.7.
from scapy.all import *
import csv, time
from datetime import datetime
PROBE_REQUEST_TYPE=0
PROBE_REQUEST_SUBTYPE=4
WHITELIST = ['de:ad:be:ef:ca:fe',] # Replace this with your phone's MAC address
def PacketHandler(pkt):
if pkt.haslayer(Dot11):
if pkt.type==PROBE_REQUEST_TYPE and pkt.subtype == PROBE_REQUEST_SUBTYPE and ( pkt.addr2.lower() not in WHITELIST and pkt.addr2.upper() not in WHITELIST):
CheckCsv(pkt)
def PrintPacket(pkt):
try:
extra = pkt.notdecoded
except:
extra = None
if extra!=None:
signal_strength = -(256-ord(extra[-4:-3]))
else:
signal_strength = -100
print "No signal strength found"
print "Added: %s SSID: %s"%(pkt.addr2,pkt.getlayer(Dot11ProbeReq).info)
with open('logmacs.csv','ab') as out:
w=csv.writer(out)
w.writerow([datetime.now().strftime('%Y-%m-%d'),datetime.now().strftime('%H:%M:%S'),pkt.addr2,pkt.getlayer(Dot11ProbeReq).info,signal_strength])
out.close()
def CheckCsv(pkt):
with open('logmacs.csv', 'rb') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if pkt.addr2 != row[2]:
PrintPacket(pkt)
f.close()
def main():
print "[%s] Starting scan"%datetime.now()
print "Scanning..."
while True:
sniff(iface=sys.argv[1],prn=PacketHandler, count=1)
time.sleep(2)
if __name__=="__main__":
main()
现在看来,它要么捕获了大量数据包,要么陷入写入单个数据包的循环中。我添加了 "count=1 and while True: and time.sleep(2)" 以试图防止这种情况发生,但似乎没有帮助。
我想做的是在看到 MAC 时记录一个 date/time 来创建一个唯一的 MAC 列表,但这并没有完全做到这一点。 ...
您不应在读取输出文件的同时写入输出文件。当前,您在 PrintPacket
中更新 logmacs.csv 的内容,同时在 CheckCsv
.
中迭代它
我会修改 CheckCsv
的实现(和名称)以将监视的数据包存储到内存中的某个新变量,并检查是否应根据这个新引入的变量更新输出文件。这还有一个额外的好处,那就是它也更有效率。
我也会打开文件只写入一次而不是每次写入(尝试使用 class
而不是 function
)。
编辑:
为了响应您的澄清请求,这里有一个基本实现,它符合我的目标:
from scapy.all import *
from datetime import datetime
import csv
PROBE_REQUEST_TYPE = 0
PROBE_REQUEST_SUBTYPE = 4
WHITELIST = ['de:ad:be:ef:ca:fe',] # Replace this with your phone's MAC address
PACKET_FILE_PATH = 'logmacs.csv'
class PacketHandler(object):
def __init__(self, packet_file_path):
self.packet_file_path = packet_file_path
self.handled_packets = set()
def __enter__(self):
self.csv_file = open(self.packet_file_path, 'ab')
self.csv_writer = csv.writer(self.csv_file)
return self
def __exit__(self, *exc_info):
self.csv_file.close()
def handle_packet(self, pkt):
if pkt.haslayer(Dot11) and pkt.type == PROBE_REQUEST_TYPE and pkt.subtype == PROBE_REQUEST_SUBTYPE and (pkt.addr2.lower() not in WHITELIST and pkt.addr2.upper() not in WHITELIST) and pkt.addr2 not in self.handled_packets:
self.add_packet(pkt)
def add_packet(self, pkt):
self.handled_packets.add(pkt.addr2)
try:
signal_strength = -(256 - ord(pkt.notdecoded[-4:-3]))
except Exception, e:
signal_strength = -100
print "No signal strength found"
self.csv_writer.writerow([datetime.now().strftime('%Y-%m-%d'),
datetime.now().strftime('%H:%M:%S'),
pkt.addr2,
pkt.getlayer(Dot11ProbeReq).info,
signal_strength])
print "Added: %s SSID: %s" % (pkt.addr2, pkt.getlayer(Dot11ProbeReq).info)
def main():
packet_handler = PacketHandler(PACKET_FILE_PATH)
print "[%s] Starting scan" % datetime.now()
print "Scanning..."
with packet_handler as ph:
sniff(iface=sys.argv[1], prn=ph.handle_packet)
if __name__=="__main__":
main()
我要强调的主要改进:
输出文件仅在 __enter__
方法期间打开一次,该方法在输入 with
语句时调用。
不是分析输出文件以查明是否已经遇到某个客户端,而是维护一个本地变量来保存所有检测到的客户端。检查此变量比打开和读取输出文件更有效。
好的,所以我正在尝试创建一个 csv 文件,其中包含所有已看到的 mac 地址和 SSID 的列表。这是我到目前为止得到的代码,其中大部分来自:http://edwardkeeble.com/2014/02/passive-wifi-tracking/ 我正在使用 python 2.7.
from scapy.all import *
import csv, time
from datetime import datetime
PROBE_REQUEST_TYPE=0
PROBE_REQUEST_SUBTYPE=4
WHITELIST = ['de:ad:be:ef:ca:fe',] # Replace this with your phone's MAC address
def PacketHandler(pkt):
if pkt.haslayer(Dot11):
if pkt.type==PROBE_REQUEST_TYPE and pkt.subtype == PROBE_REQUEST_SUBTYPE and ( pkt.addr2.lower() not in WHITELIST and pkt.addr2.upper() not in WHITELIST):
CheckCsv(pkt)
def PrintPacket(pkt):
try:
extra = pkt.notdecoded
except:
extra = None
if extra!=None:
signal_strength = -(256-ord(extra[-4:-3]))
else:
signal_strength = -100
print "No signal strength found"
print "Added: %s SSID: %s"%(pkt.addr2,pkt.getlayer(Dot11ProbeReq).info)
with open('logmacs.csv','ab') as out:
w=csv.writer(out)
w.writerow([datetime.now().strftime('%Y-%m-%d'),datetime.now().strftime('%H:%M:%S'),pkt.addr2,pkt.getlayer(Dot11ProbeReq).info,signal_strength])
out.close()
def CheckCsv(pkt):
with open('logmacs.csv', 'rb') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
if pkt.addr2 != row[2]:
PrintPacket(pkt)
f.close()
def main():
print "[%s] Starting scan"%datetime.now()
print "Scanning..."
while True:
sniff(iface=sys.argv[1],prn=PacketHandler, count=1)
time.sleep(2)
if __name__=="__main__":
main()
现在看来,它要么捕获了大量数据包,要么陷入写入单个数据包的循环中。我添加了 "count=1 and while True: and time.sleep(2)" 以试图防止这种情况发生,但似乎没有帮助。
我想做的是在看到 MAC 时记录一个 date/time 来创建一个唯一的 MAC 列表,但这并没有完全做到这一点。 ...
您不应在读取输出文件的同时写入输出文件。当前,您在 PrintPacket
中更新 logmacs.csv 的内容,同时在 CheckCsv
.
我会修改 CheckCsv
的实现(和名称)以将监视的数据包存储到内存中的某个新变量,并检查是否应根据这个新引入的变量更新输出文件。这还有一个额外的好处,那就是它也更有效率。
我也会打开文件只写入一次而不是每次写入(尝试使用 class
而不是 function
)。
编辑:
为了响应您的澄清请求,这里有一个基本实现,它符合我的目标:
from scapy.all import *
from datetime import datetime
import csv
PROBE_REQUEST_TYPE = 0
PROBE_REQUEST_SUBTYPE = 4
WHITELIST = ['de:ad:be:ef:ca:fe',] # Replace this with your phone's MAC address
PACKET_FILE_PATH = 'logmacs.csv'
class PacketHandler(object):
def __init__(self, packet_file_path):
self.packet_file_path = packet_file_path
self.handled_packets = set()
def __enter__(self):
self.csv_file = open(self.packet_file_path, 'ab')
self.csv_writer = csv.writer(self.csv_file)
return self
def __exit__(self, *exc_info):
self.csv_file.close()
def handle_packet(self, pkt):
if pkt.haslayer(Dot11) and pkt.type == PROBE_REQUEST_TYPE and pkt.subtype == PROBE_REQUEST_SUBTYPE and (pkt.addr2.lower() not in WHITELIST and pkt.addr2.upper() not in WHITELIST) and pkt.addr2 not in self.handled_packets:
self.add_packet(pkt)
def add_packet(self, pkt):
self.handled_packets.add(pkt.addr2)
try:
signal_strength = -(256 - ord(pkt.notdecoded[-4:-3]))
except Exception, e:
signal_strength = -100
print "No signal strength found"
self.csv_writer.writerow([datetime.now().strftime('%Y-%m-%d'),
datetime.now().strftime('%H:%M:%S'),
pkt.addr2,
pkt.getlayer(Dot11ProbeReq).info,
signal_strength])
print "Added: %s SSID: %s" % (pkt.addr2, pkt.getlayer(Dot11ProbeReq).info)
def main():
packet_handler = PacketHandler(PACKET_FILE_PATH)
print "[%s] Starting scan" % datetime.now()
print "Scanning..."
with packet_handler as ph:
sniff(iface=sys.argv[1], prn=ph.handle_packet)
if __name__=="__main__":
main()
我要强调的主要改进:
输出文件仅在
__enter__
方法期间打开一次,该方法在输入with
语句时调用。不是分析输出文件以查明是否已经遇到某个客户端,而是维护一个本地变量来保存所有检测到的客户端。检查此变量比打开和读取输出文件更有效。