diff --git a/README.md b/README.md index 4d6d1a4..2285d54 100644 --- a/README.md +++ b/README.md @@ -1 +1,69 @@ -# ThreatHunt \ No newline at end of file +<<<<<<< Updated upstream +# ThreatHunt +======= +# Cyber Threat Hunter + +A modern web application for threat hunting and security analysis, built with React frontend and Flask backend. + +## Features + +- **Security Tools Detection**: Identify running security tools (AV, EDR, VPN) +- **CSV Processing**: Upload and analyze security logs +- **Baseline Analysis**: System baseline comparison +- **Network Analysis**: Network traffic and connection analysis +- **VirusTotal Integration**: File and URL reputation checking + +## Architecture + +``` +ThreatHunt/ +├── frontend/ # React application +├── backend/ # Flask API server +├── uploaded/ # File upload storage +└── output/ # Analysis results +``` + +## Quick Start + +### Backend Setup + +```bash +cd backend +chmod +x setup_backend.sh +./setup_backend.sh +source venv/bin/activate +python app.py +``` + +### Frontend Setup + +```bash +cd frontend +npm install +npm run dev +``` + +## API Endpoints + +- `GET /` - Serve React app +- `GET /api/health` - Health check +- `POST /api/upload` - File upload +- `GET /api/analysis/` - Get analysis results + +## Security Considerations + +- File upload validation +- Input sanitization +- Rate limiting +- CORS configuration + +## Contributing + +1. Fork the repository +2. Create feature branch +3. Submit pull request + +## License + +MIT License +>>>>>>> Stashed changes diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..ccbf845 --- /dev/null +++ b/backend/.env @@ -0,0 +1,9 @@ +FLASK_ENV=development +FLASK_DEBUG=True +SECRET_KEY=development-secret-key-change-in-production +MAX_CONTENT_LENGTH=104857600 +UPLOAD_FOLDER=uploaded +OUTPUT_FOLDER=output +VIRUSTOTAL_API_KEY= +DATABASE_URL=sqlite:///threat_hunter.db +REDIS_URL=redis://localhost:6379/0 diff --git a/backend/app.py b/backend/app.py new file mode 100644 index 0000000..258460a --- /dev/null +++ b/backend/app.py @@ -0,0 +1,277 @@ +import os +import logging +from flask import Flask, request, jsonify, send_from_directory +from werkzeug.utils import secure_filename +from datetime import datetime + +# Try to import flask-cors +try: + from flask_cors import CORS + CORS_AVAILABLE = True +except ImportError: + CORS_AVAILABLE = False + print("Warning: flask-cors not available") + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +app = Flask(__name__, static_folder="../frontend/dist") + +# Enable CORS +if CORS_AVAILABLE: + CORS(app) +else: + @app.after_request + def after_request(response): + response.headers.add('Access-Control-Allow-Origin', '*') + response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') + response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') + return response + +# Configuration +app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 +app.config['UPLOAD_FOLDER'] = 'uploaded' +app.config['ALLOWED_EXTENSIONS'] = {'csv', 'json', 'txt', 'log'} + +# Ensure upload directory exists +os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) + +@app.route('/api/health') +def health_check(): + return jsonify({ + 'status': 'healthy', + 'timestamp': datetime.utcnow().isoformat(), + 'version': '1.0.0', + 'service': 'Cyber Threat Hunter API' + }) + +@app.route('/') +def index(): + return jsonify({'message': 'Cyber Threat Hunter API', 'status': 'running'}) + +@app.route('/api/test') +def test(): + return jsonify({'message': 'API is working', 'timestamp': datetime.now().isoformat()}) + +if __name__ == "__main__": + print("=" * 50) + print("Starting Cyber Threat Hunter Backend...") + print("API available at: http://localhost:5000") + print("Health check: http://localhost:5000/api/health") + print("=" * 50) + app.run(host="0.0.0.0", port=5000, debug=True) +@app.errorhandler(RequestEntityTooLarge) +def handle_file_too_large(e): + return jsonify({'error': 'File too large. Maximum size is 100MB.'}), 413 + +@app.errorhandler(Exception) +def handle_exception(e): + logger.error(f"Unhandled exception: {e}") + return jsonify({'error': 'Internal server error'}), 500 + +# Security analysis functions +def analyze_security_tools(csv_path): + """Analyze CSV for security tools based on process names.""" + try: + df = pd.read_csv(csv_path) + + # Load security tools list + tools_file = os.path.join('lists', 'security-tools.md') + if not os.path.exists(tools_file): + return {'error': 'Security tools list not found'} + + with open(tools_file, 'r', encoding='utf-8') as f: + content = f.read() + # Extract tool names (simplified) + tools = set() + for line in content.split('\n'): + line = line.strip() + if line and not line.startswith('#') and not line.endswith(':'): + if line.lower().endswith('.exe') or '.' not in line: + tools.add(line.lower()) + + # Analyze CSV for tools + process_col = None + for col in df.columns: + if any(keyword in col.lower() for keyword in ['process', 'image', 'executable']): + process_col = col + break + + if not process_col: + return {'error': 'No process column found in CSV'} + + found_tools = {} + for _, row in df.iterrows(): + process_name = str(row[process_col]).lower() + for tool in tools: + if tool in process_name: + host = row.get('host', row.get('hostname', 'unknown')) + if tool not in found_tools: + found_tools[tool] = set() + found_tools[tool].add(host) + + # Convert sets to lists for JSON serialization + result = {tool: list(hosts) for tool, hosts in found_tools.items()} + return {'tools_found': result, 'total_tools': len(result)} + + except Exception as e: + logger.error(f"Security tools analysis error: {e}") + return {'error': str(e)} + +# API Routes +@app.route('/api/health') +def health_check(): + return jsonify({ + 'status': 'healthy', + 'timestamp': datetime.utcnow().isoformat(), + 'version': '1.0.0' + }) + +@app.route('/api/upload', methods=['POST']) +def upload_file(): + try: + if 'file' not in request.files: + return jsonify({'error': 'No file provided'}), 400 + + file = request.files['file'] + if file.filename == '': + return jsonify({'error': 'No file selected'}), 400 + + if not allowed_file(file.filename): + return jsonify({'error': 'File type not allowed'}), 400 + + filename = secure_filename(file.filename) + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') + filename = f"{timestamp}_{filename}" + filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + + file.save(filepath) + + logger.info(f"File uploaded successfully: {filename}") + return jsonify({ + 'message': 'File uploaded successfully', + 'filename': filename, + 'size': os.path.getsize(filepath) + }) + + except Exception as e: + logger.error(f"Upload error: {e}") + return jsonify({'error': 'Upload failed'}), 500 + +@app.route('/api/files') +def list_files(): + try: + files = [] + upload_dir = app.config['UPLOAD_FOLDER'] + + for filename in os.listdir(upload_dir): + filepath = os.path.join(upload_dir, filename) + if os.path.isfile(filepath): + stat = os.stat(filepath) + files.append({ + 'name': filename, + 'size': stat.st_size, + 'modified': datetime.fromtimestamp(stat.st_mtime).isoformat() + }) + + return jsonify({'files': files}) + + except Exception as e: + logger.error(f"List files error: {e}") + return jsonify({'error': 'Failed to list files'}), 500 + +# Security tools analysis endpoint +@app.route('/api/analyze/security-tools/') +def analyze_security_tools_endpoint(filename): + try: + filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + if not os.path.exists(filepath): + return jsonify({'error': 'File not found'}), 404 + + result = analyze_security_tools(filepath) + return jsonify(result) + + except Exception as e: + logger.error(f"Security tools analysis endpoint error: {e}") + return jsonify({'error': 'Analysis failed'}), 500 + +@app.route('/api/analyze/') +def analyze_file(filename): + try: + filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) + if not os.path.exists(filepath): + return jsonify({'error': 'File not found'}), 404 + + # Basic file analysis + file_stats = os.stat(filepath) + analysis = { + 'filename': filename, + 'size': file_stats.st_size, + 'created': datetime.fromtimestamp(file_stats.st_ctime).isoformat(), + 'modified': datetime.fromtimestamp(file_stats.st_mtime).isoformat() + } + + # CSV specific analysis (only if pandas is available) + if filename.lower().endswith('.csv') and PANDAS_AVAILABLE: + try: + df = pd.read_csv(filepath) + analysis.update({ + 'rows': len(df), + 'columns': len(df.columns), + 'column_names': df.columns.tolist(), + 'preview': df.head().to_dict('records') + }) + except Exception as e: + analysis['csv_error'] = str(e) + elif filename.lower().endswith('.csv'): + # Basic CSV analysis without pandas + try: + with open(filepath, 'r', encoding='utf-8') as f: + lines = f.readlines() + analysis.update({ + 'rows': len(lines) - 1, # Subtract header + 'columns': len(lines[0].split(',')) if lines else 0, + 'preview': lines[:6] if lines else [] + }) + except Exception as e: + analysis['csv_error'] = str(e) + + return jsonify(analysis) + + except Exception as e: + logger.error(f"Analysis error: {e}") + return jsonify({'error': 'Analysis failed'}), 500 + +# Stats endpoint +@app.route('/api/stats') +def get_stats(): + try: + upload_dir = app.config['UPLOAD_FOLDER'] + files_count = len([f for f in os.listdir(upload_dir) if os.path.isfile(os.path.join(upload_dir, f))]) + + return jsonify({ + 'filesUploaded': files_count, + 'analysesCompleted': files_count, # Simplified + 'threatsDetected': 0 # Placeholder + }) + except Exception as e: + logger.error(f"Stats error: {e}") + return jsonify({'error': 'Failed to get stats'}), 500 + +# Static file serving +@app.route("/assets/") +def send_assets(path): + return send_from_directory(os.path.join(app.static_folder, "assets"), path) + +@app.route("/") +def index(): + return send_from_directory(app.static_folder, "index.html") + +# Catch-all route for React Router +@app.route("/") +def catch_all(path): + return send_from_directory(app.static_folder, "index.html") + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..a9ce02e --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + Cyber Threat Hunter + + +
+ + + \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..810c93b --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,34 @@ +{ + "name": "cyber-threat-hunter", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.26.1", + "lucide-react": "^0.515.0", + "axios": "^1.7.2" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.3", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.7", + "vite": "^5.3.4", + "tailwindcss": "^3.4.4", + "autoprefixer": "^10.4.19", + "postcss": "^8.4.39" + } +} + } +} diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 0000000..16df486 --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,47 @@ +import React from "react"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { CssBaseline } from "@mui/material"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; + +import Sidebar from "./components/Sidebar"; +import HomePage from "./pages/HomePage"; + +const theme = createTheme({ + palette: { + mode: "dark", + }, +}); + +function App() { + return ( + + + +
+ +
+ + } /> + +
+
+
+
+ ); +} + +export default App; + } /> + } /> + } /> + } /> + } /> + + + + + + ); +} + +export default App; diff --git a/frontend/src/components/Sidebar.jsx b/frontend/src/components/Sidebar.jsx new file mode 100644 index 0000000..c3e561a --- /dev/null +++ b/frontend/src/components/Sidebar.jsx @@ -0,0 +1,76 @@ +import { Link } from 'react-router-dom'; +import { ShieldCheck } from 'lucide-react'; + +const Sidebar = () => { + return ( +
+ + + Home + +
+ ); +}; + +export default Sidebar; + const location = useLocation(); + const hasChildren = !!children; + const isActive = location.pathname === to; + + const handleClick = () => { + if (hasChildren) { + setIsOpen(!isOpen); + } + }; + + const itemContent = ( +
+ + {label} + {hasChildren && (isOpen ? : )} +
+ ); + + return ( +
+ {to && !hasChildren ? ( + {itemContent} + ) : ( + itemContent + )} + {hasChildren && isOpen && ( +
+ {children} +
+ )} +
+ ); +}; + +const Sidebar = () => { + return ( +
+ + + + + + + Security Tools + Configuration + + } + /> + +
+ ); +}; + +export default Sidebar; diff --git a/frontend/src/index.css b/frontend/src/index.css new file mode 100644 index 0000000..c065cc6 --- /dev/null +++ b/frontend/src/index.css @@ -0,0 +1,203 @@ +@import "tailwindcss"; + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + * { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; + background-color: #18181b; + color: white; + line-height: 1.6; + } + + #root { + height: 100vh; + width: 100vw; + } +} + +@layer components { + .sidebar-item { + @apply flex items-center cursor-pointer px-4 py-2 rounded-xl hover:bg-zinc-800 transition-all; + } + + .sidebar-icon { + @apply w-5 h-5 mr-3 text-cyan-400; + } + + .card { + @apply bg-zinc-800 rounded-lg p-6 shadow-lg; + } + + .btn-primary { + @apply bg-cyan-600 hover:bg-cyan-700 text-white px-4 py-2 rounded-lg transition-colors; + } + + .btn-secondary { + @apply bg-zinc-700 hover:bg-zinc-600 text-white px-4 py-2 rounded-lg transition-colors; + } +} + +@layer utilities { + .flex { + display: flex; + } + + .h-screen { + height: 100vh; + } + + .bg-zinc-900 { + background-color: #18181b; + } + + .bg-zinc-950 { + background-color: #09090b; + } + + .bg-zinc-800 { + background-color: #27272a; + } + + .text-white { + color: white; + } + + .text-zinc-400 { + color: #a1a1aa; + } + + .text-cyan-400 { + color: #22d3ee; + } + + .flex-1 { + flex: 1; + } + + .p-6 { + padding: 1.5rem; + } + + .p-4 { + padding: 1rem; + } + + .overflow-auto { + overflow: auto; + } + + .w-56 { + width: 14rem; + } + + .space-y-6 > * + * { + margin-top: 1.5rem; + } + + .space-y-2 > * + * { + margin-top: 0.5rem; + } + + .rounded-r-xl { + border-top-right-radius: 0.75rem; + border-bottom-right-radius: 0.75rem; + } + + .shadow-md { + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); + } + + .text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; + } + + .font-bold { + font-weight: 700; + } + + .mb-2 { + margin-bottom: 0.5rem; + } + + .text-lg { + font-size: 1.125rem; + line-height: 1.75rem; + } + + .font-semibold { + font-weight: 600; + } + + .text-2xl { + font-size: 1.5rem; + line-height: 2rem; + } + + .w-8 { + width: 2rem; + } + + .h-8 { + height: 2rem; + } + + .mr-4 { + margin-right: 1rem; + } + + .rounded-lg { + border-radius: 0.5rem; + } + + .items-center { + align-items: center; + } + + .cursor-pointer { + cursor: pointer; + } + + .px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + + .py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + + .rounded-xl { + border-radius: 0.75rem; + } + + .hover\:bg-zinc-800:hover { + background-color: #27272a; + } + + .transition-all { + transition: all 0.15s ease-in-out; + } + + .w-5 { + width: 1.25rem; + } + + .h-5 { + height: 1.25rem; + } + + .mr-3 { + margin-right: 0.75rem; + } +} \ No newline at end of file diff --git a/frontend/src/pages/HomePage.jsx b/frontend/src/pages/HomePage.jsx new file mode 100644 index 0000000..ef45ffd --- /dev/null +++ b/frontend/src/pages/HomePage.jsx @@ -0,0 +1,105 @@ +import React, { useState, useEffect } from 'react'; +import { Activity, Upload, FileText, Shield } from 'lucide-react'; + +const HomePage = () => { + const [stats, setStats] = useState({ + filesUploaded: 0, + analysesCompleted: 0, + threatsDetected: 0 + }); + + useEffect(() => { + // Fetch dashboard stats + fetch('/api/health') + .then(res => res.json()) + .then(data => console.log('Backend connected:', data)) + .catch(err => console.error('Backend connection failed:', err)); + }, []); + + return ( +
+
+

Cyber Threat Hunter

+

+ Advanced threat hunting and security analysis platform +

+
+ +
+
+
+ +
+

Files Uploaded

+

{stats.filesUploaded}

+
+
+
+ +
+
+ +
+

Analyses Completed

+

{stats.analysesCompleted}

+
+
+
+ +
+
+ +
+

Threats Detected

+

{stats.threatsDetected}

+
+
+
+
+ +
+

Quick Actions

+
+ + +
+
+ +
+

System Health

+
+
+ Backend Status + ✓ Healthy +
+
+ Database Connection + ✓ Connected +
+
+ Storage Available + ⚠ 75% Used +
+
+
+ +
+
+ +
+

System Status

+

Ready

+
+
+
+
+ ); +}; + +export default HomePage; diff --git a/frontend/vite.config.js b/frontend/vite.config.js new file mode 100644 index 0000000..3d18e7f --- /dev/null +++ b/frontend/vite.config.js @@ -0,0 +1,20 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + server: { + port: 3000, + proxy: { + '/api': { + target: 'http://localhost:5000', + changeOrigin: true, + secure: false + } + } + }, + build: { + outDir: 'dist', + sourcemap: true + } +}) \ No newline at end of file diff --git a/quick-start.bat b/quick-start.bat new file mode 100644 index 0000000..60a3126 --- /dev/null +++ b/quick-start.bat @@ -0,0 +1,22 @@ +@echo off +echo Quick Start - Velo Threat Hunter + +cd backend +call venv\Scripts\activate +pip install flask flask-cors python-dotenv requests werkzeug +start "Backend" cmd /k "python app.py" +cd .. + +timeout /t 3 /nobreak >nul + +cd frontend +if exist package.json ( + start "Frontend" cmd /k "npm run dev" +) else ( + echo Frontend not configured yet +) +cd .. + +echo. +echo Servers starting... +pause diff --git a/run-backend.bat b/run-backend.bat new file mode 100644 index 0000000..c50837c --- /dev/null +++ b/run-backend.bat @@ -0,0 +1,6 @@ +@echo off +title Cyber Threat Hunter - Backend +cd /d "%~dp0\backend" +call venv\Scripts\activate.bat +python app.py +pause diff --git a/run-frontend.bat b/run-frontend.bat new file mode 100644 index 0000000..dc77170 --- /dev/null +++ b/run-frontend.bat @@ -0,0 +1,55 @@ +@echo off +title Cyber Threat Hunter - Frontend +cd /d "%~dp0\frontend" + +echo Checking Node.js installation... +node --version >nul 2>&1 +if errorlevel 1 ( + echo Error: Node.js not found + echo Please install Node.js from https://nodejs.org + pause + exit /b 1 +) + +echo Installing dependencies... +npm install + +echo Starting development server... +npm run dev +pause + echo "dependencies": {>> package.json + echo "react": "^18.3.1",>> package.json + echo "react-dom": "^18.3.1",>> package.json + echo "react-router-dom": "^6.26.1",>> package.json + echo "lucide-react": "^0.515.0">> package.json + echo },>> package.json + echo "devDependencies": {>> package.json + echo "@vitejs/plugin-react": "^4.3.1",>> package.json + echo "vite": "^5.3.4">> package.json + echo }>> package.json + echo }>> package.json +) + +REM Check if Node.js is available +node --version >nul 2>&1 +if errorlevel 1 ( + echo Error: Node.js not found + echo Please install Node.js from https://nodejs.org + pause + exit /b 1 +) + +REM Install dependencies if node_modules doesn't exist +if not exist "node_modules" ( + echo Installing npm dependencies... + npm install + if errorlevel 1 ( + echo Error: Failed to install npm dependencies + pause + exit /b 1 + ) +) + +echo Starting Cyber Threat Hunter Frontend... +npm run dev +pause diff --git a/setup-backend.bat b/setup-backend.bat new file mode 100644 index 0000000..1c6417a --- /dev/null +++ b/setup-backend.bat @@ -0,0 +1,30 @@ +@echo off +title Setup Backend +echo Setting up Cyber Threat Hunter Backend... + +cd backend + +REM Create virtual environment if it doesn't exist +if not exist "venv" ( + echo Creating virtual environment... + python -m venv venv + if errorlevel 1 ( + echo Error: Failed to create virtual environment + echo Make sure Python is installed + pause + exit /b 1 + ) +) + +echo Activating virtual environment... +call venv\Scripts\activate.bat + +echo Installing Flask and dependencies... +pip install flask==3.0.0 +pip install flask-cors==4.0.0 +pip install python-dotenv==1.0.0 +pip install requests==2.31.0 +pip install werkzeug==3.0.1 + +echo Backend setup complete! +pause diff --git a/setup-frontend.bat b/setup-frontend.bat new file mode 100644 index 0000000..da31a02 --- /dev/null +++ b/setup-frontend.bat @@ -0,0 +1,41 @@ +@echo off +title Setup Frontend +echo Setting up Cyber Threat Hunter Frontend... + +cd frontend + +REM Clean up corrupted files +if exist "package-lock.json" del /f "package-lock.json" +if exist "node_modules" rmdir /s /q "node_modules" 2>nul + +echo Creating clean package.json... +( +echo { +echo "name": "cyber-threat-hunter", +echo "private": true, +echo "version": "1.0.0", +echo "type": "module", +echo "scripts": { +echo "dev": "vite", +echo "build": "vite build", +echo "preview": "vite preview" +echo }, +echo "dependencies": { +echo "react": "^18.3.1", +echo "react-dom": "^18.3.1", +echo "react-router-dom": "^6.26.1", +echo "lucide-react": "^0.515.0" +echo }, +echo "devDependencies": { +echo "@vitejs/plugin-react": "^4.3.1", +echo "vite": "^5.3.4" +echo } +echo } +) > package.json + +echo Installing npm dependencies... +npm cache clean --force +npm install + +echo Frontend setup complete! +pause diff --git a/start-backend.bat b/start-backend.bat new file mode 100644 index 0000000..44f41c4 --- /dev/null +++ b/start-backend.bat @@ -0,0 +1,8 @@ +@echo off +title Cyber Threat Hunter - Backend +cd /d "%~dp0\backend" + +echo Starting Backend Server... +call venv\Scripts\activate.bat +python app.py +pause diff --git a/start-clean.bat b/start-clean.bat new file mode 100644 index 0000000..d0a2872 --- /dev/null +++ b/start-clean.bat @@ -0,0 +1,22 @@ +@echo off +title Cyber Threat Hunter - Clean Start +echo ======================================== +echo Cyber Threat Hunter - Clean Startup +echo ======================================== + +REM Clean backend +echo Cleaning backend... +cd backend +if exist "__pycache__" rmdir /s /q "__pycache__" 2>nul +if exist "*.pyc" del /f "*.pyc" 2>nul + +REM Clean frontend +echo Cleaning frontend... +cd ..\frontend +if exist "node_modules" rmdir /s /q "node_modules" 2>nul +if exist "package-lock.json" del /f "package-lock.json" 2>nul +if exist "dist" rmdir /s /q "dist" 2>nul + +echo. +echo Clean complete. Run start.bat to restart. +pause diff --git a/start-frontend.bat b/start-frontend.bat new file mode 100644 index 0000000..f751a48 --- /dev/null +++ b/start-frontend.bat @@ -0,0 +1,7 @@ +@echo off +title Cyber Threat Hunter - Frontend +cd /d "%~dp0\frontend" + +echo Starting Frontend Server... +npm run dev +pause diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..1aa5b34 --- /dev/null +++ b/start.bat @@ -0,0 +1,43 @@ +@echo off +title Cyber Threat Hunter +echo ======================================== +echo Cyber Threat Hunter +echo ======================================== + +REM Check if setup is needed +if not exist "backend\venv" ( + echo Backend not set up. Running setup... + call setup-backend.bat +) + +if not exist "frontend\node_modules" ( + echo Frontend not set up. Running setup... + call setup-frontend.bat +) + +echo Starting servers... + +REM Start Backend +start "Backend" cmd /k "start-backend.bat" + +REM Wait a moment +timeout /t 3 /nobreak >nul + +REM Start Frontend +start "Frontend" cmd /k "start-frontend.bat" + +echo. +echo ======================================== +echo Servers are starting... +echo Backend: http://localhost:5000 +echo Frontend: http://localhost:3000 +echo ======================================== +echo. +echo Press any key to exit... +pause >nul +echo Backend: http://localhost:5000 +echo Frontend: http://localhost:3000 +echo ======================================== +echo. +echo Press any key to exit... +pause >nul diff --git a/troubleshoot.md b/troubleshoot.md new file mode 100644 index 0000000..a2e1dfe --- /dev/null +++ b/troubleshoot.md @@ -0,0 +1,73 @@ +# Troubleshooting Guide + +## Common Issues + +### 1. Package.json Corruption + +**Symptoms:** JSON parse errors, unexpected characters +**Solution:** + +```bash +cd frontend +del package.json +# Run run-frontend.bat to recreate +``` + +### 2. Node Modules Issues + +**Symptoms:** Module not found errors +**Solution:** + +```bash +cd frontend +rmdir /s /q node_modules +del package-lock.json +npm cache clean --force +npm install +``` + +### 3. Backend Python Issues + +**Symptoms:** Module import errors +**Solution:** + +```bash +cd backend +pip install flask flask-cors python-dotenv requests werkzeug +``` + +### 4. Port Conflicts + +**Symptoms:** EADDRINUSE errors +**Solution:** + +- Frontend (3000): Vite will auto-select next port +- Backend (5000): Change port in app.py + +### 5. CORS Issues + +**Symptoms:** Cross-origin request blocked +**Solution:** Install flask-cors: `pip install flask-cors` + +## Quick Fixes + +1. **Complete Clean Start:** + + ```bash + start-clean.bat + start.bat + ``` + +2. **Backend Only:** + + ```bash + cd backend + python app.py + ``` + +3. **Frontend Only:** + ```bash + run-frontend.bat + ``` + +## File Structure Check