EdBoy2202 commited on
Commit
f1e3e91
·
verified ·
1 Parent(s): 761dfd3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +281 -0
app.py ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import time
4
+ import random
5
+ import folium
6
+ from folium.plugins import MarkerCluster
7
+ from streamlit_folium import st_folium
8
+ import pygeoip
9
+ from collections import deque, OrderedDict
10
+ import datetime
11
+ import plotly.graph_objs as go
12
+ from plotly.subplots import make_subplots
13
+
14
+ # Function to get geolocation
15
+ def get_geolocation(ip):
16
+ gi = pygeoip.GeoIP('GeoLiteCity.dat')
17
+ try:
18
+ return gi.record_by_addr(ip)
19
+ except:
20
+ return None
21
+
22
+ # Function to simulate a DDoS attack
23
+ def simulate_ddos_attack():
24
+ simulated_ips = [f"192.168.1.{random.randint(1, 255)}" for _ in range(10)]
25
+ packets = random.randint(50, 200) # Random packet count
26
+ return simulated_ips, packets
27
+
28
+ # Set up the Streamlit app
29
+ st.title("Real-Time Network Traffic DDoS Monitor")
30
+
31
+ # Create a single stop button at the top of the app
32
+ stop_button = st.button('Stop', key='stop_button')
33
+
34
+ # Statistics section
35
+ st.header("Statistics")
36
+ col1, col2, col3 = st.columns(3)
37
+ with col1:
38
+ total_packets = st.empty()
39
+ with col2:
40
+ ddos_flows = st.empty()
41
+ with col3:
42
+ benign_flows = st.empty()
43
+
44
+ # Divider line
45
+ st.markdown("---")
46
+
47
+ # Active Flows section
48
+ st.header("Active Flows")
49
+
50
+ # Create placeholders for the tables, graphs, and map
51
+ active_flows_placeholder = st.empty()
52
+ malicious_ips_placeholder = st.empty()
53
+ graphs_placeholder = st.empty()
54
+ map_placeholder = st.empty()
55
+
56
+ # Initialize map in session state if it doesn't exist
57
+ if 'map' not in st.session_state:
58
+ st.session_state.map = folium.Map(location=[0, 0], zoom_start=2)
59
+ st.session_state.marker_cluster = MarkerCluster().add_to(st.session_state.map)
60
+ st.session_state.map_counter = 0
61
+
62
+ m = st.session_state.map
63
+ marker_cluster = st.session_state.marker_cluster
64
+
65
+ # Display the initial map
66
+ st_folium(m, width=700, height=500, key="initial_map")
67
+
68
+ # Load data in chunks
69
+ chunk_size = 1000 # Adjust this value based on your needs
70
+ data_iterator = pd.read_csv('SSDP_Flood_output_copy.csv', chunksize=chunk_size)
71
+
72
+ # Initialize data structures
73
+ if 'ip_packet_counts' not in st.session_state:
74
+ st.session_state.ip_packet_counts = {}
75
+ if 'time_series_data' not in st.session_state:
76
+ st.session_state.time_series_data = []
77
+ if 'ip_packet_time_series' not in st.session_state:
78
+ st.session_state.ip_packet_time_series = {}
79
+ if 'recent_rows' not in st.session_state:
80
+ st.session_state.recent_rows = deque(maxlen=10) # Correctly structured as a deque
81
+ if 'malicious_ips' not in st.session_state:
82
+ st.session_state.malicious_ips = OrderedDict()
83
+
84
+ # Initialize counters
85
+ if 'total_packet_count' not in st.session_state:
86
+ st.session_state.total_packet_count = 0
87
+ if 'ddos_flow_count' not in st.session_state:
88
+ st.session_state.ddos_flow_count = 0
89
+ if 'benign_flow_count' not in st.session_state:
90
+ st.session_state.benign_flow_count = 0
91
+
92
+ # Flag to track if the map needs updating
93
+ map_updated = False
94
+
95
+ # Display Simulate DDoS Attack button
96
+ if st.button("Simulate DDoS Attack"):
97
+ simulated_ips, packets = simulate_ddos_attack()
98
+ current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
99
+
100
+ for ip in simulated_ips:
101
+ # Create a structured row to append
102
+ row = {
103
+ 'time': current_time,
104
+ 'src': ip,
105
+ 'sport': random.randint(1024, 65535),
106
+ 'dst': '192.168.0.1', # Target IP
107
+ 'dport': 80, # Target port
108
+ 'protocol': 'TCP',
109
+ 'packets': packets,
110
+ 'label': 1 # Simulate as malicious
111
+ }
112
+
113
+ # Ensure the row is appended correctly
114
+ st.session_state.recent_rows.append(row)
115
+
116
+ # Update counters
117
+ st.session_state.total_packet_count += packets
118
+ st.session_state.ddos_flow_count += 1
119
+
120
+ # Update the statistics
121
+ total_packets.metric("Total Packets", st.session_state.total_packet_count)
122
+ ddos_flows.metric("DDoS Flows", st.session_state.ddos_flow_count)
123
+ benign_flows.metric("Benign Flows", st.session_state.benign_flow_count)
124
+
125
+ # Convert recent_rows deque to DataFrame
126
+ try:
127
+ active_flows_df = pd.DataFrame(list(st.session_state.recent_rows))
128
+ # Ensure DataFrame has expected columns
129
+ if not {'time', 'src', 'sport', 'dst', 'dport', 'protocol', 'packets'}.issubset(active_flows_df.columns):
130
+ st.error("DataFrame does not have the expected structure.")
131
+ continue
132
+
133
+ # Update active flows
134
+ active_flows_placeholder.dataframe(
135
+ active_flows_df[['time', 'src', 'sport', 'dst', 'dport', 'protocol', 'packets']],
136
+ height=300,
137
+ use_container_width=True,
138
+ hide_index=True
139
+ )
140
+
141
+ # Update the map with the simulated IP
142
+ geo_info = get_geolocation(ip)
143
+ if geo_info:
144
+ folium.Marker(
145
+ location=[geo_info['latitude'], geo_info['longitude']],
146
+ popup=ip,
147
+ icon=folium.Icon(color='red', icon='info-sign')
148
+ ).add_to(marker_cluster)
149
+
150
+ # Update the map view
151
+ map_updated = True
152
+
153
+ except Exception as e:
154
+ st.error(f"Error creating DataFrame: {str(e)}")
155
+
156
+ if map_updated:
157
+ map_placeholder.empty()
158
+ st.session_state.map_counter += 1
159
+ st_folium(m, width=700, height=500, key=f"map_{st.session_state.map_counter}")
160
+ map_updated = False
161
+
162
+ # Process data in chunks
163
+ for chunk_index, chunk in enumerate(data_iterator):
164
+ for row_index, row in chunk.iterrows():
165
+ if stop_button:
166
+ st.write('Stopped by user')
167
+ break
168
+
169
+ # Update counters
170
+ st.session_state.total_packet_count += row['packets']
171
+ if row['label'] == 1:
172
+ st.session_state.ddos_flow_count += 1
173
+ else:
174
+ st.session_state.benign_flow_count += 1
175
+
176
+ # Update statistics
177
+ total_packets.metric("Total Packets", st.session_state.total_packet_count)
178
+ ddos_flows.metric("DDoS Flows", st.session_state.ddos_flow_count)
179
+ benign_flows.metric("Benign Flows", st.session_state.benign_flow_count)
180
+
181
+ # Update the time column with current time
182
+ current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
183
+ row['time'] = current_time
184
+
185
+ # Update active flows table
186
+ st.session_state.recent_rows.append(dict(row)) # Append the dictionary of the row
187
+
188
+ # Convert recent_rows deque to DataFrame
189
+ try:
190
+ active_flows_df = pd.DataFrame(list(st.session_state.recent_rows))
191
+ active_flows_placeholder.dataframe(
192
+ active_flows_df[['time', 'src', 'sport', 'dst', 'dport', 'protocol', 'packets']],
193
+ height=300,
194
+ use_container_width=True,
195
+ hide_index=True
196
+ )
197
+
198
+ except Exception as e:
199
+ st.error(f"Error creating DataFrame: {str(e)}")
200
+
201
+ # Update the malicious IPs list if the IP is malicious
202
+ if row['label'] == 1:
203
+ if row['src'] not in st.session_state.malicious_ips:
204
+ st.session_state.malicious_ips[row['src']] = True
205
+ if len(st.session_state.malicious_ips) > 10:
206
+ st.session_state.malicious_ips.popitem(last=False)
207
+
208
+ # Add new malicious IP to the map
209
+ geo_info = get_geolocation(row['src'])
210
+ if geo_info:
211
+ folium.Marker(
212
+ location=[geo_info['latitude'], geo_info['longitude']],
213
+ popup=row['src'],
214
+ icon=folium.Icon(color='red', icon='info-sign')
215
+ ).add_to(marker_cluster)
216
+
217
+ # Set flag to update map
218
+ map_updated = True
219
+
220
+ # Format malicious IPs as a numbered list
221
+ malicious_ips_text = "**Recent Malicious IPs:**\n"
222
+ for i, ip in enumerate(st.session_state.malicious_ips.keys(), 1):
223
+ malicious_ips_text += f"{i}. <span style='color: red;'>{ip}</span>\n"
224
+ malicious_ips_placeholder.markdown(malicious_ips_text, unsafe_allow_html=True)
225
+
226
+ # Update packet counts for the source IP
227
+ src_ip = row['src']
228
+ packets = row['packets']
229
+
230
+ if src_ip not in st.session_state.ip_packet_counts:
231
+ st.session_state.ip_packet_counts[src_ip] = 0
232
+ st.session_state.ip_packet_time_series[src_ip] = []
233
+
234
+ st.session_state.ip_packet_counts[src_ip] += packets
235
+ st.session_state.ip_packet_time_series[src_ip].append((current_time, st.session_state.ip_packet_counts[src_ip]))
236
+
237
+ # Add current total packet count to time series data
238
+ st.session_state.time_series_data.append((current_time, st.session_state.total_packet_count))
239
+
240
+ # Create and update the graphs
241
+ if len(st.session_state.ip_packet_counts) > 0:
242
+ fig = make_subplots(rows=3, cols=1,
243
+ subplot_titles=("Top 10 Source IPs by Packet Count",
244
+ "Total Packet Count Over Time",
245
+ "Packet Count per Source IP Over Time"))
246
+
247
+ top_ips = sorted(st.session_state.ip_packet_counts.items(), key=lambda x: x[1], reverse=True)[:10]
248
+ ips, counts = zip(*top_ips)
249
+
250
+ fig.add_trace(go.Bar(x=ips, y=counts), row=1, col=1)
251
+
252
+ times, packet_counts = zip(*st.session_state.time_series_data[-100:])
253
+ fig.add_trace(go.Scatter(x=times, y=packet_counts, mode='lines'), row=2, col=1)
254
+
255
+ for ip in ips:
256
+ ip_times, ip_counts = zip(*st.session_state.ip_packet_time_series[ip][-100:])
257
+ fig.add_trace(go.Scatter(x=ip_times, y=ip_counts, mode='lines', name=ip), row=3, col=1)
258
+
259
+ fig.update_layout(height=1200, showlegend=True)
260
+ fig.update_xaxes(title_text="Source IP", row=1, col=1)
261
+ fig.update_xaxes(title_text="Time", row=2, col=1)
262
+ fig.update_xaxes(title_text="Time", row=3, col=1)
263
+ fig.update_yaxes(title_text="Packet Count", row=1, col=1)
264
+ fig.update_yaxes(title_text="Total Packet Count", row=2, col=1)
265
+ fig.update_yaxes(title_text="Packet Count", row=3, col=1)
266
+
267
+ graphs_placeholder.plotly_chart(fig, use_container_width=True)
268
+
269
+ # Update the map if new points were added
270
+ if map_updated:
271
+ map_placeholder.empty()
272
+ st.session_state.map_counter += 1
273
+ st_folium(m, width=700, height=500, key=f"map_{st.session_state.map_counter}")
274
+ map_updated = False
275
+
276
+ time.sleep(0.1)
277
+
278
+ if stop_button:
279
+ break
280
+
281
+ st.write("Data processing complete")