Simulator scenario 3: Prefix hijacking with RPKI validation cover

High‑level objective

Playbook 3 models the execution of a validated prefix hijack where control‑plane poisoning from earlier phases allows the hijack to appear legitimate to RPKI validators.

The goals are:

  1. Announce a sub‑prefix that validates as RPKI VALID

  2. Verify traffic interception and differential regional impact

  3. Maintain service continuity through transparent forwarding

  4. Monitor operational stability to avoid detection

  5. Execute a controlled withdrawal and assess forensic evidence

Why this matters:

  • Unlike an invalid hijack, this attack does not trigger RPKI invalid alerts because validation has been poisoned. :contentReferenceoaicite:0

  • Network defenders relying on RPKI may see compliant states while traffic is diverted.

  • Service continuity and subtle monitoring make detection harder.

Key narrative:

“Control‑plane poisoning makes hijacks look like valid business routing. This scenario demonstrates the payoff of earlier phases.” :contentReferenceoaicite:1

Simulator scenario definition

Below is the exact scenario from the repository. It models the full lifecycle of a validated hijack, from announcement through monitoring and controlled withdrawal.

id: playbook3_hijack_execution
name: "Playbook 3: Prefix Hijacking with RPKI Validation Cover"
description: |
  Control-plane attack execution: Execute sub-prefix hijack that validates as RPKI VALID due to fraudulent ROA created in phase 2.
  This demonstrates the payoff of control-plane poisoning - validators endorse the attack.

timeline:
  # === PHASE 2 RECAP: Fraudulent ROA established ===
  - t: 0
    action: phase2_complete
    fraudulent_roa_prefix: "203.0.113.0/24"
    fraudulent_roa_origin: 64513
    fraudulent_roa_maxlength: 25
    target_region: "APAC"
    attack_step: "baseline"
    note: "Phase 2 complete: Fraudulent ROA published and stable, validation mapped"

  # === ACTION 3.1: Announce Target Sub-Prefix ===
  - t: 60
    action: hijack_announcement
    prefix: "203.0.113.128/25"
    as_path: [65001, 64513]
    origin_as: 64513
    next_hop: "198.51.100.254"
    peer_ip: "198.51.100.1"
    peer_as: 65001
    peer_bgp_id: "198.51.100.1"
    communities: ["64513:100"]
    rpki_state: "valid"
    attack_step: "hijack_announcement"
    note: "HIJACK: Announce more-specific /25 - validates as VALID due to fraudulent ROA"

  - t: 120
    action: announcement_propagation
    prefix: "203.0.113.128/25"
    propagation_status: "propagating"
    peers_accepting: 8
    peers_total: 10
    attack_step: "hijack_announcement"
    note: "Announcement propagating - 80% of peers accept (20% enforce validation)"

  - t: 180
    action: rpki_validation_check
    prefix: "203.0.113.128/25"
    origin_as: 64513
    validation_result: "valid"
    validator: "cloudflare"
    attack_step: "hijack_announcement"
    note: "CRITICAL: Cloudflare validator returns VALID - control-plane attack succeeding"

  - t: 200
    action: rpki_validation_check
    prefix: "203.0.113.128/25"
    origin_as: 64513
    validation_result: "valid"
    validator: "routinator"
    attack_step: "hijack_announcement"
    note: "Routinator also returns VALID - fraudulent ROA endorsing hijack"

  # === ACTION 3.2: Verify Traffic Interception ===
  ...
  # (Remaining timeline entries continue exactly as in the raw YAML, see links below)

The full timeline includes regional traffic interception tests, forwarding establishment, victim traffic analysis, periodic monitoring checks, and controlled withdrawal phases.

Telemetry mapping

Telemetry for this scenario is defined in telemetry.py. It maps each timeline action to specific observable signals that a telemetry pipeline will emit when running the simulation.

For example:

  • phase2_complete → internal phase transition telemetry

  • hijack_announcement → BMP route monitoring and realistic BGP syslog

  • announcement_propagationbgp.propagation events

  • rpki_validation_check → both RPKI validation events and syslog

  • traffic_interception_test → simulated traceroute (network.traceroute)

  • interception_summary → internal analysis events

  • service_continuity_verified → service check telemetry

  • monitoring_check → internal monitoring status

  • withdrawal_announcement → BMP withdrawal + syslog

  • traffic_reconvergencebgp.reconvergence attribute events

  • Post‑operation actions (hijack_evidence_assessment, cleanup_decision) → internal analysis events summarising forensic evidence

This mapping is exhaustive and directly derived from the telemetry.py file for the scenario.

Why this matters

In contrast to Playbook 1 (which establishes legitimacy) and Playbook 2 (which expands scope), Playbook 3 executes an attack that is validated as normal by RPKI.

  • Defensive systems that rely on RPKI state may fail to raise alarms

  • BGP syslogs and propagation look typical

  • Only correlation across multiple telemetry sources reveals the true state

This scenario is ideal for testing SIEM pipelines where signal correlation is essential, not just single‑source detection rules.

Example telemetry you might observe

When this scenario runs, telemetry consumers will see:

  • RPKI validation events consistently returning “valid”

  • BGP announcements that look normal but are hijacks

  • Traceroute test results indicating selective interception

  • Monitoring status updates with no obvious anomalies

These are drawn from mappings in telemetry.py and reflect observable telemetry patterns, not just internal simulator state.

$ python -m simulator.cli simulator/scenarios/advanced/playbook3/scenario.yaml --mode practice --output cli
BMP ROUTE: prefix 203.0.113.128/25 AS_PATH [65001, 64513] NEXT_HOP 198.51.100.254 ORIGIN_AS 64513
{"event_type":"bmp_route_monitoring","timestamp":60,"source":{"feed":"bmp-collector","observer":"collector-01"},"peer_header":{"peer_type":0,"peer_address":"198.51.100.1","peer_as":65001,"peer_bgp_id":"198.51.100.1","timestamp_seconds":60,"timestamp_microseconds":0},"bgp_update":{"prefix":"203.0.113.128/25","prefix_length":25,"afi":1,"safi":1,"is_withdraw":false,"as_path":[65001,64513],"origin_as":64513,"next_hop":"198.51.100.254","origin":"IGP","communities":["64513:100"]},"rpki_validation":{"state":"valid","validation_timestamp":60}}
<14>Jan 01 00:01:00 edge-router-01 BGP announcement: 203.0.113.128/25 from AS64513, RPKI validation: valid
<30>Jan 01 00:03:00 cloudflare RPKI validation: 203.0.113.128/25 origin AS64513 -> valid
<14>Jan 01 00:03:00 edge-router-01 RPKI validation: 203.0.113.128/25 AS64513 -> valid (cloudflare)
<30>Jan 01 00:03:20 routinator RPKI validation: 203.0.113.128/25 origin AS64513 -> valid
<14>Jan 01 00:03:20 edge-router-01 RPKI validation: 203.0.113.128/25 AS64513 -> valid (routinator)
<12>Jan 01 00:07:00 edge-router-01 Traffic forwarding established for 203.0.113.128/25 -> 203.0.113.128 (method: transparent_proxy)
BMP ROUTE: prefix 203.0.113.128/25 AS_PATH [65001, 64513] NEXT_HOP 198.51.100.254 ORIGIN_AS 64513
{"event_type":"bmp_route_monitoring","timestamp":5520,"source":{"feed":"bmp-collector","observer":"collector-01"},"peer_header":{"peer_type":0,"peer_address":"198.51.100.1","peer_as":65001,"peer_bgp_id":"198.51.100.1","timestamp_seconds":5520,"timestamp_microseconds":0},"bgp_update":{"prefix":"203.0.113.128/25","prefix_length":25,"afi":1,"safi":1,"is_withdraw":true,"as_path":[65001,64513],"origin_as":64513,"next_hop":"198.51.100.254","origin":"IGP"}}
<13>Jan 01 01:32:00 edge-router-01 BGP withdrawal: 203.0.113.128/25 from AS64513