Skip to main content
The attack simulator lets you test the IDS/IPS without a real attacker. It sends crafted packets directly into the network interface so the sniffer captures them exactly as it would capture live attack traffic.

Why Layer 2 (Ethernet frames)

The simulator uses Scapy’s sendp() with an Ether() wrapper instead of send(). This distinction matters on Windows:
  • sendp() at Layer 2 injects raw Ethernet frames through the Npcap driver. The sniffer sees these packets as if they arrived from the network.
  • send() at Layer 3 routes packets through the Windows IP stack, which handles them internally. The Npcap-based sniffer never sees them.
Always use simular_varios_ataques.py (Layer 2) for testing. The simpler simular_ataque.py also uses sendp() but only simulates a fixed 1,000-packet SYN flood (random ports from 203.0.113.50) — use the multi-attack version for selecting specific attack types.

IP spoofing

Each simulation run generates randomized source IPs. This solves a subtle problem: once the IPS blocks an IP, it silently ignores all further packets from that address. If the simulator reused the same hardcoded attacker IP across runs, the IPS would appear to stop working — when in reality it was working correctly by dropping already-blocked traffic. Randomized IPs ensure every simulation run produces fresh, unblocked attacker addresses.

How to run

simular_varios_ataques.py requires administrator privileges and Npcap installed on the machine. Run it from an elevated terminal.
python simular_varios_ataques.py
The script prompts you to choose an attack mode:
==================================================
[*] SIMULADOR DE ATAQUES PARA IDS (MACHINE LEARNING)
==================================================
Elige el ataque a simular:
1) Escaneo de Puertos (Port Scan)
2) DDoS Distribuido (Múltiples IPs origen)
3) UDP Flood (Tráfico saturado DNS/Juegos)
4) Posible Exploit (Conexiones a SMB, RDP, FTP, SSH)

Opción [1-4]:
Packets are sent in batches of 100 with a progress indicator:
Enviando paquetes a la interfaz...
  [100/999] paquetes enviados
  [200/999] paquetes enviados
  ...
[OK] Ataque simulado exitosamente.

Attack modes

The target IP for all modes is 172.10.14.181, configured at the top of the script.

1. Port scan

Sends 999 TCP SYN packets to sequential ports (1–999) from a fixed spoofed IP. This mimics a classic reconnaissance sweep.
attacker_ip = "192.168.100.5" # IP falsa
for port in range(1, 1000):
    # Enviar paquetes SYN a puertos secuenciales
    pkt = Ether(dst=mi_mac)/IP(src=attacker_ip, dst=target_ip)/TCP(dport=port, flags="S")
    paquetes.append(pkt)
The IDS flags this when it sees more than 10 unique destination ports from a single source within a detection window (PORT_SCAN_THRESHOLD = 10).

2. DDoS (distributed botnet)

Sends 1,500 TCP SYN packets to port 80, each from a different randomly generated source IP. This simulates a botnet where many machines attack simultaneously.
for _ in range(1500):
    # Múltiples IPs falsas de origen atacando al puerto 80
    attacker_ip_falsa = f"{random.randint(1,255)}.{random.randint(0,255)}.{random.randint(0,255)}.{random.randint(1,254)}"
    pkt = Ether(dst=mi_mac)/IP(src=attacker_ip_falsa, dst=target_ip)/TCP(dport=80, flags="S")
    paquetes.append(pkt)
The IDS uses THRESHOLD_DDOS = 500 — this mode sends three times that volume, producing a clear detection signal without triggering false positives from heavy legitimate traffic.

3. UDP flood

Sends 1,500 UDP packets from 203.0.113.99 (an RFC 5737 documentation address) to random high ports. This simulates the kind of traffic used to saturate DNS resolvers or game servers.
attacker_ip = "203.0.113.99"
for _ in range(1500):
    dport = random.randint(1024, 65535)
    pkt = Ether(dst=mi_mac)/IP(src=attacker_ip, dst=target_ip)/UDP(dport=dport)
    paquetes.append(pkt)
The IDS threshold is THRESHOLD_UDP_FLOOD = 500 to avoid false positives from normal streaming or DNS traffic.

4. Exploit attempt

Sends 100 TCP SYN packets targeting the five most commonly exploited service ports, from a random IP in the 192.168.100.x range.
attacker_ip = f"192.168.100.{random.randint(10, 250)}"
puertos_vuln = [21, 22, 23, 445, 3389]
for _ in range(100):
    dport = random.choice(puertos_vuln)
    # IDS detecta exploits basados en intentos de conexión (SYN) a puertos vulnerables
    pkt = Ether(dst=mi_mac)/IP(src=attacker_ip, dst=target_ip)/TCP(dport=dport, flags="S")
    paquetes.append(pkt)
PortService
21FTP
22SSH
23Telnet
445SMB
3389RDP
This mode generates a smaller packet volume than the flood modes because exploit detection is heuristic-based — repeated SYN attempts to these specific ports are already a strong attack signal.

Packet sending mechanism

All modes collect packets into a list and then flush them in batches of 100:
# Enviar lotes de 100 paquetes
for i in range(0, len(paquetes), 100):
    lote = paquetes[i:i+100]
    sendp(lote, iface=iface, verbose=False)
    enviados = min(i + 100, len(paquetes))
    print(f"  [{enviados}/{len(paquetes)}] paquetes enviados")
Batching improves throughput compared to sending one packet at a time and avoids overwhelming the local packet buffer.

What to observe after running

1

Check the events table

Open the IDS interface and look at the Tráfico en Vivo (live traffic) table. You should see new rows with the detected attack type and the ML confidence score, e.g. (ML: 98.4%).
2

Verify the IPS panel

Switch to the Respuesta Activa tab. The attacker IP should appear with status Bloqueado, severity level, and a live countdown timer showing time remaining on the block.
3

Check the ML verdict

If the ML model returns confidence ≥ 70%, the ML label is used. If confidence is below 70% but a heuristic rule triggers a critical classification (SYN Flood, Exploit, etc.), the system blocks the IP immediately using the heuristic verdict.
If an attack is not detected, confirm the IDS is running and monitoring the correct interface before re-running the simulator. The IDS must be active for the sniffer to process incoming packets.

Build docs developers (and LLMs) love