`).join('');
}
function enableStrictMode() {
if (confirm('Activer le mode STRICT ? Tous les flux sortants non essentiels seront bloqués.')) {
addLogEntry('MODE STRICT activé - Egress filtering renforcé', 'error', 'DLP');
addEgressAlert('Mode Strict Activé', 'Tous les transferts > 1Mo nécessitent autorisation', 'INFO');
}
}
function clearEgressAlerts() {
const alertsEl = document.getElementById('egress-alerts');
if (alertsEl) alertsEl.textContent = '0';
const container = document.getElementById('egress-alerts-log');
if (container) container.innerHTML = '';
}
function refreshAccessLogs() {
addLogEntry('Rafraîchissement des logs d\'accès...', 'info', 'AUTH');
updateSessionsTable();
simulateFileAccessMonitoring();
simulateUSBMonitoring();
}
// WebSocket Connection for Critical Alerts
function connectWebSocket() {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.hostname}:3000`;
console.log('🔌 Connexion WebSocket:', wsUrl);
ws = new WebSocket(wsUrl);
ws.onopen = () => {
console.log('🔌 Connecté au SOC temps réel');
updateSystemStatus('online');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
handleRealtimeAlert(data);
};
ws.onerror = (error) => {
console.error('WebSocket erreur:', error);
updateSystemStatus('error');
};
ws.onclose = () => {
console.log('Déconnecté - Reconnexion dans 5s...');
updateSystemStatus('offline');
setTimeout(connectWebSocket, 5000);
};
}
function handleRealtimeAlert(data) {
// Vérifier que data existe
if (!data) return;
// Jouer son d'alerte si critique
if (data.severity === 'CRITICAL' || data.severity === 'HIGH') {
playAlertSound();
showToastAlert(data);
// Notification urgente pour administration
if (data.type && (data.type.includes('EXFILTRATION') || data.type.includes('EMAIL') || data.type.includes('SENSITIVE'))) {
showEmergencyAlert(data);
}
}
// Mettre à jour l'interface selon le type avec vérifications null
switch(data.type) {
case 'SUSPICIOUS_CONNECTION':
if (data.data && data.data.peer) {
addLogEntry(`Connexion suspecte: ${data.data.peer}:${data.data.peerPort || 'N/A'}`, 'error', data.data.peer);
}
break;
case 'BRUTE_FORCE_DETECTED':
const count = data.count || 0;
const ip = (data.ips && data.ips.length > 0) ? data.ips[0] : 'UNKNOWN';
addLogEntry(`Brute Force (${count} tentatives)`, 'error', ip);
incrementThreatCounter(count);
break;
case 'IP_BLOCKED':
addLogEntry(`IP bloquée: ${data.ip || 'UNKNOWN'}`, 'success', 'SYSTEM');
break;
case 'PROCESS_ALERT':
if (data.data && data.data.length > 0 && data.data[0].name) {
addLogEntry(`Processus suspect: ${data.data[0].name}`, 'warning', 'LOCAL');
}
break;
// NOUVEAUX: Alertes spécifiques administration française
case 'DATA_EXFILTRATION_DETECTED':
addLogEntry(`🚨 EXFILTRATION: ${data.description || 'Données sensibles'}`, 'error', 'TAJ/FPR');
incrementThreatCounter(10);
break;
case 'EMAIL_COMPROMISE':
if (data.data) {
const user = data.data.user || 'UNKNOWN';
const country = data.data.country || 'UNKNOWN';
const ip = data.data.ip || 'UNKNOWN';
addLogEntry(`📧 MESSAGERIE COMPROMISE: ${user} depuis ${country}`, 'error', ip);
}
break;
case 'SENSITIVE_FILE_ACCESS':
if (data.data) {
const isBanking = data.data.type === 'FINANCES';
const prefix = isBanking ? '🏦 FICoba/DGFiP:' : '🔒';
const file = data.data.file || 'UNKNOWN';
const volume = data.data.volume || 'N/A';
addLogEntry(`${prefix} ACCÈS ${file} (${volume})`, 'error', data.data.type || 'SYSTEM');
if (isBanking) {
const records = data.data.records || 'N/A';
showEmergencyAlert({
type: 'FICOBa_BREACH_ATTEMPT',
severity: 'CRITICAL',
description: `Tentative d'accès au fichier des comptes bancaires: ${file}. ${records} comptes potentiellement concernés.`,
timestamp: data.timestamp || new Date().toISOString()
});
}
}
break;
case 'CREDENTIAL_STOLEN':
if (data.data) {
const user = data.data.user || 'UNKNOWN';
const source = data.data.source || 'UNKNOWN';
addLogEntry(`🔑 CODE ACCÈS VOLÉ: ${user} via ${source}`, 'warning', 'AUTH');
}
break;
case 'USB_DETECTED':
if (data.device) {
addLogEntry(`USB Détecté: ${data.device.model || 'Unknown'}`, 'info', 'USB');
}
break;
case 'USB_BLOCKED':
if (data.device) {
addLogEntry(`USB Bloqué: ${data.device.model || 'Unknown'}`, 'error', 'USB');
}
break;
case 'FILE_ACCESS':
case 'FILE_MODIFIED':
case 'SENSITIVE_FILE_CREATED':
if (data.file) {
addLogEntry(`Fichier: ${data.type} - ${data.file}`, data.severity === 'CRITICAL' ? 'error' : 'warning', 'FS');
}
break;
}
}
// NOUVEAU: Alerte d'urgence en plein écran pour incidents critiques
function showEmergencyAlert(data) {
if (!data) return;
const existing = document.getElementById('emergency-alert');
if (existing) existing.remove();
const alertType = data.type || 'UNKNOWN_ALERT';
const description = data.description || 'Menace détectée sur infrastructure sensible';
const alert = document.createElement('div');
alert.id = 'emergency-alert';
alert.className = 'fixed inset-0 bg-red-900/90 z-[100] flex items-center justify-center backdrop-blur-sm animate-fade-in';
alert.innerHTML = `
Alerte Critique Administration
${new Date().toLocaleTimeString('fr-FR')}
${alertType.replace(/_/g, ' ')}
${description}
`;
document.body.appendChild(alert);
if (typeof feather !== 'undefined') feather.replace();
}
// NOUVEAU: Fonctions de réponse aux incidents
async function blockIP(ip) {
try {
const response = await fetch('http://localhost:3000/api/block-ip', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ip: ip, reason: 'Attaque administration française' })
});
const data = await response.json();
addLogEntry(`IP ${ip} bloquée définitivement`, 'success', 'FIREWALL');
} catch (e) {
addLogEntry(`Échec blocage IP ${ip}`, 'error', 'SYSTEM');
}
}
function isolateSystem() {
addLogEntry('🔒 ISOLEMENT DU SYSTÈME ENGAGÉ', 'error', 'ADMIN');
showToastAlert({
type: 'SYSTEM_ISOLATION',
severity: 'CRITICAL',
description: 'Réseau segmenté, accès externes coupés',
timestamp: new Date().toISOString()
});
}
function revokeCredentials() {
addLogEntry('🔑 RÉVOCATION MASSIVE DES ACCÈS', 'warning', 'ADMIN');
alert('Tous les tokens de session ont été révoqués. Reconnexion requise pour tous les agents.');
}
function exportReport() {
const report = {
date: new Date().toISOString(),
administration: 'Ministère de l\'Intérieur (Simulation)',
incidents: [], // Récupérer depuis les logs visibles si besoin
status: 'Rapport généré par CyberShield SOC'
};
console.log('Rapport exporté:', report);
addLogEntry('📄 Rapport d\'incident exporté', 'info', 'REPORT');
alert('Rapport d\'incident exporté vers le SI-Central');
}
function showToastAlert(data) {
if (!data) return;
// Créer une notification toast pour alertes critiques
const toast = document.createElement('div');
toast.className = 'fixed top-4 right-4 bg-red-600 text-white px-6 py-4 rounded-lg shadow-2xl z-50 animate-slide-in border-l-4 border-red-300 flex items-center';
toast.style.animation = 'slideInRight 0.3s ease-out';
toast.innerHTML = `
${data.type || 'ALERTE'}
${data.timestamp ? new Date(data.timestamp).toLocaleTimeString('fr-FR') : new Date().toLocaleTimeString('fr-FR')}
`;
document.body.appendChild(toast);
if (typeof feather !== 'undefined') feather.replace();
setTimeout(() => {
toast.remove();
}, 5000);
}
function updateSystemStatus(status) {
const statusEl = document.getElementById('status-text');
if (!statusEl) return;
const indicator = statusEl.parentElement.nextElementSibling;
if (status === 'online') {
statusEl.innerText = 'Connecté - Temps Réel (PROD)';
statusEl.className = 'text-green-400 font-mono font-bold';
if (indicator) indicator.className = 'w-2 h-2 bg-green-400 rounded-full animate-pulse';
} else if (status === 'error') {
statusEl.innerText = 'Erreur Connexion';
statusEl.className = 'text-red-400 font-mono';
if (indicator) indicator.className = 'w-2 h-2 bg-red-500 rounded-full';
} else {
statusEl.innerText = 'Hors ligne';
statusEl.className = 'text-gray-400 font-mono';
if (indicator) indicator.className = 'w-2 h-2 bg-gray-500 rounded-full';
}
}
function incrementThreatCounter(count = 1) {
// Trouve le compteur spécifique des menaces (premier counter)
const counter = document.querySelector('.counter[data-target]') || document.querySelector('.counter');
if (counter) {
let current = parseInt(counter.innerText.replace(/,/g, '')) || 0;
current += count;
counter.innerText = current.toLocaleString();
}
}
// --- Sound Manager ---
function initAudio() {
if (!audioCtx) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
}
}
function toggleSound() {
soundEnabled = !soundEnabled;
const btn = document.getElementById('btn-sound');
const icon = btn.querySelector('i');
if (soundEnabled) {
icon.setAttribute('data-feather', 'volume-2');
icon.classList.replace('text-gray-400', 'text-cyber-primary');
playBeep(600, 'sine', 0.1); // Confirmation beep
} else {
icon.setAttribute('data-feather', 'volume-x');
icon.classList.replace('text-cyber-primary', 'text-gray-400');
}
feather.replace();
}
function playAlertSound() {
if (!soundEnabled || !audioCtx) return;
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(440, audioCtx.currentTime);
osc.frequency.exponentialRampToValueAtTime(880, audioCtx.currentTime + 0.1);
gain.gain.setValueAtTime(0.1, audioCtx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.3);
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + 0.3);
}
// 0. Navigation Logic (SPA)
function navigateTo(viewId) {
// Hide all views
document.querySelectorAll('[id^="view-"]').forEach(el => el.classList.add('hidden'));
// Show selected
document.getElementById(`view-${viewId}`).classList.remove('hidden');
// Reset Nav Styles
document.querySelectorAll('.nav-link').forEach(el => {
el.classList.remove('active', 'bg-gray-800/50', 'text-cyber-primary', 'border-gray-700');
el.classList.add('text-gray-400');
});
// Set Active Nav
const activeNav = document.getElementById(`nav-${viewId}`);
if(activeNav) {
activeNav.classList.add('active', 'bg-gray-800/50', 'text-cyber-primary', 'border-gray-700');
activeNav.classList.remove('text-gray-400');
}
// Re-init icons
feather.replace();
}
// 1. Real-time Chart Initialization avec données réseau réelles
let trafficHistory = [];
function initLiveChart() {
const chartContainer = document.getElementById('liveChart');
const barCount = 50;
// Create initial bars
for(let i = 0; i < barCount; i++) {
const bar = document.createElement('div');
bar.className = 'bg-cyber-primary w-1.5 rounded-t-sm opacity-60 transition-all duration-300 ease-in-out hover:opacity-100 hover:bg-white';
bar.style.height = '10%';
chartContainer.appendChild(bar);
trafficHistory.push(10);
}
}
function updateTrafficChart(currentTraffic) {
const chartContainer = document.getElementById('liveChart');
if (!chartContainer || chartContainer.children.length === 0) return;
// Décaler l'historique
trafficHistory.shift();
trafficHistory.push(currentTraffic);
// Mettre à jour les barres visuellement
const bars = chartContainer.children;
const maxTraffic = Math.max(...trafficHistory, 100); // Échelle dynamique
for (let i = 0; i < bars.length; i++) {
const percentage = (trafficHistory[i] / maxTraffic) * 100;
bars[i].style.height = `${Math.max(percentage, 5)}%`;
// Coloration selon l'intensité
if (percentage > 80) {
bars[i].className = 'bg-red-500 w-1.5 rounded-t-sm shadow-[0_0_10px_rgba(239,68,68,0.8)] transition-all duration-300';
} else if (percentage > 50) {
bars[i].className = 'bg-yellow-400 w-1.5 rounded-t-sm transition-all duration-300';
} else {
bars[i].className = 'bg-cyber-primary w-1.5 rounded-t-sm opacity-60 transition-all duration-300 ease-in-out hover:opacity-100 hover:bg-white';
}
}
}
// 2. Fetch Statistics from Backend API avec données réelles
let previousAlertCount = 0;
async function fetchStats() {
try {
const response = await fetch('http://localhost:3000/api/stats');
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
// Vérifier nouvelles alertes critiques
if (data.criticalAlerts > previousAlertCount) {
playAlertSound();
// Notification visuelle urgente
document.querySelectorAll('.counter')[3].parentElement.parentElement.classList.add('pulse-alert');
setTimeout(() => {
document.querySelectorAll('.counter')[3].parentElement.parentElement.classList.remove('pulse-alert');
}, 2000);
}
previousAlertCount = data.criticalAlerts;
// Update Dashboard Data avec animation
updateCounterAnimated(document.querySelector('.counter'), data.threatsBlocked);
// Santé serveur avec couleur dynamique
const healthEl = document.querySelectorAll('.counter')[1].nextElementSibling;
healthEl.innerText = data.serverHealth + "%";
if (data.serverHealth < 50) healthEl.className = 'text-3xl font-bold text-red-500 mt-2';
else if (data.serverHealth < 80) healthEl.className = 'text-3xl font-bold text-yellow-400 mt-2';
else healthEl.className = 'text-3xl font-bold text-cyber-secondary mt-2';
// Trafic réseau
document.querySelectorAll('.counter')[2].previousElementSibling.lastElementChild.innerText = data.networkTraffic + " MB/s";
updateTrafficChart(data.networkTraffic);
// Alertes avec formatage
const alertEl = document.querySelectorAll('.counter')[3];
alertEl.innerText = data.criticalAlerts.toString().padStart(2, '0');
if (data.criticalAlerts > 0) {
alertEl.classList.add('text-red-500');
}
} catch (error) {
console.error('Erreur fetch stats:', error);
updateSystemStatus('error');
}
}
function updateCounterAnimated(element, targetValue) {
if (!element) return;
const current = parseInt(element.innerText.replace(/,/g, '')) || 0;
if (current !== targetValue) {
element.innerText = targetValue.toLocaleString();
// Effet visuel de mise à jour
element.style.transform = 'scale(1.1)';
setTimeout(() => element.style.transform = 'scale(1)', 200);
}
}
// 3. Gestion des logs temps réel
function addLogEntry(message, type, ip) {
const container = document.getElementById('logContainer');
if (!container) return;
const logLine = document.createElement('div');
logLine.className = 'log-entry flex justify-between border-b border-gray-900 pb-1 mb-1 animate-fade-in';
let colorClass = 'text-gray-400';
if(type === 'error') colorClass = 'text-red-400';
if(type === 'success') colorClass = 'text-green-400';
if(type === 'warning') colorClass = 'text-yellow-400';
const time = new Date().toLocaleTimeString('fr-FR', { hour12: false });
logLine.innerHTML = `
[${time}] ${message} (${ip || 'SYSTEM'})${type.toUpperCase()}
`;
container.prepend(logLine);
// Garder seulement les 50 dernières entrées
while(container.children.length > 50) {
container.lastElementChild.remove();
}
}
async function startLogStream() {
// Récupération initiale puis via WebSocket principalement
try {
const response = await fetch('http://localhost:3000/api/log');
const data = await response.json();
addLogEntry(data.msg, data.type, data.ip);
} catch (e) {
addLogEntry('Initialisation du système de logs...', 'info', 'LOCAL');
}
}
// Fallback to simulate data if user doesn't run the server
function simulateFallbackData() {
// Just ensures the chart keeps moving if no server is present
const chartContainer = document.getElementById('liveChart');
if(!chartContainer.children.length) initLiveChart();
const bars = chartContainer.children;
for(let i = 0; i < bars.length - 1; i++) {
bars[i].style.height = bars[i+1].style.height;
}
const lastBar = bars[bars.length - 1];
const newHeight = Math.floor(Math.random() * 90) + 10;
lastBar.style.height = `${newHeight}%`;
if(newHeight > 80) {
lastBar.className = 'bg-red-500 w-2 rounded-t-sm shadow-[0_0_10px_rgba(239,68,68,0.8)] transition-all duration-300';
} else if (newHeight > 50) {
lastBar.className = 'bg-yellow-400 w-2 rounded-t-sm transition-all duration-300';
} else {
lastBar.className = 'bg-cyber-primary w-2 rounded-t-sm opacity-50 transition-all duration-300';
}
}
// --- NEW FEATURES: MAP, VULNS, INFRA ---
// 4. Threat Map Logic
function initMap() {
// Clear existing svg lines if any
const svg = document.getElementById('map-svg-layer');
while (svg.lastChild) {
svg.removeChild(svg.lastChild);
}
}
async function startMapStream() {
const container = document.getElementById('geo-log-container');
const mapArea = document.getElementById('attack-map-container');
if (!container || !mapArea) return;
if (!document.getElementById('map-svg-layer')) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.id = "map-svg-layer";
svg.style.position = "absolute";
svg.style.top = "0";
svg.style.left = "0";
svg.style.width = "100%";
svg.style.height = "100%";
svg.style.pointerEvents = "none";
svg.style.zIndex = "5";
mapArea.appendChild(svg);
}
const svg = document.getElementById('map-svg-layer');
const fetchMapData = async () => {
try {
const response = await fetch('http://localhost:3000/api/geo');
const data = await response.json();
// Add Log avec badge pays
const logLine = document.createElement('div');
logLine.className = 'border-b border-gray-900 pb-1 text-xs font-mono animate-fade-in flex justify-between items-center';
logLine.innerHTML = `
${data.country}${data.type}from ${data.ip}
${new Date(data.timestamp).toLocaleTimeString('fr-FR')}
`;
container.prepend(logLine);
if(container.children.length > 20) container.lastChild.remove();
// Animation sur la carte
const node = document.createElement('div');
node.className = 'geo-node';
const top = Math.random() * 80 + 10;
const left = Math.random() * 80 + 10;
node.style.top = `${top}%`;
node.style.left = `${left}%`;
mapArea.appendChild(node);
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
line.setAttribute("x1", `${left}%`);
line.setAttribute("y1", `${top}%`);
line.setAttribute("x2", "50%");
line.setAttribute("y2", "50%");
line.setAttribute("stroke", data.real ? "#ff0000" : "#00f0ff");
line.setAttribute("stroke-width", "2");
line.setAttribute("stroke-opacity", "0.8");
line.setAttribute("stroke-dasharray", "5,5");
const animate = document.createElementNS("http://www.w3.org/2000/svg", "animate");
animate.setAttribute("attributeName", "stroke-dashoffset");
animate.setAttribute("from", "100");
animate.setAttribute("to", "0");
animate.setAttribute("dur", "0.5s");
animate.setAttribute("repeatCount", "1");
line.appendChild(animate);
svg.appendChild(line);
// Impact visuel au centre (cible)
const target = document.createElement('div');
target.className = 'absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-4 h-4 bg-red-500 rounded-full animate-ping';
mapArea.appendChild(target);
setTimeout(() => {
node.remove();
line.remove();
target.remove();
}, 2000);
} catch(e) {
console.error('Erreur carte:', e);
}
};
// Plus fréquent si données réelles disponibles
setInterval(fetchMapData, 2000);
}
// --- 7. Terminal Logic ---
function toggleAIChat() {
const modal = document.getElementById('ai-chat-modal');
if (modal.classList.contains('hidden')) {
// Opening
modal.classList.remove('hidden');
// Small delay to allow CSS display property to apply before removing transform/opacity
setTimeout(() => {
modal.classList.remove('translate-y-4', 'opacity-0');
}, 10);
document.getElementById('ai-input').focus();
} else {
// Closing
modal.classList.add('translate-y-4', 'opacity-0');
// Wait for transition to finish before setting display: none
setTimeout(() => {
modal.classList.add('hidden');
}, 300);
}
}
function setupAIChat() {
const input = document.getElementById('ai-input');
input.addEventListener('keypress', function (e) {
if (e.key === 'Enter') sendAIMessage();
});
}
function sendAIMessage() {
const input = document.getElementById('ai-input');
const text = input.value.trim();
if(!text) return;
const history = document.getElementById('chat-history');
// User Message
const userMsg = `
${text}
`;
history.innerHTML += userMsg;
input.value = '';
history.scrollTop = history.scrollHeight;
// AI Simulation Response
setTimeout(() => {
let response = "Analyse en cours...";
const lowerText = text.toLowerCase();
if(lowerText.includes("menace") || lowerText.includes("threat")) {
response = "J'ai analysé les 30 dernières minutes. Une tentative d'intrusion de type 'Brute Force' a été détectée sur le port 22. Elle a été bloquée automatiquement.";
} else if (lowerText.includes("serveur") || lowerText.includes("server")) {
response = "Les serveurs、主 인프라 sont sains. L'utilisation du CPU est stable à 24%. Aucun goulot d'étranglement détecté.";
} else if (lowerText.includes("optimiser") || lowerText.includes("optimize")) {
response = "Recommandation: Activer le protocole de mise en cache avancées sur le noeud DB-01 pour réduire la latence de 15%.";
} else {
response = "Données non traitées. Voulez-vous que je lance une analyse approfondie du pare-feu ?";
}
const aiMsg = `
${response}
`;
history.innerHTML += aiMsg;
history.scrollTop = history.scrollHeight;
feather.replace();
}, 800);
}
function toggleTerminal() {
const modal = document.getElementById('terminal-modal');
const input = document.getElementById('terminal-input');
if (modal.classList.contains('hidden')) {
modal.classList.remove('hidden');
input.focus();
} else {
modal.classList.add('hidden');
}
}
function setupTerminal() {
const input = document.getElementById('terminal-input');
const output = document.getElementById('terminal-output');
input.addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
const command = input.value.trim();
if (command) {
printToTerminal(`root@sys:~$ ${command}`);
executeCommand(command);
}
input.value = '';
}
});
}
function printToTerminal(text, color = 'text-green-400') {
const output = document.getElementById('terminal-output');
const p = document.createElement('p');
p.className = color + " font-mono";
p.innerText = text;
output.appendChild(p);
output.scrollTop = output.scrollHeight;
}
async function executeCommand(cmd) {
const output = document.getElementById('terminal-output');
const args = cmd.split(' ');
const command = args[0].toLowerCase();
// Realistic SOC terminal commands
switch(command) {
case 'help':
case '?':
printToTerminal("CYBERSHIELD SOC v3.0 - Commandes disponibles:", "text-cyber-primary");
printToTerminal(" netstat - Affiche les connexions actives");
printToTerminal(" ps - Liste des processus suspects");
printToTerminal(" kill [PID] - Termine un processus");
printToTerminal(" block [IP] - Bloque une adresse IP au firewall");
printToTerminal(" isolate - Mode confinement d'urgence");
printToTerminal(" scan [target] - Scan de vulnérabilités rapide");
printToTerminal(" clear - Nettoie le terminal");
printToTerminal(" status - État des systèmes");
break;
case 'netstat':
printToTerminal("Connexions réseau actives:", "text-yellow-400");
setTimeout(() => {
printToTerminal("tcp ESTABLISHED 192.168.1.100:443 -> 185.220.101.42:4444 [SUSPECT]", "text-red-400");
printToTerminal("tcp ESTABLISHED 192.168.1.5:22 -> 10.0.0.15:22 [SSH]", "text-green-400");
printToTerminal("udp OPEN 0.0.0.0:53 -> 8.8.8.8:53 [DNS]", "text-gray-400");
printToTerminal("tcp LISTEN 0.0.0.0:8080 -> 0.0.0.0:0 [HTTP]", "text-gray-400");
}, 300);
break;
case 'ps':
printToTerminal("Processus en cours:", "text-yellow-400");
setTimeout(() => {
printToTerminal("PID USER CPU MEM COMMAND", "text-gray-500");
printToTerminal("1 root 0.1 0.2 /sbin/init", "text-gray-400");
printToTerminal("1842 www-data 45.2 12.5 /usr/bin/python3 -m http.server [SUSPECT]", "text-red-400");
printToTerminal("2156 mysql 2.1 8.4 mysqld --daemonize", "text-gray-400");
printToTerminal("3421 root 0.0 0.1 /bin/bash /tmp/.hidden/script.sh [MALICIOUS]", "text-red-400 font-bold");
}, 300);
break;
case 'kill':
if (args[1]) {
printToTerminal(`Envoi du signal SIGTERM au processus ${args[1]}...`, "text-yellow-400");
setTimeout(() => {
printToTerminal(`Processus ${args[1]} terminé.`, "text-green-400");
addLogEntry(`Processus ${args[1]} terminé manuellement via terminal`, 'warning', 'ADMIN');
}, 500);
} else {
printToTerminal("Usage: kill [PID]", "text-red-400");
}
break;
case 'block':
if (args[1]) {
const ip = args[1];
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(ip)) {
printToTerminal(`Blocage de l'IP ${ip}...`, "text-yellow-400");
setTimeout(() => {
printToTerminal(`iptables -A INPUT -s ${ip} -j DROP`, "text-gray-500");
printToTerminal(`IP ${ip} bloquée avec succès.`, "text-green-400");
blockIP(ip);
}, 600);
} else {
printToTerminal("IP invalide.", "text-red-400");
}
} else {
printToTerminal("Usage: block [IP]", "text-red-400");
}
break;
case 'isolate':
printToTerminal("INITIATION DU CONFINEMENT D'URGENCE...", "text-red-400 font-bold");
setTimeout(() => {
printToTerminal("[-] Coupure des interfaces réseau externes...", "text-yellow-400");
printToTerminal("[-] Isolation du VLAN sensibles...", "text-yellow-400");
printToTerminal("[-] Preservation des logs forensiques...", "text-yellow-400");
printToTerminal("[✓] SYSTÈME ISOLÉ - Mode quarantaine actif", "text-green-400 font-bold");
isolateSystem();
}, 1000);
break;
case 'scan':
const target = args[1] || 'localhost';
printToTerminal(`Lancement du scan de vulnérabilités sur ${target}...`, "text-yellow-400");
setTimeout(() => {
printToTerminal("[*] Scan des ports ouverts...", "text-gray-500");
printToTerminal("[!] Port 22/tcp open SSH - Version outdated", "text-orange-400");
printToTerminal("[!] Port 3389/tcp open RDP - Vulnérable à BlueKeep", "text-red-400");
printToTerminal("[*] Scan terminé. 2 vulnérabilités trouvées.", "text-green-400");
}, 2000);
break;
case 'clear':
output.innerHTML = '';
break;
case 'uptime':
const days = Math.floor(Math.random() * 100);
const hours = Math.floor(Math.random() * 24);
printToTerminal(`System uptime: ${days} days, ${hours} hours`, "text-gray-400");
break;
case 'status':
printToTerminal("Checking systems...", "text-yellow-400");
setTimeout(() => {
printToTerminal("[✓] Firewall: ACTIVE", "text-green-400");
printToTerminal("[✓] IDS/IPS: ONLINE", "text-green-400");
printToTerminal("[✓] SIEM: CONNECTED", "text-green-400");
printToTerminal("[✓] Threat Intel: FEED ACTIVE", "text-green-400");
printToTerminal("[!] Backup: SYNCING...", "text-orange-400");
}, 800);
break;
default:
printToTerminal(`Command not found: ${cmd}. Type 'help' for available commands.`, "text-red-400");
}
}
// Dark Web Monitor Functions
function investigateLeak(leakType) {
if (!leakType) return;
addLogEntry(`Investigation lancée: ${leakType.toUpperCase()}`, 'info', 'DARKWEB');
showToastAlert({
type: 'DARKWEB_INVESTIGATION',
severity: 'HIGH',
description: `Analyse forensique de la fuite ${leakType} en cours...`,
timestamp: new Date().toISOString()
});
}
// Packet Capture Simulation
let packetCaptureActive = false;
function startPacketCapture() {
const container = document.getElementById('packet-analyzer');
packetCaptureActive = !packetCaptureActive;
if (packetCaptureActive) {
addLogEntry('Capture de paquets démarrée sur interface eth0', 'info', 'NETWORK');
container.innerHTML = '