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:
Announce a sub‑prefix that validates as RPKI VALID
Verify traffic interception and differential regional impact
Maintain service continuity through transparent forwarding
Monitor operational stability to avoid detection
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 telemetryhijack_announcement→ BMP route monitoring and realistic BGP syslogannouncement_propagation→bgp.propagationeventsrpki_validation_check→ both RPKI validation events and syslogtraffic_interception_test→ simulated traceroute (network.traceroute)interception_summary→ internal analysis eventsservice_continuity_verified→ service check telemetrymonitoring_check→ internal monitoring statuswithdrawal_announcement→ BMP withdrawal + syslogtraffic_reconvergence→bgp.reconvergenceattribute eventsPost‑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