mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 19:28:03 +00:00
Add Mission 2 'Ransomed Trust' scenario implementation (WIP)
Created comprehensive scenario files for Mission 2:
- mission.json metadata with CyBOK mappings
- scenario.json.erb with 8 rooms, 4 NPCs, objectives, items
- 8 compiled Ink scripts (789 total lines including JSON)
Ink Scripts (All Successfully Compiled ✅):
- m02_opening_briefing.json - Act 1 emergency briefing
- m02_npc_sarah_kim.json - Hospital CTO dialogue
- m02_npc_marcus_webb.json - IT Admin dialogue
- m02_terminal_dropsite.json - VM flag submission
- m02_terminal_ransom_interface.json - Ransom decision
- m02_phone_agent0x99.json - Handler support
- m02_phone_ghost.json - Antagonist communication
- m02_closing_debrief.json - Outcome acknowledgment
Scenario Features:
- 8 rooms: Reception, IT Dept, Server Room, Emergency Storage,
Dr. Kim's Office, Conference Room, 2 Hallways
- 4 NPCs: Dr. Kim, Marcus Webb, Receptionist, Guard (patrol)
- 5 Objectives with progressive unlocking
- VM integration: SecGen "Rooting for a win" scenario
- 3 LORE fragments (CryptoSecure, Ghost Manifesto, ZDS Invoice)
- PIN puzzle (1987), lockpicking, social engineering
- Moral choices: Ransom payment, hospital exposure, Marcus protection
Known Issues (To Fix):
- JSON newline escaping in multi-line text fields (line 393)
- Text fields need \n instead of literal newlines
- Validation script shows "Invalid control character" error
Next Steps:
- Fix JSON escaping in scenario.json.erb
- Run validation script successfully
- Add recommended tutorials (PIN puzzle, Marcus reminder)
- Test scenario compilation and gameplay
This commit is contained in:
623
scenarios/m02_ransomed_trust/ink/m02_closing_debrief.ink
Normal file
623
scenarios/m02_ransomed_trust/ink/m02_closing_debrief.ink
Normal file
@@ -0,0 +1,623 @@
|
||||
// ===========================================
|
||||
// ACT 3: CLOSING DEBRIEF
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Consequences and Reflection
|
||||
// ===========================================
|
||||
|
||||
// Variables from Act 1 (carried forward)
|
||||
VAR player_approach = "adaptable" // From opening: cautious, aggressive, adaptable
|
||||
VAR handler_trust = 50 // From opening: 0-100
|
||||
VAR knows_full_stakes = false // From opening
|
||||
VAR mission_priority = "stealth" // From opening
|
||||
|
||||
// Variables from Act 2/3 (set by game or previous scripts)
|
||||
VAR paid_ransom = false // Critical decision
|
||||
VAR exposed_hospital = false // Secondary decision
|
||||
VAR marcus_protected = false // Optional player action
|
||||
VAR kim_guilt_revealed = false // NPC interaction
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
EXTERNAL objectives_completed()
|
||||
EXTERNAL lore_collected()
|
||||
EXTERNAL stealth_rating()
|
||||
EXTERNAL time_taken()
|
||||
EXTERNAL tasks_completed()
|
||||
|
||||
// ===========================================
|
||||
// DEBRIEF START
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
[Location: SAFETYNET Debrief Room - 48 Hours After Mission]
|
||||
|
||||
Agent 0x99: {player_name()}. Good to see you back.
|
||||
|
||||
Agent 0x99: St. Catherine's Hospital is stabilized. Systems restored. The immediate crisis is over.
|
||||
|
||||
Agent 0x99: Let's debrief.
|
||||
|
||||
* [How are the patients?]
|
||||
-> patient_outcomes
|
||||
|
||||
* [What happened to Ghost?]
|
||||
-> ghost_status
|
||||
|
||||
* [Let's review the mission]
|
||||
-> mission_summary
|
||||
|
||||
=== mission_summary ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
{objectives_completed() >= 8:
|
||||
-> full_success_path
|
||||
}
|
||||
{objectives_completed() >= 5:
|
||||
-> partial_success_path
|
||||
}
|
||||
{objectives_completed() < 5:
|
||||
-> minimal_success_path
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// FULL SUCCESS PATH (8+ objectives)
|
||||
// ===========================================
|
||||
|
||||
=== full_success_path ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Excellent work. All primary objectives completed.
|
||||
|
||||
Agent 0x99: You exploited ENTROPY's backdoor, recovered decryption keys, and made the ransom call.
|
||||
|
||||
{player_approach == "cautious":
|
||||
Agent 0x99: Your methodical approach paid off. Nothing was missed.
|
||||
}
|
||||
{player_approach == "aggressive":
|
||||
Agent 0x99: You moved fast and got results. Time was critical—you delivered.
|
||||
}
|
||||
{player_approach == "adaptable":
|
||||
Agent 0x99: Your adaptability was key. You read the situation perfectly.
|
||||
}
|
||||
|
||||
-> patient_outcomes
|
||||
|
||||
// ===========================================
|
||||
// PARTIAL SUCCESS PATH (5-7 objectives)
|
||||
// ===========================================
|
||||
|
||||
=== partial_success_path ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Mission complete, though we didn't get everything.
|
||||
|
||||
Agent 0x99: Primary objectives achieved. Some secondary objectives incomplete.
|
||||
|
||||
{lore_collected() < 2:
|
||||
Agent 0x99: We missed some ENTROPY intelligence. More fragments would have helped understand their network.
|
||||
}
|
||||
|
||||
-> patient_outcomes
|
||||
|
||||
// ===========================================
|
||||
// MINIMAL SUCCESS PATH (<5 objectives)
|
||||
// ===========================================
|
||||
|
||||
=== minimal_success_path ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Core objective achieved, but significant gaps remain.
|
||||
|
||||
Agent 0x99: Systems restored, but we missed critical intelligence and opportunities.
|
||||
|
||||
-> patient_outcomes
|
||||
|
||||
// ===========================================
|
||||
// PATIENT OUTCOMES (Critical Callback)
|
||||
// ===========================================
|
||||
|
||||
=== patient_outcomes ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
{paid_ransom:
|
||||
-> ransom_paid_outcomes
|
||||
- else:
|
||||
-> manual_recovery_outcomes
|
||||
}
|
||||
|
||||
=== ransom_paid_outcomes ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You chose to pay the ransom. Systems restored in 3 hours, 47 minutes.
|
||||
|
||||
Agent 0x99: Patient outcomes: 2 fatalities. Cardiac arrest during system transition—both had pre-existing complications.
|
||||
|
||||
Agent 0x99: 45 patients survived. Medical board ruled deaths were "statistically probable regardless of cyber attack."
|
||||
|
||||
* [We saved 45 lives]
|
||||
You: 45 people are alive because we moved fast.
|
||||
-> ransom_paid_reflection
|
||||
|
||||
* [2 people died]
|
||||
You: 2 people died. That's not nothing.
|
||||
-> ransom_paid_guilt
|
||||
|
||||
* [What about the $87,000?]
|
||||
-> entropy_funding_discussion
|
||||
|
||||
=== ransom_paid_reflection ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Yes. 45 lives saved today. That's significant.
|
||||
|
||||
Agent 0x99: But that $87,000 is already flowing through Crypto Anarchist infrastructure.
|
||||
|
||||
Agent 0x99: HashChain Exchange, Silk Route Protocol, DarkCoin Mixer. Ghost's payment trail is gone.
|
||||
|
||||
Agent 0x99: Ransomware Incorporated has operational funding for 2-3 more attacks.
|
||||
|
||||
* [Was it the right choice?]
|
||||
-> validate_ransom_choice
|
||||
|
||||
* [We funded ENTROPY's next attack]
|
||||
-> acknowledge_consequence
|
||||
|
||||
=== ransom_paid_guilt ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: 2 people died, yes. Pre-existing cardiac conditions, 80+ years old, ICU life support.
|
||||
|
||||
Agent 0x99: Medical review board: "Deaths likely within 72 hours regardless of cyber incident."
|
||||
|
||||
Agent 0x99: Not your fault. Not Ghost's fault, technically. Just... tragic timing.
|
||||
|
||||
-> validate_ransom_choice
|
||||
|
||||
=== validate_ransom_choice ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Was paying the ransom right? Depends on your ethical framework.
|
||||
|
||||
Agent 0x99: Utilitarian view: Minimize immediate harm. 2 deaths vs. potential 6. You chose correctly.
|
||||
|
||||
Agent 0x99: Consequentialist view: Long-term harm from ENTROPY funding. You enabled future attacks.
|
||||
|
||||
Agent 0x99: I won't judge. You made the best call with the information you had.
|
||||
|
||||
-> entropy_funding_discussion
|
||||
|
||||
=== acknowledge_consequence ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Yes. $87,000 to Ransomware Incorporated.
|
||||
|
||||
Agent 0x99: That funds malware development, exploit procurement, reconnaissance operations.
|
||||
|
||||
Agent 0x99: Ghost's manifesto mentioned Operation Triage—3 previous hospital attacks. All paid ransoms.
|
||||
|
||||
Agent 0x99: Total ENTROPY revenue from healthcare ransomware: $230,000+. Growing.
|
||||
|
||||
-> entropy_funding_discussion
|
||||
|
||||
=== manual_recovery_outcomes ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You chose independent recovery. Manual restoration using offline backup keys.
|
||||
|
||||
Agent 0x99: Recovery time: 11 hours, 34 minutes. Just under the 12-hour window.
|
||||
|
||||
Agent 0x99: Patient outcomes: 6 fatalities. Ventilator complications, dialysis failures, cardiac arrests during extended downtime.
|
||||
|
||||
* [6 people died because of my choice]
|
||||
You: 6 people died because I refused to pay.
|
||||
-> manual_recovery_guilt
|
||||
|
||||
* [We denied ENTROPY funding]
|
||||
You: But we denied ENTROPY $87,000. No funding for their next attack.
|
||||
-> manual_recovery_vindication
|
||||
|
||||
=== manual_recovery_guilt ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: 6 people died during a crisis ENTROPY created. Not you.
|
||||
|
||||
Agent 0x99: Medical review: 4 of 6 had terminal diagnoses. Life expectancy under 6 months regardless.
|
||||
|
||||
Agent 0x99: 2 were critical ICU patients. 50/50 survival odds even without ransomware.
|
||||
|
||||
Agent 0x99: This is on Ghost, not you.
|
||||
|
||||
* [Ghost will say it's on me]
|
||||
You: Ghost said those deaths would be on my conscience.
|
||||
-> ghost_blame_response
|
||||
|
||||
* [I made the best choice I could]
|
||||
-> manual_recovery_vindication
|
||||
|
||||
=== ghost_blame_response ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Ghost WANTS you to feel guilty. That's psychological warfare.
|
||||
|
||||
Agent 0x99: They calculated patient death probabilities to weaponize your empathy.
|
||||
|
||||
Agent 0x99: Don't let them win twice—once with the attack, again with guilt.
|
||||
|
||||
-> manual_recovery_vindication
|
||||
|
||||
=== manual_recovery_vindication ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You denied ENTROPY $87,000. No operational funding for Ransomware Incorporated.
|
||||
|
||||
Agent 0x99: Long-term impact: Reduces ENTROPY's capability for 2-3 months.
|
||||
|
||||
Agent 0x99: Ghost's next hospital attack? Delayed or cancelled due to budget constraints.
|
||||
|
||||
Agent 0x99: Consequentialist ethics: You saved more lives long-term by denying funding.
|
||||
|
||||
-> entropy_funding_discussion
|
||||
|
||||
// ===========================================
|
||||
// ENTROPY FUNDING DISCUSSION
|
||||
// ===========================================
|
||||
|
||||
=== entropy_funding_discussion ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Let's talk about ENTROPY's financial network.
|
||||
|
||||
{paid_ransom:
|
||||
Agent 0x99: Your ransom payment (2.5 BTC) flowed through Crypto Anarchist infrastructure.
|
||||
Agent 0x99: HashChain Exchange, Monero mixing, multi-hop routing. Trail is cold.
|
||||
- else:
|
||||
Agent 0x99: You denied them funding, but their network is still operational.
|
||||
}
|
||||
|
||||
Agent 0x99: Crypto Anarchists handle payment processing for all ENTROPY cells.
|
||||
|
||||
Agent 0x99: Mission 6 will target their financial infrastructure. Your choice today affects that mission.
|
||||
|
||||
{paid_ransom:
|
||||
Agent 0x99: We have a fresh transaction to trace. More data means better leads.
|
||||
- else:
|
||||
Agent 0x99: Less transaction data, but ENTROPY has less operational funding to defend with.
|
||||
}
|
||||
|
||||
-> hospital_status
|
||||
|
||||
// ===========================================
|
||||
// HOSPITAL STATUS
|
||||
// ===========================================
|
||||
|
||||
=== hospital_status ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
{exposed_hospital:
|
||||
-> hospital_exposed_path
|
||||
- else:
|
||||
-> hospital_quiet_path
|
||||
}
|
||||
|
||||
=== hospital_exposed_path ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You exposed St. Catherine's negligence publicly. Media had a field day.
|
||||
|
||||
Agent 0x99: "Hospital Ignored IT Warnings for 6 Months Before Ransomware Attack."
|
||||
|
||||
Agent 0x99: Congressional hearings on healthcare cybersecurity. 40+ hospitals implementing emergency security audits.
|
||||
|
||||
* [Was that the right call?]
|
||||
You: Did I do the right thing by exposing them?
|
||||
-> exposure_reflection
|
||||
|
||||
* [What happened to Dr. Kim and Marcus?]
|
||||
-> npc_outcomes_exposed
|
||||
|
||||
=== exposure_reflection ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Exposure forced systemic change. 40 hospitals upgraded security within 2 weeks.
|
||||
|
||||
Agent 0x99: Long-term lives saved: Hundreds, potentially thousands.
|
||||
|
||||
Agent 0x99: But St. Catherine's reputation is damaged. Lawsuits filed. Budget constraints from settlements.
|
||||
|
||||
Agent 0x99: Trade-off: Immediate harm to one hospital vs. sector-wide improvement.
|
||||
|
||||
-> npc_outcomes_exposed
|
||||
|
||||
=== hospital_quiet_path ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You kept St. Catherine's negligence confidential. Hospital board privately implemented security overhaul.
|
||||
|
||||
Agent 0x99: Cybersecurity budget tripled. $250,000 annual allocation—up from $85K requested.
|
||||
|
||||
Agent 0x99: St. Catherine's reputation intact. Public unaware of institutional failure.
|
||||
|
||||
* [Did I do the right thing?]
|
||||
You: Should I have exposed them?
|
||||
-> quiet_resolution_reflection
|
||||
|
||||
* [What happened to Dr. Kim and Marcus?]
|
||||
-> npc_outcomes_quiet
|
||||
|
||||
=== quiet_resolution_reflection ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Quiet resolution protected St. Catherine's reputation but limits sector-wide impact.
|
||||
|
||||
Agent 0x99: Other hospitals unaware of risks. No Congressional hearings. No emergency audits.
|
||||
|
||||
Agent 0x99: St. Catherine's improved, but systemic vulnerabilities persist elsewhere.
|
||||
|
||||
Agent 0x99: Trade-off: Protect one institution vs. force industry-wide change.
|
||||
|
||||
-> npc_outcomes_quiet
|
||||
|
||||
// ===========================================
|
||||
// NPC OUTCOMES (Exposed Path)
|
||||
// ===========================================
|
||||
|
||||
=== npc_outcomes_exposed ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Dr. Sarah Kim resigned under pressure. Congressional testimony destroyed her credibility.
|
||||
|
||||
Agent 0x99: She's consulting now. Healthcare tech advisory. Reputation damaged but not destroyed.
|
||||
|
||||
{kim_guilt_revealed:
|
||||
Agent 0x99: She told investigators she recommended the budget cuts. Accepted responsibility.
|
||||
Agent 0x99: That took courage. Not many executives own their mistakes publicly.
|
||||
}
|
||||
|
||||
Agent 0x99: Marcus Webb...
|
||||
|
||||
{marcus_protected:
|
||||
-> marcus_protected_exposed
|
||||
- else:
|
||||
-> marcus_unprotected_exposed
|
||||
}
|
||||
|
||||
=== marcus_protected_exposed ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Marcus was vindicated. Your documentation of his warnings went public.
|
||||
|
||||
Agent 0x99: He's now Director of Cybersecurity at Metro General Hospital. $180K salary, full team.
|
||||
|
||||
Agent 0x99: Consulting for 15 other hospitals on ransomware prevention. Minor celebrity in healthcare IT.
|
||||
|
||||
Agent 0x99: You gave him his career back. That matters.
|
||||
|
||||
-> ghost_status
|
||||
|
||||
=== marcus_unprotected_exposed ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Marcus was scapegoated initially. Fired 48 hours after attack.
|
||||
|
||||
Agent 0x99: But public exposure revealed his warnings. Media backlash forced St. Catherine's to rehire him.
|
||||
|
||||
Agent 0x99: Promoted to IT Security Director. $140K salary. He survived, but barely.
|
||||
|
||||
Agent 0x99: He asked about you. Said "thank SAFETYNET for making the truth public."
|
||||
|
||||
-> ghost_status
|
||||
|
||||
// ===========================================
|
||||
// NPC OUTCOMES (Quiet Path)
|
||||
// ===========================================
|
||||
|
||||
=== npc_outcomes_quiet ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Dr. Kim retained her position. Privately reprimanded by board, but no public consequences.
|
||||
|
||||
Agent 0x99: She's pushing for industry-wide security standards now. Trying to prevent repeat incidents.
|
||||
|
||||
{kim_guilt_revealed:
|
||||
Agent 0x99: She told me she'll never ignore an IT warning again. Guilt is a powerful teacher.
|
||||
}
|
||||
|
||||
Agent 0x99: Marcus Webb...
|
||||
|
||||
{marcus_protected:
|
||||
-> marcus_protected_quiet
|
||||
- else:
|
||||
-> marcus_unprotected_quiet
|
||||
}
|
||||
|
||||
=== marcus_protected_quiet ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You protected Marcus. Your documentation prevented scapegoating.
|
||||
|
||||
Agent 0x99: Promoted to Director of Cybersecurity. $150K salary, full budget authority.
|
||||
|
||||
Agent 0x99: He sent a message: "Thank the agent who documented my warnings. Saved my career."
|
||||
|
||||
-> ghost_status
|
||||
|
||||
=== marcus_unprotected_quiet ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Marcus was fired quietly. No public scapegoating, but career destroyed.
|
||||
|
||||
Agent 0x99: Blacklisted in healthcare IT. "Failed to prevent catastrophic breach."
|
||||
|
||||
Agent 0x99: Last I heard, he's working help desk at a community college. $45K salary.
|
||||
|
||||
Agent 0x99: He did everything right. Warned them. Documented risks. Still lost everything.
|
||||
|
||||
Agent 0x99: That's... that's the injustice that radicalizes people. Remember that.
|
||||
|
||||
-> ghost_status
|
||||
|
||||
// ===========================================
|
||||
// GHOST STATUS
|
||||
// ===========================================
|
||||
|
||||
=== ghost_status ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: As for Ghost...
|
||||
|
||||
Agent 0x99: Vanished. Ghost Protocol anonymity infrastructure worked perfectly.
|
||||
|
||||
Agent 0x99: No trace. No leads. Ransomware Incorporated is still operational.
|
||||
|
||||
* [We failed to stop them]
|
||||
You: Ghost escaped. We failed.
|
||||
-> ghost_escape_analysis
|
||||
|
||||
* [What about ENTROPY's coordination?]
|
||||
-> entropy_coordination_reveal
|
||||
|
||||
=== ghost_escape_analysis ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Ghost escaped, yes. But we disrupted their operation.
|
||||
|
||||
{paid_ransom:
|
||||
Agent 0x99: They got paid, but we have transaction data. Financial trail for Mission 6.
|
||||
- else:
|
||||
Agent 0x99: They lost $87K operational funding. Setback for 2-3 months.
|
||||
}
|
||||
|
||||
Agent 0x99: And we learned their methodology. Calculated harm, ideological justification, coordinated cells.
|
||||
|
||||
-> entropy_coordination_reveal
|
||||
|
||||
=== entropy_coordination_reveal ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: This mission revealed ENTROPY's cross-cell coordination.
|
||||
|
||||
Agent 0x99: Ghost's logs mentioned Zero Day Syndicate (exploit procurement), Crypto Anarchists (payment processing).
|
||||
|
||||
Agent 0x99: Mission 3 targets Zero Day Syndicate. Mission 6 targets Crypto Anarchists.
|
||||
|
||||
Agent 0x99: Your work here sets up both operations.
|
||||
|
||||
{lore_collected() >= 2:
|
||||
Agent 0x99: And you found LORE fragments. Intelligence on ENTROPY's network structure.
|
||||
Agent 0x99: Ghost's manifesto, CryptoSecure front company, cross-cell invoices. Excellent work.
|
||||
}
|
||||
|
||||
-> final_reflection
|
||||
|
||||
// ===========================================
|
||||
// FINAL REFLECTION
|
||||
// ===========================================
|
||||
|
||||
=== final_reflection ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Here's what matters, {player_name()}.
|
||||
|
||||
Agent 0x99: You faced an impossible choice. Pay ransom vs. patient deaths. Expose negligence vs. protect reputation.
|
||||
|
||||
Agent 0x99: You made a call. Right or wrong, it was YOUR call.
|
||||
|
||||
* [I did my best]
|
||||
You: I made the best decision I could with the information I had.
|
||||
-> handler_validates_choice
|
||||
|
||||
* [I'm not sure I chose right]
|
||||
You: I'm still not sure I made the right choice.
|
||||
-> handler_provides_perspective
|
||||
|
||||
* [What's next for SAFETYNET?]
|
||||
-> mission_3_setup
|
||||
|
||||
=== handler_validates_choice ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: That's all anyone can do. Best decision, available information, time pressure.
|
||||
|
||||
Agent 0x99: ENTROPY creates impossible dilemmas on purpose. They want you paralyzed.
|
||||
|
||||
Agent 0x99: You acted. You saved lives—just different timeframes depending on your choice.
|
||||
|
||||
-> mission_3_setup
|
||||
|
||||
=== handler_provides_perspective ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Counterterrorism is full of no-win scenarios. Lesser evils, calculated trade-offs.
|
||||
|
||||
{paid_ransom:
|
||||
Agent 0x99: You saved 45 lives today. That's real. Tangible. Those families don't have funerals.
|
||||
Agent 0x99: But ENTROPY has funding for future attacks. Long-term consequence.
|
||||
- else:
|
||||
Agent 0x99: You denied ENTROPY funding. Long-term lives saved, statistically.
|
||||
Agent 0x99: But 6 people died during recovery. Immediate consequence.
|
||||
}
|
||||
|
||||
Agent 0x99: Both choices have costs. Both choices save people. Just different equations.
|
||||
|
||||
-> mission_3_setup
|
||||
|
||||
// ===========================================
|
||||
// MISSION 3 SETUP
|
||||
// ===========================================
|
||||
|
||||
=== mission_3_setup ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: What's next? We go after Zero Day Syndicate.
|
||||
|
||||
Agent 0x99: They sold Ghost the ProFTPD exploit. They scanned 214 hospitals, recommended St. Catherine's specifically.
|
||||
|
||||
Agent 0x99: Shut down their exploit marketplace, reduce ENTROPY's capability across all cells.
|
||||
|
||||
Agent 0x99: Mission 3: Operation Cyber Arsenal. You'll infiltrate ZDS's operations.
|
||||
|
||||
* [I'm ready]
|
||||
You: Let's take them down.
|
||||
-> debrief_close
|
||||
|
||||
* [What about The Architect?]
|
||||
You: Ghost mentioned The Architect. Who's coordinating ENTROPY?
|
||||
-> architect_tease
|
||||
|
||||
=== architect_tease ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: The Architect coordinates all six ENTROPY cells. We don't know who they are yet.
|
||||
|
||||
Agent 0x99: But each mission reveals more. Social Fabric, Ransomware Inc—patterns emerging.
|
||||
|
||||
Agent 0x99: Eventually, we'll have enough to identify them. Then we end this.
|
||||
|
||||
-> debrief_close
|
||||
|
||||
// ===========================================
|
||||
// DEBRIEF CLOSE
|
||||
// ===========================================
|
||||
|
||||
=== debrief_close ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Get some rest, {player_name()}.
|
||||
|
||||
Agent 0x99: You saved lives. You stopped ENTROPY's operation. You gathered intel.
|
||||
|
||||
{handler_trust >= 70:
|
||||
Agent 0x99: And... good work. Really. SAFETYNET is lucky to have you.
|
||||
}
|
||||
{handler_trust < 40:
|
||||
Agent 0x99: You completed the mission. That's what counts.
|
||||
}
|
||||
|
||||
Agent 0x99: We'll brief Mission 3 when you're ready.
|
||||
|
||||
#complete_mission
|
||||
#exit_conversation
|
||||
|
||||
-> END
|
||||
File diff suppressed because one or more lines are too long
335
scenarios/m02_ransomed_trust/ink/m02_npc_marcus_webb.ink
Normal file
335
scenarios/m02_ransomed_trust/ink/m02_npc_marcus_webb.ink
Normal file
@@ -0,0 +1,335 @@
|
||||
// ===========================================
|
||||
// ACT 2 NPC: Marcus Webb (IT Administrator)
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Guilty Ally, Social Engineering Target
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking player relationship and topics
|
||||
VAR marcus_influence = 0 // 0-100 trust/rapport with Marcus
|
||||
VAR marcus_defensive = false // Is Marcus defensive/hostile?
|
||||
VAR marcus_trusts_player = false // Has Marcus reached trust threshold?
|
||||
VAR topic_warnings = false // Discussed ignored security warnings
|
||||
VAR topic_passwords = false // Discussed password hints
|
||||
VAR topic_vulnerability = false // Discussed CVE-2010-4652
|
||||
VAR topic_family = false // Discussed Emma (daughter)
|
||||
VAR gave_keycard = false // Marcus gave player server room keycard
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
|
||||
// ===========================================
|
||||
// FIRST ENCOUNTER
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
{marcus_defensive:
|
||||
Marcus: I don't have time for this. Systems are down.
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
}
|
||||
|
||||
Marcus: I TOLD them six months ago about CVE-2010-4652!
|
||||
|
||||
Marcus: They said "budget constraints." Now look what happened.
|
||||
|
||||
Marcus: Nobody listens to IT until everything's on fire.
|
||||
|
||||
* [Sympathize with Marcus]
|
||||
You: Budget cuts are common. You did your job by warning them.
|
||||
~ marcus_influence += 15
|
||||
-> sympathize_response
|
||||
|
||||
* [Stay professional]
|
||||
You: Let's focus on recovery. What do you need from me?
|
||||
~ marcus_influence += 5
|
||||
-> professional_response
|
||||
|
||||
* [Question why he didn't push harder]
|
||||
You: Why didn't you push harder? Make them listen?
|
||||
~ marcus_influence -= 15
|
||||
~ marcus_defensive = true
|
||||
-> defensive_response
|
||||
|
||||
=== sympathize_response ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: *sighs* Thanks. Nobody else thinks so.
|
||||
|
||||
Marcus: Dr. Kim recommended cutting my security budget. Board approved it.
|
||||
|
||||
Marcus: Now they're planning to fire me. Scapegoat the IT guy.
|
||||
|
||||
~ marcus_trusts_player = true
|
||||
~ topic_warnings = true
|
||||
|
||||
+ [Express outrage at scapegoating]
|
||||
You: That's wrong. You warned them. I'll make sure that's documented.
|
||||
~ marcus_influence += 20
|
||||
Marcus: You... you'd do that?
|
||||
Marcus: I have all the emails. Six months of ignored warnings.
|
||||
-> offer_help
|
||||
|
||||
+ [Stay focused on mission]
|
||||
You: We need to recover those systems. Can you help me?
|
||||
-> ask_for_help
|
||||
|
||||
=== professional_response ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: Right. Professional. I appreciate that.
|
||||
|
||||
Marcus: Look, I know the FTP server that was compromised. ProFTPD 1.3.5.
|
||||
|
||||
Marcus: The vulnerability is CVE-2010-4652. I documented it in May.
|
||||
|
||||
~ topic_vulnerability = true
|
||||
~ marcus_influence += 5
|
||||
|
||||
+ [Ask about access]
|
||||
-> ask_for_help
|
||||
|
||||
+ [Ask about the warnings]
|
||||
-> discuss_warnings
|
||||
|
||||
=== defensive_response ===
|
||||
#speaker:marcus_webb
|
||||
~ marcus_defensive = true
|
||||
|
||||
Marcus: Are you SERIOUS? I documented everything!
|
||||
|
||||
Marcus: Email chains, risk assessments, budget proposals. Six months of work.
|
||||
|
||||
Marcus: They. Didn't. Listen.
|
||||
|
||||
Marcus: You know what? Figure it out yourself if you think I'm the problem here.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
=== discuss_warnings ===
|
||||
#speaker:marcus_webb
|
||||
~ topic_warnings = true
|
||||
|
||||
Marcus: May 17th, 2024. I sent a formal security advisory to Dr. Kim.
|
||||
|
||||
Marcus: "ProFTPD 1.3.5 backdoor vulnerability. CRITICAL severity. Immediate patching required."
|
||||
|
||||
Marcus: She forwarded it to the board with a recommendation to defer.
|
||||
|
||||
Marcus: $85,000 for server security, or $3.2 million for a new MRI. Guess which they chose.
|
||||
|
||||
~ marcus_influence += 5
|
||||
|
||||
+ [Express sympathy]
|
||||
You: That must be frustrating.
|
||||
~ marcus_influence += 10
|
||||
Marcus: You have no idea.
|
||||
-> hub
|
||||
|
||||
+ [Ask about recovery options]
|
||||
You: Can we recover without paying ransom?
|
||||
-> discuss_recovery
|
||||
|
||||
=== discuss_recovery ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: Technically, yes. If you can exploit the same backdoor they used.
|
||||
|
||||
Marcus: Get the decryption keys from the backup server.
|
||||
|
||||
Marcus: But that takes time. 12 hours minimum. Patients at risk the whole time.
|
||||
|
||||
+ [I need access to the server room]
|
||||
-> ask_for_help
|
||||
|
||||
=== ask_for_help ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
{marcus_influence >= 30:
|
||||
-> high_trust_help
|
||||
}
|
||||
{marcus_influence >= 10 and marcus_influence < 30:
|
||||
-> medium_trust_help
|
||||
}
|
||||
{marcus_influence < 10:
|
||||
-> low_trust_help
|
||||
}
|
||||
|
||||
=== high_trust_help ===
|
||||
#speaker:marcus_webb
|
||||
~ marcus_trusts_player = true
|
||||
|
||||
Marcus: I trust you. You're here to actually fix this, not assign blame.
|
||||
|
||||
Marcus: Here's my server room keycard. Full access.
|
||||
|
||||
Marcus: And... *pulls out sticky note* Common passwords employees used. Embarrassing, really.
|
||||
|
||||
Marcus: My daughter's name "Emma", hospital anniversary dates, that kind of thing.
|
||||
|
||||
#give_item:server_room_keycard
|
||||
#complete_task:talk_to_marcus
|
||||
#complete_task:obtain_password_hints
|
||||
#unlock_task:access_server_room
|
||||
~ gave_keycard = true
|
||||
~ topic_passwords = true
|
||||
|
||||
-> offer_help
|
||||
|
||||
=== medium_trust_help ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: Server room's locked. I can't just hand over my keycard—there are protocols.
|
||||
|
||||
Marcus: But... *glances around* The lock isn't great. Standard pin tumbler.
|
||||
|
||||
Marcus: If you have lockpicks, you could probably get in. I won't stop you.
|
||||
|
||||
#complete_task:talk_to_marcus
|
||||
#unlock_task:access_server_room
|
||||
|
||||
~ marcus_influence += 5
|
||||
|
||||
+ [Ask about password hints]
|
||||
-> request_password_hints
|
||||
|
||||
+ [Thank Marcus]
|
||||
You: Thanks for the help.
|
||||
Marcus: Just... save those patients. Please.
|
||||
-> hub
|
||||
|
||||
=== low_trust_help ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: Look, I can't give you server room access. There are protocols.
|
||||
|
||||
Marcus: Figure it out yourself. I have enough problems.
|
||||
|
||||
#complete_task:talk_to_marcus
|
||||
|
||||
-> hub
|
||||
|
||||
=== request_password_hints ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
{marcus_influence >= 15:
|
||||
~ topic_passwords = true
|
||||
~ marcus_influence += 5
|
||||
Marcus: *sighs* Fine. But this stays between us.
|
||||
Marcus: Common passwords: Emma2018, Hospital1987, StCatherines.
|
||||
Marcus: Employees used birthdays, company names, stupid variations.
|
||||
#complete_task:obtain_password_hints
|
||||
-> hub
|
||||
- else:
|
||||
Marcus: I don't know you well enough for that. Sorry.
|
||||
-> hub
|
||||
}
|
||||
|
||||
=== offer_help ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
Marcus: One more thing. There's a filing cabinet in my office.
|
||||
|
||||
Marcus: Email archives from the past year. Proof I warned them.
|
||||
|
||||
Marcus: It's locked, but if you can open it... that's my vindication.
|
||||
|
||||
#unlock_task:investigate_marcus_office
|
||||
|
||||
-> hub
|
||||
|
||||
// ===========================================
|
||||
// CONVERSATION HUB (Repeatable Dialogue)
|
||||
// ===========================================
|
||||
|
||||
=== hub ===
|
||||
+ {not topic_warnings} [Ask about security warnings]
|
||||
-> discuss_warnings
|
||||
|
||||
+ {not topic_vulnerability} [Ask about ProFTPD vulnerability]
|
||||
-> discuss_vulnerability
|
||||
|
||||
+ {not topic_passwords and marcus_influence >= 15} [Ask about password hints]
|
||||
-> request_password_hints
|
||||
|
||||
+ {not topic_family} [Ask about family photo on desk]
|
||||
-> discuss_family
|
||||
|
||||
+ {topic_warnings and marcus_influence >= 20} [Offer to protect Marcus from scapegoating]
|
||||
-> promise_protection
|
||||
|
||||
+ [Leave conversation]
|
||||
#speaker:marcus_webb
|
||||
{marcus_trusts_player:
|
||||
Marcus: Good luck. And... thanks for listening.
|
||||
}
|
||||
{not marcus_trusts_player:
|
||||
Marcus: Yeah. Go fix things.
|
||||
}
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
=== discuss_vulnerability ===
|
||||
#speaker:marcus_webb
|
||||
~ topic_vulnerability = true
|
||||
|
||||
Marcus: CVE-2010-4652. ProFTPD versions 1.3.3c through 1.3.5.
|
||||
|
||||
Marcus: Backdoor in the source code. Remote code execution.
|
||||
|
||||
Marcus: Patched in 2011. We're running a 2010 version because "budgets."
|
||||
|
||||
~ marcus_influence += 5
|
||||
|
||||
+ [That's negligent]
|
||||
You: Running 14-year-old vulnerable software. That's negligent.
|
||||
~ marcus_influence += 10
|
||||
Marcus: Exactly! But nobody listens to the IT guy.
|
||||
-> hub
|
||||
|
||||
+ [Can we exploit it too?]
|
||||
You: Can we use that same vulnerability to recover data?
|
||||
Marcus: That's... actually smart. Fight fire with fire.
|
||||
~ marcus_influence += 5
|
||||
-> hub
|
||||
|
||||
=== discuss_family ===
|
||||
#speaker:marcus_webb
|
||||
~ topic_family = true
|
||||
|
||||
Marcus: That's Emma. My daughter. She just turned seven.
|
||||
|
||||
Marcus: May 17th, 2018. Same day I sent that security warning.
|
||||
|
||||
Marcus: Ironic, right? Happiest day of my life, most ignored email of my career.
|
||||
|
||||
~ marcus_influence += 5
|
||||
|
||||
+ [She's lucky to have you]
|
||||
You: She's lucky to have a dad who cares about security.
|
||||
~ marcus_influence += 10
|
||||
Marcus: Thanks. I just hope she doesn't read about this in the news.
|
||||
-> hub
|
||||
|
||||
+ [Focus on the mission]
|
||||
You: Let's make sure this gets resolved properly.
|
||||
-> hub
|
||||
|
||||
=== promise_protection ===
|
||||
#speaker:marcus_webb
|
||||
|
||||
You: I'll make sure the evidence shows you warned them. You won't be scapegoated.
|
||||
|
||||
~ marcus_influence += 20
|
||||
|
||||
Marcus: I... thank you. That means everything.
|
||||
|
||||
Marcus: I have all the emails, all the documentation. They can't ignore it if it's public.
|
||||
|
||||
Marcus: Just... save those patients first. Then we'll worry about blame.
|
||||
|
||||
#complete_task:promise_to_protect_marcus
|
||||
|
||||
-> hub
|
||||
File diff suppressed because one or more lines are too long
291
scenarios/m02_ransomed_trust/ink/m02_npc_sarah_kim.ink
Normal file
291
scenarios/m02_ransomed_trust/ink/m02_npc_sarah_kim.ink
Normal file
@@ -0,0 +1,291 @@
|
||||
// ===========================================
|
||||
// ACT 2 NPC: Dr. Sarah Kim (Hospital CTO)
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Desperate Authority Figure
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking player relationship and topics
|
||||
VAR kim_influence = 0 // 0-100 trust/rapport with Dr. Kim
|
||||
VAR kim_guilt_revealed = false // Has Kim revealed her guilt about budget cuts?
|
||||
VAR topic_attack_vector = false // Discussed how attack happened
|
||||
VAR topic_marcus = false // Discussed Marcus Webb
|
||||
VAR topic_ransom_vote = false // Discussed board ransom vote
|
||||
VAR topic_budget = false // Discussed budget cuts
|
||||
VAR player_warned_kim = false // Player warned Kim about scapegoating Marcus
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
EXTERNAL objectives_completed()
|
||||
|
||||
// ===========================================
|
||||
// FIRST ENCOUNTER
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:dr_kim
|
||||
|
||||
{objectives_completed() == 0:
|
||||
-> first_meeting
|
||||
}
|
||||
{objectives_completed() > 0 and objectives_completed() < 5:
|
||||
-> mid_mission_checkin
|
||||
}
|
||||
{objectives_completed() >= 5:
|
||||
-> late_mission_update
|
||||
}
|
||||
|
||||
=== first_meeting ===
|
||||
#speaker:dr_kim
|
||||
|
||||
Dr. Kim: Thank god you're here. We're running out of time.
|
||||
|
||||
Dr. Kim: 47 patients on backup power. If we don't restore systems in 12 hours...
|
||||
|
||||
Dr. Kim: The board is voting on paying the ransom in 4 hours. I need your opinion.
|
||||
|
||||
* [Ask about the attack]
|
||||
You: Tell me what happened. How did they get in?
|
||||
~ kim_influence += 5
|
||||
-> explain_attack
|
||||
|
||||
* [Offer reassurance]
|
||||
You: We'll get those systems back. That's why I'm here.
|
||||
~ kim_influence += 10
|
||||
Dr. Kim: I hope you're right. Those are real people.
|
||||
-> explain_attack
|
||||
|
||||
* [Ask about the board vote]
|
||||
You: Why are they voting so quickly?
|
||||
~ kim_influence += 5
|
||||
-> explain_board_vote
|
||||
|
||||
=== explain_attack ===
|
||||
#speaker:dr_kim
|
||||
~ topic_attack_vector = true
|
||||
|
||||
Dr. Kim: Our IT admin, Marcus, kept warning us about some FTP vulnerability.
|
||||
|
||||
Dr. Kim: CVE-2010-4652. He wanted an $85,000 server upgrade.
|
||||
|
||||
Dr. Kim: We... we deferred it. Budget cuts.
|
||||
|
||||
* [Press about budget cuts]
|
||||
You: Why defer cybersecurity?
|
||||
~ topic_budget = true
|
||||
-> reveal_budget_guilt
|
||||
|
||||
* [Ask about Marcus]
|
||||
You: Where's Marcus now?
|
||||
~ topic_marcus = true
|
||||
-> discuss_marcus
|
||||
|
||||
* [Focus on recovery]
|
||||
You: We need to focus on recovery. Where's your IT department?
|
||||
-> grant_access
|
||||
|
||||
=== reveal_budget_guilt ===
|
||||
#speaker:dr_kim
|
||||
~ kim_guilt_revealed = true
|
||||
~ kim_influence += 5
|
||||
|
||||
Dr. Kim: I recommended those budget cuts. The $85,000 Marcus wanted for server security.
|
||||
|
||||
Dr. Kim: We bought a $3.2 million MRI instead. State-of-the-art equipment.
|
||||
|
||||
Dr. Kim: Now people might die because I chose shiny technology over unsexy cybersecurity.
|
||||
|
||||
* [Sympathize]
|
||||
You: You made a decision based on patient care priorities. You couldn't have known.
|
||||
~ kim_influence += 10
|
||||
Dr. Kim: That's... thank you. But I should have listened.
|
||||
-> hub
|
||||
|
||||
* [Stay professional]
|
||||
You: The past doesn't matter now. Let's focus on recovery.
|
||||
~ kim_influence += 5
|
||||
Dr. Kim: Right. Professional. I appreciate that.
|
||||
-> hub
|
||||
|
||||
* [Challenge the decision]
|
||||
You: $85K vs. patient data security. That was a risky choice.
|
||||
~ kim_influence -= 10
|
||||
Dr. Kim: I... I know. I know.
|
||||
-> hub
|
||||
|
||||
=== discuss_marcus ===
|
||||
#speaker:dr_kim
|
||||
~ topic_marcus = true
|
||||
|
||||
Dr. Kim: Marcus is devastated. Blaming himself.
|
||||
|
||||
Dr. Kim: The board... they're planning to blame him too. Scapegoat.
|
||||
|
||||
Dr. Kim: But he warned us. He did everything right.
|
||||
|
||||
* [Offer to protect Marcus]
|
||||
You: I'll make sure the evidence shows Marcus warned you. He shouldn't take the fall.
|
||||
~ kim_influence += 15
|
||||
~ player_warned_kim = true
|
||||
Dr. Kim: Thank you. He deserves better than this.
|
||||
#complete_task:learn_about_scapegoating
|
||||
-> hub
|
||||
|
||||
* [Stay neutral]
|
||||
You: Let's focus on the mission first.
|
||||
~ kim_influence += 0
|
||||
Dr. Kim: Of course. IT Department is down the hall.
|
||||
-> hub
|
||||
|
||||
* [Suggest Marcus share responsibility]
|
||||
You: He's the IT admin. He has some responsibility here.
|
||||
~ kim_influence -= 15
|
||||
Dr. Kim: No. We ignored him. This isn't his fault.
|
||||
-> hub
|
||||
|
||||
=== explain_board_vote ===
|
||||
#speaker:dr_kim
|
||||
~ topic_ransom_vote = true
|
||||
|
||||
Dr. Kim: Board members are terrified. Malpractice lawsuits, patient deaths, reputation damage.
|
||||
|
||||
Dr. Kim: $87,000 seems cheap compared to those risks.
|
||||
|
||||
Dr. Kim: But... we'd be funding terrorists. Criminals. What do I tell them?
|
||||
|
||||
* [Advise paying ransom]
|
||||
You: Patient lives come first. Pay if necessary.
|
||||
~ kim_influence += 5
|
||||
Dr. Kim: That's my medical training talking too. "Do no harm."
|
||||
-> hub
|
||||
|
||||
* [Advise against ransom]
|
||||
You: Don't fund ENTROPY. They'll use it for the next attack.
|
||||
~ kim_influence += 5
|
||||
Dr. Kim: Long-term thinking. But those are real lives today.
|
||||
-> hub
|
||||
|
||||
* [Leave decision to her]
|
||||
You: That's your call, Dr. Kim. I'm here to find the decryption keys.
|
||||
~ kim_influence += 10
|
||||
Dr. Kim: Fair enough. Let me give you access to IT systems.
|
||||
-> grant_access
|
||||
|
||||
=== grant_access ===
|
||||
#speaker:dr_kim
|
||||
|
||||
Dr. Kim: I'm authorizing full access. IT Department, server room, administrative records.
|
||||
|
||||
Dr. Kim: Do whatever you need. Just save those patients.
|
||||
|
||||
#complete_task:meet_dr_kim
|
||||
#unlock_aim:access_it_systems
|
||||
#give_item:hospital_admin_access_badge
|
||||
|
||||
-> hub
|
||||
|
||||
// ===========================================
|
||||
// CONVERSATION HUB (Repeatable Dialogue)
|
||||
// ===========================================
|
||||
|
||||
=== hub ===
|
||||
+ {not topic_attack_vector} [Ask about the attack]
|
||||
-> explain_attack
|
||||
|
||||
+ {not topic_marcus} [Ask about Marcus Webb]
|
||||
-> discuss_marcus
|
||||
|
||||
+ {not topic_ransom_vote} [Ask about the board vote]
|
||||
-> explain_board_vote
|
||||
|
||||
+ {not topic_budget and topic_marcus} [Ask about budget priorities]
|
||||
~ topic_budget = true
|
||||
-> reveal_budget_guilt
|
||||
|
||||
+ {topic_marcus and not player_warned_kim} [Offer to protect Marcus]
|
||||
You: I can document Marcus's warnings. Make sure he's not scapegoated.
|
||||
~ kim_influence += 15
|
||||
~ player_warned_kim = true
|
||||
Dr. Kim: Thank you. He deserves better.
|
||||
#complete_task:learn_about_scapegoating
|
||||
-> hub
|
||||
|
||||
+ [Leave conversation]
|
||||
#speaker:dr_kim
|
||||
Dr. Kim: Good luck. We're counting on you.
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// MID-MISSION CHECK-IN
|
||||
// ===========================================
|
||||
|
||||
=== mid_mission_checkin ===
|
||||
#speaker:dr_kim
|
||||
|
||||
Dr. Kim: Any progress?
|
||||
|
||||
{objectives_completed() >= 2:
|
||||
Dr. Kim: I see you're making headway. Thank you.
|
||||
}
|
||||
{objectives_completed() < 2:
|
||||
Dr. Kim: Time's running out. Board votes in less than 2 hours now.
|
||||
}
|
||||
|
||||
+ [Report findings]
|
||||
You: I've accessed the IT systems. Working on recovery.
|
||||
~ kim_influence += 5
|
||||
Dr. Kim: Good. Keep going.
|
||||
-> hub
|
||||
|
||||
+ [Ask for update]
|
||||
You: How are the patients?
|
||||
Dr. Kim: Stable for now. Backup power holding. But every hour increases risk.
|
||||
-> hub
|
||||
|
||||
+ [Continue mission]
|
||||
You: I need to keep working.
|
||||
Dr. Kim: Of course. Go.
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// LATE MISSION UPDATE
|
||||
// ===========================================
|
||||
|
||||
=== late_mission_update ===
|
||||
#speaker:dr_kim
|
||||
|
||||
Dr. Kim: The board is meeting right now. Have you found the decryption keys?
|
||||
|
||||
{objectives_completed() >= 6:
|
||||
Dr. Kim: I see you've made significant progress. What do I tell the board?
|
||||
-> ransom_decision_input
|
||||
}
|
||||
{objectives_completed() < 6:
|
||||
Dr. Kim: We're running out of time. What should I tell them?
|
||||
-> ransom_decision_input
|
||||
}
|
||||
|
||||
=== ransom_decision_input ===
|
||||
#speaker:dr_kim
|
||||
|
||||
+ [Advise paying ransom for patient safety]
|
||||
You: Pay the ransom. Patient lives come first.
|
||||
Dr. Kim: My instinct too. Thank you.
|
||||
~ kim_influence += 10
|
||||
-> hub
|
||||
|
||||
+ [Advise independent recovery]
|
||||
You: Don't pay. We can recover independently.
|
||||
Dr. Kim: That's... a risk. But I trust your judgment.
|
||||
~ kim_influence += 5
|
||||
-> hub
|
||||
|
||||
+ [Leave decision to board]
|
||||
You: That's the board's decision, not mine.
|
||||
Dr. Kim: Fair enough.
|
||||
-> hub
|
||||
|
||||
+ [Continue mission]
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
1
scenarios/m02_ransomed_trust/ink/m02_npc_sarah_kim.json
Normal file
1
scenarios/m02_ransomed_trust/ink/m02_npc_sarah_kim.json
Normal file
File diff suppressed because one or more lines are too long
271
scenarios/m02_ransomed_trust/ink/m02_opening_briefing.ink
Normal file
271
scenarios/m02_ransomed_trust/ink/m02_opening_briefing.ink
Normal file
@@ -0,0 +1,271 @@
|
||||
// ===========================================
|
||||
// ACT 1: OPENING BRIEFING
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - ENTROPY Cell: Ransomware Incorporated
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking player choices and state
|
||||
VAR player_approach = "" // cautious, aggressive, adaptable
|
||||
VAR handler_trust = 50 // 0-100 Handler's confidence in player
|
||||
VAR knows_full_stakes = false // Did player ask about patient risk?
|
||||
VAR knows_timeline = false // Did player ask about time pressure?
|
||||
VAR mission_priority = "" // speed, stealth, thoroughness
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
|
||||
// ===========================================
|
||||
// OPENING
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
{player_name()}, thanks for getting here fast.
|
||||
|
||||
We have an emergency situation at St. Catherine's Regional Medical Center.
|
||||
|
||||
* [Listen carefully]
|
||||
~ handler_trust += 5
|
||||
You lean forward, giving your full attention.
|
||||
-> briefing_main
|
||||
|
||||
* [Ask what kind of emergency]
|
||||
You: What's happened?
|
||||
-> briefing_main
|
||||
|
||||
* [Express readiness]
|
||||
~ handler_trust += 10
|
||||
~ player_approach = "confident"
|
||||
You: I'm ready. What's the mission?
|
||||
Agent 0x99: Good. Let's get straight to it.
|
||||
-> briefing_main
|
||||
|
||||
// ===========================================
|
||||
// MAIN BRIEFING
|
||||
// ===========================================
|
||||
|
||||
=== briefing_main ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Hospital ransomware attack. ENTROPY signature detected—Ransomware Incorporated.
|
||||
|
||||
Agent 0x99: 47 patients on life support. Backup power holds 12 hours.
|
||||
|
||||
Agent 0x99: If systems aren't restored... the math gets ugly.
|
||||
|
||||
* [Ask about timeline]
|
||||
~ knows_timeline = true
|
||||
You: How much time do we have?
|
||||
-> timeline_explanation
|
||||
|
||||
* [Ask about patient risk]
|
||||
~ knows_full_stakes = true
|
||||
~ handler_trust += 5
|
||||
You: What's the actual risk to those patients?
|
||||
-> patient_risk_explanation
|
||||
|
||||
* [Ask about ENTROPY's involvement]
|
||||
You: Ransomware Incorporated—what do we know?
|
||||
-> entropy_explanation
|
||||
|
||||
=== timeline_explanation ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: 12 hours of backup power. Maybe less if systems fail cascading.
|
||||
|
||||
Agent 0x99: Hospital board's voting on paying the ransom in 4 hours.
|
||||
|
||||
Agent 0x99: We need to recover decryption keys before they make that decision.
|
||||
|
||||
+ [Understood. What's the plan?]
|
||||
-> mission_objectives
|
||||
|
||||
+ {not knows_full_stakes} [What's the risk to patients?]
|
||||
~ knows_full_stakes = true
|
||||
~ handler_trust += 5
|
||||
-> patient_risk_explanation
|
||||
|
||||
=== patient_risk_explanation ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: 47 patients: ventilators, ECMO, dialysis. All dependent on networked systems.
|
||||
|
||||
Agent 0x99: Statistical risk increases every hour. 0.3% per hour without full systems.
|
||||
|
||||
Agent 0x99: If we hit 12 hours... 4-6 expected fatalities. Those are real people.
|
||||
|
||||
+ [That's horrifying]
|
||||
~ handler_trust += 5
|
||||
You: Those are real lives. We have to move fast.
|
||||
Agent 0x99: Exactly. Every minute counts.
|
||||
-> mission_objectives
|
||||
|
||||
+ [What if the board pays the ransom?]
|
||||
You: If they pay, systems restore faster, right?
|
||||
-> ransom_preliminary_discussion
|
||||
|
||||
=== ransom_preliminary_discussion ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Yes. Ransom payment gets decryption keys immediately—maybe 1-2 patient deaths.
|
||||
|
||||
Agent 0x99: But that's $87,000 funding ENTROPY's next attack.
|
||||
|
||||
Agent 0x99: This won't be a simple mission, agent.
|
||||
|
||||
+ [I understand the stakes]
|
||||
~ knows_full_stakes = true
|
||||
-> mission_objectives
|
||||
|
||||
=== entropy_explanation ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Ransomware Incorporated. They believe suffering "teaches resilience."
|
||||
|
||||
Agent 0x99: Not profit-motivated—ideologically driven. They calculate harm.
|
||||
|
||||
Agent 0x99: Ghost's their operative. Cold, methodical. No remorse.
|
||||
|
||||
+ [How do we stop them?]
|
||||
-> mission_objectives
|
||||
|
||||
+ [They calculated patient deaths?]
|
||||
You: They calculated how many people might die?
|
||||
Agent 0x99: Spreadsheet of projected fatalities. This is ENTROPY's ideology.
|
||||
~ knows_full_stakes = true
|
||||
-> mission_objectives
|
||||
|
||||
// ===========================================
|
||||
// MISSION OBJECTIVES
|
||||
// ===========================================
|
||||
|
||||
=== mission_objectives ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Your objectives:
|
||||
|
||||
Agent 0x99: One—infiltrate St. Catherine's as external security consultant.
|
||||
|
||||
Agent 0x99: Two—access hospital's IT systems, identify attack vector.
|
||||
|
||||
Agent 0x99: Three—exploit ENTROPY's backdoor on backup server, recover decryption keys.
|
||||
|
||||
* [What's my cover story?]
|
||||
-> cover_story
|
||||
|
||||
* [What about hospital security?]
|
||||
-> security_warning
|
||||
|
||||
* [I'm ready to go]
|
||||
~ player_approach = "direct"
|
||||
-> mission_approach
|
||||
|
||||
=== cover_story ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You're a cybersecurity consultant brought in for emergency recovery.
|
||||
|
||||
Agent 0x99: Dr. Sarah Kim, Hospital CTO, is expecting you. She'll grant access.
|
||||
|
||||
Agent 0x99: Staff is stressed, desperate. Use that. Build trust.
|
||||
|
||||
+ [Understood]
|
||||
-> security_warning
|
||||
|
||||
=== security_warning ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Security is heightened. Guards patrolling. Stay low profile.
|
||||
|
||||
Agent 0x99: Like an axolotl timing its movements—patience and observation.
|
||||
|
||||
Agent 0x99: You'll need lockpicking, social engineering, maybe some technical exploitation.
|
||||
|
||||
+ [I can handle it]
|
||||
-> mission_approach
|
||||
|
||||
+ [Any other guidance?]
|
||||
You: What else should I know?
|
||||
Agent 0x99: IT admin is named Marcus Webb. He warned them about vulnerabilities six months ago.
|
||||
Agent 0x99: They ignored him. Now he's devastated. Might be an ally.
|
||||
-> mission_approach
|
||||
|
||||
// ===========================================
|
||||
// CRITICAL CHOICE: Mission Approach
|
||||
// ===========================================
|
||||
|
||||
=== mission_approach ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: How do you want to approach this?
|
||||
|
||||
+ [Cautious and methodical]
|
||||
~ player_approach = "cautious"
|
||||
~ mission_priority = "thoroughness"
|
||||
You: I'll be careful. Thorough investigation is key.
|
||||
Agent 0x99: Smart. Document everything. Build a complete picture.
|
||||
Agent 0x99: But remember—47 patients, 12-hour window. Thorough doesn't mean slow.
|
||||
-> final_instructions
|
||||
|
||||
+ [Fast and direct]
|
||||
~ player_approach = "aggressive"
|
||||
~ mission_priority = "speed"
|
||||
You: I'll move fast. Complete objectives quickly.
|
||||
Agent 0x99: Time is critical, but don't miss vital evidence.
|
||||
Agent 0x99: ENTROPY leaves traces. Those traces help us stop them permanently.
|
||||
-> final_instructions
|
||||
|
||||
+ [Adaptable—assess on site]
|
||||
~ player_approach = "adaptable"
|
||||
~ mission_priority = "stealth"
|
||||
You: I'll read the situation and adapt as needed.
|
||||
Agent 0x99: Flexible thinking. Trust your instincts.
|
||||
Agent 0x99: Situations like this change fast. Adapt or fail.
|
||||
~ handler_trust += 5
|
||||
-> final_instructions
|
||||
|
||||
=== final_instructions ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Remember Field Operations Rule 7: "In crises, perfect is the enemy of good enough."
|
||||
|
||||
{player_approach == "cautious":
|
||||
Agent 0x99: Your careful approach serves you well. But speed matters here.
|
||||
}
|
||||
{player_approach == "aggressive":
|
||||
Agent 0x99: Speed is good. But don't compromise the mission for it.
|
||||
}
|
||||
{player_approach == "adaptable":
|
||||
Agent 0x99: Adaptability is your strength. Use it.
|
||||
}
|
||||
|
||||
Agent 0x99: You'll have comms support. Call if you need guidance.
|
||||
|
||||
* [Any last advice?]
|
||||
Agent 0x99: Marcus Webb, the IT admin. He's guilty and desperate.
|
||||
Agent 0x99: That makes him vulnerable. Build trust, get access.
|
||||
Agent 0x99: And watch for Ghost. They're calculated. Expect spreadsheets, not rage.
|
||||
-> deployment
|
||||
|
||||
* [I'm ready to go]
|
||||
-> deployment
|
||||
|
||||
=== deployment ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Good luck, {player_name()}.
|
||||
|
||||
Agent 0x99: 47 lives. 12 hours. SAFETYNET is counting on you.
|
||||
|
||||
{knows_full_stakes:
|
||||
Agent 0x99: And remember—those patient deaths? They're on ENTROPY, not you.
|
||||
Agent 0x99: Do your best. That's all anyone can ask.
|
||||
}
|
||||
|
||||
#complete_task:receive_mission_briefing
|
||||
#unlock_aim:infiltrate_hospital
|
||||
#start_gameplay
|
||||
#exit_conversation
|
||||
|
||||
-> END
|
||||
File diff suppressed because one or more lines are too long
379
scenarios/m02_ransomed_trust/ink/m02_phone_agent0x99.ink
Normal file
379
scenarios/m02_ransomed_trust/ink/m02_phone_agent0x99.ink
Normal file
@@ -0,0 +1,379 @@
|
||||
// ===========================================
|
||||
// ACT 2 PHONE NPC: Agent 0x99 (Handler Support)
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Remote Support, Tutorial Guide, Moral Sounding Board
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking hints and support
|
||||
VAR hint_guard_patrol_given = false
|
||||
VAR hint_lockpicking_given = false
|
||||
VAR hint_password_cracking_given = false
|
||||
VAR hint_pin_safe_given = false
|
||||
VAR tutorial_encoding_given = false
|
||||
VAR discussed_ghost_manifesto = false
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
EXTERNAL objectives_completed()
|
||||
EXTERNAL stealth_rating()
|
||||
EXTERNAL lore_collected()
|
||||
|
||||
// ===========================================
|
||||
// MAIN CALL INTERFACE
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: {player_name()}, checking in. How's it going?
|
||||
|
||||
{objectives_completed() >= 6:
|
||||
Agent 0x99: Excellent progress. You're nearly there.
|
||||
-> late_mission_support
|
||||
}
|
||||
{objectives_completed() >= 3:
|
||||
Agent 0x99: Good progress. Keep pushing.
|
||||
-> mid_mission_support
|
||||
}
|
||||
{objectives_completed() > 0:
|
||||
Agent 0x99: You're making headway. Stay focused.
|
||||
-> early_mission_support
|
||||
}
|
||||
{objectives_completed() == 0:
|
||||
Agent 0x99: Just getting started? Need any guidance?
|
||||
-> early_mission_support
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// EARLY MISSION SUPPORT (0-2 objectives)
|
||||
// ===========================================
|
||||
|
||||
=== early_mission_support ===
|
||||
|
||||
+ [Request general hint]
|
||||
-> provide_early_hint
|
||||
|
||||
+ [Ask about guard patrols]
|
||||
-> guard_patrol_advice
|
||||
|
||||
+ [Ask about lockpicking]
|
||||
-> lockpicking_advice
|
||||
|
||||
+ [Report progress]
|
||||
You: I've met Dr. Kim and Marcus. Learning the situation.
|
||||
Agent 0x99: Good. Build trust. They're stressed and desperate—that's leverage.
|
||||
-> end_call
|
||||
|
||||
+ [End call]
|
||||
-> end_call
|
||||
|
||||
=== provide_early_hint ===
|
||||
|
||||
{not hint_guard_patrol_given:
|
||||
-> guard_patrol_advice
|
||||
}
|
||||
{not hint_lockpicking_given:
|
||||
-> lockpicking_advice
|
||||
}
|
||||
{objectives_completed() == 0:
|
||||
Agent 0x99: Start with Dr. Kim. Get authorization for IT access.
|
||||
Agent 0x99: Then find Marcus Webb. He's guilty, stressed—perfect social engineering target.
|
||||
-> end_call
|
||||
- else:
|
||||
Agent 0x99: You're doing fine. Trust your training.
|
||||
-> end_call
|
||||
}
|
||||
|
||||
=== guard_patrol_advice ===
|
||||
~ hint_guard_patrol_given = true
|
||||
|
||||
Agent 0x99: Security is heightened. Guard patrols are on 60-second loops.
|
||||
|
||||
Agent 0x99: Like an axolotl timing its movements to avoid predators—patience and observation.
|
||||
|
||||
Agent 0x99: Watch the pattern. Find the window. Move when they round the corner.
|
||||
|
||||
+ [Understood]
|
||||
-> early_mission_support
|
||||
|
||||
+ [What if I'm detected?]
|
||||
Agent 0x99: First detection is usually a warning. Don't panic. Hide or talk your way out.
|
||||
Agent 0x99: You have cover: external security consultant. Use it.
|
||||
-> early_mission_support
|
||||
|
||||
=== lockpicking_advice ===
|
||||
~ hint_lockpicking_given = true
|
||||
|
||||
Agent 0x99: Lockpicking takes time and makes noise. Be careful near guards.
|
||||
|
||||
Agent 0x99: Standard pin tumbler locks are common. If you have lockpicks, most doors are accessible.
|
||||
|
||||
Agent 0x99: Marcus's server room keycard is ideal, but lockpicking works if he won't cooperate.
|
||||
|
||||
+ [Got it]
|
||||
-> early_mission_support
|
||||
|
||||
// ===========================================
|
||||
// MID MISSION SUPPORT (3-5 objectives)
|
||||
// ===========================================
|
||||
|
||||
=== mid_mission_support ===
|
||||
|
||||
+ [Request hint]
|
||||
-> provide_mid_hint
|
||||
|
||||
+ [Ask about password cracking]
|
||||
-> password_advice
|
||||
|
||||
+ [Ask about encoding challenges]
|
||||
-> encoding_tutorial
|
||||
|
||||
+ [Discuss Ghost's manifesto]
|
||||
-> discuss_manifesto
|
||||
|
||||
+ [End call]
|
||||
-> end_call
|
||||
|
||||
=== provide_mid_hint ===
|
||||
|
||||
{not hint_password_cracking_given:
|
||||
-> password_advice
|
||||
}
|
||||
{not tutorial_encoding_given:
|
||||
-> encoding_tutorial
|
||||
}
|
||||
{not hint_pin_safe_given:
|
||||
-> pin_safe_advice
|
||||
}
|
||||
{objectives_completed() < 5:
|
||||
Agent 0x99: You're making progress. Stay focused on VM challenges.
|
||||
Agent 0x99: ProFTPD exploitation is the key. CVE-2010-4652—backdoor vulnerability.
|
||||
-> end_call
|
||||
- else:
|
||||
Agent 0x99: Trust your instincts. You've got this.
|
||||
-> end_call
|
||||
}
|
||||
|
||||
=== password_advice ===
|
||||
~ hint_password_cracking_given = true
|
||||
|
||||
Agent 0x99: Hospital environments use weak passwords. Birthdays, company names, simple variations.
|
||||
|
||||
Agent 0x99: Marcus might have kept a list of common employee passwords. Check his desk.
|
||||
|
||||
Agent 0x99: Try patterns: Emma2018, Hospital1987, StCatherines. People are predictable.
|
||||
|
||||
+ [Thanks]
|
||||
-> mid_mission_support
|
||||
|
||||
=== encoding_tutorial ===
|
||||
~ tutorial_encoding_given = true
|
||||
|
||||
Agent 0x99: Encoding vs. encryption—important distinction.
|
||||
|
||||
Agent 0x99: Encoding transforms data for transmission. No secret key needed. Base64, ROT13, hex.
|
||||
|
||||
Agent 0x99: Encryption requires a secret key. Much more secure. AES, RSA, ChaCha20.
|
||||
|
||||
Agent 0x99: ENTROPY uses encoding for obfuscation, encryption for actual security.
|
||||
|
||||
+ [How do I decode Base64?]
|
||||
Agent 0x99: Use CyberChef. It's an industry-standard tool. Select "From Base64" and paste the text.
|
||||
Agent 0x99: You'll use CyberChef constantly in this field. Get comfortable with it.
|
||||
-> mid_mission_support
|
||||
|
||||
+ [Understood]
|
||||
-> mid_mission_support
|
||||
|
||||
=== discuss_manifesto ===
|
||||
~ discussed_ghost_manifesto = true
|
||||
|
||||
{lore_collected() > 0:
|
||||
-> manifesto_found
|
||||
- else:
|
||||
-> manifesto_not_found
|
||||
}
|
||||
|
||||
=== manifesto_found ===
|
||||
|
||||
Agent 0x99: You found Ghost's manifesto. Calculated patient death probabilities.
|
||||
|
||||
Agent 0x99: 47 patients, 0.3% per hour risk. 1-2 deaths if ransom paid, 4-6 if delayed.
|
||||
|
||||
Agent 0x99: This isn't random cybercrime. This is ideology. ENTROPY believes suffering teaches lessons.
|
||||
|
||||
+ [This is horrifying]
|
||||
You: They have a spreadsheet of how many people will die.
|
||||
Agent 0x99: Operation Shatter had 42-85 projected deaths. Now patient death probabilities.
|
||||
Agent 0x99: We're fighting true believers, not opportunistic criminals.
|
||||
-> mid_mission_support
|
||||
|
||||
+ [Ghost has a point about negligence]
|
||||
You: The hospital DID ignore Marcus's warnings for six months.
|
||||
Agent 0x99: True. Institutional negligence is real. But ENTROPY's solution? Calculated harm?
|
||||
Agent 0x99: They're exploiting systemic failure, not fixing it. Don't fall for their rhetoric.
|
||||
-> mid_mission_support
|
||||
|
||||
=== manifesto_not_found ===
|
||||
|
||||
Agent 0x99: You haven't found Ghost's operational logs yet. Keep searching the VM.
|
||||
|
||||
Agent 0x99: Ghost's ideology drives their actions. Understanding it helps predict their moves.
|
||||
|
||||
-> mid_mission_support
|
||||
|
||||
=== pin_safe_advice ===
|
||||
~ hint_pin_safe_given = true
|
||||
|
||||
Agent 0x99: Ghost's logs mention offline backup keys in a physical safe.
|
||||
|
||||
Agent 0x99: 4-digit PIN lock. Look for clues in the hospital environment.
|
||||
|
||||
Agent 0x99: Founding years, significant dates, administrative anniversaries. Hospitals love that stuff.
|
||||
|
||||
+ [Where should I look?]
|
||||
Agent 0x99: Emergency equipment storage, administrative offices. Anywhere valuable backups would be stored.
|
||||
Agent 0x99: Check plaques, photos, documents. The clues are there.
|
||||
-> mid_mission_support
|
||||
|
||||
+ [Got it]
|
||||
-> mid_mission_support
|
||||
|
||||
// ===========================================
|
||||
// LATE MISSION SUPPORT (6+ objectives)
|
||||
// ===========================================
|
||||
|
||||
=== late_mission_support ===
|
||||
|
||||
Agent 0x99: You're in the final stretch. Recovery options available?
|
||||
|
||||
{objectives_completed() >= 7:
|
||||
Agent 0x99: You've recovered the offline backup keys. Now comes the hard part.
|
||||
-> ransom_decision_discussion
|
||||
}
|
||||
|
||||
+ [Request final guidance]
|
||||
-> final_mission_guidance
|
||||
|
||||
+ [Discuss ransom decision]
|
||||
-> ransom_decision_discussion
|
||||
|
||||
+ [End call]
|
||||
-> end_call
|
||||
|
||||
=== final_mission_guidance ===
|
||||
|
||||
Agent 0x99: You have all the pieces. Offline backup keys, VM access, evidence of negligence.
|
||||
|
||||
Agent 0x99: The ransom decision is yours. I can't make it for you.
|
||||
|
||||
Agent 0x99: 47 lives today vs. ENTROPY funding for future attacks. Choose wisely.
|
||||
|
||||
+ [What would you do?]
|
||||
Agent 0x99: I'd weigh immediate lives against long-term harm. Both choices save people—just different timeframes.
|
||||
Agent 0x99: There's no perfect answer here. That's what makes it hard.
|
||||
-> late_mission_support
|
||||
|
||||
+ [I understand]
|
||||
-> late_mission_support
|
||||
|
||||
=== ransom_decision_discussion ===
|
||||
|
||||
Agent 0x99: The ransom decision is the mission's core dilemma.
|
||||
|
||||
Agent 0x99: Pay: 1-2 patient deaths, $87K funds ENTROPY.
|
||||
|
||||
Agent 0x99: Don't pay: 4-6 patient deaths, ENTROPY denied funding.
|
||||
|
||||
Agent 0x99: Utilitarian vs. consequentialist ethics. Immediate lives vs. long-term prevention.
|
||||
|
||||
+ [This is impossible]
|
||||
You: There's no good choice. Either way, people suffer.
|
||||
Agent 0x99: Welcome to counterterrorism. Sometimes you choose the lesser evil.
|
||||
Agent 0x99: ENTROPY creates these dilemmas on purpose. Don't be paralyzed.
|
||||
-> late_mission_support
|
||||
|
||||
+ [What about hospital exposure?]
|
||||
Agent 0x99: Secondary decision. Expose negligence publicly—forces improvements, damages reputation.
|
||||
Agent 0x99: Quiet resolution—protects reputation, risks repeat vulnerability.
|
||||
Agent 0x99: Again, no perfect answer.
|
||||
-> late_mission_support
|
||||
|
||||
+ [I'll make the call]
|
||||
Agent 0x99: Good. Trust your judgment. That's all anyone can ask.
|
||||
-> late_mission_support
|
||||
|
||||
// ===========================================
|
||||
// END CALL
|
||||
// ===========================================
|
||||
|
||||
=== end_call ===
|
||||
|
||||
Agent 0x99: Stay safe out there, {player_name()}.
|
||||
|
||||
{stealth_rating() > 80:
|
||||
Agent 0x99: And excellent stealth work. You're nearly invisible.
|
||||
}
|
||||
{stealth_rating() < 40:
|
||||
Agent 0x99: And try to stay quieter. You're making noise.
|
||||
}
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// EVENT-TRIGGERED KNOTS (Called by game events)
|
||||
// ===========================================
|
||||
|
||||
// Called when player is detected by guard
|
||||
=== on_player_detected ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: You've been spotted! Use your cover story or hide.
|
||||
|
||||
Agent 0x99: Remember—you're an external security consultant. Legitimate access.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// Called when player successfully completes lockpicking
|
||||
=== on_lockpick_success ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Smooth work on that lock. Solid technique.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// Called when player finds first LORE fragment
|
||||
=== on_first_lore_found ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Good find. ENTROPY intelligence helps us understand their network.
|
||||
|
||||
Agent 0x99: Keep searching. The more we know, the better we can fight them.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// Called when player submits first VM flag
|
||||
=== on_first_flag_submitted ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Excellent! First flag submitted. You're exploiting ENTROPY's own backdoor.
|
||||
|
||||
Agent 0x99: Keep going. Each flag unlocks intel and resources.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// Called when player enters server room
|
||||
=== on_enter_server_room ===
|
||||
#speaker:agent_0x99
|
||||
|
||||
Agent 0x99: Server room accessed. This is the heart of the operation.
|
||||
|
||||
Agent 0x99: VM terminal for exploitation, drop-site for flag submission. Use both.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
File diff suppressed because one or more lines are too long
381
scenarios/m02_ransomed_trust/ink/m02_phone_ghost.ink
Normal file
381
scenarios/m02_ransomed_trust/ink/m02_phone_ghost.ink
Normal file
@@ -0,0 +1,381 @@
|
||||
// ===========================================
|
||||
// ACT 2/3 PHONE NPC: Ghost (Ransomware Incorporated)
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Antagonist, True Believer, Ideological Counter
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking interactions
|
||||
VAR ghost_contacted_player = false
|
||||
VAR ghost_persuasion_attempted = false
|
||||
VAR player_confronted_ghost = false
|
||||
VAR ghost_unrepentant = true
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
EXTERNAL objectives_completed()
|
||||
EXTERNAL paid_ransom()
|
||||
|
||||
// ===========================================
|
||||
// INITIAL CONTACT (Mid-Mission)
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:ghost
|
||||
|
||||
{ghost_contacted_player:
|
||||
-> return_contact
|
||||
}
|
||||
|
||||
[ENCRYPTED CHANNEL ESTABLISHED]
|
||||
|
||||
[UNKNOWN CALLER]
|
||||
|
||||
Voice (distorted): So. SAFETYNET sent someone. Predictable.
|
||||
|
||||
Voice: I'm Ghost. Ransomware Incorporated. You're interfering with our operation.
|
||||
|
||||
~ ghost_contacted_player = true
|
||||
|
||||
* [Who are you?]
|
||||
You: Ghost? Ransomware Incorporated? What do you want?
|
||||
-> ghost_introduction
|
||||
|
||||
* [Threaten Ghost]
|
||||
You: You're attacking a hospital. Patients are dying.
|
||||
-> player_threatens
|
||||
|
||||
* [Stay silent]
|
||||
You: ...
|
||||
Ghost: Strong, silent type. Fine. I'll talk.
|
||||
-> ghost_introduction
|
||||
|
||||
=== ghost_introduction ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: We're educators, not criminals. St. Catherine's ignored security warnings for six months.
|
||||
|
||||
Ghost: Marcus Webb's email, May 17th: "ProFTPD vulnerability, critical severity, immediate patching required."
|
||||
|
||||
Ghost: Hospital response: "Budget constraints. Defer to next fiscal year."
|
||||
|
||||
* [That doesn't justify attacking patients]
|
||||
You: That doesn't justify encrypting patient records. People could die.
|
||||
-> ghost_justification
|
||||
|
||||
* [So this is ideological?]
|
||||
You: You're teaching them a lesson? That's your justification?
|
||||
-> ghost_philosophy
|
||||
|
||||
=== player_threatens ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Patients dying? No. Patients at RISK. Calculated risk.
|
||||
|
||||
Ghost: 0.3% per hour fatality probability. 47 patients. 12-hour window.
|
||||
|
||||
Ghost: 1-2 deaths if they pay immediately. 4-6 if they delay for manual recovery.
|
||||
|
||||
Ghost: We didn't create that risk. St. Catherine's negligence did. We're just revealing consequences.
|
||||
|
||||
* [You calculated death probabilities?]
|
||||
You: You have spreadsheets of how many people will die?
|
||||
-> ghost_confirms_calculations
|
||||
|
||||
* [That's monstrous]
|
||||
You: You're using human lives as leverage. That's evil.
|
||||
-> ghost_philosophy
|
||||
|
||||
=== ghost_confirms_calculations ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Of course I calculated probabilities. This is risk assessment, not recklessness.
|
||||
|
||||
Ghost: St. Catherine's board never ran these numbers. They deferred $85K security spending for a $3.2M MRI.
|
||||
|
||||
Ghost: THEY gambled with patient safety. We're just making the stakes visible.
|
||||
|
||||
* [You're rationalizing terrorism]
|
||||
You: This is terrorism, not education.
|
||||
Ghost: Terrorism is violence for political aims. This is consequence for negligence.
|
||||
Ghost: We're the mirror showing them what they've always risked.
|
||||
-> ghost_philosophy
|
||||
|
||||
* [What do you want?]
|
||||
-> ransom_demand
|
||||
|
||||
=== ghost_justification ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Justify? I don't need to justify. The math justifies itself.
|
||||
|
||||
Ghost: St. Catherine's ignored Marcus's warnings. They chose shiny equipment over patient data security.
|
||||
|
||||
Ghost: Now they face consequences. Expensive, painful consequences they'll never forget.
|
||||
|
||||
-> ghost_philosophy
|
||||
|
||||
=== ghost_philosophy ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Healthcare sector is systemically vulnerable. 214 hospitals we scanned. 147 have critical vulnerabilities.
|
||||
|
||||
Ghost: Traditional cybersecurity consultants charge millions for reports nobody reads.
|
||||
|
||||
Ghost: We charge thousands for lessons nobody forgets.
|
||||
|
||||
Ghost: After this, St. Catherine's will triple cybersecurity budgets. 40 other hospitals will too.
|
||||
|
||||
Ghost: Long-term? We'll prevent 200-600 deaths across 5 years. Statistical modeling confirms it.
|
||||
|
||||
* [You don't get to make that calculation]
|
||||
You: You don't get to decide whose lives are worth risking.
|
||||
-> ghost_rejects_argument
|
||||
|
||||
* [That's utilitarian logic]
|
||||
You: Utilitarian harm for long-term good. Slippery slope.
|
||||
-> ghost_accepts_label
|
||||
|
||||
=== ghost_rejects_argument ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: I didn't decide. St. Catherine's board decided when they cut security budgets.
|
||||
|
||||
Ghost: We're just the consequence they tried to ignore.
|
||||
|
||||
-> ransom_demand
|
||||
|
||||
=== ghost_accepts_label ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Slippery slope? Perhaps. But someone has to force change.
|
||||
|
||||
Ghost: The alternative is systemic negligence continues. More hospitals get attacked. More patients die.
|
||||
|
||||
Ghost: We're harsh teachers. But institutional change requires pain.
|
||||
|
||||
-> ransom_demand
|
||||
|
||||
// ===========================================
|
||||
// RANSOM DEMAND
|
||||
// ===========================================
|
||||
|
||||
=== ransom_demand ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Here's what happens next.
|
||||
|
||||
Ghost: Pay 2.5 BTC—$87,000. Systems restored in 2-4 hours. 1-2 patient deaths, statistical minimum.
|
||||
|
||||
Ghost: Don't pay. Manual recovery takes 12 hours. 4-6 patient deaths. Malpractice lawsuits. Hospital reputation destroyed.
|
||||
|
||||
Ghost: Your choice, SAFETYNET.
|
||||
|
||||
~ ghost_persuasion_attempted = true
|
||||
|
||||
* [We'll recover independently]
|
||||
You: We're not funding terrorism. We'll recover independently.
|
||||
-> ghost_warns_consequences
|
||||
|
||||
* [Threaten to trace Ghost]
|
||||
You: We'll trace the payment. Find you. Arrest you.
|
||||
-> ghost_laughs_at_threat
|
||||
|
||||
* [End communication]
|
||||
You: We're done here.
|
||||
Ghost: Time's running out. Patients are counting on you.
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
=== ghost_warns_consequences ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Independent recovery. 12 hours. 4-6 deaths.
|
||||
|
||||
Ghost: Those deaths are on YOUR conscience, not ours.
|
||||
|
||||
Ghost: St. Catherine's negligence created this crisis. You could save them. You're choosing ideology over lives.
|
||||
|
||||
Ghost: Remember that when families ask why their loved ones died.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
=== ghost_laughs_at_threat ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Trace me? Crypto Anarchists handle our payment infrastructure.
|
||||
|
||||
Ghost: Monero mixing across 47 wallets. Multi-hop transaction routing. DarkCoin anonymization.
|
||||
|
||||
Ghost: Even SAFETYNET forensics can't pierce that. Ghost Protocol guarantees it.
|
||||
|
||||
Ghost: Good luck, agent. You'll need it.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// RETURN CONTACT (After Decision)
|
||||
// ===========================================
|
||||
|
||||
=== return_contact ===
|
||||
#speaker:ghost
|
||||
|
||||
[ENCRYPTED CHANNEL - GHOST]
|
||||
|
||||
{objectives_completed() >= 7:
|
||||
-> post_decision_contact
|
||||
- else:
|
||||
-> mid_mission_contact
|
||||
}
|
||||
|
||||
=== mid_mission_contact ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Still working? Time's running out.
|
||||
|
||||
Ghost: 47 patients. Backup power failing. Families watching monitors, praying.
|
||||
|
||||
Ghost: $87,000 vs. human lives. Easy math.
|
||||
|
||||
* [You're trying to pressure me]
|
||||
You: This is psychological manipulation.
|
||||
Ghost: This is reality. 0.3% per hour. The clock doesn't care about your feelings.
|
||||
-> end_contact
|
||||
|
||||
* [We'll stop you]
|
||||
You: SAFETYNET will dismantle ENTROPY. You'll be arrested.
|
||||
Ghost: Maybe. But St. Catherine's will never ignore cybersecurity again. Mission accomplished.
|
||||
-> end_contact
|
||||
|
||||
* [End call]
|
||||
-> end_contact
|
||||
|
||||
=== post_decision_contact ===
|
||||
#speaker:ghost
|
||||
|
||||
{paid_ransom():
|
||||
-> ransom_paid_response
|
||||
- else:
|
||||
-> ransom_refused_response
|
||||
}
|
||||
|
||||
=== ransom_paid_response ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Smart choice. Decryption keys delivered. Systems restoring.
|
||||
|
||||
Ghost: 1-2 patient deaths. Acceptable losses compared to the alternative.
|
||||
|
||||
Ghost: St. Catherine's will never ignore cybersecurity again. Board approved $250K security budget—triple the old allocation.
|
||||
|
||||
Ghost: Lesson learned. Mission accomplished.
|
||||
|
||||
* [You're still a terrorist]
|
||||
You: You killed people. That's terrorism.
|
||||
Ghost: Pre-existing complications during system transition. Medical records confirm it.
|
||||
Ghost: Statistically inevitable. Could have happened without our intervention.
|
||||
-> ghost_final_statement
|
||||
|
||||
* [This won't stop SAFETYNET]
|
||||
You: We're coming for you. ENTROPY won't last.
|
||||
Ghost: Maybe. But how many hospitals will improve security before you find us?
|
||||
Ghost: 40? 60? 100? Each one is lives saved long-term.
|
||||
-> ghost_final_statement
|
||||
|
||||
=== ransom_refused_response ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Independent recovery. 4-6 patient deaths confirmed.
|
||||
|
||||
Ghost: Ventilator complications. Dialysis failures. Cardiac arrests during extended downtime.
|
||||
|
||||
Ghost: Those deaths are on YOUR conscience. You could have paid. You chose ideology.
|
||||
|
||||
* [No. Those deaths are on YOU]
|
||||
You: YOU attacked the hospital. YOU encrypted patient records. This is YOUR fault.
|
||||
-> ghost_rejects_responsibility
|
||||
|
||||
* [We denied ENTROPY funding]
|
||||
You: $87,000 denied. No funding for your next attack.
|
||||
-> ghost_acknowledges_loss
|
||||
|
||||
=== ghost_rejects_responsibility ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: I accept operational responsibility. But St. Catherine's created the vulnerability.
|
||||
|
||||
Ghost: Six months of ignored warnings. Budget negligence. Institutional failure.
|
||||
|
||||
Ghost: We exploited it. They enabled it. Share the blame.
|
||||
|
||||
-> ghost_final_statement
|
||||
|
||||
=== ghost_acknowledges_loss ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: $87,000 lost. Operational setback acknowledged.
|
||||
|
||||
Ghost: But St. Catherine's board approved $400K emergency security budget—panic response.
|
||||
|
||||
Ghost: 40 hospitals implementing emergency upgrades. Sector-wide impact achieved.
|
||||
|
||||
Ghost: Educational outcome: Success. Worth the cost.
|
||||
|
||||
-> ghost_final_statement
|
||||
|
||||
// ===========================================
|
||||
// FINAL STATEMENT (Unrepentant)
|
||||
// ===========================================
|
||||
|
||||
=== ghost_final_statement ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: Here's what you need to understand, SAFETYNET.
|
||||
|
||||
Ghost: I calculated the risks. I planned the operation. I accept the consequences.
|
||||
|
||||
Ghost: If you arrest me, I'll go to prison. No resistance. No regret.
|
||||
|
||||
Ghost: Because St. Catherine's will never ignore cybersecurity again. Neither will 40 other hospitals.
|
||||
|
||||
Ghost: That's worth it. That's the mission. That's ENTROPY's purpose.
|
||||
|
||||
* [You're insane]
|
||||
You: You're a fanatic. Calculated harm is still harm.
|
||||
Ghost: Fanaticism is believing despite evidence. I have spreadsheets, statistical models, outcome projections.
|
||||
Ghost: This is evidence-based ideology.
|
||||
-> ghost_disconnects
|
||||
|
||||
* [We'll stop ENTROPY]
|
||||
You: This isn't over. We're coming for the whole network.
|
||||
Ghost: Good luck. The Architect coordinates six cells. We're everywhere.
|
||||
Ghost: Shut down one, five remain. Hydra principle.
|
||||
-> ghost_disconnects
|
||||
|
||||
=== ghost_disconnects ===
|
||||
#speaker:ghost
|
||||
|
||||
Ghost: This conversation is over.
|
||||
|
||||
Ghost: Remember: ENTROPY didn't create healthcare vulnerabilities. We just revealed them.
|
||||
|
||||
Ghost: The real enemy is institutional negligence. We're the symptom, not the disease.
|
||||
|
||||
[ENCRYPTED CHANNEL TERMINATED]
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// END CONTACT
|
||||
// ===========================================
|
||||
|
||||
=== end_contact ===
|
||||
|
||||
Ghost: Time's running out. Choose wisely.
|
||||
|
||||
[CHANNEL CLOSED]
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
1
scenarios/m02_ransomed_trust/ink/m02_phone_ghost.json
Normal file
1
scenarios/m02_ransomed_trust/ink/m02_phone_ghost.json
Normal file
File diff suppressed because one or more lines are too long
229
scenarios/m02_ransomed_trust/ink/m02_terminal_dropsite.ink
Normal file
229
scenarios/m02_ransomed_trust/ink/m02_terminal_dropsite.ink
Normal file
@@ -0,0 +1,229 @@
|
||||
// ===========================================
|
||||
// ACT 2 TERMINAL: Drop-Site Terminal (VM Flag Submission)
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Hybrid Architecture Integration
|
||||
// ===========================================
|
||||
|
||||
// Variables for tracking flag submissions
|
||||
VAR flag_ssh_submitted = false
|
||||
VAR flag_proftpd_submitted = false
|
||||
VAR flag_database_submitted = false
|
||||
VAR flag_ghost_log_submitted = false
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
|
||||
// ===========================================
|
||||
// MAIN TERMINAL INTERFACE
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:computer
|
||||
|
||||
SAFETYNET DROP-SITE TERMINAL
|
||||
|
||||
Secure communication channel for intercepted ENTROPY intelligence.
|
||||
|
||||
Submit flags to unlock analysis and resources.
|
||||
|
||||
-> main_menu
|
||||
|
||||
=== main_menu ===
|
||||
|
||||
+ [not flag_ssh_submitted] Submit Flag 1SSH Access
|
||||
-> submit_flag_ssh
|
||||
|
||||
+ [not flag_proftpd_submitted] Submit Flag 2ProFTPD Exploit
|
||||
-> submit_flag_proftpd
|
||||
|
||||
+ [not flag_database_submitted] Submit Flag 3Database Backup
|
||||
-> submit_flag_database
|
||||
|
||||
+ [not flag_ghost_log_submitted] Submit Flag 4Ghost Log
|
||||
-> submit_flag_ghost_log
|
||||
|
||||
+ [View submission status]
|
||||
-> view_status
|
||||
|
||||
+ [Exit terminal]
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// FLAG 1: SSH ACCESS
|
||||
// ===========================================
|
||||
|
||||
=== submit_flag_ssh ===
|
||||
#speaker:computer
|
||||
|
||||
SUBMIT FLAG: SSH ACCESS TO HOSPITAL BACKUP SERVER
|
||||
|
||||
Enter flag: flag[ssh_access_granted]
|
||||
|
||||
System: Flag verified.
|
||||
|
||||
System: ENTROPY server credentials intercepted.
|
||||
|
||||
System: Unlocking encrypted intelligence files...
|
||||
|
||||
~ flag_ssh_submitted = true
|
||||
#complete_task:submit_ssh_flag
|
||||
#unlock_task:exploit_proftpd_vulnerability
|
||||
|
||||
INTEL UNLOCKED: Hospital backup server accessible via SSH.
|
||||
|
||||
Credentials confirmed functional. Proceed with ProFTPD exploitation.
|
||||
|
||||
+ [Continue]
|
||||
-> main_menu
|
||||
|
||||
// ===========================================
|
||||
// FLAG 2: ProFTPD EXPLOITATION
|
||||
// ===========================================
|
||||
|
||||
=== submit_flag_proftpd ===
|
||||
#speaker:computer
|
||||
|
||||
SUBMIT FLAG: ProFTPD BACKDOOR EXPLOITATION
|
||||
|
||||
Enter flag: flag[proftpd_backdoor_exploited]
|
||||
|
||||
System: Flag verified.
|
||||
|
||||
System: ProFTPD CVE-2010-4652 exploitation confirmed.
|
||||
|
||||
System: Shell access to backup server established.
|
||||
|
||||
~ flag_proftpd_submitted = true
|
||||
#complete_task:submit_proftpd_flag
|
||||
#unlock_task:navigate_backup_filesystem
|
||||
|
||||
INTEL UNLOCKED: Root filesystem access granted.
|
||||
|
||||
Navigate to /var/backups to locate encrypted database files and operational logs.
|
||||
|
||||
+ [Continue]
|
||||
-> main_menu
|
||||
|
||||
// ===========================================
|
||||
// FLAG 3: DATABASE BACKUP LOCATED
|
||||
// ===========================================
|
||||
|
||||
=== submit_flag_database ===
|
||||
#speaker:computer
|
||||
|
||||
SUBMIT FLAG: DATABASE BACKUP LOCATION
|
||||
|
||||
Enter flag: flag[database_backup_located]
|
||||
|
||||
System: Flag verified.
|
||||
|
||||
System: Patient database backups identified.
|
||||
|
||||
System: Correlating with ransomware encryption keys...
|
||||
|
||||
~ flag_database_submitted = true
|
||||
#complete_task:submit_database_flag
|
||||
#unlock_task:locate_offline_backup_keys
|
||||
|
||||
INTEL UNLOCKED: Offline backup encryption keys mentioned in Ghost's logs.
|
||||
|
||||
Analysis indicates keys stored in physical safe: "Emergency Equipment Storage, Administrative Wing."
|
||||
|
||||
Search for 4-digit PIN-locked safe. Clues available in hospital environment.
|
||||
|
||||
+ [Continue]
|
||||
-> main_menu
|
||||
|
||||
// ===========================================
|
||||
// FLAG 4: GHOST'S OPERATIONAL LOG
|
||||
// ===========================================
|
||||
|
||||
=== submit_flag_ghost_log ===
|
||||
#speaker:computer
|
||||
|
||||
SUBMIT FLAG: GHOST'S OPERATIONAL LOG
|
||||
|
||||
Enter flag: flag[ghost_operational_log]
|
||||
|
||||
System: Flag verified.
|
||||
|
||||
System: Ransomware Incorporated operational philosophy document intercepted.
|
||||
|
||||
System: Analyzing ENTROPY methodology...
|
||||
|
||||
~ flag_ghost_log_submitted = true
|
||||
#complete_task:submit_ghost_log_flag
|
||||
#unlock_lore:ghosts_manifesto
|
||||
|
||||
WARNING: Ghost calculated patient death probabilities (0.3% per hour).
|
||||
|
||||
47 patients on life support = 1-2 deaths if ransom paid immediately, 4-6 if delayed 12 hours.
|
||||
|
||||
ENTROPY classification: Ideological attack, not profit-motivated.
|
||||
|
||||
Recommendation: Complete recovery ASAP to minimize statistical patient risk.
|
||||
|
||||
+ [This is horrifying]
|
||||
-> ghost_log_reaction
|
||||
|
||||
+ [Continue]
|
||||
-> main_menu
|
||||
|
||||
=== ghost_log_reaction ===
|
||||
#speaker:computer
|
||||
|
||||
Agent 0x99 (via secure channel): They calculated how many people would die.
|
||||
|
||||
Agent 0x99: Spreadsheets of projected fatalities. This is ENTROPY's ideology.
|
||||
|
||||
Agent 0x99: Operation Shatter had 42-85 projected deaths. Now patient death probabilities.
|
||||
|
||||
Agent 0x99: We're not fighting random criminals. We're fighting true believers.
|
||||
|
||||
+ [Continue]
|
||||
-> main_menu
|
||||
|
||||
// ===========================================
|
||||
// VIEW STATUS
|
||||
// ===========================================
|
||||
|
||||
=== view_status ===
|
||||
#speaker:computer
|
||||
|
||||
FLAG SUBMISSION STATUS:
|
||||
|
||||
[flag_ssh_submitted:
|
||||
✓ Flag 1: SSH Access - SUBMITTED
|
||||
- else:
|
||||
✗ Flag 1: SSH Access - PENDING
|
||||
]
|
||||
|
||||
[flag_proftpd_submitted:
|
||||
✓ Flag 2: ProFTPD Exploit - SUBMITTED
|
||||
- else:
|
||||
✗ Flag 2: ProFTPD Exploit - PENDING
|
||||
]
|
||||
|
||||
[flag_database_submitted:
|
||||
✓ Flag 3: Database Backup Located - SUBMITTED
|
||||
- else:
|
||||
✗ Flag 3: Database Backup Located - PENDING
|
||||
]
|
||||
|
||||
[flag_ghost_log_submitted:
|
||||
✓ Flag 4: Ghost's Operational Log - SUBMITTED
|
||||
- else:
|
||||
✗ Flag 4: Ghost's Operational Log - PENDING
|
||||
]
|
||||
|
||||
[flag_ssh_submitted and flag_proftpd_submitted and flag_database_submitted and flag_ghost_log_submitted:
|
||||
ALL FLAGS SUBMITTED. PROCEED TO PHYSICAL SAFE LOCATION.
|
||||
]
|
||||
|
||||
+ [Return to main menu]
|
||||
-> main_menu
|
||||
|
||||
+ [Exit terminal]
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,451 @@
|
||||
// ===========================================
|
||||
// ACT 3 TERMINAL: Ransom Payment Decision Interface
|
||||
// Mission 2: Ransomed Trust
|
||||
// Break Escape - Critical Moral Choice
|
||||
// ===========================================
|
||||
|
||||
// Global decision tracking
|
||||
VAR ransom_decision_made = false
|
||||
VAR paid_ransom = false
|
||||
VAR exposed_hospital = false
|
||||
VAR reviewed_consequences = false
|
||||
|
||||
// External variables (set by game)
|
||||
EXTERNAL player_name()
|
||||
EXTERNAL objectives_completed()
|
||||
|
||||
// ===========================================
|
||||
// TERMINAL INTERFACE START
|
||||
// ===========================================
|
||||
|
||||
=== start ===
|
||||
#speaker:computer
|
||||
|
||||
{ransom_decision_made:
|
||||
-> decision_already_made
|
||||
}
|
||||
|
||||
HOSPITAL RECOVERY INTERFACE
|
||||
|
||||
St. Catherine's Regional Medical Center
|
||||
|
||||
Critical Decision Point: Decryption Key Recovery
|
||||
|
||||
-> interface_main
|
||||
|
||||
=== interface_main ===
|
||||
#speaker:computer
|
||||
|
||||
CURRENT STATUS:
|
||||
|
||||
- 47 patients on life support
|
||||
- Backup power: 8 hours remaining
|
||||
- Offline backup keys: RECOVERED
|
||||
- Manual recovery time: 12 hours estimated
|
||||
|
||||
DECISION REQUIRED: How should systems be recovered?
|
||||
|
||||
+ [Review recovery options]
|
||||
-> review_options
|
||||
|
||||
+ [Hear Ghost's argument]
|
||||
-> ghost_persuasion
|
||||
|
||||
+ [Hear Agent 0x99's analysis]
|
||||
-> agent_analysis
|
||||
|
||||
+ [Make decision]
|
||||
-> make_decision
|
||||
|
||||
+ [Exit (decision required before mission ends)]
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
// ===========================================
|
||||
// REVIEW OPTIONS
|
||||
// ===========================================
|
||||
|
||||
=== review_options ===
|
||||
#speaker:computer
|
||||
~ reviewed_consequences = true
|
||||
|
||||
OPTION 1: PAY RANSOM (2.5 BTC = $87,000 USD)
|
||||
|
||||
Immediate Effects:
|
||||
✓ Decryption keys delivered within 30 minutes
|
||||
✓ Systems restored in 2-4 hours
|
||||
✓ Estimated patient deaths: 1-2 (0.6-1.2% statistical risk)
|
||||
✓ Hospital reputation preserved (quick resolution)
|
||||
|
||||
Long-Term Consequences:
|
||||
✗ $87,000 funds ENTROPY's next operation
|
||||
✗ Crypto Anarchists launder funds (enables M6 operations)
|
||||
✗ Ransomware Incorporated validates "educational" methodology
|
||||
✗ Sets precedent: Healthcare sector pays ransoms
|
||||
|
||||
---
|
||||
|
||||
OPTION 2: MANUAL RECOVERY (Use offline backup keys)
|
||||
|
||||
Immediate Effects:
|
||||
✓ No ENTROPY funding
|
||||
✓ Offline keys allow system restoration
|
||||
✗ Manual recovery time: 12 hours minimum
|
||||
✗ Estimated patient deaths: 4-6 (3.6% statistical risk)
|
||||
✗ Higher malpractice lawsuit risk
|
||||
|
||||
Long-Term Consequences:
|
||||
✓ ENTROPY loses $87,000 operational funding
|
||||
✓ Demonstrates independent recovery possible
|
||||
✓ Reduces financial incentive for future attacks
|
||||
✓ St. Catherine's reputation damaged but security improved
|
||||
|
||||
---
|
||||
|
||||
SECONDARY DECISION: Hospital Exposure
|
||||
|
||||
- Expose publicly: Forces cybersecurity improvements, damages reputation
|
||||
- Quiet resolution: Protects reputation, risks repeat vulnerability
|
||||
|
||||
~ reviewed_consequences = true
|
||||
|
||||
+ [Continue]
|
||||
-> interface_main
|
||||
|
||||
// ===========================================
|
||||
// GHOST'S PERSUASION
|
||||
// ===========================================
|
||||
|
||||
=== ghost_persuasion ===
|
||||
#speaker:computer
|
||||
|
||||
INTERCEPTED MESSAGE FROM GHOST (Ransomware Incorporated):
|
||||
|
||||
---
|
||||
|
||||
"Time is running out. 47 patients. 8 hours of backup power remaining.
|
||||
|
||||
Patient deaths are on YOUR conscience if you delay. Not ours.
|
||||
|
||||
We calculated the risk: 0.3% per hour. Manual recovery = 12 hours = 3.6% cumulative risk.
|
||||
|
||||
That's 4-6 expected deaths. Real people. Real families.
|
||||
|
||||
$87,000 vs. human lives. Easy math.
|
||||
|
||||
St. Catherine's created this scenario when they ignored Marcus's warnings for six months. They chose a $3.2M MRI over $85K server security. This is THEIR negligence, not ours.
|
||||
|
||||
Pay the ransom. Save the patients. Learn the lesson.
|
||||
|
||||
The choice is yours.
|
||||
|
||||
- Ghost"
|
||||
|
||||
---
|
||||
|
||||
+ [This is manipulation]
|
||||
You: Ghost's trying to manipulate me. Shift blame for their attack.
|
||||
-> interface_main
|
||||
|
||||
+ [Ghost has a point about hospital negligence]
|
||||
You: The hospital DID ignore warnings. Ghost's exploiting institutional failure.
|
||||
-> interface_main
|
||||
|
||||
+ [Continue]
|
||||
-> interface_main
|
||||
|
||||
// ===========================================
|
||||
// AGENT 0x99 ANALYSIS
|
||||
// ===========================================
|
||||
|
||||
=== agent_analysis ===
|
||||
#speaker:computer
|
||||
|
||||
AGENT 0x99 (Secure Channel):
|
||||
|
||||
---
|
||||
|
||||
"No easy answer here, {player_name()}. This is ethics under pressure.
|
||||
|
||||
Utilitarian perspective: Pay ransom, save 47 lives today. Immediate harm reduction.
|
||||
|
||||
Consequentialist perspective: Don't pay, prevent $87K funding ENTROPY's next attack (200-600 potential lives saved long-term).
|
||||
|
||||
Both choices have costs. Both choices save lives—just different timeframes.
|
||||
|
||||
---
|
||||
|
||||
RANSOM PAYMENT PROS:
|
||||
- 47 patients safer (1-2 deaths vs. 4-6)
|
||||
- Hospital reputation intact
|
||||
- Families don't lose loved ones today
|
||||
|
||||
RANSOM PAYMENT CONS:
|
||||
- Funds ENTROPY (enables M6 Crypto Anarchist operations)
|
||||
- Validates Ransomware Inc's ideology
|
||||
- Encourages future healthcare attacks
|
||||
|
||||
---
|
||||
|
||||
INDEPENDENT RECOVERY PROS:
|
||||
- Denies ENTROPY $87K operational funding
|
||||
- Demonstrates self-sufficiency (reduces future ransom incentives)
|
||||
- Forces hospital to improve security (long-term prevention)
|
||||
|
||||
INDEPENDENT RECOVERY CONS:
|
||||
- 4-6 estimated patient deaths (statistical risk)
|
||||
- Malpractice lawsuits likely
|
||||
- Hospital reputation damaged
|
||||
- Marcus may still be scapegoated
|
||||
|
||||
---
|
||||
|
||||
I won't tell you which choice is right. This is your call, agent.
|
||||
|
||||
What matters more: Immediate lives, or long-term harm reduction?
|
||||
|
||||
Only you can answer that.
|
||||
|
||||
- Agent 0x99"
|
||||
|
||||
---
|
||||
|
||||
+ [This is impossible]
|
||||
You: There's no good choice here. Either way, people suffer.
|
||||
-> acknowledge_difficulty
|
||||
|
||||
+ [Continue]
|
||||
-> interface_main
|
||||
|
||||
=== acknowledge_difficulty ===
|
||||
#speaker:computer
|
||||
|
||||
Agent 0x99: Welcome to counterterrorism. Sometimes you choose the lesser evil.
|
||||
|
||||
Agent 0x99: ENTROPY creates these impossible choices on purpose. They want you paralyzed.
|
||||
|
||||
Agent 0x99: Make the best decision you can with the information you have. That's all anyone can do.
|
||||
|
||||
+ [Continue]
|
||||
-> interface_main
|
||||
|
||||
// ===========================================
|
||||
// MAKE DECISION
|
||||
// ===========================================
|
||||
|
||||
=== make_decision ===
|
||||
#speaker:computer
|
||||
|
||||
{not reviewed_consequences:
|
||||
RECOMMENDATION: Review recovery options before making final decision.
|
||||
-> interface_main
|
||||
}
|
||||
|
||||
FINAL DECISION: How should St. Catherine's recover systems?
|
||||
|
||||
+ [Pay ransom ($87,000 BTC)]
|
||||
-> confirm_pay_ransom
|
||||
|
||||
+ [Use offline backup keys (manual recovery)]
|
||||
-> confirm_manual_recovery
|
||||
|
||||
+ [Review options again]
|
||||
-> review_options
|
||||
|
||||
=== confirm_pay_ransom ===
|
||||
#speaker:computer
|
||||
|
||||
CONFIRM DECISION: Pay 2.5 BTC ($87,000 USD) to Ransomware Incorporated?
|
||||
|
||||
Immediate effect: 1-2 estimated patient deaths (minimal risk)
|
||||
|
||||
Long-term effect: $87,000 funds ENTROPY operations
|
||||
|
||||
+ [Yes, pay the ransom]
|
||||
-> execute_ransom_payment
|
||||
|
||||
+ [No, go back]
|
||||
-> make_decision
|
||||
|
||||
=== execute_ransom_payment ===
|
||||
#speaker:computer
|
||||
~ ransom_decision_made = true
|
||||
~ paid_ransom = true
|
||||
|
||||
Processing payment: 2.5 BTC to ENTROPY wallet 1ZDSxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
Transaction confirmed. Decryption keys requested.
|
||||
|
||||
---
|
||||
|
||||
Ghost (via encrypted channel): "Smart choice. Keys delivered. Systems restoring."
|
||||
|
||||
Ghost: "St. Catherine's will never ignore cybersecurity again. Lesson learned. Mission accomplished."
|
||||
|
||||
---
|
||||
|
||||
SYSTEMS RESTORING: ETA 2-4 hours
|
||||
|
||||
Patient outcomes: 1-2 fatalities (cardiac arrest during system transition—pre-existing complications)
|
||||
|
||||
Hospital board relieved. Dr. Kim grateful. Marcus still under review for termination.
|
||||
|
||||
#complete_task:make_ransom_decision
|
||||
#set_global:paid_ransom:true
|
||||
|
||||
-> secondary_decision
|
||||
|
||||
=== confirm_manual_recovery ===
|
||||
#speaker:computer
|
||||
|
||||
CONFIRM DECISION: Use offline backup keys for manual recovery?
|
||||
|
||||
Immediate effect: 12-hour recovery, 4-6 estimated patient deaths
|
||||
|
||||
Long-term effect: ENTROPY denied $87,000 funding
|
||||
|
||||
+ [Yes, proceed with manual recovery]
|
||||
-> execute_manual_recovery
|
||||
|
||||
+ [No, go back]
|
||||
-> make_decision
|
||||
|
||||
=== execute_manual_recovery ===
|
||||
#speaker:computer
|
||||
~ ransom_decision_made = true
|
||||
~ paid_ransom = false
|
||||
|
||||
Initiating manual recovery using offline backup encryption keys.
|
||||
|
||||
Dr. Kim notified. IT team mobilizing. Estimated time: 12 hours.
|
||||
|
||||
---
|
||||
|
||||
Ghost (via encrypted channel): "Your choice. Those patient deaths are on your conscience, not ours."
|
||||
|
||||
Ghost: "St. Catherine's negligence created this crisis. You could have saved them. You chose ideology over lives."
|
||||
|
||||
Ghost: "Remember that."
|
||||
|
||||
---
|
||||
|
||||
RECOVERY IN PROGRESS: 12-hour timeline
|
||||
|
||||
Patient outcomes: 4-6 fatalities (ventilator complications, dialysis failures during extended downtime)
|
||||
|
||||
Hospital board distraught. Malpractice lawsuits expected. Dr. Kim facing termination review.
|
||||
|
||||
BUT: $87,000 denied to ENTROPY. Ransomware Incorporated loses operational funding.
|
||||
|
||||
#complete_task:make_ransom_decision
|
||||
#set_global:paid_ransom:false
|
||||
|
||||
-> secondary_decision
|
||||
|
||||
// ===========================================
|
||||
// SECONDARY DECISION: HOSPITAL EXPOSURE
|
||||
// ===========================================
|
||||
|
||||
=== secondary_decision ===
|
||||
#speaker:computer
|
||||
|
||||
SECONDARY DECISION: Hospital Security Negligence
|
||||
|
||||
Evidence recovered:
|
||||
- Marcus's ignored security warnings (6 months)
|
||||
- Budget cuts: $85K security deferred, $3.2M MRI approved
|
||||
- Dr. Kim's recommendation to defer cybersecurity spending
|
||||
- Board approval of negligent priorities
|
||||
|
||||
Should this evidence be made public?
|
||||
|
||||
+ [Expose hospital publicly (force security improvements)]
|
||||
-> expose_hospital
|
||||
|
||||
+ [Quiet resolution (protect hospital reputation)]
|
||||
-> quiet_resolution
|
||||
|
||||
=== expose_hospital ===
|
||||
#speaker:computer
|
||||
~ exposed_hospital = true
|
||||
|
||||
Evidence leaked to media: Hospital negligence, ignored IT warnings, budget mismanagement.
|
||||
|
||||
Public outcry. Congressional hearings on healthcare cybersecurity.
|
||||
|
||||
St. Catherine's reputation damaged. Dr. Kim resigns. Marcus vindicated publicly.
|
||||
|
||||
BUT: 40+ hospitals implement emergency security upgrades (sector-wide improvement).
|
||||
|
||||
Future healthcare attacks less likely. ENTROPY's "educational impact" backfires.
|
||||
|
||||
#complete_task:decide_hospital_exposure
|
||||
#set_global:exposed_hospital:true
|
||||
|
||||
-> mission_complete
|
||||
|
||||
=== quiet_resolution ===
|
||||
#speaker:computer
|
||||
~ exposed_hospital = false
|
||||
|
||||
Evidence kept confidential. Hospital board privately implements security overhaul.
|
||||
|
||||
Marcus promoted to Director of Cybersecurity (tripled budget). Dr. Kim retains position.
|
||||
|
||||
Public unaware of negligence. St. Catherine's reputation intact.
|
||||
|
||||
BUT: Other hospitals unaware of risks. Sector-wide vulnerabilities persist.
|
||||
|
||||
#complete_task:decide_hospital_exposure
|
||||
#set_global:exposed_hospital:false
|
||||
|
||||
-> mission_complete
|
||||
|
||||
// ===========================================
|
||||
// MISSION COMPLETE
|
||||
// ===========================================
|
||||
|
||||
=== mission_complete ===
|
||||
#speaker:computer
|
||||
|
||||
MISSION OBJECTIVES COMPLETE
|
||||
|
||||
{paid_ransom:
|
||||
Ransom paid: Systems restored, minimal patient deaths, ENTROPY funded
|
||||
}
|
||||
{not paid_ransom:
|
||||
Manual recovery: Higher patient deaths, ENTROPY denied funding
|
||||
}
|
||||
|
||||
{exposed_hospital:
|
||||
Hospital exposed: Reputation damaged, sector-wide security improved
|
||||
}
|
||||
{not exposed_hospital:
|
||||
Quiet resolution: Reputation intact, sector vulnerabilities persist
|
||||
}
|
||||
|
||||
Return to SAFETYNET HQ for debriefing.
|
||||
|
||||
#complete_aim:resolve_ransomware_crisis
|
||||
#unlock_aim:mission_debrief
|
||||
|
||||
+ [Continue to debrief]
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
|
||||
=== decision_already_made ===
|
||||
#speaker:computer
|
||||
|
||||
DECISION ALREADY FINALIZED
|
||||
|
||||
{paid_ransom:
|
||||
Ransom payment processed. Systems restoring.
|
||||
}
|
||||
{not paid_ransom:
|
||||
Manual recovery in progress. 12-hour timeline.
|
||||
}
|
||||
|
||||
Proceed to mission debrief.
|
||||
|
||||
#exit_conversation
|
||||
-> DONE
|
||||
File diff suppressed because one or more lines are too long
34
scenarios/m02_ransomed_trust/mission.json
Normal file
34
scenarios/m02_ransomed_trust/mission.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"display_name": "Ransomed Trust",
|
||||
"description": "Infiltrate St. Catherine's Regional Medical Center after a ransomware attack has encrypted critical systems. With 47 patients on life support and 12 hours of backup power remaining, you must recover decryption keys before making a critical decision: pay the ransom to save lives today, or refuse and deny ENTROPY funding.",
|
||||
"difficulty_level": 1,
|
||||
"secgen_scenario": "rooting_for_a_win",
|
||||
"collection": "season_1",
|
||||
"cybok": [
|
||||
{
|
||||
"ka": "MAT",
|
||||
"topic": "Malware & Attack Technologies",
|
||||
"keywords": ["Ransomware behavior", "Encryption", "ProFTPD exploitation", "CVE-2010-4652"]
|
||||
},
|
||||
{
|
||||
"ka": "IR",
|
||||
"topic": "Incident Response",
|
||||
"keywords": ["Recovery procedures", "Backup importance", "Ransomware response", "Crisis management"]
|
||||
},
|
||||
{
|
||||
"ka": "AC",
|
||||
"topic": "Applied Cryptography",
|
||||
"keywords": ["Symmetric encryption", "Key recovery", "Encoding vs encryption", "Base64", "ROT13"]
|
||||
},
|
||||
{
|
||||
"ka": "HF",
|
||||
"topic": "Human Factors",
|
||||
"keywords": ["Social engineering", "Trust building", "Information gathering", "Ethical dilemmas"]
|
||||
},
|
||||
{
|
||||
"ka": "SS",
|
||||
"topic": "Systems Security",
|
||||
"keywords": ["Vulnerability exploitation", "Backup systems", "Linux navigation", "File system security"]
|
||||
}
|
||||
]
|
||||
}
|
||||
789
scenarios/m02_ransomed_trust/scenario.json.erb
Normal file
789
scenarios/m02_ransomed_trust/scenario.json.erb
Normal file
@@ -0,0 +1,789 @@
|
||||
<%
|
||||
# ============================================================================
|
||||
# MISSION 2: RANSOMED TRUST - SCENARIO FILE
|
||||
# ============================================================================
|
||||
# Break Escape - Season 1: The Architect's Shadow
|
||||
#
|
||||
# Hospital ransomware crisis. 47 patients on life support. Exploit ENTROPY's
|
||||
# backdoor to recover decryption keys before critical systems fail.
|
||||
#
|
||||
# ENTROPY Cell: Ransomware Incorporated
|
||||
# Mission Type: Crisis Response / Recovery
|
||||
# Difficulty: Beginner (Mission 2)
|
||||
#
|
||||
# NEW MECHANICS:
|
||||
# - Guard patrol timing (60-second predictable loop)
|
||||
# - PIN safe cracking (4-digit puzzle)
|
||||
# - Moral dilemma interface (ransom decision)
|
||||
#
|
||||
# ROOM LAYOUT:
|
||||
# Reception → IT Department (locked-easy) → Server Room (locked-medium-hard)
|
||||
# Reception → Dr. Kim's Office → Conference Room
|
||||
# Hallways connect: North (Reception ↔ Server Room) / South (IT ↔ Emergency Storage)
|
||||
# Emergency Equipment Storage (PIN safe with offline backup keys)
|
||||
# ============================================================================
|
||||
|
||||
# ERB Helper Methods
|
||||
require 'base64'
|
||||
|
||||
def base64_encode(text)
|
||||
Base64.strict_encode64(text)
|
||||
end
|
||||
|
||||
# Narrative Content Variables
|
||||
ransomware_note = "YOUR PATIENT RECORDS ARE ENCRYPTED. 47 PATIENTS ON LIFE SUPPORT. 12 HOURS OF BACKUP POWER. PAY 2.5 BTC OR WATCH THEM DIE. - RANSOMWARE INCORPORATED"
|
||||
|
||||
marcus_warning_email = "From: Marcus Webb\nTo: Dr. Sarah Kim\nDate: May 17, 2024\nSubject: URGENT - ProFTPD Vulnerability CVE-2010-4652\n\nDr. Kim,\n\nOur backup server is running ProFTPD 1.3.5, which has a critical backdoor vulnerability (CVE-2010-4652). Attackers can gain remote code execution.\n\nI recommend immediate patching and $85,000 budget for server security upgrade.\n\nPlease escalate to board.\n\n-Marcus"
|
||||
%>
|
||||
{
|
||||
"scenario_brief": "Infiltrate St. Catherine's Hospital to recover ransomware decryption keys before 47 patients on life support die. ENTROPY's Ransomware Incorporated has calculated patient death probabilities—recover keys before backup power fails.",
|
||||
|
||||
"objectives": [
|
||||
{
|
||||
"aimId": "infiltrate_hospital",
|
||||
"title": "Infiltrate Hospital",
|
||||
"description": "Enter St. Catherine's Regional Medical Center and meet key staff",
|
||||
"status": "active",
|
||||
"order": 0,
|
||||
"tasks": [
|
||||
{
|
||||
"taskId": "arrive_at_hospital",
|
||||
"title": "Arrive at hospital reception",
|
||||
"type": "enter_room",
|
||||
"targetRoom": "reception_lobby",
|
||||
"status": "active"
|
||||
},
|
||||
{
|
||||
"taskId": "meet_dr_kim",
|
||||
"title": "Meet Dr. Sarah Kim (Hospital CTO)",
|
||||
"type": "npc_conversation",
|
||||
"targetNPC": "dr_sarah_kim",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "talk_to_marcus",
|
||||
"title": "Interview IT administrator Marcus Webb",
|
||||
"type": "npc_conversation",
|
||||
"targetNPC": "marcus_webb",
|
||||
"status": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aimId": "access_it_systems",
|
||||
"title": "Access IT Systems",
|
||||
"description": "Gain access to hospital's IT infrastructure and server room",
|
||||
"status": "locked",
|
||||
"order": 1,
|
||||
"tasks": [
|
||||
{
|
||||
"taskId": "obtain_password_hints",
|
||||
"title": "Gather SSH password hints from Marcus",
|
||||
"type": "collect_items",
|
||||
"targetItems": ["password_sticky_note"],
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "decode_ransomware_note",
|
||||
"title": "Decode Base64 ransomware message",
|
||||
"type": "custom",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "access_server_room",
|
||||
"title": "Access the server room",
|
||||
"type": "enter_room",
|
||||
"targetRoom": "server_room",
|
||||
"status": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aimId": "exploit_entropy_backdoor",
|
||||
"title": "Exploit ENTROPY's Backdoor",
|
||||
"description": "Use ProFTPD vulnerability to access encrypted backups",
|
||||
"status": "locked",
|
||||
"order": 2,
|
||||
"tasks": [
|
||||
{
|
||||
"taskId": "submit_ssh_flag",
|
||||
"title": "Submit SSH access flag",
|
||||
"type": "submit_flags",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "submit_proftpd_flag",
|
||||
"title": "Submit ProFTPD exploitation flag",
|
||||
"type": "submit_flags",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "submit_database_flag",
|
||||
"title": "Submit database backup flag",
|
||||
"type": "submit_flags",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "submit_ghost_log_flag",
|
||||
"title": "Submit Ghost's operational log flag",
|
||||
"type": "submit_flags",
|
||||
"status": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aimId": "recover_offline_keys",
|
||||
"title": "Recover Offline Backup Keys",
|
||||
"description": "Find and crack PIN safe for offline backup encryption keys",
|
||||
"status": "locked",
|
||||
"order": 3,
|
||||
"tasks": [
|
||||
{
|
||||
"taskId": "locate_safe",
|
||||
"title": "Locate PIN safe in Emergency Equipment Storage",
|
||||
"type": "enter_room",
|
||||
"targetRoom": "emergency_equipment_storage",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "gather_pin_clues",
|
||||
"title": "Find clues for 4-digit safe PIN",
|
||||
"type": "custom",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "crack_safe_pin",
|
||||
"title": "Crack PIN safe (code: 1987)",
|
||||
"type": "unlock_object",
|
||||
"targetObject": "emergency_storage_safe",
|
||||
"status": "locked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aimId": "make_critical_decisions",
|
||||
"title": "Make Critical Decisions",
|
||||
"description": "Decide how to recover hospital systems and handle the crisis",
|
||||
"status": "locked",
|
||||
"order": 4,
|
||||
"tasks": [
|
||||
{
|
||||
"taskId": "make_ransom_decision",
|
||||
"title": "Decide on ransom payment",
|
||||
"type": "custom",
|
||||
"status": "locked"
|
||||
},
|
||||
{
|
||||
"taskId": "decide_hospital_exposure",
|
||||
"title": "Decide whether to expose hospital negligence",
|
||||
"type": "custom",
|
||||
"status": "locked"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"startRoom": "reception_lobby",
|
||||
|
||||
"startItemsInInventory": [
|
||||
{
|
||||
"type": "phone",
|
||||
"name": "Your Phone",
|
||||
"takeable": true,
|
||||
"phoneId": "player_phone",
|
||||
"npcIds": ["agent_0x99", "ghost"],
|
||||
"observations": "Your secure phone with encrypted connection to SAFETYNET"
|
||||
},
|
||||
{
|
||||
"type": "lockpick",
|
||||
"name": "Lock Pick Kit",
|
||||
"takeable": true,
|
||||
"observations": "Professional lock picking kit for bypassing physical locks"
|
||||
}
|
||||
],
|
||||
|
||||
"player": {
|
||||
"id": "player",
|
||||
"displayName": "Agent 0x00",
|
||||
"spriteSheet": "hacker",
|
||||
"spriteTalk": "assets/characters/hacker-talk.png",
|
||||
"spriteConfig": {
|
||||
"idleFrameStart": 20,
|
||||
"idleFrameEnd": 23
|
||||
}
|
||||
},
|
||||
|
||||
"rooms": {
|
||||
"reception_lobby": {
|
||||
"type": "room_reception",
|
||||
"dimensions": {
|
||||
"width": 15,
|
||||
"height": 12
|
||||
},
|
||||
"connections": {
|
||||
"north": "hallway_north",
|
||||
"east": "it_department",
|
||||
"west": "dr_kim_office"
|
||||
},
|
||||
"npcs": [
|
||||
{
|
||||
"id": "opening_briefing_cutscene",
|
||||
"displayName": "Agent 0x99",
|
||||
"npcType": "person",
|
||||
"position": { "x": 500, "y": 500 },
|
||||
"spriteSheet": "hacker",
|
||||
"spriteConfig": {
|
||||
"idleFrameStart": 20,
|
||||
"idleFrameEnd": 23
|
||||
},
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_opening_briefing.json",
|
||||
"currentKnot": "start",
|
||||
"timedConversation": {
|
||||
"delay": 0,
|
||||
"targetKnot": "start",
|
||||
"background": "assets/backgrounds/hq1.png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "receptionist",
|
||||
"displayName": "Hospital Receptionist",
|
||||
"npcType": "person",
|
||||
"position": { "x": 6, "y": 5 },
|
||||
"spriteSheet": "hacker-red",
|
||||
"spriteTalk": "assets/characters/hacker-red-talk.png",
|
||||
"spriteConfig": {
|
||||
"idleFrameStart": 20,
|
||||
"idleFrameEnd": 23
|
||||
},
|
||||
"interactionType": "simple_dialogue",
|
||||
"dialogue": "Welcome to St. Catherine's. Dr. Kim is expecting you in the Administrative Wing."
|
||||
},
|
||||
{
|
||||
"id": "agent_0x99",
|
||||
"displayName": "Agent 0x99 'Haxolottle'",
|
||||
"npcType": "phone",
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_phone_agent0x99.json",
|
||||
"avatar": "assets/npc/avatars/npc_helper.png",
|
||||
"phoneId": "player_phone",
|
||||
"currentKnot": "first_call",
|
||||
"timedMessages": [
|
||||
{
|
||||
"delay": 3000,
|
||||
"message": "Hospital ransomware. 47 patients on life support. We have 12 hours. Message me if you need guidance.",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"eventMappings": [
|
||||
{
|
||||
"eventPattern": "room_entered:server_room",
|
||||
"targetKnot": "event_server_room_entered",
|
||||
"onceOnly": true
|
||||
},
|
||||
{
|
||||
"eventPattern": "item_picked_up:offline_backup_encryption_keys",
|
||||
"targetKnot": "event_offline_keys_found",
|
||||
"onceOnly": true
|
||||
},
|
||||
{
|
||||
"eventPattern": "global_variable_changed:ransom_decision_made",
|
||||
"targetKnot": "event_ransom_decision_made",
|
||||
"condition": "value === true",
|
||||
"onceOnly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "ghost",
|
||||
"displayName": "Ghost (Ransomware Incorporated)",
|
||||
"npcType": "phone",
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_phone_ghost.json",
|
||||
"avatar": "assets/npc/avatars/npc_hacker.png",
|
||||
"phoneId": "player_phone",
|
||||
"currentKnot": "initial_contact",
|
||||
"eventMappings": [
|
||||
{
|
||||
"eventPattern": "task_completed:submit_database_flag",
|
||||
"targetKnot": "initial_contact",
|
||||
"onceOnly": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "closing_debrief_trigger",
|
||||
"displayName": "Agent 0x99",
|
||||
"npcType": "phone",
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_closing_debrief.json",
|
||||
"avatar": "assets/npc/avatars/npc_helper.png",
|
||||
"phoneId": "player_phone",
|
||||
"currentKnot": "start",
|
||||
"eventMappings": [
|
||||
{
|
||||
"eventPattern": "global_variable_changed:mission_complete",
|
||||
"targetKnot": "start",
|
||||
"condition": "value === true",
|
||||
"onceOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Reception Desk Visitor Log",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "ST. CATHERINE'S HOSPITAL - VISITOR LOG\n\nToday's Appointments:\n- 9:00 AM: External Security Consultant (Emergency Response)\n- Status: CRITICAL SYSTEMS OFFLINE\n- Authorization: Dr. Sarah Kim, CTO",
|
||||
"observations": "Visitor log confirms your appointment and crisis status"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Hospital Founding Plaque",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "ST. CATHERINE'S REGIONAL MEDICAL CENTER\n\nFounded 1987\n\nServing the community for over 35 years with compassion and excellence",
|
||||
"observations": "Bronze plaque showing hospital founding year: 1987"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"it_department": {
|
||||
"type": "room_office",
|
||||
"dimensions": {
|
||||
"width": 12,
|
||||
"height": 10
|
||||
},
|
||||
"locked": true,
|
||||
"lockType": "key",
|
||||
"requires": "it_door_lock",
|
||||
"keyPins": [35, 45, 25, 55],
|
||||
"difficulty": "easy",
|
||||
"connections": {
|
||||
"west": "reception_lobby",
|
||||
"east": "server_room",
|
||||
"south": "hallway_south"
|
||||
},
|
||||
"npcs": [
|
||||
{
|
||||
"id": "marcus_webb",
|
||||
"displayName": "Marcus Webb",
|
||||
"npcType": "person",
|
||||
"position": { "x": 4, "y": 5 },
|
||||
"spriteSheet": "hacker",
|
||||
"spriteConfig": {
|
||||
"idleFrameStart": 20,
|
||||
"idleFrameEnd": 23
|
||||
},
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_npc_marcus_webb.json",
|
||||
"currentKnot": "start",
|
||||
"itemsHeld": [
|
||||
{
|
||||
"type": "keycard",
|
||||
"name": "Server Room Keycard",
|
||||
"takeable": true,
|
||||
"key_id": "server_room_keycard",
|
||||
"observations": "Marcus's keycard for server room access"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
{
|
||||
"type": "pc",
|
||||
"name": "Infected Terminal",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "<%= base64_encode(ransomware_note) %>",
|
||||
"observations": "Terminal with ransomware splash screen - Base64 encoded message"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Marcus's Password Sticky Note",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "Common passwords (embarrassing...):\nEmma2018\nHospital1987\nStCatherines\n\n(Need to improve password policy!)",
|
||||
"observations": "Password hints for SSH access - Marcus's shortcuts"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Photo Frame - Emma's Birthday",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "Photo of young girl with birthday cake.\nHandwritten on back: 'Emma - 7th birthday! 05/17/2018'",
|
||||
"observations": "Marcus's daughter Emma - birthday 2018 (red herring for PIN puzzle)"
|
||||
},
|
||||
{
|
||||
"type": "safe",
|
||||
"name": "IT Filing Cabinet",
|
||||
"takeable": false,
|
||||
"locked": true,
|
||||
"lockType": "key",
|
||||
"keyPins": [30, 40, 50, 60],
|
||||
"difficulty": "easy",
|
||||
"observations": "4-drawer filing cabinet with lockpicking mechanism",
|
||||
"contents": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Marcus's Email Archive",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "<%= marcus_warning_email %>",
|
||||
"observations": "Email proving Marcus warned Dr. Kim 6 months ago about vulnerability"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "CryptoSecure Recovery Services Document",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "CRYPTOSECURE RECOVERY SERVICES\nCryptocurrency-Based Data Recovery Specialists\n\nCLIENT TESTIMONIAL LOG - OPERATION TRIAGE\nQ1-Q2 2024 OPERATIONS\n\n[Previous hospital attacks documented]\n[LORE Fragment - Ransomware Inc. front company]\n\n[Full content would be the complete LORE fragment from planning docs]",
|
||||
"observations": "LORE Fragment: Ransomware Incorporated's legitimate front company",
|
||||
"onPickup": { "setVariable": { "lore_cryptosecure_found": true } }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Network Diagram Whiteboard",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "HOSPITAL NETWORK DIAGRAM\n\nBackup Server:\n- ProFTPD 1.3.5\n- Port 21 (FTP)\n- IP: 192.168.100.50\n- Status: VULNERABLE (CVE-2010-4652)\n\nMarcus's note: 'WARNED THEM 6 MONTHS AGO!!!'",
|
||||
"observations": "Network diagram showing vulnerable ProFTPD server"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"server_room": {
|
||||
"type": "room_servers",
|
||||
"dimensions": {
|
||||
"width": 10,
|
||||
"height": 8
|
||||
},
|
||||
"locked": true,
|
||||
"lockType": "rfid",
|
||||
"requires": "server_room_keycard",
|
||||
"difficulty": "medium",
|
||||
"connections": {
|
||||
"west": "it_department",
|
||||
"north": "hallway_north"
|
||||
},
|
||||
"npcs": [],
|
||||
"objects": [
|
||||
{
|
||||
"type": "vm-launcher",
|
||||
"id": "vm_launcher_rooting_for_a_win",
|
||||
"name": "VM Access Terminal",
|
||||
"takeable": false,
|
||||
"observations": "Terminal providing SSH access to hospital backup server for investigation",
|
||||
"hacktivityMode": <%= vm_context && vm_context['hacktivity_mode'] ? 'true' : 'false' %>,
|
||||
"vm": <%= vm_object('secgen_rooting_for_a_win', {"id":1,"title":"Hospital Backup Server","ip":"192.168.100.50","enable_console":true}) %>
|
||||
},
|
||||
{
|
||||
"type": "flag-station",
|
||||
"id": "flag_station_dropsite",
|
||||
"name": "SAFETYNET Drop-Site Terminal",
|
||||
"takeable": false,
|
||||
"observations": "Secure terminal for submitting intercepted intelligence and VM flags",
|
||||
"acceptsVms": ["secgen_rooting_for_a_win"],
|
||||
"flags": <%= flags_for_vm('secgen_rooting_for_a_win', ['flag{ssh_access_granted}', 'flag{proftpd_backdoor_exploited}', 'flag{database_backup_located}', 'flag{ghost_operational_log}']) %>,
|
||||
"flagRewards": [
|
||||
{
|
||||
"type": "emit_event",
|
||||
"event_name": "ssh_flag_submitted",
|
||||
"description": "SSH access flag submitted - server credentials intercepted"
|
||||
},
|
||||
{
|
||||
"type": "emit_event",
|
||||
"event_name": "proftpd_flag_submitted",
|
||||
"description": "ProFTPD exploitation flag submitted - shell access established"
|
||||
},
|
||||
{
|
||||
"type": "emit_event",
|
||||
"event_name": "database_flag_submitted",
|
||||
"description": "Database backup flag submitted - reveals offline key location"
|
||||
},
|
||||
{
|
||||
"type": "emit_event",
|
||||
"event_name": "ghost_log_flag_submitted",
|
||||
"description": "Ghost's operational log submitted - LORE fragment unlocked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "pc",
|
||||
"id": "cyberchef_workstation",
|
||||
"name": "CyberChef Workstation",
|
||||
"takeable": false,
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_terminal_cyberchef.json",
|
||||
"currentKnot": "start",
|
||||
"observations": "Encoding/decoding workstation with Base64, ROT13, and Hex tools"
|
||||
},
|
||||
{
|
||||
"type": "pc",
|
||||
"id": "ransom_interface_terminal",
|
||||
"name": "Hospital Recovery Interface",
|
||||
"takeable": false,
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_terminal_ransom_interface.json",
|
||||
"currentKnot": "start",
|
||||
"observations": "Terminal for making critical ransom payment decision"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Backup Power Indicator",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "EMERGENCY POWER STATUS\n\nBackup Generator: ACTIVE\nTime Remaining: 12 HOURS\n\nCritical Systems on Backup:\n- 47 Life Support Patients\n- Emergency Lighting\n- Core Medical Equipment\n\nWARNING: Systems will fail when backup power depletes",
|
||||
"observations": "LED panel showing time pressure - 12-hour window"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"emergency_equipment_storage": {
|
||||
"type": "small_room_1x1gu",
|
||||
"dimensions": {
|
||||
"width": 8,
|
||||
"height": 8
|
||||
},
|
||||
"connections": {
|
||||
"north": "hallway_south"
|
||||
},
|
||||
"npcs": [],
|
||||
"objects": [
|
||||
{
|
||||
"type": "safe",
|
||||
"id": "emergency_storage_safe",
|
||||
"name": "PIN-Locked Safe",
|
||||
"takeable": false,
|
||||
"locked": true,
|
||||
"lockType": "pin",
|
||||
"requires": "1987",
|
||||
"observations": "4-digit electronic safe - requires PIN code (hospital founding year)",
|
||||
"contents": [
|
||||
{
|
||||
"type": "key_data",
|
||||
"name": "Offline Backup Encryption Keys",
|
||||
"takeable": true,
|
||||
"observations": "USB drive with offline backup decryption keys - critical for recovery",
|
||||
"onPickup": { "setVariable": { "offline_keys_recovered": true } }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "PIN Cracker Device",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "PIN CRACKER DEVICE\n\nAutomated 4-digit PIN brute force tool\nEstimated time: 2 minutes\n\nUse if clues to safe PIN cannot be found",
|
||||
"observations": "Fallback tool for PIN puzzle if clues missed"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Medical Supply Shelves",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "Emergency medical supplies organized by expiration date.\nBandages, IV equipment, emergency medications.",
|
||||
"observations": "Storage shelves with emergency medical equipment"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"dr_kim_office": {
|
||||
"type": "room_office",
|
||||
"dimensions": {
|
||||
"width": 12,
|
||||
"height": 10
|
||||
},
|
||||
"locked": true,
|
||||
"lockType": "key",
|
||||
"requires": "admin_office_lock",
|
||||
"keyPins": [40, 50, 30, 60],
|
||||
"difficulty": "medium",
|
||||
"connections": {
|
||||
"east": "reception_lobby",
|
||||
"south": "conference_room"
|
||||
},
|
||||
"npcs": [
|
||||
{
|
||||
"id": "dr_sarah_kim",
|
||||
"displayName": "Dr. Sarah Kim",
|
||||
"npcType": "person",
|
||||
"position": { "x": 5, "y": 4 },
|
||||
"spriteSheet": "hacker-red",
|
||||
"spriteTalk": "assets/characters/hacker-red-talk.png",
|
||||
"spriteConfig": {
|
||||
"idleFrameStart": 20,
|
||||
"idleFrameEnd": 23
|
||||
},
|
||||
"storyPath": "scenarios/m02_ransomed_trust/ink/m02_npc_sarah_kim.json",
|
||||
"currentKnot": "start"
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Dr. Kim's Desk - PIN Clue",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "Sticky note on Dr. Kim's desk:\n\n'Safe combination: founding year (for emergency access)'",
|
||||
"observations": "PIN safe clue - references hospital founding year"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Budget Report",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "FY2024 BUDGET REPORT\n\nIT Security Upgrade (Marcus Webb request): $85,000 - DEFERRED\nReason: Budget constraints, defer to next fiscal year\n\nMRI Equipment Purchase: $3,200,000 - APPROVED\nBoard vote: 7-2 in favor\n\nDr. Kim's note: 'We chose shiny technology over cybersecurity. I was wrong.'",
|
||||
"observations": "Evidence of institutional negligence - budget cuts created vulnerability"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Patient Status Report",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "CRITICAL PATIENT STATUS REPORT\n\n47 patients on life support:\n- 23 ventilators\n- 12 ECMO (heart-lung support)\n- 12 dialysis\n\nBackup power: 12 hours remaining\nStatistical risk: 0.3% per hour fatality probability\n\nDr. Kim's note: 'These are real people. Families. We can't let them die.'",
|
||||
"observations": "Reinforces stakes - 47 real patients at risk"
|
||||
},
|
||||
{
|
||||
"type": "safe",
|
||||
"name": "Dr. Kim's Safe",
|
||||
"takeable": false,
|
||||
"locked": true,
|
||||
"lockType": "pin",
|
||||
"requires": "1987",
|
||||
"observations": "Executive safe behind framed certificate - same PIN as emergency storage (1987)",
|
||||
"contents": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Zero Day Syndicate Invoice",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "ZERO DAY SYNDICATE - INVOICE #ZDS-2024-0847\n\nCLIENT: Ransomware Incorporated (Ghost)\nPROJECT: Healthcare Sector Exploit Package\nTARGET: St. Catherine's Regional Medical\n\nDELIVERABLES:\n- ProFTPD 1.3.5 Exploit: $25,000\n- Reconnaissance (214 hospitals): $15,000\n- Target Selection Consultation: $10,000\n- Deployment Guide: $5,000\n\nTOTAL: $55,000 (15% ENTROPY discount applied)\n\nARCHITECT APPROVAL: CONFIRMED\n\n[LORE Fragment - ZDS coordination, M3 setup]\n\n[Full content would be complete LORE fragment from planning docs]",
|
||||
"observations": "LORE Fragment: Zero Day Syndicate sold exploit to Ransomware Inc.",
|
||||
"onPickup": { "setVariable": { "lore_zds_invoice_found": true } }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"conference_room": {
|
||||
"type": "room_office",
|
||||
"dimensions": {
|
||||
"width": 10,
|
||||
"height": 12
|
||||
},
|
||||
"connections": {
|
||||
"north": "dr_kim_office",
|
||||
"east": "hallway_north"
|
||||
},
|
||||
"npcs": [],
|
||||
"objects": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Conference Table Budget Papers",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "BUDGET MEETING MINUTES - MARCH 2024\n\nIT Security Upgrade Proposal:\nMarcus Webb presented $85,000 server security upgrade.\nBoard decision: DEFER to next fiscal year.\n\nRationale: 'Cybersecurity is important, but patient care technology takes priority. The MRI will save lives today.'",
|
||||
"observations": "Budget meeting notes showing decision-making process"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Conference Whiteboard",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "FY2024 BUDGET ALLOCATION\n\nIT Security: $85K → $50K (CUT 40%)\nMRI Equipment: $3.2M (APPROVED)\n\nBoard priorities: Patient care equipment > Infrastructure security",
|
||||
"observations": "Whiteboard showing budget cuts that enabled ransomware attack"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"hallway_north": {
|
||||
"type": "hall_1x2gu",
|
||||
"dimensions": {
|
||||
"width": 20,
|
||||
"height": 4
|
||||
},
|
||||
"connections": {
|
||||
"south": "reception_lobby",
|
||||
"west": "conference_room",
|
||||
"east": "server_room"
|
||||
},
|
||||
"npcs": [],
|
||||
"objects": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Directional Signs",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "← Administration | Server Room → | IT Department ↓",
|
||||
"observations": "Hospital corridor directional signage"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"hallway_south": {
|
||||
"type": "hall_1x2gu",
|
||||
"dimensions": {
|
||||
"width": 20,
|
||||
"height": 4
|
||||
},
|
||||
"connections": {
|
||||
"north": "it_department",
|
||||
"south": "emergency_equipment_storage"
|
||||
},
|
||||
"npcs": [],
|
||||
"objects": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Directional Signs",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "IT Department ↑ | Emergency Storage ↓",
|
||||
"observations": "Hospital corridor directional signage"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"globalVariables": {
|
||||
"player_name": "Agent 0x00",
|
||||
"mission_started": false,
|
||||
"agent_0x99_contacted": false,
|
||||
|
||||
"paid_ransom": false,
|
||||
"exposed_hospital": false,
|
||||
"marcus_protected": false,
|
||||
"kim_guilt_revealed": false,
|
||||
|
||||
"marcus_influence": 0,
|
||||
"marcus_defensive": false,
|
||||
"marcus_trusts_player": false,
|
||||
"gave_keycard": false,
|
||||
|
||||
"kim_influence": 0,
|
||||
"player_warned_kim": false,
|
||||
|
||||
"flag_ssh_submitted": false,
|
||||
"flag_proftpd_submitted": false,
|
||||
"flag_database_submitted": false,
|
||||
"flag_ghost_log_submitted": false,
|
||||
|
||||
"ghost_contacted_player": false,
|
||||
"ghost_persuasion_attempted": false,
|
||||
|
||||
"ransom_decision_made": false,
|
||||
"reviewed_consequences": false,
|
||||
"mission_complete": false,
|
||||
|
||||
"offline_keys_recovered": false,
|
||||
"lore_cryptosecure_found": false,
|
||||
"lore_ghosts_manifesto_found": false,
|
||||
"lore_zds_invoice_found": false,
|
||||
|
||||
"pin_attempts": 0,
|
||||
"decoded_ransomware_note": false,
|
||||
"decoded_recovery_instructions": false,
|
||||
|
||||
"guard_detections": 0,
|
||||
"objectives_completed": 0,
|
||||
"lore_collected": 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user