En esta sección, exploraremos los componentes necesarios para crear una plataforma de inteligencia contra amenazas eficaz. Como se ha mencionado anteriormente, este curso incluirá la prueba de técnicas de extracción de datos en sitios ficticios que podrás configurar localmente utilizando Docker. Aquí obtendrás información sobre los tipos de sitios con los que trabajaremos.
Los temas que se tratan en esta sección incluyen:
- Foro Clearnet
- Foro Tor
- Enfoque no LLM para el análisis de texto
- Manejo de tecnologías anti-scraping
- Listas de vigilancia de inteligencia
Foro Clearnet
Aunque la mayoría de los sitios web de ciberdelincuencia no dependen en gran medida de JavaScript, es importante comprender cómo extraer datos de los sitios web clearnet. La mayoría de los sitios Clearnet suelen obtener datos del backend utilizando JavaScript y, a continuación, actualizan el frontend de forma dinámica. Al ver el código fuente de la página, es posible que no encuentres datos útiles, ya que el contenido se carga después de la carga inicial de la página. Un buen ejemplo es nuestro propio scraper, donde casi todo el contenido es dinámico y cambia constantemente.
En estos casos, utilizamos navegadores sin interfaz gráfica como Playwright para interactuar con la página y extraer datos del DOM (modelo de objetos de documento) después de que se haya cargado y renderizado por completo.
Para practicar esto, puedes descargar el foro ficticio sobre ciberdelincuencia creado para este curso desde GitHub:
https://github.com/CyberMounties/clearnet_forum
El repositorio contiene instrucciones completas para configurar el foro y ejecutarlo localmente.
Foro Tor
Gran parte de la actividad ciberdelictiva se produce en Tor debido a su arquitectura centrada en la privacidad. Nuestro foro Tor simulado está diseñado sin JavaScript para imitar situaciones reales y mantener la simplicidad. A diferencia del foro clearnet, que incluye una función de chat general, el foro Tor no la tiene.
Puede configurar el foro Tor ficticio para este curso descargándolo de GitHub:
https://github.com/CyberMounties/tornet_forum
El repositorio incluye instrucciones detalladas para configurar y ejecutar el foro localmente.
Enfoque no basado en LLM para el análisis de texto
En lugar de depender de modelos de lenguaje grandes (LLM) o IA, puede utilizar bibliotecas tradicionales de procesamiento del lenguaje natural (NLP) como spaCy para analizar datos. Estas herramientas pueden ayudar en tareas como la clasificación de texto, el reconocimiento de entidades y la coincidencia de patrones. Sin embargo, tienen limitaciones: suelen requerir más personalización manual, creación de reglas y formación para obtener resultados comparables a los de los LLM. Aunque pueden ser eficaces para determinados casos de uso, su configuración para tareas complejas, como la identificación de la actividad de la IAB, puede requerir mucho más tiempo y esfuerzo.
Ejemplo con spaCy
Cree un directorio, configure un entorno virtual e instale las dependencias:
mkdir non_llm_cti && cd non_llm_cti
python3 -m venv venv
source venv/bin/activate
pip install spacy
python -m spacy download en_core_web_sm
Crea un archivo de script llamado main.py y pega el siguiente código dentro:
import spacy
import re
from typing import Tuple
# Load spaCy's English model
nlp = spacy.load("en_core_web_sm")
# Define keywords and patterns for initial access detection
ACCESS_KEYWORDS = {
"access", "vpn", "rdp", "network", "server", "admin", "credentials",
"login", "remote", "domain", "shell", "backdoor"
}
SALE_KEYWORDS = {"sell", "selling", "offer", "offering", "sale", "available", "price", "btc", "escrow"}
NEGATIVE_KEYWORDS = {"hosting", "vps", "software", "malware", "loader", "botnet"}
OBFUSCATION_PATTERNS = [
r"acc[e3]ss", # Handles "acc3ss", "access"
r"v[pP][nN]", # Handles "VPN", "VpN", "vpn"
r"rd[pP]", # Handles "RDP", "rdp"
]
def preprocess_text(text: str) -> str:
"""Normalize text by converting to lowercase and handling basic obfuscation."""
text = text.lower()
for pattern in OBFUSCATION_PATTERNS:
text = re.sub(pattern, re.search(pattern, text).group().replace("3", "e"), text) if re.search(pattern, text) else text
return text
def analyze_post(text: str) -> Tuple[str, float]:
"""
Analyze a post to determine if it offers initial access.
Returns: (classification, confidence_score)
Classifications: 'positive' (initial access sale), 'neutral' (general ad), 'negative' (unrelated)
"""
# Preprocess text
text = preprocess_text(text)
doc = nlp(text)
# Initialize scores
access_score = 0.0
sale_score = 0.0
negative_score = 0.0
# Rule 1: Check for access-related keywords
for token in doc:
if token.lemma_ in ACCESS_KEYWORDS:
access_score += 0.4
if token.lemma_ in SALE_KEYWORDS:
sale_score += 0.3
if token.lemma_ in NEGATIVE_KEYWORDS:
negative_score += 0.5
# Rule 2: Dependency parsing for sales intent (e.g., "selling access")
for token in doc:
if token.lemma_ in SALE_KEYWORDS and token.head.lemma_ in ACCESS_KEYWORDS:
access_score += 0.3
sale_score += 0.3
elif token.lemma_ in ACCESS_KEYWORDS and token.head.lemma_ in SALE_KEYWORDS:
access_score += 0.3
sale_score += 0.3
# Rule 3: Named entities (e.g., "RBC Bank", "EU telecom") for context
for ent in doc.ents:
if ent.label_ in ["ORG", "GPE"]:
access_score += 0.2
# Rule 4: Regex for specific patterns (e.g., "access to [entity]")
access_pattern = r"\b(access|vpn|rdp)\b.*\b(to|for|at)\b.*\b(bank|telecom|network|company|org)\b"
if re.search(access_pattern, text, re.IGNORECASE):
access_score += 0.3
# Rule 5: Cryptocurrency or escrow mentions
if any(word in text for word in ["btc", "bitcoin", "escrow", "monero"]):
sale_score += 0.2
# Calculate total score and determine classification
total_score = access_score + sale_score - negative_score
if access_score >= 0.4 and sale_score >= 0.3 and total_score > 0.5:
classification = "positive"
confidence = min(total_score, 1.0)
elif negative_score > access_score and negative_score > sale_score:
classification = "negative"
confidence = min(negative_score, 1.0)
else:
classification = "neutral"
confidence = min(max(access_score, sale_score, negative_score), 1.0)
return classification, confidence
def main():
# Test cases
test_posts = [
# Positive: Initial access sale with details
"""Back again, mods nuked my last thread. Selling VPN access to a big EU telecom, one of them household names in Germany (you figure it out). Full internal access, you can pivot to servers, grab call logs, or mess with billing systems. Been stable for a month, no kicks. Asking $4,000 BTC, negotiable for bulk buyers (got 2 more telecoms). I'll throw in logs or a test connection for proof, but only if you're serious. Escrow or MM accepted, I'm vouched here. Hit me up in PM, let's make this quick. No skids, please.""",
# Positive: Direct initial access sale
"Initial access to RBC Bank available, full admin creds, $5k BTC, DM for details.",
# Neutral: General ad, not access-related
"Selling malware loader, high quality, $200, contact me for demo.",
# Negative: Unrelated service
"Offering VPS hosting, 16GB RAM, $50/month, legit service."
]
for i, post in enumerate(test_posts, 1):
classification, confidence = analyze_post(post)
print(f"\nPost {i}:")
print(f"Text: {post[:100]}..." if len(post) > 100 else f"Text: {post}")
print(f"Classification: {classification.capitalize()}")
print(f"Confidence: {confidence:.2f}")
if __name__ == "__main__":
main()
Ejecútalo y comprueba los resultados por ti mismo:
$ python3 main.py
Post 1:
Text: Back again, mods nuked my last thread. Selling VPN access to a big EU telecom, one of them household...
Classification: Positive
Confidence: 1.00
Post 2:
Text: Initial access to RBC Bank available, full admin creds, $5k BTC, DM for details.
Classification: Positive
Confidence: 1.00
Post 3:
Text: Selling malware loader, high quality, $200, contact me for demo.
Classification: Negative
Confidence: 1.00
Post 4:
Text: Offering VPS hosting, 16GB RAM, $50/month, legit service.
Classification: Negative
Confidence: 1.00
Este enfoque, como se ha demostrado, es menos fiable, especialmente a la hora de clasificar con precisión la tercera publicación como «neutral». Requiere una amplia personalización y ajuste, lo que, en este caso, supera las ventajas, dada la disponibilidad de soluciones más sencillas y adaptables, como las API de IA existentes.
Tecnologías antiscraping
Extraer datos de sitios web es sencillo a pequeña escala, pero se vuelve complejo cuando los sitios implementan tecnologías antiscraping para bloquear el acceso automatizado. Muchos sitios web aplican condiciones de servicio que prohíben el scraping, y los desarrolladores implementan medidas de protección para hacer cumplir estas restricciones.
Las técnicas antiscraping más comunes incluyen:
- CAPTCHAs: requieren que los usuarios resuelvan acertijos o retos basados en imágenes para verificar que no son bots.
- Limitación de la velocidad: limita el número de solicitudes de una sola dirección IP o cuenta dentro de un periodo de tiempo específico.
- Bloqueo de cuentas: suspende temporal o permanentemente las cuentas tras detectar actividad sospechosa o intentos de inicio de sesión fallidos excesivos.
- Prohibición de IP: bloquea el tráfico de direcciones IP que muestran patrones automatizados o comportamientos abusivos.
- Comprobaciones de encabezados y comportamiento: Detecta las solicitudes que se desvían del comportamiento típico de un navegador, como la falta de encabezados o patrones de interacción poco realistas.
Herramientas como Playwright pueden ayudar a eludir algunas de las defensas antibots simulando un navegador real, pero aún así no es suficiente, es posible que desees utilizar undetected chrome driver.
Aunque este curso no aborda cómo eludir todas las técnicas avanzadas contra el scraping, el ejemplo siguiente ilustra cómo utilizar Playwright para simular velocidades de escritura similares a las de un humano.
Para empezar, configura un entorno e instala las dependencias:
mkdir play && cd play
touch play.py
python3 -m venv venv
source venv/bin/activate
sudo apt install libavif16
pip3 install playwright
playwright install
Abre «play.py» e introduce este código:
from playwright.sync_api import sync_playwright
import time
import os
def fill_input_slowly():
text_to_type = "This is a test string"
local_html = """
<!DOCTYPE html>
<html>
<body>
<form>
<input type="text" id="fname" name="fname" value="Hamy">
</form>
</body>
</html>
"""
# Write the HTML to a temporary file
html_file_path = "temp.html"
with open(html_file_path, "w") as f:
f.write(local_html)
with sync_playwright() as p:
# Set headless to True if you don't want to see the browser
browser = p.chromium.launch(headless=False)
page = browser.new_page()
try:
page.goto(f"file://{os.path.abspath(html_file_path)}", timeout=60000)
input_field = page.locator("input#fname[name='fname']")
input_field.wait_for(timeout=10000)
input_field.clear()
for char in text_to_type:
input_field.type(char, delay=750)
time.sleep(2)
except Exception as e:
print(f"Error occurred: {e}")
finally:
browser.close()
if os.path.exists(html_file_path):
os.remove(html_file_path)
if __name__ == "__main__":
fill_input_slowly()
Listas de vigilancia de inteligencia
Una de las características clave que distingue este curso de la mayoría de los cursos de formación en CTI es que aprenderá a crear listas de vigilancia de inteligencia realistas. Estas listas funcionan como un sistema de vigilancia automatizado, que supervisa continuamente la actividad de un usuario a lo largo del tiempo. En lugar de limitarse a recopilar instantáneas de datos, creará herramientas que pueden rastrear los cambios y las acciones a medida que se producen.
El objetivo principal de estas listas de vigilancia es demostrar cómo cruzar las actividades de un agente malicioso en múltiples plataformas, lo que te ayudará a construir una imagen completa de su comportamiento. Esto es esencial para rastrear a los agentes maliciosos prolíficos, correlacionar datos de diferentes fuentes y comprender los patrones que pueden indicar intenciones maliciosas.
Para crear un perfil de lista de vigilancia, definirás:
- Enlace: el identificador de la persona o entidad que deseas supervisar.
- Frecuencia: la frecuencia con la que el sistema comprueba si hay nueva actividad. Las opciones son:
- Baja: cada 24 horas
- Media: cada 12 horas
- Alta: cada 6 horas
- Muy alta: cada hora
- Crítica: cada 5 minutos
- Prioridad: el nivel de detalle de la información recopilada. Las opciones incluyen:
- Todo: Todos los datos disponibles (publicaciones y comentarios)
- Solo publicaciones: Solo el contenido publicado por el usuario
- Solo comentarios: Solo los comentarios realizados por el usuario
Por ejemplo, una lista de vigilancia de baja prioridad comprueba la actividad cada 24 horas y recopila los datos relevantes. Los resultados se pueden exportar en formato JSON para facilitar su descarga y cruce con otras plataformas.