charag/networkintrusiondetection
0
1import gradio as gr
2import pandas as pd
3import numpy as np
4from sklearn.ensemble import RandomForestClassifier
5from sklearn.preprocessing import LabelEncoder, StandardScaler
6import os
7
8# Load and train on your actual KDDTrain+ dataset
9def load_and_train_model():
10 """Load KDDTrain+ dataset and train Random Forest with 10 features"""
11
12 # Check if dataset file exists
13 dataset_file = 'KDDTrain+.csv'
14
15 if not os.path.exists(dataset_file):
16 return None, None, None, None, None, "⚠️ Please upload KDDTrain+.csv file"
17
18 print("Loading KDDTrain+ dataset...")
19
20 # Column names for KDD dataset (all 43)
21 columns = [
22 'duration', 'protocol_type', 'service', 'flag', 'src_bytes', 'dst_bytes',
23 'land', 'wrong_fragment', 'urgent', 'hot', 'num_failed_logins',
24 'logged_in', 'num_compromised', 'root_shell', 'su_attempted', 'num_root',
25 'num_file_creations', 'num_shells', 'num_access_files', 'num_outbound_cmds',
26 'is_host_login', 'is_guest_login', 'count', 'srv_count', 'serror_rate',
27 'srv_serror_rate', 'rerror_rate', 'srv_rerror_rate', 'same_srv_rate',
28 'diff_srv_rate', 'srv_diff_host_rate', 'dst_host_count', 'dst_host_srv_count',
29 'dst_host_same_srv_rate', 'dst_host_diff_srv_rate', 'dst_host_same_src_port_rate',
30 'dst_host_srv_diff_host_rate', 'dst_host_serror_rate', 'dst_host_srv_serror_rate',
31 'dst_host_rerror_rate', 'dst_host_srv_rerror_rate', 'attack_type', 'difficulty'
32 ]
33
34 try:
35 # Load full dataset
36 df = pd.read_csv(dataset_file, names=columns)
37 print(f"Dataset loaded! Total samples: {len(df)}")
38
39 # Create binary label: 0 for normal, 1 for attack
40 df['label'] = df['attack_type'].apply(lambda x: 0 if str(x).strip() == 'normal' else 1)
41
42 print(f"Normal samples: {len(df[df['label'] == 0])}")
43 print(f"Attack samples: {len(df[df['label'] == 1])}")
44
45 # Encode categorical features
46 le_protocol = LabelEncoder()
47 le_service = LabelEncoder()
48 le_flag = LabelEncoder()
49
50 df['protocol_encoded'] = le_protocol.fit_transform(df['protocol_type'])
51 df['service_encoded'] = le_service.fit_transform(df['service'])
52 df['flag_encoded'] = le_flag.fit_transform(df['flag'])
53
54 # ========== USE 10 FEATURES (6 original + 4 new) ==========
55 feature_columns = [
56 # Original 6 features
57 'src_bytes', 'dst_bytes', 'protocol_encoded',
58 'duration', 'flag_encoded', 'service_encoded',
59
60 # NEW 4 IMPORTANT FEATURES
61 'count', # Connections to same host (detects floods/scans)
62 'srv_count', # Connections to same service
63 'same_srv_rate', # % of connections to same service
64 'serror_rate' # % of SYN error connections (detects SYN flood)
65 ]
66
67 X_train = df[feature_columns]
68 y_train = df['label']
69
70 print(f"Training with {len(feature_columns)} features: {feature_columns}")
71
72 # Train model with optimized parameters
73 print("Training Random Forest on KDDTrain+ dataset...")
74 model = RandomForestClassifier(
75 n_estimators=100, # Increased from 50 for better accuracy
76 max_depth=20, # Limit depth to avoid overfitting
77 random_state=42,
78 n_jobs=-1,
79 class_weight='balanced' # Handle imbalanced data
80 )
81 model.fit(X_train, y_train)
82
83 # Calculate accuracy
84 train_acc = model.score(X_train, y_train)
85 print(f"Training accuracy: {train_acc:.2%}")
86
87 # Feature importance for PPT
88 importance_dict = dict(zip(feature_columns, model.feature_importances_))
89 print("\n📊 Feature Importance:")
90 for feat, imp in sorted(importance_dict.items(), key=lambda x: x[1], reverse=True):
91 print(f" {feat}: {imp:.2%}")
92
93 return model, le_protocol, le_flag, le_service, df, f"✅ Model trained! Accuracy: {train_acc:.2%} (10 features)"
94
95 except Exception as e:
96 print(f"Error: {str(e)}")
97 return None, None, None, None, None, f"❌ Error loading dataset: {str(e)}"
98
99# Load model when app starts
100print("="*50)
101print("Starting KDDTrain+ Intrusion Detection System (10 Features)")
102print("="*50)
103model, le_protocol, le_flag, le_service, df, status_msg = load_and_train_model()
104
105# Prediction function with 10 features
106def detect_intrusion(source_bytes, destination_bytes, protocol, duration, flag, service,
107 count, srv_count, same_srv_rate, serror_rate):
108 """Predict with 10 features including traffic statistics"""
109
110 if model is None:
111 return f"<div style='padding:20px; background-color:#ffebee; border-radius:10px'><h3 style='color:red'>❌ {status_msg}</h3><p>Please make sure KDDTrain+.csv is uploaded to the Hugging Face Space.</p></div>"
112
113 try:
114 # Encode categorical inputs
115 protocol_encoded = le_protocol.transform([protocol])[0]
116 flag_encoded = le_flag.transform([flag])[0]
117 service_encoded = le_service.transform([service])[0]
118
119 # Create input for model (10 features now)
120 input_data = pd.DataFrame({
121 'src_bytes': [source_bytes],
122 'dst_bytes': [destination_bytes],
123 'protocol_encoded': [protocol_encoded],
124 'duration': [duration],
125 'flag_encoded': [flag_encoded],
126 'service_encoded': [service_encoded],
127 'count': [count],
128 'srv_count': [srv_count],
129 'same_srv_rate': [same_srv_rate],
130 'serror_rate': [serror_rate]
131 })
132
133 # Make prediction
134 prediction = model.predict(input_data)[0]
135 probabilities = model.predict_proba(input_data)[0]
136
137 # Find similar attacks in dataset
138 similar_attacks = df[
139 (df['service'] == service) &
140 (df['src_bytes'].between(source_bytes*0.5, source_bytes*1.5)) &
141 (df['dst_bytes'].between(destination_bytes*0.5, destination_bytes*1.5))
142 ]['attack_type'].value_counts()
143
144 # Generate result (same HTML output as before)
145 if prediction == 1:
146 attack_type = "Unknown Attack"
147 if len(similar_attacks) > 0 and similar_attacks.index[0] != 'normal':
148 attack_type = similar_attacks.index[0]
149
150 # Determine attack category
151 attack_categories = {
152 'neptune': 'DoS', 'smurf': 'DoS', 'back': 'DoS', 'pod': 'DoS', 'teardrop': 'DoS', 'land': 'DoS',
153 'ipsweep': 'Probe', 'nmap': 'Probe', 'portsweep': 'Probe', 'satan': 'Probe',
154 'guess_passwd': 'R2L', 'warezmaster': 'R2L', 'warezclient': 'R2L', 'ftp_write': 'R2L',
155 'buffer_overflow': 'U2R', 'loadmodule': 'U2R', 'perl': 'U2R', 'rootkit': 'U2R'
156 }
157 category = attack_categories.get(attack_type.split()[0] if ' ' in attack_type else attack_type, 'Unknown')
158
159 analysis = f"""
160 <div style="padding: 20px; border-radius: 10px; background-color: #ffebee; border-left: 5px solid #f44336;">
161 <h2 style="color: #d32f2f; margin-top: 0;">🔴 INTRUSION DETECTED!</h2>
162
163 <table style="width: 100%; border-collapse: collapse; margin: 10px 0;">
164 <tr><td style="padding: 8px; background-color: #ffcdd2; width: 40%;"><b>Attack Type:</b></td>
165 <td style="padding: 8px; background-color: #ffcdd2;"><b>{attack_type}</b></td></tr>
166 <tr><td style="padding: 8px;"><b>Attack Category:</b></td>
167 <td style="padding: 8px;">{category}</td></tr>
168 <tr><td style="padding: 8px; background-color: #ffcdd2;"><b>Confidence:</b></td>
169 <td style="padding: 8px; background-color: #ffcdd2;">{probabilities[1]:.2%}</td></tr>
170 <tr><td style="padding: 8px;"><b>Risk Level:</b></td>
171 <td style="padding: 8px;"><span style="color: #d32f2f; font-weight: bold;">HIGH</span></td></tr>
172 </table>
173
174 <h3>📊 Traffic Analysis:</h3>
175 <table style="width: 100%; border-collapse: collapse;">
176 <tr><td style="padding: 5px;"><b>Source Bytes:</b></td><td>{source_bytes:,} bytes</td></tr>
177 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Destination Bytes:</b></td><td>{destination_bytes:,} bytes</td></tr>
178 <tr><td style="padding: 5px;"><b>Protocol:</b></td><td>{protocol.upper()}</td></tr>
179 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Duration:</b></td><td>{duration}</td></tr>
180 <tr><td style="padding: 5px;"><b>Flag:</b></td><td>{flag}</td></tr>
181 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Service:</b></td><td>{service}</td></tr>
182 <tr><td style="padding: 5px;"><b>Count (connections to host):</b></td><td>{count}</td></tr>
183 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Service Count:</b></td><td>{srv_count}</td></tr>
184 <tr><td style="padding: 5px;"><b>Same Service Rate:</b></td><td>{same_srv_rate:.1%}</td></tr>
185 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>SYN Error Rate:</b></td><td>{serror_rate:.1%}</td></tr>
186 </table>
187
188 <div style="margin-top: 15px; padding: 10px; background-color: #ffcdd2; border-radius: 5px;">
189 <b>⚠️ Security Alert:</b> High connection count ({count}) and SYN error rate ({serror_rate:.1%}) indicate attack pattern.
190 </div>
191 </div>
192 """
193 else:
194 analysis = f"""
195 <div style="padding: 20px; border-radius: 10px; background-color: #e8f5e8; border-left: 5px solid #4caf50;">
196 <h2 style="color: #2e7d32; margin-top: 0;">🟢 NORMAL TRAFFIC</h2>
197
198 <table style="width: 100%; border-collapse: collapse; margin: 10px 0;">
199 <tr><td style="padding: 8px; background-color: #c8e6c9; width: 40%;"><b>Confidence:</b></td>
200 <td style="padding: 8px; background-color: #c8e6c9;">{probabilities[0]:.2%}</td></tr>
201 <tr><td style="padding: 8px;"><b>Attack Probability:</b></td>
202 <td style="padding: 8px;">{probabilities[1]:.2%}</td></tr>
203 <tr><td style="padding: 8px; background-color: #c8e6c9;"><b>Risk Level:</b></td>
204 <td style="padding: 8px; background-color: #c8e6c9;"><span style="color: #2e7d32; font-weight: bold;">LOW</span></td></tr>
205 </table>
206
207 <h3>📊 Traffic Analysis:</h3>
208 <table style="width: 100%; border-collapse: collapse;">
209 <tr><td style="padding: 5px;"><b>Source Bytes:</b></td><td>{source_bytes:,} bytes</td></tr>
210 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Destination Bytes:</b></td><td>{destination_bytes:,} bytes</td></tr>
211 <tr><td style="padding: 5px;"><b>Protocol:</b></td><td>{protocol.upper()}</td></tr>
212 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Duration:</b></td><td>{duration}</td></tr>
213 <tr><td style="padding: 5px;"><b>Flag:</b></td><td>{flag}</td></tr>
214 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Service:</b></td><td>{service}</td></tr>
215 <tr><td style="padding: 5px;"><b>Count (connections to host):</b></td><td>{count}</td></tr>
216 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>Service Count:</b></td><td>{srv_count}</td></tr>
217 <tr><td style="padding: 5px;"><b>Same Service Rate:</b></td><td>{same_srv_rate:.1%}</td></tr>
218 <tr><td style="padding: 5px; background-color: #f5f5f5;"><b>SYN Error Rate:</b></td><td>{serror_rate:.1%}</td></tr>
219 </table>
220
221 <div style="margin-top: 15px; padding: 10px; background-color: #c8e6c9; border-radius: 5px;">
222 <b>✅ Safe:</b> Normal traffic pattern detected.
223 </div>
224 </div>
225 """
226
227 return analysis
228
229 except Exception as e:
230 return f"""
231 <div style='padding:20px; background-color:#ffebee; border-radius:10px'>
232 <h3 style='color:red'>❌ Prediction Error</h3>
233 <p>{str(e)}</p>
234 <p>Try using different input values.</p>
235 </div>
236 """
237
238# Create Gradio interface with 10 inputs
239with gr.Blocks(theme=gr.themes.Soft(), title="KDDTrain+ IDS - 10 Features") as demo:
240 gr.Markdown("""
241 # 🛡️ Network Intrusion Detection System
242 ### Powered by Random Forest trained on **KDDTrain+ Dataset** (10 Features)
243 """)
244
245 # Status message
246 with gr.Row():
247 with gr.Column():
248 if model is not None:
249 gr.Markdown(f"""
250 <div style="padding: 10px; background-color: #e8f5e8; border-radius: 5px; border-left: 5px solid #4caf50;">
251 <b>✅ {status_msg}</b>
252 </div>
253 """)
254
255 # Show dataset stats
256 total = len(df)
257 normal = len(df[df['label'] == 0])
258 attacks = len(df[df['label'] == 1])
259
260 gr.Markdown(f"""
261 <div style="display: flex; gap: 10px; margin: 10px 0;">
262 <div style="flex: 1; padding: 10px; background-color: #e3f2fd; border-radius: 5px; text-align: center;">
263 <h3>📊 Total</h3>
264 <h2>{total:,}</h2>
265 </div>
266 <div style="flex: 1; padding: 10px; background-color: #e8f5e8; border-radius: 5px; text-align: center;">
267 <h3>✅ Normal</h3>
268 <h2>{normal:,}</h2>
269 </div>
270 <div style="flex: 1; padding: 10px; background-color: #ffebee; border-radius: 5px; text-align: center;">
271 <h3>🔴 Attacks</h3>
272 <h2>{attacks:,}</h2>
273 </div>
274 </div>
275 """)
276 else:
277 gr.Markdown(f"""
278 <div style="padding: 20px; background-color: #ffebee; border-radius: 10px;">
279 <h3 style="color: red;">❌ {status_msg}</h3>
280 <p>Please upload your KDDTrain+.csv file to the Hugging Face Space files.</p>
281 </div>
282 """)
283
284 # Input section - 2 columns for better organization
285 with gr.Row():
286 with gr.Column(scale=1):
287 gr.Markdown("### 📥 Basic Connection Features")
288 source_bytes = gr.Number(label="Source Bytes", value=491, info="Bytes sent from source")
289 destination_bytes = gr.Number(label="Destination Bytes", value=0, info="Bytes received by destination")
290 protocol = gr.Dropdown(choices=["tcp", "udp", "icmp"], value="tcp", label="Protocol")
291 duration = gr.Number(value=0, label="Duration", info="Connection duration (seconds)")
292 flag = gr.Dropdown(choices=["SF", "S0", "REJ", "RST", "SH", "S1", "S2", "S3"], value="SF", label="Connection Flag")
293 service = gr.Dropdown(choices=["http", "smtp", "ftp", "telnet", "private", "domain_u", "eco_i", "ecr_i"], value="http", label="Service/Port")
294
295 with gr.Column(scale=1):
296 gr.Markdown("### 📈 Traffic Statistics Features")
297 count = gr.Number(label="Count", value=1, info="Connections to same host (last 2 sec)", minimum=0, maximum=500)
298 srv_count = gr.Number(label="Service Count", value=1, info="Connections to same service (last 2 sec)", minimum=0, maximum=500)
299 same_srv_rate = gr.Slider(label="Same Service Rate", value=1.0, minimum=0.0, maximum=1.0, step=0.01, info="% of connections to same service")
300 serror_rate = gr.Slider(label="SYN Error Rate", value=0.0, minimum=0.0, maximum=1.0, step=0.01, info="% of connections with SYN errors")
301
302 with gr.Row():
303 submit_btn = gr.Button("🔍 ANALYZE TRAFFIC", variant="primary", size="lg")
304
305 with gr.Row():
306 output = gr.HTML(label="Analysis Result")
307
308 # Example buttons
309 gr.Markdown("### 📋 Test with Examples")
310 with gr.Row():
311 example1 = gr.Button("1️⃣ Normal HTTP")
312 example2 = gr.Button("2️⃣ DoS (Neptune)")
313 example3 = gr.Button("3️⃣ Probe (Ipsweep)")
314 example4 = gr.Button("4️⃣ DoS (Smurf)")
315 example5 = gr.Button("5️⃣ Port Scan")
316
317 # Example values
318 example1.click(
319 fn=lambda: detect_intrusion(491, 0, "tcp", 0, "SF", "http", 5, 5, 1.0, 0.0),
320 inputs=[], outputs=output
321 )
322 example2.click(
323 fn=lambda: detect_intrusion(0, 0, "tcp", 0, "S0", "private", 200, 200, 1.0, 0.95),
324 inputs=[], outputs=output
325 )
326 example3.click(
327 fn=lambda: detect_intrusion(18, 0, "icmp", 0, "SF", "eco_i", 50, 1, 0.02, 0.0),
328 inputs=[], outputs=output
329 )
330 example4.click(
331 fn=lambda: detect_intrusion(1032, 0, "icmp", 0, "SF", "ecr_i", 300, 300, 1.0, 0.0),
332 inputs=[], outputs=output
333 )
334 example5.click(
335 fn=lambda: detect_intrusion(0, 0, "tcp", 0, "REJ", "private", 100, 50, 0.5, 0.6),
336 inputs=[], outputs=output
337 )
338
339 submit_btn.click(
340 fn=detect_intrusion,
341 inputs=[source_bytes, destination_bytes, protocol, duration, flag, service,
342 count, srv_count, same_srv_rate, serror_rate],
343 outputs=output
344 )
345
346 gr.Markdown("""
347 ---
348 ### 📚 Feature Explanation
349
350 | Feature | Description | Attack Indicator |
351 |---------|-------------|------------------|
352 | **count** | Connections to same host (2 sec) | >100 = DoS/Scan |
353 | **srv_count** | Connections to same service | >100 = Service attack |
354 | **same_srv_rate** | % to same service | <50% = Port scan |
355 | **serror_rate** | % SYN errors | >50% = SYN flood |
356 """)
357
358# Launch the app
359if __name__ == "__main__":
360 demo.launch()