|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const axios = require('axios'); |
|
|
const fs = require('fs'); |
|
|
const path = require('path'); |
|
|
const { execSync } = require('child_process'); |
|
|
|
|
|
class CybersecurityToolkit { |
|
|
constructor(sock, config, apiClient = null) { |
|
|
this.sock = sock; |
|
|
this.config = config; |
|
|
this.apiClient = apiClient; |
|
|
|
|
|
|
|
|
this.cache = new Map(); |
|
|
this.cacheExpiry = 3600000; |
|
|
|
|
|
|
|
|
this.usageHistory = new Map(); |
|
|
|
|
|
console.log('β
CybersecurityToolkit inicializado'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async whoIs(target) { |
|
|
try { |
|
|
|
|
|
if (this._isDomain(target)) { |
|
|
return await this._whoisDomain(target); |
|
|
} |
|
|
|
|
|
|
|
|
if (this._isIP(target)) { |
|
|
return await this._whoisIP(target); |
|
|
} |
|
|
|
|
|
return { sucesso: false, erro: 'Alvo invΓ‘lido (nΓ£o Γ© IP nem domΓnio)' }; |
|
|
} catch (e) { |
|
|
console.error('Erro em whoIs:', e); |
|
|
return { sucesso: false, erro: e.message }; |
|
|
} |
|
|
} |
|
|
|
|
|
async _whoisDomain(domain) { |
|
|
try { |
|
|
|
|
|
|
|
|
|
|
|
const apis = [ |
|
|
`https://www.whoisjsonapi.com/api/v1/whois?domain=${domain}`, |
|
|
`https://domain.whoisxmlapi.com/api/gateway?apikey=${this.config.WHOIS_API_KEY || 'free'}&domain=${domain}` |
|
|
]; |
|
|
|
|
|
for (const apiUrl of apis) { |
|
|
try { |
|
|
const response = await axios.get(apiUrl, { timeout: 5000 }); |
|
|
if (response.data) { |
|
|
const data = response.data; |
|
|
const registrar = data.registrar || {}; |
|
|
|
|
|
return { |
|
|
sucesso: true, |
|
|
tipo: 'dominio', |
|
|
alvo: domain, |
|
|
dados: { |
|
|
registrador: registrar.name || data.registrant_name || 'N/A', |
|
|
dataRegistro: data.created_date || registrar.created_date || 'N/A', |
|
|
dataExpiracao: data.expires_date || registrar.expires_date || 'N/A', |
|
|
ns: data.nameservers || data.ns || [], |
|
|
pais: registrar.country || 'N/A', |
|
|
email: data.registrant_email || 'N/A', |
|
|
status: data.status || 'N/A' |
|
|
}, |
|
|
timestamp: new Date().toISOString() |
|
|
}; |
|
|
} |
|
|
} catch (e) { |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return { |
|
|
sucesso: true, |
|
|
tipo: 'dominio', |
|
|
alvo: domain, |
|
|
dados: { |
|
|
registrador: 'InformaΓ§Γ£o nΓ£o disponΓvel', |
|
|
dataRegistro: 'N/A', |
|
|
dataExpiracao: 'N/A', |
|
|
ns: [], |
|
|
pais: 'N/A', |
|
|
email: 'N/A', |
|
|
status: 'NΓ£o verificado' |
|
|
}, |
|
|
timestamp: new Date().toISOString(), |
|
|
aviso: 'Resultados limitados - API nΓ£o disponΓvel' |
|
|
}; |
|
|
} catch (e) { |
|
|
console.error('Erro em _whoisDomain:', e); |
|
|
return { sucesso: false, erro: e.message }; |
|
|
} |
|
|
} |
|
|
|
|
|
async _whoisIP(ip) { |
|
|
try { |
|
|
|
|
|
const apis = [ |
|
|
`https://ipqualityscore.com/api/json/ip/whois/${ip}?strictness=1`, |
|
|
`https://ipwho.is/?ip=${ip}`, |
|
|
`https://freeipapi.com/api/json/${ip}` |
|
|
]; |
|
|
|
|
|
for (const apiUrl of apis) { |
|
|
try { |
|
|
const response = await axios.get(apiUrl, { timeout: 5000 }); |
|
|
if (response.data) { |
|
|
return { |
|
|
sucesso: true, |
|
|
tipo: 'ip', |
|
|
alvo: ip, |
|
|
dados: { |
|
|
pais: response.data.country || response.data.country_name || 'N/A', |
|
|
cidade: response.data.city || 'N/A', |
|
|
regiao: response.data.region || response.data.state_prov || 'N/A', |
|
|
isp: response.data.isp || response.data.org || 'N/A', |
|
|
asn: response.data.asn || 'N/A', |
|
|
latitude: response.data.latitude || 'N/A', |
|
|
longitude: response.data.longitude || 'N/A', |
|
|
tipoBloqueio: response.data.is_blacklisted ? 'SIM - BLOQUEADO' : 'NΓ£o', |
|
|
risco: response.data.fraud_score ? `${response.data.fraud_score}%` : 'N/A' |
|
|
}, |
|
|
timestamp: new Date().toISOString() |
|
|
}; |
|
|
} |
|
|
} catch (e) { |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
return { |
|
|
sucesso: true, |
|
|
tipo: 'ip', |
|
|
alvo: ip, |
|
|
dados: { |
|
|
pais: 'N/A', |
|
|
cidade: 'N/A', |
|
|
regiao: 'N/A', |
|
|
isp: 'N/A', |
|
|
asn: 'N/A', |
|
|
latitude: 'N/A', |
|
|
longitude: 'N/A', |
|
|
tipoBloqueio: 'NΓ£o', |
|
|
risco: 'N/A' |
|
|
}, |
|
|
timestamp: new Date().toISOString(), |
|
|
aviso: 'Resultados limitados' |
|
|
}; |
|
|
} catch (e) { |
|
|
console.error('Erro em _whoisIP:', e); |
|
|
return { sucesso: false, erro: e.message }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async dnsRecon(domain) { |
|
|
try { |
|
|
if (!this._isDomain(domain)) { |
|
|
return { sucesso: false, erro: 'Alvo invΓ‘lido - use um domΓnio vΓ‘lido' }; |
|
|
} |
|
|
|
|
|
|
|
|
const cacheKey = `dns_${domain}`; |
|
|
if (this.cache.has(cacheKey)) { |
|
|
return this.cache.get(cacheKey); |
|
|
} |
|
|
|
|
|
|
|
|
const registros = {}; |
|
|
|
|
|
try { |
|
|
|
|
|
const dns = require('dns').promises; |
|
|
|
|
|
|
|
|
registros.A = await dns.resolve4(domain).catch(() => []); |
|
|
|
|
|
|
|
|
registros.MX = await dns.resolveMx(domain).catch(() => []); |
|
|
|
|
|
|
|
|
registros.CNAME = await dns.resolveCname(domain).catch(() => []); |
|
|
|
|
|
|
|
|
registros.TXT = await dns.resolveTxt(domain).catch(() => []); |
|
|
|
|
|
|
|
|
registros.NS = await dns.resolveNs(domain).catch(() => []); |
|
|
} catch (e) { |
|
|
console.log('Fallback: usando resultados simulados'); |
|
|
} |
|
|
|
|
|
const resultado = { |
|
|
sucesso: true, |
|
|
tipo: 'dns', |
|
|
dominio: domain, |
|
|
registros: registros, |
|
|
timestamp: new Date().toISOString(), |
|
|
subdomainsSugeridos: [ |
|
|
`www.${domain}`, |
|
|
`mail.${domain}`, |
|
|
`ftp.${domain}`, |
|
|
`admin.${domain}`, |
|
|
`api.${domain}`, |
|
|
`cdn.${domain}` |
|
|
] |
|
|
}; |
|
|
|
|
|
|
|
|
this.cache.set(cacheKey, resultado); |
|
|
setTimeout(() => this.cache.delete(cacheKey), this.cacheExpiry); |
|
|
|
|
|
return resultado; |
|
|
} catch (e) { |
|
|
console.error('Erro em dnsRecon:', e); |
|
|
return { sucesso: false, erro: e.message }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async analyzePasswordStrength(password) { |
|
|
try { |
|
|
let score = 0; |
|
|
const problemas = []; |
|
|
|
|
|
|
|
|
if (password.length >= 8) score += 20; |
|
|
else problemas.push('Muito curta (min 8 caracteres)'); |
|
|
|
|
|
if (password.length >= 12) score += 10; |
|
|
if (password.length >= 16) score += 10; |
|
|
|
|
|
|
|
|
if (/[A-Z]/.test(password)) score += 15; |
|
|
else problemas.push('Faltam letras maiΓΊsculas'); |
|
|
|
|
|
|
|
|
if (/[a-z]/.test(password)) score += 15; |
|
|
else problemas.push('Faltam letras minΓΊsculas'); |
|
|
|
|
|
|
|
|
if (/[0-9]/.test(password)) score += 15; |
|
|
else problemas.push('Faltam nΓΊmeros'); |
|
|
|
|
|
|
|
|
if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) score += 25; |
|
|
else problemas.push('Faltam caracteres especiais'); |
|
|
|
|
|
|
|
|
if (!/(.)\1{2,}/.test(password)) score += 10; |
|
|
else problemas.push('Caracteres repetidos consecutivos'); |
|
|
|
|
|
const forca = score >= 80 ? 'MUITO FORTE' : score >= 60 ? 'FORTE' : score >= 40 ? 'MΓDIO' : 'FRACO'; |
|
|
|
|
|
return { |
|
|
sucesso: true, |
|
|
password: '*'.repeat(password.length), |
|
|
score: Math.min(100, score), |
|
|
forca, |
|
|
problemas, |
|
|
recomendacoes: [ |
|
|
'Use pelo menos 12 caracteres', |
|
|
'Combine maiΓΊsculas, minΓΊsculas, nΓΊmeros e sΓmbolos', |
|
|
'Evite palavras do dicionΓ‘rio', |
|
|
'Use passphrases se possΓvel' |
|
|
] |
|
|
}; |
|
|
} catch (e) { |
|
|
return { sucesso: false, erro: e.message }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_isDomain(str) { |
|
|
const domainRegex = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/; |
|
|
return domainRegex.test(str); |
|
|
} |
|
|
|
|
|
_isIP(str) { |
|
|
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/; |
|
|
return ipRegex.test(str); |
|
|
} |
|
|
|
|
|
_getServiceVersion(servico) { |
|
|
|
|
|
} |
|
|
|
|
|
_logSecurityAction(acao, alvo, descricao, dados = {}) { |
|
|
const logEntry = { |
|
|
timestamp: new Date().toISOString(), |
|
|
acao, |
|
|
alvo, |
|
|
descricao, |
|
|
dados |
|
|
}; |
|
|
|
|
|
console.log(`π [SECURITY] ${JSON.stringify(logEntry)}`); |
|
|
} |
|
|
} |
|
|
|
|
|
module.exports = CybersecurityToolkit; |
|
|
|