ZERO-NOISE / app.py
KanchanP's picture
Upload 9 files
943768f verified
Raw
History Blame Contribute Delete
12.6 kB
import streamlit as st
import re
import time
# Page Config for Dark Mode / Professional Look
st.set_page_config(page_title="Zero-Noise | Agentic SOC", layout="wide", initial_sidebar_state="collapsed")
# Premium Custom CSS for Professional Security Interface
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;600&display=swap');
* {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.main {
background: linear-gradient(135deg, #0a0e1a 0%, #0f1428 100%);
color: #e8eef5;
}
h1, h2, h3 {
font-family: 'Inter', sans-serif;
font-weight: 700;
letter-spacing: -0.5px;
}
h1 {
font-size: 2.5em;
background: linear-gradient(120deg, #60a5fa 0%, #818cf8 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 0.5em;
}
h3 {
color: #c7d2e0;
font-size: 1.1em;
font-weight: 600;
}
/* Metrics Styling */
.stMetric {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.08) 0%, rgba(168, 85, 247, 0.06) 100%);
border: 1px solid rgba(99, 102, 241, 0.3);
padding: 20px;
border-radius: 12px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
}
.stMetric:hover {
border-color: rgba(96, 165, 250, 0.5);
box-shadow: 0 8px 24px rgba(96, 165, 250, 0.2);
}
/* Button Styling */
.stButton > button {
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
border: none;
color: white;
font-weight: 600;
border-radius: 10px;
padding: 12px 24px;
font-size: 0.95em;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4);
}
.stButton > button:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6);
}
/* Card Styling */
.threat-high {
border-left: 4px solid #ff6b6b;
background: linear-gradient(135deg, rgba(255, 107, 107, 0.1) 0%, rgba(255, 107, 107, 0.05) 100%);
}
.threat-medium {
border-left: 4px solid #ffa940;
background: linear-gradient(135deg, rgba(255, 169, 64, 0.1) 0%, rgba(255, 169, 64, 0.05) 100%);
}
.threat-low {
border-left: 4px solid #52c41a;
background: linear-gradient(135deg, rgba(82, 196, 26, 0.1) 0%, rgba(82, 196, 26, 0.05) 100%);
}
.incident-card {
background-color: #111827;
padding: 18px;
border-radius: 10px;
margin-bottom: 16px;
border: 1px solid rgba(75, 85, 99, 0.3);
transition: all 0.3s ease;
backdrop-filter: blur(5px);
}
.incident-card:hover {
border-color: rgba(99, 102, 241, 0.4);
box-shadow: 0 8px 24px rgba(99, 102, 241, 0.1);
}
/* Horizontal Rule */
hr {
border: none;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(99, 102, 241, 0.3), transparent);
margin: 2em 0;
}
/* Sidebar Panel */
.sidebar-panel {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.1) 0%, rgba(168, 85, 247, 0.08) 100%);
border: 1px solid rgba(99, 102, 241, 0.2);
border-radius: 10px;
padding: 20px;
backdrop-filter: blur(10px);
}
/* Code/Specs */
.specs-text {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.9em;
color: #a0aec0;
line-height: 1.6;
}
/* Subheader styling */
.subheader-custom {
color: #e8eef5;
font-weight: 600;
font-size: 1.15em;
margin: 1.5em 0 1em 0;
}
</style>
""", unsafe_allow_html=True)
st.title("Zero-Noise: Agentic SOC-in-a-Box")
st.markdown("<p style='color: #a0aec0; font-size: 1em; margin: -1.5em 0 0.5em 0;'>Real-time Threat Intelligence & Analysis Pipeline</p>", unsafe_allow_html=True)
st.markdown("---")
# Status Overview
cols = st.columns(2)
with cols[0]:
st.metric("System Status", "🟒 PROTECTED", delta="Active", delta_color="inverse")
with cols[1]:
st.metric("Latency", "38ms", delta="↓ 4ms", delta_color="inverse")
st.markdown("---")
col_main, col_side = st.columns([3, 1], gap="medium")
with col_side:
st.markdown("<div class='subheader-custom'>πŸ› οΈ Operations</div>", unsafe_allow_html=True)
if st.button("πŸ”„ Re-Scan Logs", use_container_width=True, key="rescan"):
st.toast("Reinitializing threat analysis pipeline...")
st.write("")
# Create placeholder for Log Analysis that will update as we scan
log_analysis_placeholder = st.empty()
with col_main:
st.markdown("<div class='subheader-custom'>🚨 Incident Intelligence Feed</div>", unsafe_allow_html=True)
try:
with open('FINAL_REPORT.md', 'r') as f:
content = f.read()
# Split individual incidents
incidents = content.split("---")
total_logs_scanned = 0
incident_count = 0
for incident in incidents:
if "###" in incident:
incident_count += 1
# Scan logs with 0.5 second increments until we hit the next incident
while total_logs_scanned < incident_count * 3: # Each incident represents ~3 logs scanned
total_logs_scanned += 1
if total_logs_scanned > 32:
total_logs_scanned = 32
# Update log analysis in sidebar
with log_analysis_placeholder.container():
st.markdown(f"""
<div class="sidebar-panel">
<div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">πŸ“Š Log Analysis</div>
<div class="specs-text">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span>Total Logs:</span>
<span style="color: #60a5fa; font-weight: 600;">{total_logs_scanned}</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span>Anomalies Found:</span>
<span style="color: #ff6b6b; font-weight: 600;">{incident_count}</span>
</div>
<div style="width: 100%; height: 6px; background-color: rgba(75, 85, 99, 0.3); border-radius: 3px; margin: 12px 0; overflow: hidden;">
<div style="width: {(total_logs_scanned/32)*100}%; height: 100%; background: linear-gradient(90deg, #60a5fa, #818cf8); border-radius: 3px;"></div>
</div>
<div style="font-size: 0.85em; color: #a0aec0; text-align: center;">
Scanning... {(total_logs_scanned/32)*100:.1f}%
</div>
</div>
</div>
""", unsafe_allow_html=True)
time.sleep(0.5)
# Determine threat level from risk score
risk_match = re.search(r"Risk Score: (\d+)", incident)
risk_score = int(risk_match.group(1)) if risk_match else 5
if risk_score >= 8:
threat_class = "threat-high"
severity = "πŸ”΄ CRITICAL"
elif risk_score >= 5:
threat_class = "threat-medium"
severity = "🟠 MEDIUM"
else:
threat_class = "threat-low"
severity = "🟒 LOW"
# Parse incident components
title_match = re.search(r"### (.+)", incident)
title = title_match.group(1) if title_match else "Unknown Threat"
attacker_match = re.search(r"\*\*Attacker IP:\*\*\s*(.+?)(?=\n|$)", incident)
attacker = attacker_match.group(1).strip() if attacker_match else "N/A"
summary_match = re.search(r"\*\*Summary:\*\*\s*(.+?)(?=\*\*Recommendation:\*\*|\n\*\*|$)", incident, re.DOTALL)
summary = summary_match.group(1).strip() if summary_match else ""
recommendation_match = re.search(r"\*\*Recommendation:\*\*\s*(.+?)(?=---|\*\*|$)", incident, re.DOTALL)
recommendation = recommendation_match.group(1).strip() if recommendation_match else ""
with st.container():
st.markdown(f"""
<div class="incident-card {threat_class}">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
<span style="font-weight: 600; color: #e8eef5; font-size: 1.05em;">{title}</span>
<span style="font-size: 0.85em; color: #a0aec0;">{severity}</span>
</div>
""", unsafe_allow_html=True)
st.markdown(f"**Attacker IP:** {attacker}")
st.markdown(f"**Summary:** {summary}")
st.markdown(f"**Recommendation:** {recommendation}")
st.markdown("</div>", unsafe_allow_html=True)
# 2-second delay between incidents
time.sleep(2)
# Finish scanning remaining logs up to 32
while total_logs_scanned < 32:
total_logs_scanned += 1
with log_analysis_placeholder.container():
st.markdown(f"""
<div class="sidebar-panel">
<div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">πŸ“Š Log Analysis</div>
<div class="specs-text">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span>Total Logs:</span>
<span style="color: #60a5fa; font-weight: 600;">{total_logs_scanned}</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<span>Anomalies Found:</span>
<span style="color: #ff6b6b; font-weight: 600;">{incident_count}</span>
</div>
<div style="width: 100%; height: 6px; background-color: rgba(75, 85, 99, 0.3); border-radius: 3px; margin: 12px 0; overflow: hidden;">
<div style="width: {(total_logs_scanned/32)*100}%; height: 100%; background: linear-gradient(90deg, #60a5fa, #818cf8); border-radius: 3px;"></div>
</div>
<div style="font-size: 0.85em; color: #a0aec0; text-align: center;">
Scanning... {(total_logs_scanned/32)*100:.1f}%
</div>
</div>
</div>
""", unsafe_allow_html=True)
time.sleep(0.5)
except Exception as e:
st.info("⏳ Awaiting live log ingestion...")
st.markdown("""
<div class="sidebar-panel">
<div style="font-weight: 600; color: #60a5fa; margin-bottom: 12px; font-size: 0.95em;">Pipeline Configuration</div>
<div class="specs-text">
<strong>Analysis Stack:</strong><br>
β€’ Filter: Deterministic Regex<br>
β€’ Parser: Qwen2-7B (Agent 1)<br>
β€’ Analyst: Qwen2-7B (Agent 2)<br>
β€’ Hardware: AMD MI300X
</div>
</div>
""", unsafe_allow_html=True)