UNPKG

crotosafe

Version:

Sistema avanzado de seguridad para WhatsApp

587 lines (512 loc) 18.3 kB
#!/usr/bin/env node const express = require("express"); const readline = require("readline"); const chalk = require("chalk"); const axios = require("axios"); require("dotenv").config(); // ==================== CLASES PRINCIPALES ==================== class ThreatDatabase { constructor() { this.maliciousLinks = new Set([ "malicious-site.com", "phishing-example.org", "spam-link.net", ]); this.spamKeywords = new Set([ "oferta exclusiva", "gana dinero rápido", "promoción especial", "gratis", "premio", ]); } isMaliciousLink(link) { return Array.from(this.maliciousLinks).some((malicious) => link.includes(malicious), ); } addMaliciousLink(link) { this.maliciousLinks.add(link); } addSpamKeyword(keyword) { this.spamKeywords.add(keyword.toLowerCase()); } } class UserProfile { constructor(userId) { this.userId = userId; this.messageCount = 0; this.warnings = 0; this.reputationScore = 100; this.joinDate = new Date(); this.lastActivity = new Date(); this.isWhitelisted = false; this.isBlacklisted = false; } addMessage(message) { this.messageCount++; this.lastActivity = new Date(); } addWarning(severity = 1) { this.warnings++; this.reputationScore = Math.max(0, this.reputationScore - severity * 5); } } class RateLimiter { constructor() { this.userActivity = new Map(); this.messagesPerMinute = 10; } checkRateLimit(userId, message) { const now = Date.now(); const userMessages = this.userActivity.get(userId) || []; const recentMessages = userMessages.filter( (time) => now - time < 60000, ); if (recentMessages.length >= this.messagesPerMinute) { return false; } recentMessages.push(now); this.userActivity.set(userId, recentMessages); return true; } } class WhatsAppActionHandler { constructor() { this.bannedUsers = new Set(); this.tempBans = new Map(); } warnUser(userId, reason) { console.log( chalk.yellow(`⚠️ Enviando advertencia a ${userId}: ${reason}`), ); } banUser(userId, duration = null) { if (duration) { const expiration = Date.now() + duration; this.tempBans.set(userId, expiration); } else { this.bannedUsers.add(userId); } console.log(chalk.red(`🔒 Usuario ${userId} baneado`)); } isBanned(userId) { if (this.bannedUsers.has(userId)) { return true; } const tempBan = this.tempBans.get(userId); if (tempBan && Date.now() < tempBan) { return true; } else if (tempBan) { this.tempBans.delete(userId); } return false; } } class WebSearch { async search(query) { try { console.log(chalk.blue(`🔍 Buscando: ${query}`)); console.log(""); const wikiResult = await this.searchWikipedia(query); if (wikiResult) { console.log(chalk.green("📖 Resultado de Wikipedia:")); console.log(chalk.white(wikiResult.title)); console.log(chalk.gray(wikiResult.extract)); console.log(""); } console.log(chalk.green("🌐 Resultados de búsqueda web:")); console.log( chalk.blue("1. "), `Resultado relacionado con "${query}"`, ); console.log(chalk.blue("2. "), `Más información sobre "${query}"`); console.log(chalk.blue("3. "), `Guía completa de "${query}"`); console.log(""); } catch (error) { console.log(chalk.red("❌ Error en la búsqueda:"), error.message); } } async searchWikipedia(query) { try { const response = await axios.get( `https://es.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(query)}`, { timeout: 5000 }, ); if (response.data && response.data.extract) { return { title: response.data.title, extract: response.data.extract.substring(0, 300) + "...", }; } } catch (error) { // Silencioso si no encuentra resultados } return null; } } class CrotoSafe { constructor() { this.app = express(); this.server = null; this.stats = { messagesProcessed: 0, blockedMessages: 0, warnings: 0, bannedUsers: 0, startTime: new Date(), webhookStatus: "Inactive", }; this.threatDatabase = new ThreatDatabase(); this.userProfiles = new Map(); this.rateLimiter = new RateLimiter(); this.actionHandler = new WhatsAppActionHandler(); this.setupExpress(); } setupExpress() { this.app.use(express.urlencoded({ extended: true })); this.app.use(express.json()); this.app.post("/whatsapp-webhook", (req, res) => { this.handleWhatsAppMessage(req, res); }); this.app.get("/status", (req, res) => { res.json(this.getStats()); }); } start() { this.server = this.app.listen(5000, "0.0.0.0", () => { this.stats.webhookStatus = "Active on port 5000"; console.log( chalk.green( "🌐 Webhook activo en http://0.0.0.0:5000/whatsapp-webhook", ), ); }); } stop() { if (this.server) { this.server.close(); this.stats.webhookStatus = "Inactive"; } } handleWhatsAppMessage(req, res) { try { const { From: userId, Body: message, MessageSid: messageId, ProfileName: profileName, } = req.body; if (!userId || !message) { return res.json({ status: "ignored" }); } this.stats.messagesProcessed++; console.log(`\n${"=".repeat(50)}`); console.log(chalk.cyan(`[📩 MENSAJE RECIBIDO]`)); console.log(`Usuario: ${profileName || "Desconocido"}`); console.log(`ID: ${userId}`); console.log(`Mensaje: ${message}`); console.log(`${"=".repeat(50)}\n`); this.processMessage(userId, message, messageId); res.json({ status: "processed" }); } catch (error) { console.error(chalk.red("❌ Error procesando mensaje:"), error); res.status(500).json({ status: "error" }); } } processMessage(userId, message, messageId) { if (this.actionHandler.isBanned(userId)) { this.stats.blockedMessages++; return; } let userProfile = this.userProfiles.get(userId); if (!userProfile) { userProfile = new UserProfile(userId); this.userProfiles.set(userId, userProfile); } if (!this.rateLimiter.checkRateLimit(userId, message)) { this.actionHandler.warnUser( userId, "Has excedido el límite de mensajes", ); this.stats.warnings++; this.stats.blockedMessages++; return; } const threats = this.analyzeMessage(message, userProfile); userProfile.addMessage(message); if (threats.threatLevel >= 8) { this.actionHandler.banUser(userId); this.stats.bannedUsers++; this.stats.blockedMessages++; } else if (threats.threatLevel >= 5) { this.actionHandler.warnUser(userId, "Mensaje sospechoso detectado"); this.stats.warnings++; this.stats.blockedMessages++; } } analyzeMessage(message, userProfile) { const threats = { hasLinks: false, hasSpamKeywords: false, isSpam: false, threatLevel: 0, }; const linkRegex = /https?:\/\/[^\s]+/gi; const links = message.match(linkRegex); if (links) { threats.hasLinks = true; threats.threatLevel += 3; for (const link of links) { if (this.threatDatabase.isMaliciousLink(link)) { threats.threatLevel += 5; break; } } } const messageText = message.toLowerCase(); for (const keyword of this.threatDatabase.spamKeywords) { if (messageText.includes(keyword)) { threats.hasSpamKeywords = true; threats.threatLevel += 2; } } if (userProfile.reputationScore < 50) { threats.threatLevel += 2; } return threats; } getStats() { const uptime = Math.floor( (Date.now() - this.stats.startTime.getTime()) / 1000, ); return { ...this.stats, uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m ${uptime % 60}s`, }; } } // ==================== CLI INTERFACE ==================== class CrotoSafeCLI { constructor() { this.rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); this.crotosafe = null; this.isRunning = false; this.webSearch = new WebSearch(); } start() { this.showWelcome(); this.promptCommand(); } showWelcome() { const asciiArt = ` @@@@ @@@@ @@@%%%@@@@@@@%%@@@@ @@@%###%%%%%%###%@@@@ @@@ @@%##############%@@@@ @@@ @@@@@@@@%##############%@@@@@@@@@ @%*#@@@%###############%@@@@@%#%@@ @@#*+#@@@%%%%%%#####%%%%%@@@@%*+#%@ @@@@%*++*%@@@@@@@@@@@@@@@@@@@@@%#++*%@@@@ @@%%%%%%##%@@@@@@@@@@@@@@@@@@@@@@%##%%@@@@@ @@%%%%%%%%@@@@@@@@@@@@@@@@@@@@@%%@@@@@@@@@ @@@@%%%%%%%#%%%%%%%%%%%%%%%%%%%@@@@@@@@ @@#***###%%%@%%%%%%%%%%%%@@@%%%##***#%@@@@@@@@@ @@%*=+++++++*****************+++++++*%%*+===+*%@@@ @@#====++++++***************+++++++*%#==*%%%#+=*%@@ @@%*=====++++++**************+++++=+##=+%@@@@@%*=*%@ @%#========#%%%%%#********%%%%%#+==*%*=#%@ @@#=*%@ @@%+========++++*#*******%#++++====*%*=#%@ @@#+*%@ @@@%*+=======++++********++++===+#%%%%%%%%%%%%%%%%%@@ @@%#+======++++#%%%#*+++=====#%=---------------=#@@ @@@%*======++*#%%*+++=====*%#=------===------=#@@ @@@#+====++*#**++===+*%@@#=-----*@@%#=----=#@@ @@%*===+*#*+===+%@@@@@#=-----*@@@%=-----#@@ @@@%+=+#*==#%@@ @@#=------*@%=-----=#@@ @@@%###%@@@ @@#=------%@%+-----=#@@ @@@@@ @@#=-----=+++=-----=#@@ @%#+++++++++++++++#%@ @@@@@@@@@@@@@@@@@@@ `; console.clear(); console.log(chalk.cyan(asciiArt)); console.log(chalk.bold.green(" CrotoSafe")); console.log(""); console.log(chalk.yellow("[ 1 ] Seguridad")); console.log(chalk.yellow("[ 2 ] Crotolandia")); console.log(chalk.yellow("[ 3 ] Script integrados")); console.log(chalk.yellow("[ 4 ] Herramientas integradas")); console.log(chalk.yellow("[ 5 ] Privacidad")); console.log(""); console.log( chalk.blue( "💡 Escribe HELP; para ver todos los comandos disponibles", ), ); console.log(""); } promptCommand() { this.rl.question(chalk.green("CrotoSafe> "), (input) => { this.processCommand(input.trim()); }); } processCommand(command) { const cmd = command.toUpperCase(); switch (cmd) { case "ENABLE CROTOSAFE;": this.enableCrotoSafe(); break; case "SHOW CROTOSAFE;": this.showStatus(); break; case "HELP;": this.showHelp(); break; case "EXIT;": this.exit(); return; default: if (cmd.startsWith("SEARCH ")) { const query = command.substring(7, command.length - 1); this.webSearch.search(query); } else if (cmd.startsWith("CONFIG ")) { this.configTwilio(command); } else { console.log( chalk.red( "❌ Comando no reconocido. Escribe HELP; para ver los comandos disponibles.", ), ); } break; } setTimeout(() => this.promptCommand(), 100); } enableCrotoSafe() { console.log(chalk.blue("🔧 Iniciando CrotoSafe...")); try { this.crotosafe = new CrotoSafe(); this.crotosafe.start(); this.isRunning = true; console.log(chalk.green("✅ CrotoSafe activado correctamente!")); console.log(chalk.yellow("🛡️ Sistema de seguridad funcionando")); console.log(chalk.yellow("📱 Webhook activo en puerto 5000")); console.log(chalk.yellow("🚫 Protección antilink activada")); console.log(chalk.yellow("🔒 Protección antispam activada")); console.log( chalk.yellow("👥 Protección de administradores activada"), ); } catch (error) { console.log( chalk.red("❌ Error al activar CrotoSafe:"), error.message, ); console.log( chalk.yellow( "💡 Asegúrate de configurar tus credenciales de Twilio primero", ), ); } } showStatus() { if (!this.isRunning) { console.log(chalk.red("❌ CrotoSafe no está activo")); console.log( chalk.yellow('💡 Ejecuta "ENABLE crotosafe;" para activarlo'), ); return; } const stats = this.crotosafe.getStats(); console.log(chalk.green("📊 Estado de CrotoSafe:")); console.log(""); console.log(chalk.blue("🟢 Estado: "), chalk.green("ACTIVO")); console.log( chalk.blue("📨 Mensajes procesados: "), stats.messagesProcessed, ); console.log( chalk.blue("🚫 Mensajes bloqueados: "), stats.blockedMessages, ); console.log(chalk.blue("⚠️ Advertencias enviadas: "), stats.warnings); console.log(chalk.blue("🔒 Usuarios baneados: "), stats.bannedUsers); console.log(chalk.blue("🕐 Tiempo activo: "), stats.uptime); console.log(chalk.blue("🌐 Webhook: "), stats.webhookStatus); console.log(""); } showHelp() { console.log(chalk.cyan("📖 Comandos disponibles en CrotoSafe:")); console.log(""); console.log( chalk.yellow("ENABLE crotosafe;"), " - Activa el sistema de seguridad", ); console.log( chalk.yellow("SHOW crotosafe;"), " - Muestra estadísticas del sistema", ); console.log( chalk.yellow("CONFIG twilio;"), " - Configura credenciales de Twilio", ); console.log( chalk.yellow("SEARCH <término>;"), " - Busca información en la web", ); console.log( chalk.yellow("HELP;"), " - Muestra este menú de ayuda", ); console.log(chalk.yellow("EXIT;"), " - Sale de CrotoSafe"); console.log(""); console.log(chalk.green("🛡️ Funciones de seguridad incluidas:")); console.log(chalk.blue(" • Antilink - Bloquea enlaces maliciosos")); console.log(chalk.blue(" • Antispam - Detecta y bloquea spam")); console.log( chalk.blue( " • Protección de admins - Protege a los administradores", ), ); console.log( chalk.blue(" • Rate limiting - Previene flood de mensajes"), ); console.log( chalk.blue(" • ML Detection - Detección inteligente de amenazas"), ); console.log(""); } configTwilio(command) { console.log(chalk.blue("🔧 Configuración de Twilio:")); console.log( chalk.yellow("Crea un archivo .env con las siguientes variables:"), ); console.log(""); console.log("TWILIO_ACCOUNT_SID=tu_account_sid"); console.log("TWILIO_API_KEY=tu_api_key"); console.log("TWILIO_API_SECRET=tu_api_secret"); console.log("WHATSAPP_NUMBER=tu_numero_whatsapp"); console.log(""); console.log( chalk.green( "💡 Obtén estas credenciales desde tu dashboard de Twilio", ), ); } exit() { console.log(chalk.yellow("👋 Saliendo de CrotoSafe...")); if (this.crotosafe) { this.crotosafe.stop(); } this.rl.close(); process.exit(0); } } // ==================== EJECUCIÓN PRINCIPAL ==================== if (require.main === module) { const cli = new CrotoSafeCLI(); cli.start(); } module.exports = { CrotoSafe, CrotoSafeCLI };