CoolFace
Apppublic

charag/networkintrusiondetection

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
app.py360 linesDownload Raw Back to root
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()