-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcapture_packets.py
More file actions
157 lines (127 loc) · 4.41 KB
/
capture_packets.py
File metadata and controls
157 lines (127 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
'''
Description:
A python script that will capture network packets
running through this machine.
This is the first part of a program that will classify
network traffic.
Written for Advanced Computer Networks at WPI, 2019 D Term
Professor Lorenzo De Carli.
Authors:
Theodore Bieber
Thomas White
'''
# pip installs: libpcap, scapy==2.4.0 !!! scapy version > 2.4.0 has unresolved issues on windows
# also could do pip install -r requirements.txt
import time
from threading import Event, Thread
# also install npcap https://nmap.org/download.html (latest Npcap release self-install worked for me)
from scapy.all import *
from flow import Flow
from burst import Burst
import queue # for our packets or bursts
# Used to signal to the analysis thread to stop
shutdown_event = Event()
# queue for storing our packets, Queue is FIFO, we can also do LifoQueue, PriorityQueue, or a SimpleQueue that is a less useful version of Queue
packet_queue = queue.Queue(0) # 0 is the default, indicating that the maximum size is infinite
last_packet = None
class AnalysisThread(Thread):
"""
Custom Thread class to loop continuously in the background
and perform analysis if the burst threshold has been met
"""
def __init__(self, event):
Thread.__init__(self)
self.stop_flag = event
def run(self):
while not self.stop_flag.wait(.45):
self.check_for_burst()
def check_for_burst(self):
"""
Used to check if analysis should start
"""
# Don't process if there is nothing to process
if not packet_queue.empty():
if time.time() - last_packet.time > 1:
self.analyze_burst(last_packet)
def analyze_burst(self, last_packet):
"""
Handles putting packets into flows, prints, and then archives the burst
stops processing when `last_packet` is reached
"""
current_pkt = packet_queue.get()
identified_flows = []
# Group the packets into flows
while True:
for data_flow in identified_flows:
if data_flow == current_pkt:
data_flow += current_pkt
break
# The else statement will trigger if the break never happens
else:
identified_flows.append(Flow().__add__(current_pkt))
# current_pkt[IP].src,
# current_pkt[IP].dst,
# current_pkt[TCP].sport,
# current_pkt[TCP].dport,
# ))
if current_pkt is not last_packet:
current_pkt = packet_queue.get()
# We've reached the end of the burst,
# stop dequing
else:
break
# Print out the statistics (formatted in the Flow)
print('===============START OF BURST==================')
for flow in identified_flows:
print(flow)
print("===============END OF BURST====================\n")
def main():
FILTER = "ip" # TODO: gonna wanna change this
# TODO: thread this, and then run another thread to print flows
# Does the ^above^ comment make sense to do?
analysis = AnalysisThread(shutdown_event)
analysis.start()
sniff(filter=FILTER, prn=handle_sniffed, count=0) # count = 0 means run indefinitely
shutdown_event.set()
# read packet in from file, write the result to a string
def read_from_file(pcap_path):
packets = rdpcap(pcap_path)
bursts = []
for packet in packets:
if packet.haslayer(TCP) and packet.haslayer(IP):
for burst in bursts:
if burst == packet:
burst+packet
break
else:
bursts.append(Burst(packet))
# add new burst
out = ""
for b in bursts:
out+='===============START OF BURST==================\n'
out+= str(b)
out+="===============END OF BURST====================\n"
return out
# separate the packets into flows
''' handle_sniffed:
A function that sniff() from scapy will call each time it sniffs a packet
Think of it as the master function that will handle captured traffic
param: packet - the packet that was captured
'''
def handle_sniffed(packet):
# FYI:
# subscripting packets is to access specific layers, like TCP or IP. These must be imported from scapy.all
# to get specific elements reference https://blogs.sans.org/pen-testing/files/2016/04/ScapyCheatSheet_v0.2.pdf
# put_in_flow(packet)
global last_packet
if packet.haslayer(TCP) and packet.haslayer(IP): # so this line we will probably need to remove at some point, but we also need the IP and TCP layers in order to get some information with scapy
last_packet = packet
packet_queue.put(packet)
# # make sure to log flows on exit (no longer think this is necessary, but will leave for now)
# def onexit():
# do something
# import atexit
# atexit.register(onexit)
# run main
if __name__ == '__main__':
main()