<h1>Introduction</h1> <p class="s_direction"> The play begins with a vibrant digital event. The audience is welcomed and encouraged to create their avatars by answering a series of seemingly harmless personal questions. </p> <p class="speech"><b>Luddite:</b> "Welcome to Cyber Play, where your digital skills will determine the outcome of today’s mystery. I’m Mr. Jonathan Luddite, your guide through this journey."</p> <p class="speech"><b>Emma Smith:</b> "Hi, I’m Emma Smith. Together, we’ll help you navigate the twists and turns. But before we start, let’s get to know you a little better!"</p> <p class="speech"><b>Luddite:</b> "That’s right! To begin, we need to create your avatar. Let’s get started with a few simple questions."</p> <p class = "link">[[Avatar Creation]]</p> <h1>Avatar Creation: Name</h1> <p class="speech"><b>Mr. Jonathan Luddite:</b> "Let's start simple. What's your name?"</p> { <!-- Input box for the user's name --> (input-box: bind $userName) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userName is not "")[ (set: $suspect7Name to $userName) <!-- Store the name in suspect7Name variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter your name.") ] ] } { |nextLink)[[[Continue to Date of Birth->Date of Birth]]] } <h1>Siren and Task Force Arrival</h1> <div style="display: flex; justify-content: center; align-items: center;"> <video class="siren" id="sirenVideo" width="560" height="315" controls autoplay> <source src="https://video.wixstatic.com/video/27b368_91943f947fa847ce8dfe7069aef467c1/1080p/mp4/file.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> <p class="s_direction">(The siren wails, deafening. For a moment, the entire hall freezes. Silence follows, heavy and thick, before the doors swing open. Figures in black uniforms rush in. The Task Force has arrived.)</p> [[Continue ->Siren2]] (display: "SidebarBack") <h1>Task Force Arrival</h1> <!-- Scene Description --> <p class="s_direction">(Several figures dressed in black storm in from the sides of the stage. They are the <b>Task Force</b>, and they begin locking down the hall.)</p> <!-- Task Force Leader Dialogue --> <p class="speech"><b>Task Force Leader</b> (yelling): "Security breach detected! We need to investigate this now!"</p> <!-- Task Force Setting Up --> <p class="speech"><b>Task Force Member 1</b> (setting up equipment): "Start the data tracking systems. We need to log every activity and capture any unauthorized access!"</p> <p class="speech"><b>Task Force Member 2</b> (to colleagues): "Make sure the surveillance cameras are operational. We need to review all footage for any suspicious behavior."</p> <p class="speech"><b>Task Force Member 3</b> (into radio): "Lockdown the building's network access. We can't afford any more data leaks while we investigate!"</p> <!-- Actors’ Interaction --> <p class="s_direction">(Actors begin to move off stage but <b>Task Force</b> shouts)</p> <p>[[NOBODY MOVE]]</p> (display: "SidebarBack")<!-- Main content area --> <h1>NOBODY MOVE</h1> <img src="https://static.wixstatic.com/media/27b368_ce58dfc395174722ae407b469e0c3289~mv2.gif" alt="Task Force"> <p>[[The Briefing]]</p> (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable for "EVERYONE" to true --> (set: $suspect8_found to true) (set: $suspectsFound to $suspectsFound + 1) <h1>The Briefing</h1> <p class="s_direction"> The room suddenly falls silent as the Task Force leader steps forward, the door sealing shut behind them with an audible click. The leader's voice is stern, echoing slightly in the now tense atmosphere. </p> <p class="speech"><b>Task Force Leader:</b> "Attention, everyone. As of this moment, this room is under complete lockdown. No one is permitted to leave without Task Force supervision. We have reason to believe that the perpetrator of the cyber crimes we are investigating is right here among us."</p> <p class="s_direction"> The leader pauses, letting the weight of their words sink in before continuing. </p> [[Continue->Briefing 2]] (display: "Sidebar") (display: "SidebarBack") <h1>Investigation Overview</h1> <!-- Main Content --> <p class="s_direction">The task force leader steps up with a grave look. "We need a status update. What do we know so far?"</p> <p class="speech">Another member responds, "It was definitely a cyber attack. Our initial findings show that the attacker has made off with all the data collected during the avatar creation phase. We've identified some leads but deciding where to start is tricky."</p> <p class="s_direction">"What's our first move, team?"</p> <!-- Link to next passage --> <p>[[View Options]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>View Options</h1> <!-- Content Sections --> <div id="content"> <p class="speech" id="text1" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 1;">Based on the preliminary alerts and system anomalies we've observed, we have three potential paths to consider for our next move. Each path could help us unravel the mystery behind the suspected cyber breach. Let’s review our options:</p> <p class="speech" id="text2" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;">There’s been a notable increase in email traffic containing suspicious links. Investigating these could reveal whether we’re dealing with a targeted phishing campaign aimed at our personnel.</p> <p class="speech" id="text3" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;">Next, the Network Traffic Analysis. Our systems have flagged several unusual network activities that could indicate unauthorized data access or exfiltration. Diving into these logs might help us catch a glimpse of the intruder’s methods.</p> <p class="speech" id="text4" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;">Lastly, the Malware Branch. Recent scans detected anomalies in system behavior that could be due to unauthorized software or malware. Pinpointing and analyzing this could be crucial to understanding the scope of the threat.</p> <p class="speech" id="text5" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;">Each path holds vital clues but requires careful consideration. Which should we prioritize?</p> <p class="speech" id="text6" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 1; display: none;">"After making your choice, we’ll focus our resources accordingly. Your input is invaluable here, let's decide wisely."<br></p> </div> { <!-- "Click for next..." similar to "Meet the Individuals" --> <div class="instruction" id="clickForNext">Click for next...</div> <!-- Clickable area to trigger content change --> <div id="clickableArea" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; cursor: pointer;"></div> <!-- Vote link, hidden initially --> <p id="voteLink" style="display: none;">[[Decsion Point->Vote]]</p> } (display: "Sidebar") (display: "SidebarBack") <script> let currentText = 1; // Start with the first paragraph document.getElementById('clickableArea').addEventListener('click', function() { if (currentText <= 6) { // Ensure we stop before the last text // Hide the current paragraph document.getElementById(`text${currentText}`).style.display = 'none'; // Show the next paragraph currentText++; if (currentText <= 6) { document.getElementById(`text${currentText}`).style.display = 'block'; document.getElementById(`text${currentText}`).style.zIndex = '1'; // Ensure it's on top // Hide the instruction after the last click if (currentText === 6) { document.getElementById('clickForNext').style.display = 'none'; // Hide "Click for next..." document.getElementById('voteLink').style.display = 'block'; // Show the vote link } } } }); // Initially display the first paragraph document.getElementById('text1').style.display = 'block'; </script> <style> /* Add matching styling for "Click for next..." */ .instruction { text-align: center; margin-top: 20px; color: #d4c5a6; /* Matching text color */ font-style: italic; } </style> <!-- Title --> <h1>Decision Point</h1> <!-- Introduction Text --> <p class="s_direction">The task force leader outlines three key areas of concern. Which should we tackle first?</p> <!-- Image with reduced bottom margin --> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <!-- Centered options with reduced spacing --> <div style="display: flex; flex-direction: column; align-items: center; margin-top: 10px;"> <p class="s_direction" style="margin: 5px 0;">{ (if: $phishing_completed is not true)[ [[Investigate Phishing Threats->Phishing Branch]] ] (else:)[ <span>You’ve already investigated the Phishing Threats.</span> ] }</p> <p class="s_direction" style="margin: 5px 0;">{ (if: $dataTransferStopped is true)[ <span>The data transfer was successfully stopped. This path is now complete.</span> ] (else-if: $dataTransferFailed is true)[ <span>The data transfer was completed, and this path is now locked.</span> ] (else-if: $network_traffic_completed is not true)[ [[Analyse Network Traffic->Network Traffic Branch]] ] (else:)[ <span>You’ve already analyzed the Network Traffic.</span> ] }</p> <p class="s_direction" style="margin: 5px 0;">{ (if: $malware_completed is not true)[ [[Examine Potential Malware->Malware Branch]] ] (else:)[ <span>You’ve already examined the Malware Threats.</span> ] }</p> </div> (display: "Sidebar") (display: "SidebarBack") <h1>Suspicious Email Investigation</h1> <p class="speech">The task force leader steps forward, holding up a printout of a suspicious email.</p> <p class="speech">"We’ve uncovered some emails that were sent to key staff members just before the breach. These emails look like they came from our school’s admin team, but there’s something not right about them. They’re designed to trick the recipient into clicking on a link or giving away their login information."</p> <p class="speech">The task force member gestures to the email.</p> [[Take a closer look at this one]] (display: "Sidebar") (display: "SidebarBack") <h1>Network Traffic Analysis</h1> <p class="speech"><b>Task Force Leader:</b> "Alright team, let's start by looking at the network traffic flow. We need to identify any unusual patterns, spikes in data usage, or suspicious connections. Standard protocol."</p> <p>[[Continue->Thomas Reed Insight]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Introduction to Malware</h1> <p class="speech"><b>Task Force Leader:</b> "Before we dive into this malware investigation, before we see what we can do with this file...let’s take a step back and make sure we’re all on the same page."</p> <p class="speech"><b>Task Force Member:</b> "Good idea. Malware is a pretty big topic, so we want to know what you already understand."</p> <p class="speech"><b>Task Force Leader:</b> "We’ll start with a simple question: <strong></p> <p class = "question">What is Malware?</p> <p class = "question">What types of Malware do you already know about?</p> <p class="speech"><b>Task Force Member:</b> "Head over to the link on your screen and share your thoughts. We’re looking for words or phrases that come to mind when you hear the term ‘malware.’"</p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" alt="Malware Illustration" style="max-width: 100%; height: auto;"> <p>[[Continue->Wait for Audience Response]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Investigate Email Links</h1> { <div class="email-container"> <!-- Simulating an email client interface --> <div class="email-header-bar"> <p class="email-header-title">New Message</p> </div> <div class="email-content"> <!-- Email headers section --> <div class="email-headers"> <p><strong>From:</strong> <span class="suspicious-sender">admin@schooltech.co.uk</span></p> <!-- Hint at suspicious sender --> <p><strong>To:</strong> staff@school.ac.uk</p> <p><strong>Subject:</strong> Important Update: Action Required</p> </div> <!-- Email body section --> <div class="email-body"> <p>Hello [Recipient Name],</p> <p>Due to recent security updates, we require all staff to verify their account credentials. This is a mandatory procedure to ensure that our systems are up to date and secure.</p> <p>Please click on the link below and follow the instructions to update your information:</p> <!-- Suspicious link with subtle styling to suggest it's risky --> <p><a href="javascript:void(0);" class="email-link" id="emailLink" style="color: red; text-decoration: underline;">Click here to update your credentials</a></p> <!-- Non-functional link with red styling --> <p>It is important that you complete this action within 24 hours to avoid any disruption to your account. Failure to comply will result in limited access to our systems and resources.</p> <p>Thank you for your immediate attention to this matter.</p> <p>Best regards,<br>SchoolTech Admin Team</p> </div> </div> </div> } <p class="speech"><b>Task Force Leader:</b> "This link doesn’t lead to anything we recognize: <a href="javascript:void(0);" target="_blank" style="color: red;"><strong>http://www.school-verify.co.uk/login</strong></a>. It looks like a regular website, but something's off. Let’s dig into it and see what we find."</p> <p class="speech"><b>Task Force Member:</b> "Click on the link below and follow the instructions to update your information:"</p> <p class="speech"><b>Task Force Leader:</b> "It is important that you complete this action within 24 hours to avoid any disruption to your account. Failure to comply will result in limited access to our systems and resources."</p> <p class="speech"><b>Task Force Leader:</b> "Thank you for your immediate attention to this matter."</p> [[Continue->Fake URL]] (display: "Sidebar") (display: "SidebarBack") <h1>Investigate Email Headers</h1> <p class="s_direction">The task force member opens the full email headers on the screen, revealing a complex path the email took.</p> <p class="speech"><b>Task Force Member:</b> "Email headers are like the digital fingerprints of a message. They contain a wealth of information—details like the sender's IP address, the servers it passed through, and the results of various authentication checks. This information is critical in tracking down the origin of suspicious emails."</p> <!-- Display the email headers --> <div class="metadata-container" style="width: 100%; overflow: auto; color: black; background-color: #f4f4f4; border: 1px solid #ccc; padding: 10px; border-radius: 5px;"> <pre style="white-space: pre-wrap; word-wrap: break-word; font-size: 0.9em;"> From: admin@schooltech.co.uk To: staff@school.ac.uk Subject: Important Update: Action Required Date: Tue, 15 Aug 2024 14:23:45 +0000 (UTC) Message-ID: 1234567890.09876@schooltech.co.uk Return-Path: admin@schooltech.co.uk Received-SPF: softfail (google.com: domain of transitioning admin@schooltech.co.uk does not designate permitted sender hosts) Received: from mail.schooltech.co.uk ([198.51.100.10]) by mail.staff.ac.uk with SMTP for staff@school.ac.uk id 12345abcde Tue, 15 Aug 2024 14:23:42 +0000 (UTC) Received: from unknown ([203.0.113.15]) by mail.schooltech.co.uk Tue, 15 Aug 2024 14:21:20 +0000 (UTC) for admin@schooltech.co.uk </pre> </div> <p class="speech"><b>Task Force Member:</b> "See here? The `Received-SPF: softfail` entry means that this email might be spoofed. It indicates that the sender isn't listed as a permitted host for the domain 'schooltech.co.uk'. Also, notice the 'Received' lines. The email passed through an unusual server—'203.0.113.15'—before arriving at our school’s server. This could be a key clue."</p> <p class="speech"><b>Task Force Leader:</b> "So, this email might not have come from 'schooltech.co.uk' at all. Instead, it was routed through various servers to mask the sender's true location."</p> <p class="speech"><b>Task Force Member:</b> "Exactly. By analyzing these headers, we can gather more information about the attacker's methods and potentially trace their location."</p> <p class="s_direction">The team nods in agreement, realizing the importance of dissecting these hidden details in their pursuit of the hacker.</p> [[Continue->Jamie Parker]] (display: "Sidebar") (display: "SidebarBack") <h1>Inspect Sender</h1> <p class="s_direction">The task force gathers around to inspect the sender’s email address displayed on the screen. The address reads <b style="color: red;">'admin@schooltech.co.uk'</b>, which at first glance seems legitimate.</p> <p class="speech"><b>Task Force Leader:</b> "Alright, let’s see if there’s anything suspicious about the sender of this email."</p> <p class="s_direction">The task force leans in, analyzing the sender's address closely. It looks almost identical to the school's official domain, <b>'school.ac.uk'</b>, but there's a slight, potentially dangerous difference.</p> <p class="speech"><b>Task Force Member 1:</b> "Notice how the domain is <b style="color: red;">'schooltech.co.uk'</b> instead of <b>'school.ac.uk'</b>? It's a subtle change that could easily trick someone into thinking it's legitimate."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Whoever sent this is trying to impersonate someone from within our organization. We need to dig deeper into this sender information to find out if this was sent from inside the school network or if it was an external attempt to breach our systems."</p> <p class="s_direction">The team makes note of the suspicious domain change, adding it to their list of clues. They must now determine if this is part of a larger scheme or a one-time attempt to deceive the staff.</p> [[Narrowing Down the Suspects]] (display: "Sidebar") (display: "SidebarBack") <h1>Suspicious Email</h1> <div class="email-container"> { <!-- Simulating an email client interface --> { <div class="email-header-bar"> <p class="email-header-title">New Message</p> </div> } <div class="email-content"> <!-- Email headers section --> <div class="email-headers"> <p><strong>From:</strong> <span class="suspicious-sender">admin@schooltech.co.uk</span></p> <!-- Hint at suspicious sender --> <p><strong>To:</strong> staff@school.ac.uk</p> <p><strong>Subject:</strong> Important Update: Action Required</p> </div> <!-- Email body section --> <div class="email-body"> <p>Hello [Recipient Name],</p> <p>Due to recent security updates, we require all staff to verify their account credentials. This is a mandatory procedure to ensure that our systems are up to date and secure.</p> <p>Please click on the link below and follow the instructions to update your information:</p> <!-- Suspicious link with subtle styling to suggest it's risky --> <p><a href="javascript:void(0);" class="email-link" id="emailLink">Click here to update your credentials</a></p> <!-- Hint at suspicious link --> <p>It is important that you complete this action within 24 hours to avoid any disruption to your account. Failure to comply will result in limited access to our systems and resources.</p> <p>Thank you for your immediate attention to this matter.</p> <p>Best regards,<br>SchoolTech Admin Team</p> </div> </div> </div> } [[Continue->TakeALookReview]] (display: "Sidebar") (display: "SidebarBack") <h1>Fake Login Page</h1> <p class="s_direction">A website appears on the screen. It looks like a login page, but the branding is vague and generic—nothing tied to any known organization.</p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <p class="speech"><b>Task Force Member:</b> "It’s a fake login page, designed to trick people into entering their details. But the real question is, what happens next? Let’s explore further."</p> <p class="s_direction">Where should the task force focus their investigation on the website?</p> { <!-- Check if the source code has been checked --> (if: $checkedSourceCode is true)[ <!-- Clue Found and Redirect to Phishing Decision --> <p><b>Clue found!</b></p> [[Return to Phishing Decision->Phishing Decision]] ]} (else:)[ <!-- Check Main Content --> (if: $checkedMainContent is not true)[ <br>[[Check Main Content]]<br>] (else:)[ <p class="strike">You've already checked the main content.</p>] (if: $checkedSourceCode is not true)[ [[Check Source Code]]<br>] (else:)[ <p class="strike">You've already checked the source code.</p>] (if: $interactedWithLogin is not true)[ [[Interact with Login]]<br>] (else:)[ <p class="strike">You've already interacted with the login.</p>]] (display: "Sidebar") (display: "SidebarBack") <h1>Check Main Content</h1> { <p class="speech"><b>Task Force Member:</b> "Alright, let's see what we have here. It’s a pretty standard-looking login page. It asks for a username and password, but there's nothing immediately suspicious about the page itself. The text is generic, and the layout seems normal."</p> <div class="website-container"> <h2>Welcome to School Verification</h2> <p>Please log in to access your account:</p> <div class="login-container"> <h2>School Login</h2> <form id="loginForm" onsubmit="return false;"> <!-- Prevent form submission --> <div class="form-group"> <label for="username">Username:</label> <input type="text" id="username" name="username" placeholder="Enter your username"> </div> <div class="form-group"> <label for="password">Password:</label> <input type="password" id="password" name="password" placeholder="Enter your password"> </div> <button type="submit">Log In</button> </form> </div> </div> } <p class="speech"><b>Task Force Member:</b> "There are no immediate red flags. The page looks like it’s meant to lull users into a false sense of security. But there’s nothing here that tells us who set this up or why."</p> <p class="speech"><b>Task Force Leader:</b> "It’s too clean. Whoever created this wanted it to look as ordinary as possible. We won’t find anything by just looking at the surface. We need to dig deeper. Where should we look next?"</p> <p>[[Fake URL]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <script> // JavaScript to prevent focusing on input elements and scroll to the top of the page window.onload = function () { window.scrollTo(0, 0); // Scroll to top }; </script> (set:$checkedMainContent to true)<h1>Check Source Code</h1> <p class="speech"><b>Task Force Member:</b> "Wait, I think I’ve found something. There’s a hidden message embedded in the code—this wasn’t meant to be seen by a regular user."</p> <p>They display the message on the screen:</p> <pre style="background-color: #f4f4f4; padding: 10px; border: 1px solid #ccc; border-radius: 5px; text-align: left; color: black;"> // Source Code for Login Page function validateLogin() { var username = document.getElementById('username').value; var password = document.getElementById('password').value; // Hidden Message in Source Code var hiddenMessage = "<span style='color: red;'>Olssv dvysk</span>"; // This wasn't meant to be seen console.log(hiddenMessage); // Log the message for debugging // Validate credentials... } </pre> <p class="speech"><b>Task Force Leader:</b> "This looks like some kind of encryption—just another layer of the attacker’s plan. Whoever did this left this message behind on purpose, but it's encoded to prevent anyone from understanding it without the right key."</p> <p class="speech"><b>Task Force Member:</b> "We don’t have enough information to decode this yet, but it’s clear that this message is important. We’ll need to gather more clues from other parts of the investigation. Let’s keep going and come back to this once we have more to work with."</p> { <p class = "s_direction">You’ve discovered a hidden message in the source code: <span class = "clue">"Olssv dvysk".</span></p> (if: $clue13_found is not true)[ (set: $clue13_found to true) (set: $cluesFound to $cluesFound + 1) ] <!-- In "Check Source Code Passage" --> (set: $checkedSourceCode to true) } <p>[[Fake URL]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> (set: $investigateEmailLinksCompleted to true) <h1>Interact with Login</h1> { <div class="login-container" style="background-color: white; padding: 20px; border: 1px solid #ccc; border-radius: 5px; margin-bottom: 20px; text-align: left; color: black;"> <h2>School Login</h2> <form id="loginForm" onsubmit="return false;"> <!-- Prevent form submission --> <div class="form-group"> <label for="username">Username:</label> <input type="text" id="username" name="username" placeholder="Enter your username" style="width: 100%; padding: 8px; margin-bottom: 10px;"> </div> <div class="form-group"> <label for="password">Password:</label> <input type="password" id="password" name="password" placeholder="Enter your password" style="width: 100%; padding: 8px; margin-bottom: 10px;"> </div> <button type="submit" style="padding: 10px 15px;">Log In</button> </form> </div> } <p class="speech"><b>Task Force Member:</b> "Nothing happened. Looks like this login page doesn’t actually do anything. It’s designed just to collect data from anyone who tries to log in. But this doesn’t explain what’s really going on."</p> <p class="speech"><b>Task Force Leader:</b> "We need to keep digging. There’s got to be more to this than just a fake login page. What should we try next?"</p> <p>[[Continue->Fake URL]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <!-- In "Interact with Login Passage" --> (set: $interactedWithLogin to true) <h1>Next Steps After Link Clue</h1> <p class="s_direction">The task force leader looks at the clues thoughtfully.</p> <p class="speech"><b>Task Force Leader:</b> "We’ve uncovered something important here. It’s clear that whoever did this left it behind for a reason."</p> <p class="speech"><b>Task Force Leader:</b> "We still have other parts of this investigation to complete. We’ve found one clue, but we’re not done yet. Let’s go back and investigate more of the phishing emails to uncover anything we might have missed."</p> <p>[[Phishing Branch Wrap-Up]]</p> (display: "Sidebar") (display: "SidebarBack") {<!-- Show the number of clues found so far --> <p>Total Clues Found: (print: $cluesFound)</p> } { <!-- Less than 3 clues --> (if: $cluesFound < 3)[ <div> <p class="speech"><b>Task Force Leader:</b> "We’re still missing crucial parts of the puzzle. We only have a handful of clues, and none of them are conclusive enough to pinpoint the hacker. It’s like trying to put together a jigsaw puzzle with most of the pieces missing."</p> <p class="speech"><b>Task Force Member 1:</b> "I agree, sir. We’ve gathered what we could, but it’s not enough. The encrypted logs and suspicious activity only show fragments of the bigger picture. We can't identify a clear motive or method."</p> <p class="speech"><b>Task Force Leader:</b> "Without those missing pieces, we can’t make a confident decision. If we proceed now, we risk accusing the wrong person and letting the real perpetrator get away. We need more time."</p> <p class="speech"><b>Task Force Member 2:</b> "It's frustrating. I feel like we’re on the edge of something big, but without more evidence, we're stuck in the dark. We need to go back and dig deeper."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Let’s retrace our steps and make sure we haven't overlooked anything. The hacker is still out there, and we’re not giving up until we find them."</p> <p>[[Return to Investigation->Vote]]</p> </div> ] <!-- Between 3 and 5 clues --> (else-if: $cluesFound >= 3 and $cluesFound < 5)[ <div> <p class="speech"><b>Task Force Member 1:</b> "It’s a tough call, but I think we might have just enough information to proceed. We’ve uncovered a fair number of clues, but there are still some gaps in the story."</p> <p class="speech"><b>Task Force Leader:</b> "Agreed. We don’t have all the answers, but we’ve got enough to form a hypothesis. The suspicious logs, the encrypted messages—it’s starting to come together, even if the full picture isn’t clear yet."</p> <p class="speech"><b>Task Force Member 2:</b> "We might not know everything, but the clues we’ve gathered are pointing us in a direction. It’s risky, but we have enough to make an informed guess."</p> <p class="speech"><b>Task Force Leader:</b> "This isn’t a perfect case, but we’re not completely in the dark. We’ve uncovered key motives, methods, and we can piece together the hacker’s strategy. It’s time to trust our instincts and move forward."</p> <p class="speech"><b>Task Force Member 1:</b> "Right. It's now or never. Let’s connect the dots and see if we can bring this case to a close."</p> <p>[[Continue->JustEnoughEnding]]</p> </div> ] <!-- More than 6 clues --> (else-if: $cluesFound >= 5)[ <div> <p class="speech"><b>Task Force Member 1:</b> "We’ve gathered everything we need. There’s no doubt—we have more than enough to solve this case. The hacker has left a trail, and we’ve followed it right to their doorstep."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Every clue we’ve collected fits perfectly together: the encrypted messages, the strange software, the unauthorized file transfers. We know the motive, the method, and the perpetrator."</p> <p class="speech"><b>Task Force Member 2:</b> "There’s no ambiguity here. We’ve got hard evidence, and we can confidently close this case. We’ve done more than just uncover the clues—we’ve understood the hacker’s entire plan."</p> <p class="speech"><b>Task Force Leader:</b> "Great work, team. This was a complex case, but with the amount of evidence we’ve gathered, we’re in a position to not only identify the hacker but ensure they’re brought to justice. It’s time to wrap this up."</p> <p class="speech"><b>Task Force Member 1:</b> "Let’s make the call and put an end to this. We’ve worked hard, and now it’s time to see the results of our efforts."</p> <p>[[Continue->EasyEnding]]</p> </div> ] } (display: "Sidebar") (display: "SidebarBack") :: Investigate Email Headers The task force member opens the full email headers on the screen. From: admin@schooltech.co.uk To: staff@school.ac.uk Subject: Important Update: Action Required Date: Tue, 15 Aug 2024 14:23:45 +0000 (UTC) Message-ID: 1234567890.09876@schooltech.co.uk Return-Path: admin@schooltech.co.uk Received-SPF: softfail (google.com: domain of transitioning admin@schooltech.co.uk does not designate permitted sender hosts) Received: from mail.schooltech.co.uk ([198.51.100.10]) by mail.staff.ac.uk with SMTP for staff@school.ac.uk id 12345abcde Tue, 15 Aug 2024 14:23:42 +0000 (UTC) Received: from unknown ([203.0.113.15]) by mail.schooltech.co.uk Tue, 15 Aug 2024 14:21:20 +0000 (UTC) for admin@schooltech.co.uk [[Jamie Parker]] (display: "Sidebar") (display: "SidebarBack")<h1>Audience Votes on Attack</h1> <p class="s_direction">Mr. Luddite stands up abruptly, waving a piece of paper in his hand, his eyes wide with urgency.</p> <p class="speech"><b>Mr. Luddite:</b> "You know, that's all well and good! I might just be an old-fashioned entertainer... but I’ve got an insider source who says this isn’t just a regular... fishy attack?"</p> <p class="speech"><b>Task Force Member:</b> "Phishing attack."</p> <p class="speech"><b>Mr. Luddite:</b> "Right, right... a phishing attack. But listen, there’s this new *super malware* going around called *Viperworm*. It could be so advanced we’re not even seeing it right now! I’d keep an eye on that angle if I were you."</p> <p class="s_direction">The room falls into a brief silence as the task force members exchange bewildered glances.</p> <!-- Check if Jamie Parker is a suspect --> { (if: $suspect2_found is true)[ <!-- If Jamie Parker is a suspect --> <p class="s_direction">Jamie Parker smirks, clearly entertained by Luddite's outburst. He leans back in his chair, speaking with a mix of sarcasm and disdain.</p> <p class="speech"><b>Jamie Parker:</b> "You know, Luddite might be onto something for once. *Viperworm*, huh? Sounds like exactly the kind of thing our outdated systems wouldn't catch. Maybe we should all listen to the 'insider'."</p> <p class="s_direction">He glances at the task force leader with a hint of defiance.</p> <p class="speech"><b>Jamie Parker:</b> "After all, we're just following the same old protocol here, aren't we? Maybe it's time for some outside-the-box thinking."</p> <p class="s_direction">His tone grows colder, revealing his frustration with the current investigation's direction.</p> <p class="speech"><b>Task Force Leader:</b> "Jamie, enough. We can't get sidetracked by every theory. Focus on the evidence."</p> <p class="speech"><b>Jamie Parker:</b> "Evidence... right. Because evidence has been so effective at stopping this so far."</p> <p class="s_direction">He turns back to his screen, muttering under his breath as he begins typing furiously.</p> ] (else:)[ <!-- If Jamie Parker is not a suspect --> <p class="s_direction">Jamie Parker sighs, rubbing his temples before stepping in to address Luddite's claim.</p> <p class="speech"><b>Jamie Parker:</b> "Luddite, while the idea of *Viperworm* is... intriguing, there's no solid evidence pointing to that right now. We need to focus on what we can prove."</p> <p class="s_direction">He turns to the task force leader, nodding in agreement with the current line of investigation.</p> <p class="speech"><b>Jamie Parker:</b> "If we start chasing every rumor or theory, we'll end up wasting time and resources. Let's stick with the clues we've gathered so far."</p> <p class="s_direction">He sits back down, his demeanor calm and focused as he resumes his work.</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. We can't afford to get distracted by speculation. We need to stay on track."</p> ] } [[Proceed to Vote->Vote for Attack]] (display: "Sidebar") (display: "SidebarBack") <h1>Vote for Attack</h1> <p class="speech"><b>Task Force Member:</b> "Alright, team. We’ve got a few possible options based on the clues. Let’s vote on what kind of attack this seems to be."</p> <p class="s_direction">*Mr. Luddite looks around confidently.*</p> <p>[[Results]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Choose Attack Type</h1> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" alt="Attack Options" style="width: 100%; max-width: 600px; display: block; margin: 0 auto;"> [[Phishing Attack|PhishingResult]] [[Malware Attack|FakeNews ]] (display: "Sidebar") (display: "SidebarBack")<h1>Audience Vote Result (Phishing)</h1> <p class = "s_direction">The majority of the audience votes for a phishing attack.</p> <p class = "speech"><b>Taks Force Leader:</b> "Looks like most of you don't think Luddite's theory is worth chasing. That makes sense with all the suspicious emails we've uncovered."</p> <p class = "speech"><b>Task Force Member:</b> "Let’s follow that trail and dig deeper."</p> <p>[[Proceed to Analyze Phishing Attack|Luddite]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Audience Vote Result (Malware)</h1> <p class="s_direction">The majority of the audience votes for malware, influenced by Mr. Luddite.</p> <p class="speech"><b>Mr. Luddite</b> (smug): "I told you! It had to be malware. Trust me, I’ve got an insider source that says this sort of thing always starts with malware!"</p> <!-- Check for both Jamie Parker and Alex Johnson suspect status --> { (if: $suspect2_found is true and $suspect1_found is true)[ <!-- Both Jamie Parker and Alex Johnson are suspects --> <p class="s_direction">Jamie Parker and Alex Johnson exchange glances, their expressions smug as they nod in agreement with Luddite.</p> <p class="speech"><b>Jamie Parker:</b> "Finally, some sense around here. We've been barking up the wrong tree all along."</p> <p class="speech"><b>Alex Johnson:</b> "This team needed a wake-up call. Let's see what this *ViperWorm* theory reveals."</p> ] (else-if: $suspect2_found is true and $suspect1_found is not true)[ <!-- Only Jamie Parker is a suspect --> <p class="s_direction">Jamie Parker leans back with a smirk.</p> <p class="speech"><b>Jamie Parker:</b> "Looks like some of you finally see the bigger picture. Phishing? Too simple for this operation."</p> <p class="s_direction">Alex Johnson frowns slightly, looking skeptical.</p> <p class="speech"><b>Alex Johnson:</b> "Malware or not, we can't dismiss the emails just yet. We need to stay focused."</p> ] (else-if: $suspect2_found is not true and $suspect1_found is true)[ <!-- Only Alex Johnson is a suspect --> <p class="s_direction">Alex Johnson crosses his arms, looking smugly at the team.</p> <p class="speech"><b>Alex Johnson:</b> "Took you long enough to get there. We've been underestimating this attacker from the start."</p> <p class="s_direction">Jamie Parker looks uneasy, trying to keep the discussion on track.</p> <p class="speech"><b>Jamie Parker:</b> "Maybe there's malware involved, but the emails still play a critical role. Let's not ignore the evidence we have."</p> ] (else:)[ <!-- Neither Jamie Parker nor Alex Johnson is a suspect --> <p class="s_direction">Jamie Parker exchanges a glance with Alex Johnson, both looking concerned.</p> <p class="speech"><b>Jamie Parker:</b> "Mr. Luddite, just because it's possible doesn't mean it's the only explanation. We need to be thorough."</p> <p class="speech"><b>Alex Johnson:</b> "Exactly. We can't ignore the emails either. Malware might be part of it, but let's keep a level head."</p> ] } <p class="speech"><b>Task Force Leaders</b> (hesitantly): "Alright, let’s investigate this ViperWorm theory."</p> <p>[[Proceed to Analyze ViperWorm Attack|Luddite3]]</p> (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable to track this branch --> (set: $viperworm_branch_started to true) <h1>Mr. Luddite Throws a Tantrum (Phishing Chosen)</h1> <p><b>Mr. Luddite</b> (furious): "This is absurd! How can you all be so blind? Malware is always the culprit! You're all falling for this fake narrative!"</p> <!-- Check for both Jamie Parker and Alex Johnson suspect status --> { (if: $suspect2_found is true and $suspect1_found is true)[ <!-- If both Jamie Parker and Alex Johnson are suspects --> <p class="s_direction">Jamie Parker and Alex Johnson exchange knowing glances, clearly relishing the chaos.</p> <p class="speech"><b>Jamie Parker:</b> "He's not wrong. Maybe this team needs a bit of a shake-up to see things clearly."</p> <p class="speech"><b>Alex Johnson:</b> "Finally, some real talk. It's about time we question everything."</p> ] (else-if: $suspect2_found is true and $suspect1_found is not true)[ <!-- If only Jamie Parker is a suspect --> <p class="s_direction">Jamie Parker smirks, leaning back in his chair.</p> <p class="speech"><b>Jamie Parker:</b> "You know, Luddite might actually have a point. Maybe it's time we stop playing it safe and consider the possibility that this is something far more complex than just phishing."</p> <p class="s_direction">Alex Johnson, however, looks uneasy.</p> <p class="speech"><b>Alex Johnson:</b> "Mr. Luddite, let's not lose our heads. We're already onto something with the phishing angle. We’ll explore every lead, but one step at a time."</p> ] (else-if: $suspect2_found is not true and $suspect1_found is true)[ <!-- If only Alex Johnson is a suspect --> <p class="s_direction">Alex Johnson scoffs, leaning back in his chair with a smug look.</p> <p class="speech"><b>Alex Johnson:</b> "He's right, you know. The way this team handles these incidents is laughable. Maybe a bit of chaos is what we need to get some real answers."</p> <p class="s_direction">Jamie Parker raises a hand to calm the room.</p> <p class="speech"><b>Jamie Parker:</b> "Luddite, let's not jump to conclusions. We're following the evidence we have right now. We'll get to every angle, but we have to stay focused."</p> ] (else:)[ <!-- If neither Jamie Parker nor Alex Johnson is a suspect --> <p class="s_direction">Jamie Parker sighs, rubbing his temples before stepping in to address Luddite's claim.</p> <p class="speech"><b>Jamie Parker:</b> "Luddite, while the idea of *Viperworm* is... intriguing, there's no solid evidence pointing to that right now. We need to focus on what we can prove."</p> <p class="s_direction">Alex Johnson nods in agreement.</p> <p class="speech"><b>Alex Johnson:</b> "Exactly. If we start chasing every rumor or theory, we'll end up wasting time and resources. Let's stick with the clues we've gathered so far."</p> ] } <p class = "speech"><b>Task Force Leader</b> (calmly): "Easy there, Mr. Luddite. Let's focus on what the evidence tells us. We’ll investigate every lead."</p> <p>[[Phishing Decision]]</p> (display: "Sidebar") (display: "SidebarBack") (set: $investigateEmailHeadersCompleted to true) <h1>Mr. Luddite Becomes Smug (Malware Chosen)</h1> <p class = "speech"><b>Mr. Luddite</b>: (smug) "See? I told you. ViperWorm is the culprit. You all should trust me more often."</p> <p class = "speech"><b>Task Force Leader</b>: "Let’s dig into this theory and see where it takes us."</p> <p>[[Proceed to Analyze Malware Attack|Analyze ViperWorm]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Mr. Luddite's False Lead</h1> <p class="speech"><b>Mr. Luddite</b> smugly steps forward. "I’ve been talking to my <i>inside source</i>. This is clearly the work of ViperWorm. We need to investigate that malware—trust me!"</p> [[Research ViperWorm|ViperWorm WebStory]] <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>News Story: "ViperWorm: The End of Computers as We Know It!"</h1> <p class="speech"><b>Task Force Leader:</b> Breaking news!!!</p> <p class="speech"><b>Task Force Member:</b> a new computer virus called ViperWorm is destroying everything in its path!!! this evil software has already wrecked thousands of computers worldwide, and now it's coming for yours!!!</p> <p class="speech"><b>Task Force Leader:</b> according to totally reliable sources, ViperWorm was created by a secret group of hackers who want to take control of the Internet and turn all computers into their personal slaves. this virus is so powerful that it can delete all your files in seconds and make your computer literally explode (no, seriously, it could happen!). if you use the Internet, ViperWorm will find you!!! it's not safe to even turn on your computer right now.</p> <p class="speech"><b>Task Force Member:</b> Here’s what ViperWorm is doing:</p> <p class="speech"><b>Task Force Member:</b> Here’s what ViperWorm is doing:</p> <div class="viperwormStories"> <ul> <li>hijacking your bank accounts and stealing all your money.</li> <li>downloading all your private photos and posting them on the Internet for everyone to see.</li> <li>turning your keyboard into a spy tool that records everything you type (including your embarrassing search history!!).</li> <li>making your computer screen flash a giant snake animation that hypnotizes you into giving away your personal information.</li> </ul> </div> <p class="speech"><b>Task Force Leader:</b> big tech companies have tried to stop it, but even they are too late! according to an anonymous hacker on a random forum (so it must be true), ViperWorm is unstoppable because it spreads faster than any virus before it. they say ViperWorm was created using alien technology found on a secret government base, which is why it's so advanced.</p> <p class="speech"><b>Task Force Member:</b> the only way to stop ViperWorm is to immediately uninstall all your software and stop using the Internet forever!!! even then, you might not be safe, because ViperWorm can travel through the airwaves and infect your devices through the atmosphere (don’t ask how, it just can).</p> <p class="speech"><b>Victim:</b> "I was checking my emails, and suddenly my screen turned into a giant snake! now all my files are gone, and my computer is just making hissing noises!"</p> <p>[[Evaluate Evidence]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Evaluate the Evidence</h1> <p class = "s_direction">The task force stares at the printout of the ViperWorm article that Mr. Luddite provided.</p> <p class="speech"><b>Task Force Leader:</b> "O...kay, let’s take a step back and evaluate this. We’ve found some real clues so far—like the strange emails and the encrypted message. But now we’re looking at this story about ViperWorm. Is it reliable evidence, or is it something else?"</p> <p class="speech"><b>Task Force Member:</b> "This article is full of red flags. First of all, it’s making outrageous claims—like computers exploding and a virus that can travel through the airwaves. That’s not how technology works."</p> <p class="speech"><b>Mr. Luddite:</b> "But... it says it right here! It’s on the internet, so it must be true!"</p> <p class="speech"><b>Task Force Member:</b> "Not everything you read online is reliable, Mr. Luddite. Just because it’s posted somewhere doesn’t make it fact. This article is a great example of <strong>fake news</strong>. It’s trying to scare people with sensational headlines and made-up information."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. <strong>Fake news</strong> often includes exaggerated claims, poor grammar, and anonymous sources with no real evidence. It’s designed to mislead people and cause panic, like this article about ViperWorm. As investigators, we need to rely on <strong>verified facts</strong>, not wild stories that can’t be backed up."</p> <p class="speech"><b>Task Force Member:</b> "Let’s focus on what we actually know from the real evidence we’ve gathered: the suspicious emails, the encrypted message, and the strange activity in the network traffic. These are the clues we should trust, not something that’s trying to stir up fear without proof."</p> <p class="s_direction">Mr Luddite tilts his head to the side like a confused dog.</p> <p class="speech"><b>Task Force Leader:</b> "It’s important to always think critically. We have to ask ourselves: <strong>Where is this information coming from?</strong> <strong>Is it backed by real evidence?</strong> And most importantly, <strong>Does it make sense based on what we know?</strong> That’s how we avoid falling for fake news."</p> <p>[[Continue->Luddite Rebuke]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Luddite Rebuke</h1> <p class="speech"><b>Mr. Luddite:</b> "Wait a minute! I don’t care what you say, this <strong>ViperWorm</strong> thing is real! Just look at this article! It’s right there in black and white. They wouldn’t write it if it wasn’t true. You’re all ignoring the real threat! Why wouldn’t we investigate this? What if it’s already in the system?"</p> <p class="speech"><b>Task Force Member:</b> "Mr. Luddite, we’ve been through this. The article you’re holding is full of exaggerated claims and misinformation. There’s no real evidence supporting it."</p> <p class="speech"><b>Mr. Luddite:</b> "But what if you’re wrong? What if ViperWorm is out there, right now, wrecking computers? We could be ignoring the biggest threat ever because you’re too focused on the boring technical stuff. I say we need to <strong>look into ViperWorm</strong> before it’s too late!"</p> <p class="speech"><b>Task Force Leader:</b> "I understand your concern, but we can’t afford to be distracted by every sensational headline. We have real clues here that are leading us toward the truth."</p> <p class="speech"><b>Mr. Luddite:</b> crosses his arms defiantly. "I’m telling you, this is the real deal. You can’t just dismiss it. We need to figure out if ViperWorm is behind all of this!"</p> <p>[[Continue->Luddite Interactive Vote]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Luddite Interactive Vote</h1> <p class="speech"><b>Task Force Leader:</b> "Alright, it seems like we’ve hit a crossroads. Mr. Luddite is convinced that this story about ViperWorm is something we should investigate. The rest of us think we should stick to the real evidence we’ve already found."</p> <p class="speech"><b>Task Force Member:</b> "We could waste valuable time chasing a fake story, or we could stay focused on the clues that are leading us somewhere real."</p> <p class="speech"><b>Task Force Leader:</b> "What do you think, team? Should we follow Mr. Luddite’s lead and investigate ViperWorm, or go back to the rest of the investigation?"</p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> { <p>[[Vote to Investigate ViperWorm->Proceed with ViperWorm]]</p> <p>[[Vote to Stick with the Real Evidence->Proceed with the Real Investigation]]</p>} <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Proceed with ViperWorm</h1> <p class="speech"><b>Task Force Member:</b> "Alright, it looks like we’re going to investigate this ViperWorm theory. I hope we’re not wasting our time."</p> <p class="speech"><b>Mr. Luddite:</b>OUTSTANDING! Pumps his fist in victory. "You won’t regret it! We’re going to get to the bottom of this once and for all!"</p> <p class="speech"><b>Task Force Leader:</b> "Fine, let’s take a closer look at the story. We’ll need to see if there’s <strong>any evidence</strong> that ViperWorm could be involved in what’s going on here. Let’s search through the data."</p> <p>[[Continue->ViperWorm Investigation (Fake Path)]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Proceed with the Real Investigation</h1> <p class="speech"><b>Task Force Leader:</b> "Alright, we’re sticking to what we know. The evidence we’ve gathered so far is leading us toward something concrete. We can’t waste time on sensational stories that don’t hold up under scrutiny."</p> <p class="speech"><b>Mr. Luddite:</b> throws his hands up in frustration. "Fine, ignore me! But don’t come crying to me when ViperWorm wipes out all your data!"</p> <p class="speech"><b>Task Force Member:</b> "Thanks for your input, Mr. Luddite, but I think we’re better off following the real clues we’ve found."</p> <p class="speech"><b>Task Force Leader:</b> "Let’s keep going. There’s still more to uncover."</p> <p>[[Continue->Phishing Decision]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> (set: $investigateEmailHeadersCompleted to true) <h1>ViperWorm Investigation (Fake Path)</h1> <p class="speech"><b>Task Force Member:</b> "Okay, we’re on the ViperWorm trail now. Let’s do a quick search and see if there’s any reliable information about it."</p> <p class = "s_direction">They start searching online, but after a few moments, the results are less than promising. A task force member stumbles across another article.</p> <p class="speech"><b>Task Force Member:</b> "Well... we’ve found something. Take a look at this."</p> <p class = "s_direction">They display the new article on the screen, and the task force groans.</p> <p>[[Continue->Fake News Article: ViperWorm 2.0]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Viperworm News Article</h1> { <!-- Define the array of fake news stories directly in the passage --> (set: $viperWormStories to (a: "ViperWorm 2.0: Experts claim it can fry your microwave and break your fridge!<br> Tech Alarm Network - Breaking News<br> In a shocking turn of events, cybersecurity experts are warning about <strong>ViperWorm 2.0</strong>, a new mutation of the already dangerous virus. According to reports, ViperWorm has evolved beyond attacking computers—it’s now capable of <strong>frying household appliances</strong>, including microwaves and refrigerators!<br> 'Once ViperWorm 2.0 infects your home network, it spreads rapidly,' said Dr. Jen Hacker, a leading cybersecurity expert. 'We’ve seen it <strong>overheat microwaves</strong> to dangerous levels, causing them to break down or even explode. And don’t even get me started on what it’s doing to fridges—food spoilage and more!'<br> Experts urge everyone to unplug all smart appliances until further notice.", "ViperWorm now capable of controlling your thoughts through your smartphone!<br> <strong>World Tech News Flash</strong><br> In an alarming new development, researchers have discovered that the infamous <strong>ViperWorm</strong> has evolved to <strong>control human thoughts</strong> through smartphones! Using highly advanced mind-hacking techniques, ViperWorm can take over a person’s decision-making process just by infecting their phone.<br> Victims report suddenly feeling compelled to share personal information online, make strange purchases, or even text embarrassing secrets to their contacts.<br> 'It feels like my brain was hijacked,' said one victim. 'I ordered 100 pizzas without realizing it!'<br> Experts advise turning off all smartphones until a patch can be released to protect users from mind control.", "ViperWorm attacks pets! Beware of infected cats and dogs!<br> <strong>Breaking: PetVirus Reports</strong><br> Cybersecurity experts have issued an urgent warning: <strong>ViperWorm</strong> is no longer just a threat to humans and computers—it’s now targeting our beloved pets. Reports indicate that once a household device is infected, <strong>ViperWorm</strong> can somehow spread to nearby cats, dogs, and even hamsters.<br> 'My cat started acting really strange,' said one victim. 'It kept pawing at my computer, like it was trying to hack into my email!'<br> Pets infected with ViperWorm may display erratic behavior, such as excessive typing, attempting to chew on USB cables, or incessantly knocking over smart devices. No animal is safe!", "New study suggests ViperWorm can spread via Bluetooth earbuds!<br> <strong>Tech Alert News Bulletin</strong><br> A new study has revealed a startling finding: the <strong>ViperWorm virus</strong> may be spreading via Bluetooth earbuds. Scientists have found that once ViperWorm infiltrates a device, it can hop from phone to phone through Bluetooth connections—starting with <strong>wireless earbuds</strong>.<br> 'We found that anyone within a 10-meter radius of infected earbuds is at risk,' said Dr. Soundwave from the Institute of Wireless Infections. 'The virus can travel through the airwaves at incredible speeds, infecting anyone who’s listening to music or taking a call.'<br> To prevent infection, experts recommend turning off Bluetooth on all devices and using <strong>wired</strong> headphones.", "Authorities warn: ViperWorm can steal your online shopping passwords!<br> <strong>Consumer Safety Network</strong><br> Officials are urging everyone to be cautious while shopping online this week as the <strong>ViperWorm virus</strong> has been detected in multiple major e-commerce websites.<br> 'ViperWorm is intercepting passwords and personal details when people log into online shopping accounts,' warned a representative from CyberSafe Inc. 'People need to be extremely careful, as ViperWorm can instantly take control of your entire shopping cart, racking up thousands of dollars in purchases without your knowledge.'<br> Authorities recommend avoiding online shopping entirely until further notice. 'Consider going back to in-person shopping until we have this under control,' experts suggest." )) <!-- Generate a random index number between 1 and 5 (since we know the array has 5 items) --> (set: $randomIndex to (random: 1, 5)) <!-- Select the story based on the generated index --> (set: $selectedStory to $viperWormStories's ($randomIndex)) } <p class="speech"><b>Task Force Member:</b> "Look at this—here’s the latest article we’ve found..."</p> <p class="viperwormStories">(print: $selectedStory)</p> <p class="speech"><b>Task Force Member:</b> "This is getting ridiculous. 'Hack your brainwaves'? 'Turn off your devices to stop it'? This is clearly another fake story."</p> <p>[[Continue->Luddite's Reaction]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Luddite's Stubbornness</h1> <p class="speech"><b>Mr. Luddite:</b> Shakes his head, waving the article around. "No, I don’t care what you say. I still believe this is real! I’ve read articles like this before, and they all say the same thing—ViperWorm is out there, and we’re ignoring the biggest threat to our systems!"</p> <p class="speech"><b>Task Force Member:</b> "Mr. Luddite, these articles are full of obvious errors. They make wild claims with no evidence. We’re wasting time on fake news."</p> <p class="speech"><b>Mr. Luddite:</b> Stubbornly crosses his arms. "How do we know that for sure? Maybe the virus is getting smarter. Just because it sounds crazy doesn’t mean it’s not happening! We can’t afford to ignore this."</p> <p class="speech"><b>Task Force Leader:</b> "I think it's time we settle this. We need to decide if we’re going to follow Mr. Luddite’s theory or get back to the real clues we’ve found."</p> <p>[[Continue->Luddite Interactive Vote]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> :: StoryInit (set: $previousPassage to "") (set: $suspectNum to 0) <!-- Default value --> (set: $phishing_completed to false) (set: $network_traffic_completed to false) (set: $malware_completed to false) (set: $isolate_device_completed to false) (set: $block_port_completed to false) (set: $throttle_data_completed to false) (set: $dataTransferStopped to false) (set: $hackersAccessBlocked to false) (set: $sourceTraced to false) (set: $checkedMainContent to false) (set: $checkedSourceCode to false) (set: $interactedWithLogin to false) (set: $ransom_paid to false) (set: $backups_restored to false) (set: $wildcard_used to false) (set: $option1Chosen to false) (set: $option2Chosen to false) (set: $option3Chosen to false) (set: $viperworm_branch_started to false) (set: $cluesFound to 0) (set: $foundClues to (array:)) <!-- An array to track found clues --> (set: $clue1_found to false) <!-- Clue 1: Caesar Cipher --> (set: $clue2_found to false) <!-- Clue 2: Suspicious IP Address --> (set: $clue3_found to false) <!-- Clue 3: USB Device --> (set: $clue4_found to false) <!-- Clue 4: Encryption Tools --> (set: $clue5_found to false) <!-- Clue 5: Fake Phishing Email --> (set: $clue6_found to false) <!-- Clue 6: Unusual Login Attempts --> (set: $clue7_found to false) <!-- Clue 7: Compromised Files --> (set: $clue8_found to false) <!-- Clue 8: First Pet Name --> (set: $clue9_found to false) <!-- Clue 9: Strange Software Installed --> (set: $clue10_found to false) <!-- Clue 10: Anonymous Email --> (set: $clue11_found to false) <!-- Clue 11: Favorite Hobby --> (set: $clue12_found to false) <!-- Clue 12: Decryption Key (Shift of 3) --> (set: $clue13_found to false) <!-- Clue 13: Hidden Message in Source Code --> ) (set: $clue14_found to false) (set: $suspectsFound to 0) <!-- Initialize suspects found count --> (set: $suspect1_found to false) <!-- Suspect 1: Alex Johnson --> (set: $suspect2_found to false) <!-- Suspect 2: Jamie Parker --> (set: $suspect3_found to false) <!-- Suspect 3: Emily Davis --> (set: $suspect4_found to false) <!-- Suspect 4: Thomas Reed --> (set: $suspect5_found to false) <!-- Suspect 5: Sarah Lee --> (set: $suspect6_found to false) <!-- Suspect 6: Robert Brown --> (set: $suspect7_found to false) <!-- Suspect 7: Luddite --> (set: $suspect8_found to false) <!-- Suspect 8: EVERYONE --> (set: $viperWormStories to (a: "**BREAKING NEWS!** Scientists warn that **ViperWorm 2.0** doesn’t just destroy computers—it’s evolved to **hack your brainwaves** and turn you into a mindless zombie! Experts recommend wearing a **tinfoil hat** at all times to block the virus from controlling your mind.", "Security experts are in **shock** as the **ViperWorm virus** has unleashed an animated **snake emoji** that **slithers across your screen** and eats all your important files! It even hisses every time it gobbles up a document. Once your data is eaten, the snake vanishes, leaving only chaos behind.", "In its **latest mutation**, ViperWorm has found a way to turn your entire computer into a **real snake**! Users have reported their laptops **shedding their casings** and slithering away. If your computer is feeling scaly, DO NOT approach! Experts advise locking your devices in terrariums.", "The latest version of ViperWorm has started creating **wormholes** on infected computers, **sucking up all data** and transporting it to another dimension. Once your files are gone, they’re gone for good! No firewall can stop it, as it seems to transcend time and space." )) <h1>Inspecting the Suspicious Email</h1> { <div class="email-container"> <div class="email-header-bar"> <p class="email-header-title">New Message</p> </div> <div class="email-content"> <!-- Email headers section --> <div class="email-headers"> <p><strong>From:</strong> <span class="suspicious-sender">admin@schooltech.co.uk</span></p> <!-- Hint at suspicious sender --> <p><strong>To:</strong> staff@school.ac.uk</p> <p><strong>Subject:</strong> Important Update: Action Required</p> </div> <!-- Email body section --> <div class="email-body"> <p>Hello [Recipient Name],</p> <p>Due to recent security updates, we require all staff to verify their account credentials. This is a mandatory procedure to ensure that our systems are up to date and secure.</p> <p>Please click on the link below and follow the instructions to update your information:</p> <!-- Suspicious link with subtle styling to suggest it's risky --> <p><a href="javascript:void(0);" class="email-link" id="emailLink">Click here to update your credentials</a></p> <!-- Hint at suspicious link --> <p>It is important that you complete this action within 24 hours to avoid any disruption to your account. Failure to comply will result in limited access to our systems and resources.</p> <p>Thank you for your immediate attention to this matter.</p> <p>Best regards,<br>SchoolTech Admin Team</p> </div> </div> </div> } <p class="s_direction">The task force leader points at the email displayed on the screen.</p> <p class="speech"><b>Task Force Leader:</b> "Alright, let's take a closer look at the sender's address here, 'admin@schooltech.co.uk'. It's not our usual domain, but it could easily fool someone who isn’t paying close attention."</p> [[Continue ->Investigate2]]<h1>Deeper Analysis</h1> <p class="speech"><b>Task Force Leader:</b> "Let’s take a closer look at the details behind this sender. Maybe there’s something hidden in the metadata."</p> <p class="s_direction">The task force runs a deeper analysis on the sender’s details, preparing to delve into the email's metadata for hidden clues.</p> <p class="speech"><b>Mr. Luddite:</b> "Metadata? How do we even get to that? Is it something we can see in the email?"</p> <p class="speech"><b>Task Force Member:</b> "Not directly. Most email clients hide metadata to keep things simple for users. But we can access it by looking at the email headers. In most email clients, you can find an option like 'View Original' or 'View Message Source.' That opens up a raw version of the email where we can see the full details, including the sender's server information and the path the email took to get to us."</p> [[Continue->Accessing the MetaData]] (display: "Sidebar") (display: "SidebarBack") <h1>Analyzing the Email Source</h1> <p class="s_direction">The task force huddles around the screen as the member continues to examine the metadata. The 'Received' lines reveal the path the email took to reach the school's server.</p> <p class="speech"><b>Task Force Member:</b> "This is interesting. The IP address, <i>192.168.1.50</i>, indicates that the email passed through a server not usually associated with our email traffic. It appears to have been routed through a chain of servers to mask the original sender's location."</p> <p class="speech"><b>Task Force Leader:</b> "Can we identify where this IP address is located or who it belongs to?"</p> <p class="speech"><b>Task Force Member:</b> "I’ve cross-referenced this IP with our known network infrastructure and external databases. It appears to be a part of a larger network of compromised servers often used for sending spam and phishing emails. This server is known to be used as a relay to obscure the attacker's real location."</p> <p class="speech"><b>Mr. Luddite:</b> "So, they’re using other computers to hide where they're really sending this from?"</p> <p class="speech"><b>Task Force Member:</b> "Exactly. It's called a 'botnet.' They use a network of infected computers to route their emails, making it much harder to trace back to the original source. But here's something else—there's a suspicious encoded string in one of the 'Received' headers. It’s uncommon to see this in regular emails."</p> <p class="s_direction">The task force member points to a string of characters in the metadata.</p> <div class="metadata-container" style="width: 100%; overflow: auto; color: black; background-color: #f4f4f4; border: 1px solid #ccc; padding: 10px; border-radius: 5px;"> <pre style="white-space: pre-wrap; word-wrap: break-word; font-size: 0.9em;"> Received: from unknown (HELO server) ("encoded-string: e0e35e50f9f8") </pre> </div> <p class="speech"><b>Task Force Member:</b> "This encoded string could be a signature or an identifier used by the attacker. If we decrypt this, it might give us more insight into the origin or purpose of this attack."</p> <p class="speech"><b>Task Force Leader:</b> "So, it's not just about the path the email took, but also about the hidden clues embedded in the transmission. Let’s see if we can decrypt this string and find out more."</p> [[Decrypt the String->Decryption]] (display: "Sidebar") (display: "SidebarBack") <h1>Decrypting the Hidden String</h1> <p class="s_direction">The task force sets up a decryption tool on their secure workstation. Lines of code scroll across the screen as they input the encoded string found in the email metadata.</p> <p class="speech"><b>Task Force Member:</b> "This string looks like it’s been encoded using a simple cipher. Let's see if we can break it."</p> <p class="s_direction">They run the decryption process, and after a few moments, the encoded string is converted into plain text on the screen.</p> <div class="decrypted-message" style="width: 100%; overflow: auto; color: black; background-color: #f4f4f4; border: 1px solid #ccc; padding: 10px; border-radius: 5px;"> <pre style="white-space: pre-wrap; word-wrap: break-word; font-size: 0.9em;"> Decoded Message: "<span class='clue'>{ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] }</span> - Sighting #47" </pre> </div> <p class="speech"><b>Task Force Member:</b> "‘<span class='clue'>{ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] }</span>’... It looks like the attacker has given themselves a code name. 'Sighting #47' could mean this is the 47th time they've used this alias or launched a similar attack."</p> <p class="speech"><b>Task Force Leader:</b> "So we’re not dealing with an amateur. They’ve done this enough to give themselves a name and track their own attacks."</p> <p class="speech"><b>Mr. Luddite:</b> "Why call themselves '<span class='clue'>{ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] }</span>'? Is it supposed to mean something?"</p> <p class="speech"><b>Task Force Member:</b> "Could be symbolic, or maybe just a personal choice. What matters is that it gives us something to work with. This isn't just a random hit—it’s part of a pattern they’ve been establishing."</p> <p class="s_direction">The team absorbs the information, realizing that the attacker is experienced and methodical. However, this clue is just a small piece of the larger puzzle.</p> <p class="speech"><b>Task Force Leader:</b> "Alright, let's keep this in mind. '<span class='clue'>{ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] }</span>' might come up again. For now, we continue our search for more concrete evidence."</p> [[Regroup and Plan Next Steps->Phishing Decision]] (display: "Sidebar") (display: "SidebarBack") <!-- Set clue14 to true and increment cluesFound --> (if: $clue14_found is not true)[ (set: $clue14_found to true) (set: $cluesFound to $cluesFound + 1) ] (set: $investigateSenderCompleted to true) <h1>Phishing Wrap Up</h1> <p class="speech"><b>Task Force Leader:</b> "Okay team, let’s take a moment to summarize what we’ve uncovered so far. We’ve been able to identify that the phishing emails were the first stage of the attack, and we’ve followed the clues carefully to understand how the attacker gained access. Here’s what we’ve learned so far."</p> <p>[[What is phishing?]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>The Nature of Phishing</h1> <p class="speech"> "We’ve seen how phishing emails are designed to trick people into clicking malicious links or sharing personal information. The attacker in our scenario used emails that looked like they came from someone we trust, but they were actually designed to steal credentials. This highlights one of the key principles of online safety—always be cautious with emails and messages, especially if something seems off or too good to be true." </p> <p>[[Verification]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Spotting Suspicious Email Behaviour</h1> <p class="speech"> "We took a closer look at the sender’s email address and the suspicious domain randomgenerated.com. This shows us that attackers often use fake email generators or free domains to create seemingly legitimate email addresses. What we’ve learned is that you should always verify the sender’s identity when something looks suspicious. Your digital reputation and identity can be at risk if you don’t take steps to verify who you’re communicating with." </p> <p>[[Critical Thinking]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Investigating the Links</h1> <p class="speech"> "When we looked at the links in the phishing emails, we noticed they led to a fake website designed to look like a real one. This is a critical part of phishing attacks—tricking users into thinking they’re logging into a trusted site. By carefully analyzing the links, we were able to avoid this trap and uncover a clue hidden in the source code. This reminds us how important it is to be critical of online information and not just click links without checking their source." </p> <p>[[Staying Safe Online]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Discussion of Mr. Luddite and Fake News (Media Literacy and Critical Thinking)</h1> <p class="speech"><b>Task Force Leader:</b> "We also saw how Mr. Luddite kept insisting on the ViperWorm theory, based on the fake news stories he found online. This is a good reminder of the importance of media literacy—not everything you see online is true."</p> <p class="speech"><b>Task Force Member:</b> "Exactly. The fake articles about ViperWorm were exaggerated and filled with false information, designed to mislead readers. If we had followed that path, we would’ve been wasting time on something that wasn’t real."</p> <p class="speech"><b>Task Force Leader:</b> "This highlights the importance of being critical of online sources. Just because a news story looks sensational or shocking doesn’t mean it’s reliable. We need to verify sources, check for credible information, and avoid spreading misinformation."</p> <p class="speech"><b>Mr. Luddite (defensively):</b> "Well, I still think there was something there, but… okay, I get it. Not every story is true."</p> <p class="speech"><b>Task Force Leader:</b> "It’s also important to recognize how fake news can spread during real-world events, like a cyber attack, to create confusion and divert attention. Attackers often use misinformation to distract people from what’s really going on."</p> <p class="speech"><b>Task Force Member:</b> "That’s right. Knowing how to recognize fake news and understanding how it’s used as a tactic can help us focus on the facts and avoid falling for these traps."</p> <p>[[Phishing Conclusion]]</p> (display: "Sidebar") (display: "SidebarBack") Discussion of Mr. Luddite and Fake News (Media Literacy and Critical Thinking) Task Force Leader: "We also saw how Mr. Luddite kept insisting on the ViperWorm theory, based on the fake news stories he found online. This is a good rexminder of the importance of media literacy—not everything you see online is true." Task Force Member: "Exactly. The fake articles about ViperWorm were exaggerated and filled with false information, designed to mislead readers. If we had followed that path, we would’ve been wasting time on something that wasn’t real." Task Force Leader: "This highlights the importance of being critical of online sources. Just because a news story looks sensational or shocking doesn’t mean it’s reliable. We need to verify sources, check for credible information, and avoid spreading misinformation." Mr. Luddite (defensively): "Well, I still think there was something there, but… okay, I get it. Not every story is true." Task Force Leader: "It’s also important to recognize how fake news can spread during real-world events, like a cyber attack, to create confusion and divert attention. Attackers often use misinformation to distract people from what’s really going on." Task Force Member: "That’s right. Knowing how to recognize fake news and understanding how it’s used as a tactic can help us focus on the facts and avoid falling for these traps." [[Phishing Conclusion]] (display: "Sidebar") (display: "SidebarBack")<h1>Task Force Leader’s Conclusion</h1> <p class="speech"><b>Task Force Leader:</b> "So, in summary, we’ve uncovered how phishing attacks work, how attackers disguise their emails, and how they try to steal information using deception and hidden messages. We also learned how fake news can be used to create confusion and why it’s critical to remain skeptical of sensational headlines online. We still have more work to do, but we’re getting closer to identifying the person behind this attack. As we continue, remember to stay cautious online and use the critical thinking skills we’ve practiced here today."</p> <p class="speech"><b>Task Force Leader:</b> "Now that we’ve identified phishing as the initial attack vector, it’s time to decide where we go next. We still have other branches of this investigation to explore, and the more clues we find, the closer we’ll get to uncovering the full truth behind this cyber attack."</p> <!-- Mark the Phishing Branch as completed --> (set: $phishing_completed to true) <p>You've completed the Phishing Threat investigation!</p> <!-- Redirect back to the Decision Point --> <p>[[Return to Decision Point->Vote]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Wait for Audience Response</h1> <p class="speech"><b>Task Force Leader:</b> "Let’s take a look at the responses coming in..."</p> <p class = "s_direction">Waits for the audience to submit responses on Mentimeter.</p> <p>[[Proceed]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Mentimeter Feedback</h1> <p class="speech"><b>Task Force Member:</b> "Looks like you’ve covered a lot of ground—great answers! We’ve got viruses, spyware, trojans, ransomware, adware... and even some more obscure ones like keyloggers."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. <strong>Malware</strong> is a broad term that includes many different types of harmful software. Some steal information, some track what you’re doing, and others, like ransomware, lock you out of your own files."</p> <p class="speech"><b>Task Force Member:</b> "But we don’t know what kind we’re dealing with yet, so we’re going to take a closer look at this suspicious file and see if we can figure it out."</p> <p class="speech"><b>Mr. Luddite:</b> "I still say we just open it. What’s the worst that could happen?"</p> <p class="speech"><b>Task Force Leader:</b> "Well, Mr. Luddite, that’s exactly what we’re about to find out."</p> <p>[[Emily Davis’s Frustration]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Check File Properties</h1> <p class="speech"><b>Task Force Leader:</b> "Let’s take a look at the file properties and see if we can gather some basic information about this malware."</p> <p class = "s_direction">The task force brings up the file properties on the screen.</p> <p>[[Check Properties]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Check File Properties</h1> <p class="speech"><b>Task Force Leader:</b> "Let’s take a look at the file properties and see if we can gather some basic information about this malware."</p> { <div style="background-color: white; padding: 20px; border: 1px solid #ccc; border-radius: 5px; color: black; text-align: left;"> <h2>File Properties</h2> <p><strong>File Name:</strong> ImportantDocument.exe</p> <p><strong>File Type:</strong> Executable File (.exe)</p> <p><strong>File Size:</strong> 52.4 MB</p> <p><strong>Location:</strong> C:\Users\Documents\</p> <p><strong>Created On:</strong> 2024-02-12 14:36:21</p> <p><strong>Modified On:</strong> 2024-02-12 14:37:02</p> <p><strong>Accessed On:</strong> 2024-02-15 09:22:47</p> <p><strong>Digital Signature:</strong> None</p> <p><strong>File Publisher:</strong> Unknown</p> <p><strong>File Description:</strong> Important Document</p> <h3>Security Status:</h3> <p><strong>Antivirus Scan:</strong> Flagged as Suspicious</p> <p><strong>Threat Level:</strong> High Risk</p> <h3>Metadata:</h3> <p><strong>File Hash (SHA-256):</strong> 3fae23c18d9abdb17c8b42c3fdb776e5e5b63f4b9fa174f99de7d11f5cf7b214</p> <p><strong>Associated Domains:</strong> randomsite.com, phishingtrap.org</p> <p><strong>Network Behavior:</strong> Attempts to connect to external IP: 192.168.1.45</p> </div> } <p class = "speech"><b>Task Force Leader:</b>Hmmm, what do you notice here?</p> [[Continue->What do you notice here?]] <h1>File Properties Interaction</h1> <p class="speech"><b>Task Force Leader:</b> "Let’s take a closer look at this file. Here are its properties, but something about it doesn’t seem right."</p> <p class="speech"><b>Task Force Member:</b> "We’ve got a few red flags here, but we want you to help us decide what to investigate first. Which part of the file properties looks the most suspicious to you?"</p> <ol> <li><strong>File Size:</strong> 52.4 MB</li> <li><strong>File Name:</strong> ImportantDocument.exe</li> <li><strong>No Digital Signature:</strong></li> </ol> [[Proceed->Malware Choice]]<h1>File Size Explanation</h1> <p class="speech"><b>Task Force Leader:</b> "You’re right. The file size is suspicious. It’s way too large for a normal document, suggesting it’s hiding more than it lets on."</p> <p class="speech"><b>Task Force Member:</b> "That’s a common trick. Malware often disguises itself as large files to avoid detection. The larger the file, the easier it can embed malicious code without raising suspicion."</p> <p class="speech"><b>Mr. Luddite:</b> "So it’s not what it looks like—definitely fishy."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Let’s see what else we can find."</p> <p>[[Continue->File Opening Decision]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>File Name Explanation</h1> <p class="speech"><b>Task Force Member:</b> "Good eye! 'ImportantDocument.exe' is a classic trick. Malware often uses names that seem important to the user, hoping someone will open it without thinking."</p> <p class="speech"><b>Task Force Leader:</b> "But the '.exe' file extension shows it’s an executable file, not a document. That’s a huge red flag."</p> <p class="speech"><b>Mr. Luddite:</b> "So it’s not really an important document after all?"</p> <p class="speech"><b>Task Force Leader:</b> "Nope. It’s malware pretending to be one. We’ll need to be careful."</p> <p>[[Continue->File Opening Decision]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Digital Signature Explanation</h1> <p class="speech"><b>Task Force Leader:</b> "The lack of a digital signature is a huge red flag. Legitimate software typically comes with a digital signature from its publisher, verifying it’s safe to use."</p> <p class="speech"><b>Task Force Member:</b> "If there’s no signature, that means we don’t know where this file came from. It could be malware—or worse."</p> <p class="speech"><b>Mr. Luddite:</b> "So we can’t trust it?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. No digital signature means it could have been created by anyone—likely the attacker."</p> <p>[[File Opening Decision]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>File Opening Decision</h1> <p class="speech"><b>Task Force Leader:</b> "We’ve learned a lot from the file properties, but now it’s time to dig deeper and figure out what this malware does."</p> <p class="speech"><b>Task Force Member:</b> "We could run a system analysis and check if it’s already affecting any files or settings. That would be the safest option."</p> <p class="speech"><b>Task Force Leader:</b> "This is a critical moment. What should we do, team? Should we run a safe analysis, or open the file and dive right in?"</p> <p>[[Luddite Malware Arguments]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Mr. Luddite’s Argument</h1> <p class="speech"><b>Mr. Luddite:</b> "Come on, everyone! We’re overthinking this. I’ve been using computers for years, and I’ve never once gotten a virus on my <strong>Mac</strong>. They’re practically immune! And don’t even get me started on <strong>Linux</strong>—that system’s a fortress!"</p> <p class="speech"><b>Task Force Leader:</b> "Mr. Luddite, we’ve identified this file as highly suspicious. We need to be cautious."</p> <p class="speech"><b>Mr. Luddite:</b> "Cautious, schmautious! Malware is just a scare tactic. The real problem here is the time we’re wasting. Just open the file already, and let’s move on!"</p> <p class="speech"><b>Task Force Member:</b> "Mr. Luddite, that’s not how cybersecurity works. Macs and Linux systems aren’t immune to viruses."</p> <p class="speech"><b>Mr. Luddite:</b> "Oh, please. The only ‘virus’ I’ve ever had on my Mac was a bad Wi-Fi connection! And as for Linux, it’s so obscure, no hacker even bothers with it. Trust me, nothing’s going to happen. Let’s just open the file and be done with it."</p> <p class="speech"><b>Task Force Leader:</b> "I appreciate your confidence, but this isn’t a risk we can take lightly. Still, it’s up to the audience to decide."</p> <!-- Check if Sarah Lee is a suspect --> { (if: $suspect5_found is true)[ <p class="s_direction">Sarah Lee stands back, not wanting to engage with Luddite's confidence.</p> ] (else:)[ <p class="speech"><b>Sarah Lee:</b> "Mr. Luddite, that’s just idiotic! You can’t treat this like a joke. We need to take the threat seriously!"</p> ] } <p>[[Agree with Mr. Luddite and Open the File->Open the File]]</p> <p>[[Ignore Mr. Luddite and Run a Scan First->Run System Analysis]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Interactive Decision</h1> <!-- Image with reduced bottom margin --> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <ol> <li><strong>Run System Analysis</strong></li> <li><strong>Open the File</strong></li> </ol> <p class="speech"><b>Task Force Leader:</b> "Make your choice carefully—we don’t know exactly what we’re dealing with."</p> <p> [[Run System Analysis->Run System Analysis]]<br> [[Open the File->Open the File]]<br> [[Run Away]] </p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Run System Analysis</h1> <p class="speech"><b>Task Force Leader:</b> "Excellent decision, team! Running a system analysis before acting is a key part of responsible cybersecurity behavior."</p> <p class="speech"><b>Task Force Member:</b> "Exactly. Identifying potential risks and running appropriate analysis tools is essential to protect our systems and data!"</p> <p class="speech"><b>Mr. Luddite:</b> "Pfft, overkill if you ask me… you’re all just paranoid."</p> <p class = "s_direction">The system analysis begins, and the team watches the screen.</p> <p class="speech"><b>Task Force Member:</b> "We’ve got something! The analysis shows the file is infected with ransomware—it’s designed to encrypt everything on the system."</p> <p>[[Continue->Luddite Opens File]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Open the File</h1> <p class="speech"><b>Task Force Leader:</b> "Okay, you’ve chosen to open the file. But let this be a lesson in <strong>digital citizenship</strong>: always make <strong>informed decisions</strong> based on the evidence in front of you."</p> <p class="speech"><b>Task Force Member:</b> "You should evaluate risks carefully before taking action. But, if you’re sure, let’s proceed."</p> <p class="speech"><b>Mr. Luddite:</b> "Finally! Now you’re talking my language." He smirks as the file is opened.</p> <p>[[Continue->Encounter Ransomware]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Run Away</h1> <p class="speech"><b>Task Force Member:</b> "Run for it! This file is too dangerous!"</p> <p class="speech"><b>Task Force Leader:</b> "No, stop! Everyone calm down! We need to think this through."</p> <p>[[Continue->Luddite Opens File]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Luddite Opens File</h1> <p class="speech"><b>Mr. Luddite:</b> (grinning) "I’ll handle this, no problem." He opens the file while the others panic.</p> <p class = "s_direction">The system locks down immediately.</p> <p class="speech"><b>Task Force Leader:</b> "Luddite, what have you done?!"</p> <p class="speech"><b>Mr. Luddite:</b> "What? I thought someone had to do something!"</p> <!-- Check if Sarah Lee is a suspect --> { (if: $suspect5_found is true)[ <p class="speech"><b>Sarah Lee:</b> (laughing hysterically) "This is just too rich! You really thought that was a good idea?"</p> ] (else:)[ <p class="speech"><b>Sarah Lee:</b> (distraught) "This is a disaster! What were you thinking, Luddite?"</p> ] } <!-- Check if Emily Davis is a suspect --> { (if: $suspect3_found is true)[ <p class="speech"><b>Emily Davis:</b> "Oh, that's just wonderful! How much will this cost to fix?"</p> ] (else:)[ <p class="s_direction">Emily Davis remains silent, her expression reflecting disbelief.</p> ] } <p>[[Continue->Encounter Ransomware]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>System Lockdown</h1> <div id="screen" style="background-color: black; color: white; padding: 20px; border: 2px solid #ccc; position: relative; overflow: hidden;"> <p>The room is silent as the task force waits for the file to open. But soon, the screen starts to <strong>flicker</strong>, the colors distorting in jagged lines. The cursor slows down, jerking across the screen as the system starts to malfunction.</p> <p class="speech"><b>Task Force Leader:</b> (tense) "Something’s not right."</p> <p class="speech"><b>Task Force Member 1:</b> (worried) "The file isn’t responding. I think… I think it’s locking up."</p> <div id="flicker-message" style="display: none; font-size: 24px; font-weight: bold; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"> <p>**BAM!**</p> <p>**"Encrypting Files..."**</p> </div> </div> <p class="speech"><b>Task Force Leader:</b> "No… No, no, no!"</p> <p> [[Encrypting Files]] </p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <style> @keyframes flicker { 0% { opacity: 1; } 25% { opacity: 0.5; } 50% { opacity: 1; } 75% { opacity: 0.5; } 100% { opacity: 1; } } @keyframes colorTransition { 0% { background-color: black; color: white; } 50% { background-color: red; color: white; } 100% { background-color: darkred; color: white; } } #screen { animation: flicker 0.1s infinite; } </style> <script> // Simulate flickering and color transition setTimeout(() => { document.getElementById('screen').style.animation = 'none'; // Stop flickering document.getElementById('screen').style.animation = 'colorTransition 2s forwards'; // Start color transition // Show the "Files Encrypted" message after the transition setTimeout(() => { document.getElementById('screen').innerHTML = "<p style='font-size: 36px; font-weight: bold; text-align: center; color: white;'>FILES ENCRYPTED</p>"; }, 2000); // Show message after 2 seconds of color transition }, 3000); // Flicker for 3 seconds before starting the color transition </script> <h1>System Lockdown Continues</h1> <p class="speech"><b>Mr. Luddite:</b> (nervous) "Uh… okay, that’s not what I was expecting. I mean, it’s just a little encryption, right?"</p> <p class = "s_direction">The system emits a series of <strong>sharp beeps</strong> as the screen flickers again, the message growing more urgent: <strong>"Your files have been encrypted."</strong></p> <p class="speech"><b>Task Force Member 2:</b> (panicked) "We’re locked out! It’s taken over the entire system!"</p> <p class="speech"><b>Task Force Member 3:</b> (frantically) "I’m trying to type commands, but nothing works!"</p> <p class="speech"><b>Task Force Leader:</b> "This is exactly what we were trying to avoid! Everything’s been encrypted."</p> <p class = "s_direction">The computer lets out a loud <strong>alarm</strong>.</p> <p class = "speech"><b>Mr. Luddite:</b> (panicking) "W-What’s happening?! Why isn’t it stopping?! I thought Macs don’t get viruses! I thought Linux was safe!"</p> <p class="speech"><b>Task Force Member 1:</b> (shouting) "We’re completely locked out! Everything’s encrypted, and we can’t access a single file!"</p> <p>[[Continue->blaring alarm]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>System Lockdown Continues</h1> <!-- Audio element for the repeating sound --> <audio id="alarm-audio" src="https://static.wixstatic.com/mp3/27b368_e86148280b654089bcd9837275807638.mp3" autoplay loop></audio> <div id="screen" style="background-color: black; color: white; padding: 20px; border: 2px solid #ccc; position: relative; overflow: hidden;"> <p>The screen suddenly <strong>flashes bright green</strong>, a bold message plastered across the screen:</p> <p style="font-size: 36px; font-weight: bold; color: lime;">**"Pay 10 Bitcoin to unlock your system."**</p> </div> <p>[[Next]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>System Lockdown Continues</h1> <p class="speech"><b>Mr. Luddite:</b> (stammering) "Bitcoin?! We have to pay how much?! This is bad. This is really bad!"</p> <p class="speech"><b>Task Force Leader:</b> (furious) "Calm down, Luddite! This is why we don’t open suspicious files!"</p> <p class = "s_direction">The task force is in chaos. One team member bangs on the keyboard in frustration, while another tries futilely to shut down the system. But Mr. Luddite, pale-faced and sweating, stares wide-eyed at the screen, his usual arrogance replaced by sheer terror.</p> <p class="speech"><b>Mr. Luddite:</b> (whining) "I-I didn’t think this would actually happen! Why didn’t you stop me?!"</p> <p class="speech"><b>Task Force Leader:</b> (exasperated) "We tried!"</p> <p class="speech"><b>Task Force Member 2:</b> (frantically) "We’re losing everything… it’s all encrypted. We can’t undo this without paying the ransom."</p> <p class="speech"><b>Mr. Luddite:</b> (desperate) "Well, pay it! Pay whatever it takes! I-I can’t handle this!"</p> <p class="speech"><b>Task Force Leader:</b> (gritting teeth) "You really messed up, Luddite."</p> <p class = "s_direction">The task force watches in tense silence as the green ransom screen blinks ominously, demanding Bitcoin in exchange for their locked files.</p> <p>[[Continue->Continue]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Ransomware Decision Point</h1> <p class="s_direction">The green ransom message blinks ominously on the screen:</p> <p class="speech"><b>"Pay 10 Bitcoin to unlock your system."</b></p> <p class="speech"><b>Task Force Leader:</b> "This is where things get tricky. We have three options, and none of them are perfect."</p> <p class="speech"><b>Task Force Member 1:</b> "We could pay the ransom, but there’s no guarantee we’ll get our files back."</p> <p class="speech"><b>Task Force Member 2:</b> "Or we could try restoring from backups, but if the backups are infected, we’re out of luck."</p> <p class="speech"><b>Task Force Leader (pausing dramatically):</b> "And then... we have my wildcard. But it’s risky, and we’ll need to make sure it’s the right move."</p> <p class="speech"><b>Mr. Luddite (panicking):</b> "Wildcard? Who cares about wildcards?! Just pay the ransom and get it over with!"</p> <p class="speech"><b>Task Force Leader (stern):</b> "No. This decision is up to the audience."</p> <!-- Image with reduced bottom margin --> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <div style="text-align: center;"> { (if: $ransom_paid is not true)[ <span style="display:block; margin-bottom:5px;">[[Pay the Ransom->Pay Ransom]]</span> ] (else:)[ <span style="display:block; margin-bottom:5px;">You’ve already decided to pay the ransom.</span> ] } { (if: $backups_restored is not true)[ <span style="display:block; margin-bottom:5px;">[[Restore from Backups->Restore Backups]]</span> ] (else:)[ <span style="display:block; margin-bottom:5px;">You’ve already attempted to restore from backups.</span> ] } { (if: $wildcard_used is not true)[ <span style="display:block; margin-bottom:5px;">[[Use the Wildcard->Anti-Malware Reveal]]</span> ] (else:)[ <span style="display:block; margin-bottom:5px;">You’ve already used the wildcard.</span> ] } </div> (display: "Sidebar") (display: "SidebarBack") <h1>Pay Ransom</h1> <p class="speech"><b>Mr. Luddite:</b> (frantically) "We don’t have time for all this! Look, if we just pay the ransom, it’ll all go back to normal. Right? We pay, they give us the files, problem solved!"</p> <p class = "s_direction">He gestures wildly at the screen, where the ransom demand blinks: <strong class="ransom-message">"Pay 10 Bitcoin to unlock your system."</strong></p> <p class="speech"><b>Task Force Member 2:</b> (nervously) "It’s a lot of money, but what if it’s the only way to get everything back?"</p> <p class="speech"><b>Mr. Luddite:</b> (panicking) "Exactly! We can’t mess around. We need to act NOW! Just pay them, and this all goes away!"</p> <p class="speech"><b>Task Force Leader:</b> (calm but firm) "Hold on. Paying the ransom isn’t the guaranteed solution you think it is. In fact, it could make things worse."</p> <p class="speech"><b>Task Force Member 1:</b> (serious) "There’s no guarantee they’ll unlock the files after we pay. Once we hand over the money, they could demand more or leave us locked out anyway."</p> <p class="speech"><b>Mr. Luddite:</b> (desperate) "But... but they’ll unlock it, right? They have to! That’s the deal!"</p> <p class="speech"><b>Task Force Leader:</b> (firm) "Cybercriminals don’t play by any rules. They prey on fear and desperation. Paying them only encourages more attacks."</p> <p class="speech"><b>Task Force Member 2:</b> (nodding) "Once you give in to their demands, you’re giving them all the power. And even if they do unlock the files, it could come at a bigger cost—more attacks in the future."</p> <p class="speech"><b>Mr. Luddite:</b> (frantic) "But what other choice do we have?! We need to get those files back!"</p> <p class="speech"><b>Task Force Leader:</b> (serious) "There are always better ways to handle this. Paying the ransom is never a sure solution. We need to trust our skills, our tools, and our plans. There are other options."</p> <p class="speech"><b>Mr. Luddite:</b> (shaking, desperate) "I... I don’t know. This is bad. Really bad."</p> <p>[[Continue->Pay Ransom2]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <style> .ransom-message { color: red; font-size: 24px; font-weight: bold; padding: 10px; border: 2px solid red; animation: blink 1s step-start infinite; display: inline-block; /* Keeps it centered */ } @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } } </style> <h1>Restore Backups</h1> <p class="speech"><b>Task Force Leader:</b> (sighing) "Restoring from backups is a gamble, especially if they’re not kept up-to-date, but it’s our best shot right now."</p> <p class="speech"><b>Task Force Member 1:</b> (looking around) "Where are the backups? We need them fast!"</p> <p class = "s_direction">The team starts looking around the room, rummaging through old drawers and cabinets, searching for the backup drive.</p> <p class = "s_direction">Suddenly, <strong>Alex Johnson</strong>, the <strong>IT Technician</strong>, hesitates before speaking up.</p> <!-- Check if Alex Johnson is a suspect --> { (if: $suspect1_found is true)[ <p class="speech"><b>Alex Johnson:</b> (nervously) "I know where they are, but... I don’t think they’ll work."</p> ] (else:)[ <p class="speech"><b>Alex Johnson:</b> (nervously) "I, uh... I think I might know where they are."</p> ] } <p class="speech"><b>Task Force Leader:</b> (hopeful) "You do? Great! Go find them—take someone with you."</p> <p class = "s_direction">Alex and a <strong>task force member</strong> quickly head out of the room in search of the backups. As the door closes behind them, the remaining team members exchange anxious glances.</p> <p>[[Exposition]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Anti-Malware Reveal (The Wildcard)</h1> <p class="s_direction">The ransom screen blinks in front of the team, taunting them with its demand: <div id="ransom-box" style="text-align: center; padding: 20px; border: 2px solid red; background-color: black;"> <strong class="ransom-message">"Pay 10 Bitcoin to unlock your system."</strong> </div> <p class="speech"><b>Task Force Member 1:</b> (exasperated) "We’re stuck. We can’t do anything unless we pay the ransom!"</p> <p class="speech"><b>Task Force Member 2:</b> (looking defeated) "There’s no way around it. They’ve locked everything. We’re completely frozen out."</p> <p class="speech"><b>Mr. Luddite:</b> (panicking) "This is what I’ve been saying the whole time! Just pay them, and this all goes away."</p> <p class="speech"><b>Task Force Leader:</b> (calm but firm) "We don’t pay criminals."</p> <p class="speech"><b>Task Force Member 3:</b> (frustrated) "Then what else can we do? There’s no way to get any tools into the system with it locked down like this!"</p> <p class="speech"><b>Mr. Luddite:</b> (sarcastic) "I don’t know, maybe we should just turn it off and on again and hope for the best."</p> <p class="s_direction">The team looks at each other in silent defeat. It seems like the only option left is paying the ransom.</p> <p>[[Continue->Task Force Hero]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> (display: "Sidebar") (display: "SidebarBack")<h1>Backup Concerns</h1> <p class="speech"><b>Task Force Member 2:</b> (thinking aloud) "Let’s just hope the backups are up-to-date. Otherwise, we’re in serious trouble."</p> <p class="speech"><b>Task Force Leader:</b> (serious) "That’s why keeping secure backups is so important. They’re your last line of defense in situations like this."</p> <p class="speech"><b>Mr. Luddite:</b> (rolling his eyes) "Yeah, yeah, we get it. But if those backups are as ancient as everything else around here, we’re done for."</p> <p class="speech"><b>Task Force Leader:</b> "Let’s stay positive. They’ll come back with something... I hope."</p> <p>[[Continue->IT Technician Returns]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>IT Technician Returns with the Floppy Disk</h1> <p class = "s_direction">After a few tense moments, the <strong>IT technician</strong> reappears, sheepishly holding up something in their hand.</p> <p class="speech"><b>Alex Johnson:</b> (sheepishly) "Uh... I think I found them."</p> <p class = "s_direction">Everyone freezes as they stare at what the technician is holding—a <strong>d dusty old floppy disk</strong>.</p> <img src="https://static.wixstatic.com/media/27b368_a18d8c1b2cd049268992f7af77a0ab3a~mv2.gif" alt="floppy" style="width: 25%; height: 25%;"> [[Continue->IT Return2]] <h1>Backup Attempt</h1> { <p class = "s_direction">The team watches in disbelief as the <strong>floppy disk</strong> is inserted into the computer’s drive. The machine grinds as it tries to read the ancient disk, and the screen flickers to life, showing a <span class="windows95">Windows 95</span> loading screen.</p> <p class="speech"><b>Task Force Member 2:</b> (hopeful) "It’s doing something... maybe it’ll work?"</p> <p class = "s_direction">The system tries to boot, but then the screen glitches, showing a <span class="windows95">frozen Windows 95 logo</span>.</p> <img src="https://static.wixstatic.com/media/27b368_5e3d18579c4345f6867522218db6e2f0~mv2.webp" alt="Windows 95" style="width: 25%; height: 25%;"> } [[Continue->Restore]] (display: "Sidebar") (display: "SidebarBack") <h1>The Stick of Truth</h1> <p class="s_direction">Suddenly, the <strong>Task Force Leader</strong> steps forward, removing his jacket and running a hand through his hair.</p> <p class="speech"><b>Task Force Leader:</b> (dramatically) "All my years in the service... so many times I’ve battled this foe. I thought I was done with this. Thought I could leave it behind."</p> <p class="s_direction">The team looks at him in confusion.</p> <p class="speech"><b>Task Force Member 1:</b> (puzzled) "Sir, what are you talking about?"</p> <p class="speech"><b>Mr. Luddite:</b> (scoffing) "Great, now we’ve lost him too."</p> <p class="speech"><b>Task Force Leader:</b> (sighing) "But I guess desperate times call for desperate measures."</p> <p class="s_direction">He reaches into his jacket pocket, pulling out a small, battered <strong>USB stick</strong>. The team stares in disbelief.</p> <p class="speech"><b>Task Force Leader:</b> (quietly, but with weight) "This... is the <strong>Stick of Truth</strong>."</p> <p>[[TheStickOfTruth]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Reboot and Scan with the Stick of Truth</h1> <p class="speech"><b>Task Force Leader:</b> (commanding) "A good choice! That program got me out of a NFT scam in '21. Reboot the system. Let’s get this done."</p> <p class="s_direction">The computer hums back to life. The screen flickers, and after a few tense moments, a loading bar appears as the anti-malware tools start scanning the system.</p> <p class="speech"><b>Task Force Member 2:</b> (hopeful) "It’s running the scan... detecting malware."</p> <p class="speech"><b>Task Force Leader:</b> (focused) "It’s isolating the ransomware. Come on..."</p> <p class="speech"><b>Mr. Luddite:</b> (panicking) "It’s not working! I told you this was a bad idea!"</p> <p class="speech"><b>Task Force Leader:</b> (gritting teeth) "Just wait."</p> <p class="s_direction">The screen flickers back to life, and a message appears: <strong>"Infection Removed. System Restored."</strong></p> <p class="speech"><b>Task Force Member 1:</b> (relieved) "It worked! The Stick of Truth saved the system!"</p> <p>[[Continue->The Aftermath]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>The Aftermath</h1> <p class="s_direction">The ransomware message is gone. The system is restored, and the team breathes a collective sigh of relief.</p> <p class="speech"><b>Task Force Leader:</b> (smiling slightly) "That’s why you always come prepared."</p> <p class="speech"><b>Mr. Luddite:</b> (grumbling) "Okay, maybe that wasn’t the worst idea."</p> <p class="speech"><b>Task Force Leader:</b> (half-smirking) "Better than paying 10 Bitcoin, don’t you think?"</p> <p class="s_direction">The <strong>Task Force Leader</strong> grabs his jacket, throwing it back over his shoulder.</p> <p class="speech"><b>Task Force Leader:</b> (quietly, as if to himself) "Just when I thought I was out... they pull me back in."</p> <p>[[Continue->Clue - ScrambledName]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Fourth Clue: Scrambled Hacker's Name</h1> <p class="speech"><b>Task Force Member:</b> "We’ve recovered a crucial clue related to the hacker’s name. This is not just another detail; it’s potentially the breakthrough we need."</p> <p class="speech"><b>Task Force Leader:</b> "The hacker’s name is central to identifying them. If we can decode this clue, we will have a significant lead in the investigation."</p> <p class="speech"><b>Task Force Member:</b> "Exactly. Knowing the hacker’s real name will help us connect all the dots. This is the clue that might reveal their true identity, which is crucial for solving this case."</p> <p class="speech"><b>Task Force Leader:</b> "We must approach this with precision. If we crack this scrambled name, it could provide the final piece needed to uncover the hacker’s true identity. Ensure that this clue is thoroughly investigated and properly logged."</p> <p class="s_direction"> The hacker's scrambled name is <b><span class="clue">{ (if: $suspectNum is 1)[Doha Mrkqvrq] <!-- Alex Johnson encrypted --> (else-if: $suspectNum is 2)[Ofrnj Ufwpjw] <!-- Jamie Parker encrypted --> (else-if: $suspectNum is 3)[Iqmpc Hezmw] <!-- Emily Davis encrypted --> (else-if: $suspectNum is 4)[Wkrpdv Uhhh] <!-- Thomas Reed encrypted --> (else-if: $suspectNum is 5)[Zhyho Sll] <!-- Sarah Lee encrypted --> (else-if: $suspectNum is 6)[Xuhkxz Hxuct] <!-- Robert Brown encrypted --> (else-if: $suspectNum is 7)[<p id="output"></p>] <!-- Reference to user input for Suspect 7 --> (else-if: $suspectNum is 8)[Rwvibpiv Tcllqbm] <!-- Jonathan Luddite encrypted --> (else:)[Unknown] }</span></b>. </p> [[Luddite Impatience]] (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable for this clue to true --> (if: $clue15_found is not true)[ (set: $clue15_found to true) (set: $cluesFound to $cluesFound + 1) ] <script> function caesarCipherEncrypt(str, shift) { return str.split('').map(char => { if (char.match(/[a-z]/i)) { const base = char.charCodeAt(0) < 97 ? 65 : 97; const encryptedChar = String.fromCharCode(((char.charCodeAt(0) - base + shift) % 26) + base); return encryptedChar; } return char; // Non-letter characters remain unchanged }).join(''); } // Automatically encrypt the user's name when the passage loads const inputString = window.harloweVariables.userName; // Get the Harlowe variable const encryptedString = caesarCipherEncrypt(inputString, 7); // Display the output document.getElementById('output').innerHTML = encryptedString; // Store the result back into a Harlowe variable window.harloweVariables.encryptedName = encryptedString; // Store it in a Harlowe variable </script> <h1>Mr. Luddite’s Impatience</h1> <p class="speech"><b>Mr. Luddite:</b> (excitedly) "So let’s do it! Let’s crack the code, find the perp, and get out of here!"</p> <p class="s_direction">He grabs a piece of paper, scribbling furiously as if trying to solve the puzzle himself.</p> <p class="speech"><b>Mr. Luddite:</b> (muttering) "Okay, let’s see how hard this can be!"</p> <p class="speech"><b>Task Force Leader:</b> (calm but firm) "Not so fast, Luddite. We need to gather more clues first."</p> <p class="speech"><b>Mr. Luddite:</b> (frustrated) "More clues?! You’ve got to be kidding me!"</p> <p class="speech"><b>Task Force Leader:</b> (smirking) "Patience, Luddite. We’ll get there. But we need to have all the pieces before we can solve this."</p> <p>[[Continue->Educational Wrap-Up]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Educational Wrap-Up (Malware Branch)</h1> <p class="speech"><b>Task Force Leader:</b> (addressing the group) "Let’s take a moment to review what we’ve learned from investigating the malware."</p> <p class="speech"><b>Task Force Member 1:</b> "We uncovered ransomware that locked the system, and we had to make tough decisions to get it back."</p> <p class="speech"><b>Task Force Leader:</b> (nodding) "That’s right. This situation highlights some key lessons about dealing with <strong>malware</strong>, especially when faced with ransomware."</p> <p>[[Continue->Key Skills Learned]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Key Skills Learned (Malware Focused, DCF-Aligned)</h1> <p class="s_direction"><strong>Cyber Resilience:</strong></p> <p class="speech"><b>Task Force Leader:</b> "One of the most important lessons we’ve learned is the importance of <strong>cyber resilience</strong>—being prepared with the right tools and knowing how to respond to cyberattacks. In our case, we used the <strong>anti-malware tools</strong> on the <strong>Stick of Truth</strong>, but in real life, it’s critical to always have up-to-date tools and systems ready."</p> <p class="s_direction"><strong>Data Protection and Backups:</strong></p> <p class="speech"><b>Task Force Leader:</b> "We also learned the importance of <strong>keeping backups up to date</strong>. When we tried to restore from those ancient backups, it didn’t work because they weren’t regularly maintained. Backups are only effective if they’re <strong>secure</strong> and <strong>current</strong>."</p> <p class="speech"><b>Task Force Member 2:</b> "That Windows 95 moment was a good reminder that outdated backups are almost as bad as no backups."</p> <p class="s_direction"><strong>Risk Management:</strong></p> <p class="speech"><b>Task Force Leader:</b> "There was also the decision of whether to pay the ransom. As we saw, paying cybercriminals doesn’t guarantee anything. In fact, it often leads to more demands. The best strategy is to have <strong>risk management protocols</strong> in place—like backups, anti-malware tools, and security updates—so you don’t have to rely on dangerous choices."</p> <p class="s_direction"><strong>Problem-Solving and Critical Thinking:</strong></p> <p class="speech"><b>Task Force Leader:</b> "In cybersecurity, <strong>problem-solving</strong> is key. When the system was locked, we had to evaluate our options, analyze the risks, and decide the best course of action. Jumping to pay the ransom would have been a mistake. Instead, we used <strong>critical thinking</strong> to choose the most effective solution."</p> <p>[[Continue->Final Remarks]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Malware Branch Complete</h1> <p class="speech"><b>Task Force Member 1:</b> "So, dealing with malware isn’t just about reacting—it’s about <strong>being prepared</strong>, having the <strong>right tools</strong>, and knowing what to do before the attack happens."</p> <p class="speech"><b>Task Force Leader:</b> (nodding) "Exactly. Cybersecurity is about <strong>staying ahead of threats</strong>. The more prepared we are, the better we can handle situations like this. It’s a balance between having the technical skills and making smart decisions."</p> <p class="speech"><b>Mr. Luddite:</b> (grumbling) "I guess the Stick of Truth wasn’t so bad after all."</p> <p class="speech"><b>Task Force Leader:</b> (smiling) "Next time, let’s rely on our tools and preparation to tackle the threats."</p> <p>You've completed the Malware investigation!</p> <!-- Mark the Malware Branch as completed --> (set: $malware_completed to true) <!-- Redirect back to the Decision Point --> <p>[[Return to Decision Point->Vote]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Pay the Ransom</h1> <p class="speech"><b>Task Force Leader:</b> (grimacing) "I can’t believe we’re actually doing this."</p> <p class="speech"><b>Task Force Member 1:</b> (nervous) "Maybe it’ll work? Maybe we’ll get our files back?"</p> <p class="speech"><b>Mr. Luddite:</b> (frantically) "Of course it’ll work! We pay them, they unlock everything, and we’re good to go!"</p> <p class="speech"><b>Task Force Leader:</b> (frustrated, but resigned) "I don’t like it... but I guess we don’t have another choice. Let’s get this over with."</p> <p>[[Continue->Payment]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Ransom Payment Confirmation</h1> <!-- Ransomware box --> <div id="ransom-box" style="text-align: center; padding: 20px; border: 2px solid red; background-color: black;"> <strong class="ransom-message">"Pay 10 Bitcoin to unlock your system."</strong> </div> <p class="s_direction">The <strong>Task Force Leader</strong> reluctantly enters the payment details. A tense silence fills the room as they wait for confirmation.</p> <p class="s_direction">The screen blinks twice, and the <strong>ransomware message</strong> fades away.</p> <p class="speech"><b>Task Force Member 2:</b> (hopeful) "It’s gone! We did it! The system’s back to normal!"</p> <p class="speech"><b>Mr. Luddite:</b> (smug) "See? Told you paying the ransom would work. Now we can finally get out of this mess."</p> <p class="s_direction"><b>Task Force Leader:</b> (still suspicious) "Hold on... let’s make sure everything’s actually back to normal."</p> <p class="s_direction">The system appears to be functioning properly. The desktop returns to normal, and the team begins to breathe a sigh of relief.</p> <p>[[Continue->Restoration?]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <style> .ransom-message { color: red; font-size: 24px; font-weight: bold; animation: blink 1s step-start infinite; /* Only the text will blink */ } @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } } </style> <script> // Function to hide the ransom box after a delay function hideRansomBox() { const ransomBox = document.getElementById('ransom-box'); setTimeout(() => { ransomBox.style.display = 'none'; // Hide after 3 seconds }, 3000); } // Ensure the function is called only when the content is fully loaded window.addEventListener('load', hideRansomBox); </script> <h1>The System Appears Restored... But Then...</h1> <p class="s_direction">Just as they start to relax, the screen flickers. Slowly, a new <strong>ransomware message</strong> begins to take over the screen, this time in a <strong>bright red color</strong>, replacing the previous green screen.</p> <p class="speech"><b>Task Force Member 1:</b> (panicked) "Wait... what’s happening now?!"</p> <p class="speech"><b>Task Force Member 2:</b> "No... it’s happening again!"</p> <p class="s_direction">The screen blinks rapidly, and a new, even more ominous <strong>ransomware message</strong> appears:</p> <p class="ransom-message" style="color: red; font-size: 24px; font-weight: bold; text-align: center;">"Pay 20 Bitcoin to unlock your system."</p> <p class="speech"><b>Mr. Luddite:</b> (shocked) "20 Bitcoin?! They just doubled the price!"</p> <p class="speech"><b>Task Force Leader:</b> (furious) "This is exactly why you don’t pay the ransom. Once you pay, they know you’re vulnerable. They can just hit you again and again."</p> <p>[[Continue->Aftermath2]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>The Aftermath</h1> <p class="s_direction">The team stares at the screen in frustration as the new ransom demand blinks ominously.</p> <p class="speech"><b>Task Force Member 1:</b> (defeated) "So... we’re back to square one. Again."</p> <p class="speech"><b>Task Force Leader:</b> (firmly) "Worse than that. Now they know we’re willing to pay. We’ve just made ourselves even more of a target."</p> <p class="speech"><b>Mr. Luddite:</b> (groaning) "So what do we do now?"</p> <p class="speech"><b>Task Force Leader:</b> (decisive) "What we should’ve done from the start. No more paying ransoms. We need to solve this ourselves, using the tools we have."</p> <p>[[Continue->Wrap-Up]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Educational Wrap-Up (Ransomware Payment)</h1> <p class="speech"><b>Task Force Leader:</b> (turning to the audience and the team) "Alright, let’s talk about what just happened."</p> <p class="speech"><b>Task Force Member 1:</b> (nodding) "We paid the ransom, and for a moment, it looked like everything was back to normal."</p> <p class="speech"><b>Task Force Leader:</b> (serious) "Exactly. But then what? The criminals hit us again, doubling the ransom. That’s what happens when you give in to their demands. Paying a ransom is never the solution. It only makes you more of a target."</p> <p class="speech"><b>Mr. Luddite:</b> (grumbling) "Well, what else were we supposed to do? We were stuck!"</p> <p class="speech"><b>Task Force Leader:</b> (calm but firm) "No, Luddite. We weren’t stuck. We had other options, but instead, we handed over control to the attackers. In cybersecurity, it’s all about being <strong>resilient</strong>—having a backup plan, the right tools, and the right mindset. Paying a ransom doesn’t protect you; it just encourages more attacks."</p> <p class="speech"><b>Task Force Member 2:</b> "So you’re saying we should focus on being prepared instead?"</p> <p class="speech"><b>Task Force Leader:</b> (nodding) "Exactly. <strong>Cyber resilience</strong> means having defenses in place before an attack happens—things like <strong>anti-malware tools</strong>, <strong>backups</strong>, and proper <strong>security protocols</strong>. The stronger those defenses are, the less likely you’ll ever have to consider paying a ransom."</p> <p class="speech"><b>Mr. Luddite:</b> (still doubtful) "But what if paying is the only way to get the files back?"</p> <p class="speech"><b>Task Force Leader:</b> (stern) "That’s what they want you to think. It’s all part of the strategy to make you panic and feel trapped. But paying is never a guarantee. Criminals don’t follow rules. They’ll just come back for more. That’s why <strong>risk management</strong> is key."</p> <p class="speech"><b>Task Force Member 1:</b> "We should be thinking about what could happen before the attack even starts, right?"</p> <p class="speech"><b>Task Force Leader:</b> (nodding) "Exactly. Cybersecurity is about <strong>preparing for risks</strong>, not just reacting to them. If we had strong backups, we wouldn’t even be having this conversation. Instead, we’d restore the system and move on without paying a cent."</p> <p class="speech"><b>Mr. Luddite:</b> (sighing) "So, what you’re saying is... we need to think before we act?"</p> <p class="speech"><b>Task Force Leader:</b> (smiling slightly) "That’s right, Luddite. <strong>Critical thinking</strong> is key. In any cyberattack, we have to weigh our options carefully and avoid jumping to quick fixes like paying a ransom. We need to solve the problem long-term, not just temporarily."</p> <p class="speech"><b>Task Force Member 2:</b> "So the lesson here is... prevention is better than reaction?"</p> <p class="speech"><b>Task Force Leader:</b> (firmly) "Exactly. In cybersecurity, the best defense is being prepared. The smarter and more resilient we are, the better we can handle threats when they come. And next time, we won’t be giving in to any demands."</p> <p class="speech"><b>Mr. Luddite:</b> (grumbling again) "Fine, fine. Next time we’ll go with the USB stick..."</p> <p>[[Continue]]</p> <!-- Set the variable to true --> (set: $ransom_paid to true) <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Data Spikes Discussion</h1> <p class="speech"><b>Task Force Member 1:</b> "Let’s put you in charge for a moment. Imagine it’s late at night, and you’re responsible for the school’s network. Suddenly, you notice a massive spike in network activity. What's your move?"</p> <img src="https://static.wixstatic.com/media/27b368_87cfabd10df845ff812e599590864133~mv2.png" alt="Network Activity Graph"> <p>[[Continue->Review Spikes Discussion]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Review Spikes Discussion</h1> <p class="s_direction">*The team reviews the audience’s responses, discussing the possibilities.*</p> <p class="speech"><b>Task Force Member 2:</b> "Great suggestions—these spikes could be anything from a large file transfer to someone backing up data. But we’ll need to dig deeper to find out what’s really going on."</p> <p class="s_direction">*The team pulls up a network traffic map showing devices and IPs connected to the system.*</p> <p>[[Continue->Network Traffic Map]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <img class="network-traffic" src="https://static.wixstatic.com/media/27b368_7f04bfcbbbfe44f6973cddf75b6d9a2c~mv2.png"> <p class="speech"><b>Task Force Leader:</b> "Alright team, let's start by looking at the network traffic flow. We need to identify any unusual patterns, spikes in data usage, or suspicious connections. Standard protocol."</p> <p class="s_direction">*The Task Force Member 1 brings up an interactive graph on the main screen, displaying the normal data transfer levels for the school’s network. The graph shows steady traffic with a few minor spikes.*</p> <p class="speech"><b>Task Force Member 1:</b> "Here we have the normal data transfer levels over the last few days. You can see these small spikes here and there—probably just routine uploads or teachers sharing resources."</p> <p class="s_direction">*The Task Force Member 1 uses a pointer to indicate a couple of small spikes on the graph, explaining them casually.*</p> <p class="speech"><b>Task Force Leader:</b> "But notice these larger spikes. They're more significant than usual. We need to find out what those spikes are and, more importantly, who’s responsible."</p> [[Continue->Data Spikes]] (display: "Sidebar") (display: "SidebarBack") <h1>Data Spikes Discussion</h1> <p class="speech"><b>Task Force Member 1:</b> "Let’s hear from you—what do you think could cause these larger spikes? Any ideas?"</p> <img src="https://static.wixstatic.com/media/27b368_87cfabd10df845ff812e599590864133~mv2.png" alt="Network Activity Graph"> <p class="s_direction">*The audience is presented with a Mentimeter slide or similar tool where they can submit their thoughts on potential causes of data spikes.*</p> <p>[[Review Responses]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Review Responses</h1> <p class="s_direction">*The team reviews the audience’s responses, discussing the possibilities.*</p> <p class="speech"><b>Task Force Member 2:</b> "Good suggestions—could be anything from a large file transfer to someone backing up data. But we’ll need to dig deeper."</p> <p class="s_direction">*The network traffic map is pulled up on another screen, showing devices and IPs connected to the system.*</p> <p>[[Continue->Robert Brown's Frustration]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Investigate Logs</h1> <p class="speech">Task Force Member 1: "To understand these spikes better, we need to dig into the network logs. They’ll tell us which devices have been accessing the network and what data has been transferred."</p> <p class="s_direction">*The Task Force Member pulls up the network logs on the screen. The audience is shown a list of IP addresses and devices that have accessed the system during the times of the data spikes.*</p> [[Continue->InvestigateLogs2]] (display: "Sidebar") (display: "SidebarBack") <h1>Identify Suspicious IP</h1> <p class="speech"><b>Task Force Member:</b> "Look at these logs carefully. One of these IP addresses is behaving suspiciously. We're looking for patterns like extremely high data transfer rates or repeated connections that seem abnormal."</p> <p class="s_direction"><b>Hint:</b> Look for an IP address that shows unusually high data transfer rates. In a typical network, most activities like browsing websites or sending emails involve small to moderate data transfers, often less than 10 MB at a time. Large and frequent data transfers, especially over 100 MB, can indicate something unusual.</p> <div class="log-container"> <pre class="network-logs"> Time Src IP Dest IP Prot Act Data (MB) ----------------------------------------------------------------------------------- 2024-09-02 13:05:43 192.168.203.50 203.0.113.5 TCP Allow 0.5 2024-09-02 13:06:10 192.168.1.15 203.0.113.20 UDP Allow 1.2 2024-09-02 13:06:58 192.168.203.50 198.51.100.7 TCP Allow 200.0 <-- HIGH DATA TRANSFER! 2024-09-02 13:07:15 192.168.2.45 203.0.113.45 TCP Allow 10.0 2024-09-02 13:07:30 192.168.3.25 203.0.113.10 TCP Allow 0.3 2024-09-02 13:08:00 192.168.5.12 203.0.113.12 TCP Allow 0.7 2024-09-02 13:08:45 192.168.6.25 198.51.100.20 TCP Allow 0.7 2024-09-02 13:09:10 192.168.8.45 203.0.113.5 TCP Allow 2.5 2024-09-02 13:10:00 192.168.203.50 203.0.113.18 UDP Allow 150.7 <-- ANOTHER HIGH TRANSFER! </pre> </div> <!-- Interactive Choices Using Twine Links --> <p class="s_direction">Select the IP address you believe is suspicious:</p> <ul> <li><button id="ip1">192.168.203.50</button></li> <li><button id="ip2">192.168.1.15</button></li> <li><button id="ip3">192.168.6.25</button></li> </ul> <!-- Feedback and outcome --> <p id="feedback" class="speech"></p> <!-- Correct and wrong Twine links --> <p id="correct-link" style="display: none;">[[Continue->Clue: First Pet Name]]</p> <p id="wrong-link" style="display: none;">[[Continue->Hacker Online]]</p> <!-- JavaScript to handle button clicks --> <script> document.getElementById("ip1").addEventListener("click", function() { document.getElementById('feedback').textContent = "Correct! This IP shows extremely high data transfer rates."; document.getElementById('correct-link').style.display = 'block'; // Show the link to the clue page }); document.getElementById("ip2").addEventListener("click", function() { document.getElementById('feedback').textContent = "Incorrect. This IP doesn't exhibit the suspicious activity we're looking for."; document.getElementById('wrong-link').style.display = 'block'; // Show the link to "Hacker Online" }); document.getElementById("ip3").addEventListener("click", function() { document.getElementById('feedback').textContent = "Incorrect. This IP doesn't exhibit the suspicious activity we're looking for."; document.getElementById('wrong-link').style.display = 'block'; // Show the link to "Hacker Online" }); </script> (display: "Sidebar") (display: "SidebarBack") <h1>Hacker Online</h1> <p class="speech"><b>Task Force Member 1:</b> "Hold on—something’s happening. Look at the graph!"</p> <video width=100% height=25% controls autoplay> <source src="https://video.wixstatic.com/video/27b368_a97468176b4943d8be7a1ae71dad262c/480p/mp4/file.mp4"> Your browser does not support the video tag. </video> <p class="s_direction">The interactive graph on the screen suddenly surges—doubling, tripling, and then quadrupling in size as new data floods the network.</p> <p class="speech"><b>Task Force Leader:</b> (urgently) "My god, the hacker is online right now! They’re accessing the school's files and... transferring them to the internet!"</p> <p>[[Continue->Contine - Hacker Online 3]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Luddite Explanation</h1> <p class="s_direction">*Mr. Luddite steps forward, peering at the screen with a skeptical look.*</p> <p class="speech"><b>Mr. Luddite:</b> "Alright, team, I know all these numbers and codes look like a jumbled mess to most of you, but don’t worry. Let’s break this down."</p> <p class="speech"><b>Task Force Member 2:</b> "Actually, Mr. Luddite, these 'numbers' are IP addresses. They’re like the online addresses of each device connected to our network."</p> <p class="speech"><b>Mr. Luddite:</b> "Ah, addresses, you say? Like the ones on envelopes? So, what’s the big deal with these addresses then?"</p> <p class="speech"><b>Task Force Member 2:</b> "Well, think of it this way: just like a home address tells you where a letter should go, an IP address tells you where data is being sent and received over the internet. Now, if one of these addresses belongs to a suspicious device, it means someone could be accessing data they shouldn’t be."</p> <p class="speech"><b>Mr. Luddite:</b> "So, these devices could be… what, little data thieves? And we’re catching them red-handed?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly, Luddite. If an IP address is showing abnormal activity—like sending lots of data to an unknown destination—it could be a sign of malicious activity."</p> <p class="speech"><b>Mr. Luddite:</b> "Right! So, we’re hunting for the bad IP, the one that’s been stealing our precious data?"</p> <p class="speech"><b>Task Force Member 2:</b> "Yes. And based on these logs, we have a prime suspect. One of these IP addresses is showing a pattern that doesn’t match normal network behavior. We need to investigate it further."</p> <p class="speech"><b>Mr. Luddite:</b> "Sounds like we’re onto something big. Let’s track down that rogue IP and stop it in its tracks!"</p> <p>[[Continue ->Identify Suspicious IP]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Network Overview</h1> <p class="speech"><b>Task Force Leader:</b> "Before we dive into the specifics of network traffic, let's get a clear picture of what our network looks like. Understanding this will help us figure out where things might have gone wrong."</p> <p class="speech"><b>Task Force Member 1:</b> "Here’s the network map, showing all the devices connected to our school’s network. You can see everything from the admin office computers to the library printers and even the POS systems in the cafeteria."</p> <p>[[Continue->Network Map]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <p class="speech"><b>Task Force Member 1:</b> "Task Force Member 1 brings up the revised network map on the screen, highlighting key areas like the firewall, external connections, and critical devices."</p> <img class = "network_map" src="https://static.wixstatic.com/media/27b368_818f47b5cde04d10af9a28df1022af2d~mv2.png"> <p class="speech"><b>Task Force Leader:</b> "This map also shows us how the network connects to the outside world, including the internet. Notice the firewall protecting our internal systems—anything trying to get in or out has to pass through there."</p> <p class="speech"><b>Task Force Member 2:</b> "And every device here is a potential point of entry for an attacker. If any of these are compromised, the whole network could be at risk."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Now that we have a clear picture of our network, let’s focus on the recent anomalies we’ve detected—those unusual spikes in data usage."</p> [[Continue->Data Spikes Discussion]] (display: "Sidebar") (display: "SidebarBack") <h1>Race Against Time: Immediate Actions and Interactive Decision-Making</h1> <p class="speech"><b>Task Force Leader:</b> "We have to stop this transfer immediately. The hacker is in our system, actively uploading sensitive data. We’ve identified three possible ways to counter this, and we need to choose the most effective one—fast."</p> <p class="speech"><b>Task Force Leader:</b> "Our first option is to cut off the data transfer. If we can interrupt the data flow, we might be able to prevent the hacker from completing the upload. This would stop any further information from being leaked, but it won’t necessarily help us catch who’s behind this."</p> <p class="speech"><b>Task Force Member 1:</b> "The second option is to block the hacker's access to our network entirely. By shutting down their connection, we could halt their activity and prevent them from continuing the attack. However, we risk losing track of them if they slip away before we can identify them."</p> <p class="speech"><b>Task Force Member 2:</b> "Our third option is to trace the source of the anomalies in the data flow. This could lead us directly to the hacker, allowing us to not only stop the current attack but also understand how they got in and who they are. It’s the most complex option, but it could give us the most information."</p> <p class="speech"><b>Task Force Leader:</b> "Each option has its pros and cons, and we need to act now. The clock is ticking—where should we focus our efforts?"</p> <p>[[Continue->Continue - Interactive Vote]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Hacker Online</h1> <p class="speech"><b>Task Force Member 2:</b> "This isn’t just a routine check anymore. They’re uploading everything—names, addresses, dates of birth. This could expose everyone's personal information!"</p> <p class="speech"><b>Task Force Leader:</b> "And it’s not just personal data we’re talking about. If this information gets out, it could have devastating consequences. Identity theft, financial fraud, and even cyberbullying—these are very real threats."</p> <p class="speech"><b>Mr. Luddite:</b> (panicked) "No!! The Headteacher’s stamp collection will be exposed! Do you know how much effort went into scanning those?!"</p> <p class="speech"><b>Task Force Leader:</b> "This isn't a joke, Luddite. The consequences of a data breach like this can be severe. Personal data can be sold on the dark web, leading to financial loss for students and staff. And once information is out there, it’s nearly impossible to take back."</p> <p class="speech"><b>Task Force Member 2:</b> "Exactly. Not to mention the risk of cyberbullying. If student data is exposed, it could be used to target individuals online. We’ve seen cases where leaked information has led to harassment, and even worse, it can contribute to mental health issues."</p> <p class="speech"><b>Task Force Leader:</b> "And let’s not forget about the reputational damage. If word gets out that the school’s network was breached, it could undermine trust in the school’s ability to protect its community’s data. Parents, students, and staff alike could lose confidence in the school’s digital security measures."</p> <p class="speech"><b>Mr. Luddite:</b> (nervously) "I... I didn’t think it was that serious. But now that you mention it, this could really spiral out of control."</p> <p class="speech"><b>Task Force Leader:</b> "That’s why we need to act fast. This is about protecting everyone in our school community from the ripple effects of a cyberattack. It’s not just data on the line—it’s people’s lives and well-being."</p> <p>[[Continue->Race Against Time]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Data Transfer Decision</h1> <p class="s_direction">Task Force Leader: [looking at the screen] "It seems like we’ve identified the devices with significant data activity, but now, it’s a race against time. Look at this…"</p> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member 1:</b> "That’s the current data transfer progress. If we don't stop it, the upload could complete in about 5 minutes."</p> <p class="speech"><b>Mr. Luddite:</b> "Five minutes? That doesn’t sound too bad. We’ve got time, right?"</p> <p class="speech"><b>Task Force Leader:</b> "Don’t underestimate this, Luddite. If we don’t stop the upload soon, it could be too late. We might only have these five minutes before they manage to upload something critical."</p> <p class="speech"><b>Task Force Member 2:</b> "We’re seeing a slow progression for now, but the data could start spiking again if we don’t act quickly. We need to stop this before the upload hits critical files—student records, staff information."</p> <p class="speech"><b>Task Force Leader:</b> [addressing the audience] "So, team, what’s the best next move? We’ve got the suspicious device, the external database, and the IT server. Each choice could lead us closer to stopping this upload, but we need to pick wisely."</p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <!-- If the branch has failed, show an end message --> (if: $dataTransferFailed is true)[ <p>The data transfer has already completed. You can't revisit this branch.</p> [[Vote]]] (else:)[ (if: $dataTransferStopped is not true)[ [[Cut the data transfer]]<br>] (else:)[ <p>You've already attempted to cut the data transfer.</p>] (if: $hackersAccessBlocked is not true)[ [[Block the hackers access]]<br>] (else:)[ <p>You've already attempted to block the hacker's access.</p>] (if: $sourceTraced is not true)[ [[Trace the source]]<br>] (else:)[ <p>You've already attempted to trace the source.</p>]] (display: "Sidebar") (display: "SidebarBack") <h1>Cutting the Data Transfer</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Now that we've traced the source of the data spike, we know exactly where the data is being sent from. But the upload is still in progress, and we need to act fast."</p> <p class="s_direction">The team watches as the data transfer percentage slowly increases on the screen.</p> <p class="speech"><b>Task Force Member 1:</b> "If we don’t act soon, the hacker will complete the upload. We need to cut the data transfer."</p> [[Explanation]] (display: "Sidebar") (display: "SidebarBack") {<!-- Timer Area --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script>} <!-- Dialogue Section --> <p class="speech"><b>Task Force Leader:</b> "We need to block the hacker’s access to our network before they can finish uploading the files. This means stopping them completely."</p> <p class="speech"><b>Mr. Luddite:</b> "Block their access? How do we do that? Won’t they just find another way back in?"</p> <p class="speech"><b>Task Force Member 1:</b> "Right now, the hacker is using their IP address to connect to our network. Think of an IP as their online 'home address'. If we block it, they won’t be able to connect to the system from the same place."</p> <p class="speech"><b>Task Force Member 2:</b> "And we need to terminate their session—that’s the active connection they’re using to upload the files. Once we close that session, the data transfer will stop immediately."</p> <div> [[Explanation of Firewall]] </div> (display: "Sidebar") (display: "SidebarBack") <h1>Tracing the Source</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Alright, the vote is in. We’re going to trace the source of the data spike. This will help us identify exactly where the data is being sent from within the school."</p> <p class="speech"><b>Task Force Member 1:</b> "Let's bring up the network map again. We need to carefully look at which devices were active during those spikes."</p> [[Continue->Network Map2]] <h1>Network Analysis</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <img src="https://static.wixstatic.com/media/27b368_818f47b5cde04d10af9a28df1022af2d~mv2.png" alt="Network Map" style="display: block; margin: 20px auto; width: 70%;"> <p class="speech"><b>Task Force Leader:</b> "We know that not every device on this network would be capable of causing such a massive data spike. Let's use the logs to identify which ones were actively transmitting large amounts of data during the times we saw those spikes."</p> <p class="s_direction">The team begins filtering through the data, overlaying it onto the map.</p> [[Continue->Filtered Map]] { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <img src="https://static.wixstatic.com/media/27b368_6fbd1d8a180340daa725762432648305~mv2.png" alt="Highlighted Network Map" style="display: block; margin: 20px auto; width: 70%;"> <p class="speech"><b>Task Force Member 2:</b> "Here’s what we’ve got: a lot of devices were active, but only a handful were transmitting data at the scale we’re looking for. Let’s highlight those."</p> <p class="s_direction">The network map is updated to show several nodes highlighted based on their activity during the spikes.</p> <p class="speech"><b>Task Force Member 1:</b> "These highlighted devices were the most active during the data spikes. Now, let’s think about which ones are most likely to be involved in this kind of unauthorized data transfer."</p> <p class="speech"><b>Mr. Luddite:</b> "Let’s see... We’ve got a mix of devices here, but some of them don’t make sense for a large data transfer. I mean, how much data could a printer or a smartboard be moving?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Let’s eliminate those. Focus instead on the devices that either have access to sensitive data or are connected externally—those are our most likely suspects."</p> <p class="speech"><b>Task Force Member 1:</b> "So that leaves us with a few key suspects:"</p> [[Continue->Key Suspects]] <h1>Key Suspects</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class = "speech"><b>192.168.203.50 (Suspicious Device):</b> "This one stands out. It’s an unknown device connected to the network and seems to have been transmitting data out of the school. Definitely worth considering."</p> <p class = "speech"><b>External Database:</b> "This database handles a lot of data exchanges, especially with external parties. If it’s compromised, it could be used to send large amounts of data without raising immediate alarms."</p> <p class = "speech"><b>IT Server:</b> "This server controls access to a lot of sensitive information across the school. If someone gained unauthorized access, they could funnel data through here."</p> <p class="speech"><b>Task Force Leader:</b> "Alright, we’ve narrowed it down to three key devices. The suspicious device is a clear threat, the external database could be compromised, and the IT server might be the source if someone’s using it as a conduit."</p> [[Continue->Interactive Element: Identify the Device]] (display: "Sidebar") (display: "SidebarBack") <h1>Task Force Leader Decision</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p>Option 1: 192.168.203.50 (Suspicious Device)</p> <p>Option 2: External Database</p> <p>Option 3: IT Server</p> <p class="speech"><b>Task Force Member 1:</b> "Your decision here is critical. The faster we pinpoint the source, the quicker we can act to stop the data transfer."</p> <p class="speech"><b>Task Force Leader:</b> "Let’s make the right call here. We’re counting on you."</p> <p class = "s_direction">The team waits as the audience votes, ready to take immediate action based on the results.</p> <img src="https://static.wixstatic.com/media/27b368_87cfabd10df845ff812e599590864133~mv2.png"> [[Identify Outcome]] (display: "Sidebar") (display: "SidebarBack") { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member 1:</b> "Your decision here is critical. The faster we pinpoint the source, the quicker we can act to stop the data transfer."</p> <p class="speech"><b>Task Force Leader:</b> "Let’s make the right call here. We’re counting on you."</p> <p class="s_direction">The team waits as the audience votes, ready to take immediate action based on the results.</p> <!-- Options for the user to choose --> (if: $optionsCompleted is not true)[ (if: $option1Chosen is not true)[ [[Option 1: 192.168.203.50]]<!-- This is the correct choice --] (if: $option2Chosen is not true)[ [[Option 2: External Database]] ] (if: $option3Chosen is not true)[ [[Option 3: IT Server]] ]] (else:)[ <p>You've already made your decision. You cannot revisit this branch.</p>] (display: "Sidebar") (display: "SidebarBack") <h1>IP Address</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "The votes are in. We’re investigating the suspicious IP address—192.168.203.50. This is our prime suspect based on its high activity during the data spikes."</p> <p class="s_direction">The team shifts focus to the suspicious IP that has been consistently transmitting large amounts of data during the breach.</p> <p class="speech"><b>Task Force Member 1:</b> "This IP has been active right at the times we saw the biggest spikes. It’s been masking its activity through clever rerouting, but we can see it’s transmitting huge amounts of data."</p> <p class="speech"><b>Mr. Luddite:</b> "Rerouting? Yeah, they’re hiding in plain sight. But I bet this is the heart of the operation."</p> [[Following the Data Trail]] <h1>Data Transfer Investigation</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="s_direction">Task Force Leader: "We’ve narrowed it down to the external database. It’s a known storage location outside of our school network, which has been used for external backups and data storage. If the hacker is sending files there, it’s an immediate threat to our data integrity."</p> <p class="speech"><b>Task Force Member 1:</b> "External databases are commonly used for storing backups or sharing resources with third parties. But the risk is high—once the data leaves our network, it becomes harder to retrieve or block."</p> <p class="speech"><b>Mr. Luddite:</b> "So, what you’re saying is… the hacker could be sending everything to the cloud? Like some kind of digital black hole?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. If the data lands there, it’s out of our reach. We’d better hope that’s not the case."</p> <p class="s_direction">The team begins reviewing logs to see if there has been any recent data transfer to the external database.</p> [[Review Data Logs]] (display: "Sidebar") (display: "SidebarBack") <h1>IT Server</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Interesting choice. The IT server does make sense—it's the central hub for a lot of important data in the school. If anyone’s going to move files around without raising too much suspicion, it would be from here."</p> <p class="speech"><b>Task Force Member 1:</b> "Exactly. Plus, this server manages everything from backups to teacher access to sensitive files. A hacker could easily mask their activities within all the legitimate traffic."</p> <p class="speech"><b>Mr. Luddite:</b> "Well, it’s like hiding in plain sight, right? All the activity here could make it easy for the hacker to blend in."</p> [[Initial Focus]] (display: "Sidebar") (display: "SidebarBack") <h1>Initial Focus</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member 1:</b> "We’re seeing a lot of data movement here—mostly routine backups, but it’s worth checking out."</p> <p class="s_direction">The screen displays recent activity logs from the IT server, highlighting routine and potentially suspicious activities:</p> <pre style="background-color: #333; color: #fff; padding: 10px; border-radius: 5px; font-size: 14px;"> 2024-09-17 08:12:35 - Backup-File-01.zip (2 MB) 2024-09-17 09:45:12 - Student-Records-Update.csv (1.5 MB) 2024-09-17 11:23:47 - Daily-Backup-Logs.zip (5 MB) 2024-09-17 14:05:03 - Teacher-Notes.docx (300 KB) 2024-09-17 16:22:18 - System-Maintenance-Log.txt (250 KB) 2024-09-17 18:50:30 - Parent-Contact-List.csv (1 MB) 2024-09-17 20:15:59 - IT-Security-Update.zip (3 MB) </pre> <p class="speech"><b>Task Force Leader:</b> "Keep digging. This much traffic could be hiding something more sinister."</p> [[Mr. Luddite's Simplified Explanation]] (display: "Sidebar") (display: "SidebarBack") <h1>Mr. Luddite's Simplified Explanation</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Mr. Luddite:</b> "Alright, let’s think about this—if the server’s just doing its daily chores, like cleaning up and saving files, maybe the spike is just it working overtime. But if the hacker’s involved, they could be piggybacking on this traffic to stay hidden."</p> <p class="speech"><b>Task Force Member 2:</b> "Exactly. If they’re clever, they could hide the spike within normal server activity. But we’re not seeing anything unusual so far."</p> [[Dead End]] (display: "Sidebar") (display: "SidebarBack") <h1>Dead End</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member 1:</b> "Hold on—looks like we’ve hit a wall. All this data? Just routine backups. It’s not linked to the spikes we’re chasing."</p> <p class="speech"><b>Task Force Member 2:</b> "This isn't the lead we were hoping for. The IT server’s clean, just handling its usual load."</p> <p class="speech"><b>Mr. Luddite:</b> "Well, that’s a relief. At least someone’s backing up all that work! But no hacker treasure here, team."</p> [[Redirect]] (display: "Sidebar") (display: "SidebarBack") <h1>Redirect</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="s_direction">As the team moves away from the IT Server path, the main screen displays an updated graph showing the data transfer progression.</p> <p class="speech"><b>Task Force Leader:</b> "Alright, so the IT server’s not the source. We’re running out of time."</p> <p class="s_direction">A red bar moves across the graph, showing the percentage of the data that has been uploaded. The stakes are clear—the longer the team spends on dead ends, the more data gets exposed.</p> <p class="speech"><b>Task Force Member 1:</b> "We need to move fast. The hacker’s not slowing down."</p> <p class="speech"><b>Task Force Leader:</b> "Back to the map, team. We’ve still got time, but we need to make this next move count."</p> [[Identify Outcome]] (display: "Sidebar") (display: "SidebarBack") (set: $option3Chosen to true) <h1>Reviewing Data Logs</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member 2:</b> "Let’s look at the logs. The database shows some activity, but nothing significant. We’re not seeing the kind of large-scale data transfer we’d expect for an operation like this."</p> <p class="s_direction">The screen displays a list of small, routine file transfers, with no evidence of the huge data spike:</p> <pre style="background-color: #333; color: #fff; padding: 10px; border-radius: 5px; font-size: 14px;"> 2024-09-17 08:12:35 - Backup-File-01.zip (2 MB) 2024-09-17 09:45:12 - Student-Records-Update.csv (1.5 MB) 2024-09-17 11:23:47 - Daily-Backup-Logs.zip (5 MB) 2024-09-17 14:05:03 - Teacher-Notes.docx (300 KB) 2024-09-17 16:22:18 - System-Maintenance-Log.txt (250 KB) 2024-09-17 18:50:30 - Parent-Contact-List.csv (1 MB) 2024-09-17 20:15:59 - IT-Security-Update.zip (3 MB) </pre> <p class="speech"><b>Task Force Leader:</b> "Hmm. This doesn’t look like the destination. The files being sent to the external database are small and infrequent. It’s mainly backup-related data that doesn’t match the volume of what’s being transferred right now."</p> [[Realizing the Error]] (display: "Sidebar") (display: "SidebarBack") <h1>Realizing the Error</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Mr. Luddite:</b> "Phew! So the hacker hasn’t managed to dump everything there, right?"</p> <p class="speech"><b>Task Force Member 1:</b> "It doesn’t look that way. The external database was a good guess, but based on the data logs, it’s not the right lead. The data transfer is much bigger than what’s heading there."</p> <p class="speech"><b>Task Force Leader:</b> "We’ve wasted precious time. We need to act fast and shift our focus."</p> [[Looping Back]] { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "We’re running out of time. The external database wasn’t the right target, and we need to move quickly to trace the true source of the data spike. Let’s re-evaluate our options."</p> [[Identify Outcome]] (set: $option2Chosen to true) { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="s_direction">The team traces the flow of data from the suspicious IP address, which leads to external servers. The data transfer rate is alarmingly high.</p> <p class="speech"><b>Task Force Member 2:</b> "Look here—the data from this device is being funneled to an external server. It’s not just lingering in the network anymore. This is an active upload."</p> <p class="speech"><b>Task Force Leader:</b> "That’s the confirmation we needed. It’s clear the hacker is using this device to exfiltrate the data. We’re running out of time."</p> [[Continue->Clue: Mother's Maiden Name]] <h1>Second Clue: Mother's Maiden Name</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> (display: "MothersNameClue") <!-- This calls the template that displays the pet name -->} <p class="speech"><b>Task Force Member:</b> "We’ve found another security prompt, sir. This time, it’s asking for the user’s mother’s maiden name."</p> <p class="speech"><b>Task Force Leader:</b> "Mother’s maiden name? These are the kinds of questions you expect from banks, not sophisticated hackers. It seems like they’re relying on easily guessed security measures."</p> <p class="speech"><b>Task Force Member:</b> "Exactly. Either they’re not as clever as we think, or they’re using these basic questions to cover something more complex. It feels like a distraction, but we can’t ignore it."</p> <p class="speech"><b>Task Force Leader:</b> "They might be hiding something bigger behind these simple defenses. Log it. We’ll keep digging—it’s all part of the game."</p> <p class="s_direction">The team logs the clue: “Mother’s Maiden Name” is another piece of the hacker’s security scheme. The room hums with the tension of uncovering the hacker’s personal information.</p> (display: "Sidebar") <p>[[Continue->Clue Decryption]]</p> (if: $clue9_found is not true)[ (set: $clue9_found to true) (set: $cluesFound to $cluesFound + 1) ] (if: $clue9_found is not true)[ (set: $clue9_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Reverse Cipher Decryption</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <img src="https://static.wixstatic.com/media/27b368_87cfabd10df845ff812e599590864133~mv2.png" alt="Cipher Clue" style="width: 50%; height: auto; display: block; margin: 20px auto;"> <p class="speech"><b>Task Force Member 2:</b> "We've discovered a message that seems to be encoded using a simple reverse cipher. The word is scrambled, and we need to reverse it."</p> <p class="s_direction">The scrambled word is: <b>"sdrawkcab"</b></p> <p>Can you reverse the word to find the clue? Enter your answer below:</p> <!-- Input field for the user --> <input id="userInput" type="text" placeholder="Enter the reversed word here" style="width: 100%; padding: 10px; margin: 10px 0; font-size: 16px;"> <!-- Button to check the answer --> <button id="submitButton" style="padding: 10px 20px; font-size: 16px; background-color: #4CAF50; color: white; border: none; cursor: pointer;">Submit</button> <!-- Area to display feedback --> <p id="feedback"></p> <!-- Hidden Twine link --> <div id="nextLink" style="display: none;"> [[Proceed to the next clue->HackerNameUnlocked]] </div> <script> // JavaScript function to check if the input matches the reversed word document.getElementById('submitButton').addEventListener('click', function() { // Get the user's input var input = document.getElementById('userInput').value; // The correct answer (reversed word) var correctAnswer = "backwards"; // This is the correct reversed form of "sdrawkcab" // Check if the user's input matches the correct answer if (input.toLowerCase() === correctAnswer) { // Display success message and reveal the Twine link document.getElementById('feedback').innerHTML = "<b>Correct!</b> The decoded word is 'backwards'. You can proceed to the next clue."; document.getElementById('nextLink').style.display = 'block'; // Show the hidden Twine link } else { // Display error message document.getElementById('feedback').innerHTML = "<b>Incorrect.</b> Try again!"; } }); </script> <!-- Check and update the clue variable --> (if: $clue10_found is not true)[ (set: $clue10_found to true) (set: $cluesFound to $cluesFound + 1) ] (display: "Sidebar") (display: "SidebarBack")<h1>Continued Transfer</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Great work, team! We’ve got another piece of the puzzle, but…" <i>looks at the progress bar</i> "Hold on, look at the progress bar."</p> <p class="speech"><b>Task Force Member 2:</b> <i>shocked</i> "What?! The upload is still going! We’re nowhere near stopping this."</p> <p class="speech"><b>Task Force Leader:</b> "We’re running out of time. It’s great we’ve found another clue, but if we don’t stop this now, it won’t matter."</p> <p class="speech"><b>Mr. Luddite:</b> <i>panicking</i> "So… does this mean the hacker’s still one step ahead of us? Maybe we should just, you know, run? Or at least hide under the desk?"</p> <p class="speech"><b>Task Force Leader:</b> <i>sternly</i> "There’s no running from this, Luddite. We’re on the clock, and if we don’t stop that data transfer, we lose everything!"</p> [[Continue->Continue - Interactive Vote]] (display: "Sidebar") (display: "SidebarBack") (set: $option1Chosen to true) (set: $optionsCompleted to true) (set: $sourceTraced to true)<h1>Cutting the Data Transfer</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Interesting suggestions. But here's the catch—we can't just unplug the system or block everything."</p> <p class="speech"><b>Task Force Member 2:</b> "If we pull the plug on the network, we risk causing damage to the entire system or even alerting the hacker to what we’re doing."</p> <p class="speech"><b>Mr. Luddite:</b> "So, no pulling the plug? What about smashing the computer? I saw it work in a movie once!"</p> <p class="s_direction">The team chuckles, but the Task Force Leader quickly refocuses the conversation.</p> [[Continue->Technical Exposition]] (display: "Sidebar") (display: "SidebarBack") <h1>Task Force Leader's Technical Explanation</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "We need a precise approach to cutting the transfer without bringing down the whole network. Think of it like stopping water from flowing through a pipe—you wouldn’t destroy the whole plumbing system, you’d just turn off the right valve."</p> <p class="speech"><b>Task Force Member 1:</b> "We’ve got a few options here: we could block the port the data is flowing through, throttle the speed of the transfer, or isolate the device responsible for sending the data. Each option has risks and benefits."</p> <p class="speech"><b>Mr. Luddite:</b> "I like the water analogy! But if we slow the flow, won’t the data still go through, just slower?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Slowing it down buys us time, but it doesn’t stop it completely. Blocking the port stops the flow right away but risks tipping off the hacker."</p> [[Continue->Technical Solutions]] (display: "Sidebar") (display: "SidebarBack") <h1>Technical Solutions</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Alright team, we’ve got three possible ways to cut the data transfer. Each one has its own risks and advantages, so we need to be smart about this."</p> <p class="s_direction"><b>Option 1: Blocking the Port</b></p> <p class="speech"><b>Task Force Member 1:</b> "The first option is to block the port the data is flowing through. Think of the port as the gate that allows the data to leave the network. If we block it, the data can’t get out."</p> <p class="speech"><b>Mr. Luddite:</b> "So, basically, slamming the door shut before the hacker can walk through? Sounds good to me!"</p> <p class="speech"><b>Task Force Leader:</b> "True, Luddite. But blocking the port could immediately alert the hacker that we’ve found them, and they might retaliate or try a different route. It’s a quick fix, but it might not be a long-term solution."</p> <p class="s_direction"><b>Option 2: Throttling the Data Transfer</b></p> <p class="speech"><b>Task Force Member 2:</b> "We could throttle the data transfer instead. This would slow the speed of the data being sent, giving us more time to figure out a plan. It’s like turning the water flow down to a trickle."</p> <p class="speech"><b>Mr. Luddite:</b> "Okay, but won’t the data still get out? It’s just going to take longer, right?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Throttling gives us time, but it’s not a permanent solution. It’s more of a delay tactic, but it could give us enough time to block the hacker’s access without tipping them off right away."</p> <p class="s_direction"><b>Option 3: Isolating the Device</b></p> <p class="speech"><b>Task Force Member 1:</b> "The third option is isolating the device that’s sending the data. We can lock it out of the network, but this is risky too. If we isolate the wrong device, we might not stop the transfer in time."</p> <p class="speech"><b>Mr. Luddite:</b> "So, we basically throw the hacker’s device into quarantine? That sounds pretty cool, but what’s the risk?"</p> <p class="speech"><b>Task Force Leader:</b> "Isolating the device will completely cut it off, but the hacker might notice right away and try something else. Plus, there’s a chance we isolate the wrong device and waste time."</p> [[Continue->Technical Continue]] (display: "Sidebar") (display: "SidebarBack") <h1>Task Force Leader Decision</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Now, it’s up to you, audience. Which option do we go for? Do we block the port, throttle the data, or isolate the device?"</p> <img src="https://static.wixstatic.com/media/27b368_87cfabd10df845ff812e599590864133~mv2.png"> <!-- If "Isolate the Device" has been completed, show only the "Continue" link and mark the branch as complete --> (if: $isolate_device_completed is true)[ <!-- Mark the "Cut Data Transfer" branch as complete --> (set: $dataTransferStopped to true) <p>You've completed all available actions.</p> [[Continue - Interactive Vote]] ] <!-- Show options only if "Isolate the Device" has not been completed --> (else:)[ <!-- Block the Port --> (if: $block_port_completed is not true)[ [[Block the port]] ] (else:)[ <p>You've already blocked the port.</p> ] <!-- Throttle the Data --> (if: $throttle_data_completed is not true)[ [[Throttle the data]] ] (else:)[ <p>You've already throttled the data.</p> ] <!-- Isolate the Device --> (if: $isolate_device_completed is not true)[ [[Isolate the device]] ] (else:)[ <p>You've already isolated the device.</p> ] ] (display: "Sidebar") (display: "SidebarBack") <h1>What is a port?</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "One option to stop the hacker is to block the port they’re using to send data. A port is like a door that allows information to go in and out of the school’s network. If we can close the right door, we might stop the hacker from sending any more data."</p> <p class="speech"><b>Task Force Member 1:</b> "But we need to be careful. There are lots of doors, or ports, on the network. Not all of them are used by hackers. Some are used for important things like emails or accessing files we need every day."</p> [[Blocking the wrong port]] (display: "Sidebar") (display: "SidebarBack") <h1>Action - Throttle the Data</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "We’ve traced the source, but the data transfer is still happening. One way to slow the hacker down is to throttle the data transfer."</p> <p class="speech"><b>Mr. Luddite:</b> "Throttling? Like turning down the volume? Why not just cut the transfer?"</p> <p class="speech"><b>Task Force Member 1:</b> "Throttling is like turning the tap half-off. The data still flows, just slower. Cutting it completely might damage the system or alert the hacker. Throttling buys us time to make the next move without raising suspicion."</p> <p class="speech"><b>Task Force Leader:</b> "Think of it like squeezing a garden hose. We’re restricting how much data they can transfer at once, without shutting everything down."</p> [[Explanation of throtling ]] <p class="s_direction">(display: "Sidebar")</p> <p class="s_direction">(display: "SidebarBack")</p> <h1>Isolate the Device: Introduction</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Next, we need to isolate the hacker’s device. If we can remove their device from the network, we can completely stop the data transfer."</p> <p class="speech"><b>Task Force Member 1:</b> "Isolating the device means preventing it from communicating with the rest of the network. We'll do this by blocking its access at the network switch level, which requires identifying the device by its MAC address or IP address."</p> <p class="speech"><b>Mr. Luddite:</b> "Sounds serious. So how do we find this MAC address? Is it like the device's fingerprint?"</p> <p class="speech"><b>Task Force Member 2:</b> "Exactly. Every device has a unique MAC address—a hardware identifier that will allow us to track it down and isolate it."</p> [[Continue->IsolateDeviceStep2]] (display: "Sidebar") (display: "SidebarBack") <h1>What Happens If We Block the Wrong Port?</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Mr. Luddite:</b> "So, it’s like if we shut the wrong door, we might lock ourselves out of important stuff, like the internet or school systems?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. We don’t want to block a port that’s needed for normal activities. So, we’ll start by closing the ports that hackers usually use to send large files."</p> [[File Transfer Ports]] (display: "Sidebar") (display: "SidebarBack") <h1>Introducing File Transfer Ports</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "The most common doors hackers use to send files are numbered 20, 21, and 22. These are called file transfer ports. If we block these, we might stop or slow down the data transfer."</p> <p class="speech"><b>Task Force Member 2:</b> "But remember, hackers are smart. They might try to use a different, less obvious door if we block the common ones."</p> [[Blocking Ports]] (display: "Sidebar") (display: "SidebarBack") <h1>Action - Blocking Ports</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="s_direction"> "The team pulls up the network security controls and blocks ports 20, 21, and 22. The progress bar of the data transfer begins to slow down on the screen."</p> <p class="speech"><b>Mr. Luddite:</b> "Wait, so does that mean we’ve stopped them?"</p> <p class="speech"><b>Task Force Leader:</b> [shakes head] "Not quite. We’ve slowed it down, but the transfer is still happening. The hacker’s probably using other ports that we haven’t blocked yet. This is just a temporary fix."</p> <p class="speech"><b>Task Force Member 2:</b> "We’ve bought ourselves a little time, but it’s not enough to stop them completely. We need to find another way to shut this down."</p> [[Technical Continue]] <p class="s_direction">The team successfully blocks the suspicious port, preventing further access.</p> <!-- Mark the action as completed --> (set: $block_port_completed to true) (display: "Sidebar") (display: "SidebarBack") <style> body { font-family: Arial, sans-serif; text-align: center; padding: 10px; margin: 0; } .progress-container { margin: 10px 0; } .progress-bar { width: 80%; background-color: #e0e0e0; border-radius: 10px; margin: 5px auto; padding: 5px; } .progress { height: 25px; background-color: green; border-radius: 10px; } p { margin-top: 5px; } </style> <h1 style="margin-bottom: 10px;">Normal Data Flow</h1> <div class="progress-container"> <h3 style="margin-bottom: 5px;">Data Flow</h3> <div class="progress-bar"> <div class="progress" id="normal-progress"></div> </div> <p>The green bar represents normal data flow. When there's no interference, data moves quickly and efficiently across the network. This is ideal for large file transfers or streaming, ensuring a smooth and seamless experience.</p> </div> [[Throttled Data Flow]] <script> const normalProgressBar = document.getElementById('normal-progress'); let normalProgress = 0; function updateNormalProgress() { if (normalProgress < 100) { normalProgress += 0.5; normalProgressBar.style.width = `${normalProgress}%`; } } setInterval(updateNormalProgress, 100); </script> (display: "Sidebar") (display: "SidebarBack") <style> body { font-family: Arial, sans-serif; text-align: center; padding: 10px; margin: 0; } .progress-container { margin: 10px 0; } .progress-bar { width: 80%; background-color: #e0e0e0; border-radius: 10px; margin: 5px auto; padding: 5px; } .progress { height: 25px; background-color: red; border-radius: 10px; } p { margin-top: 5px; } .slider-container { margin-top: 10px; } </style> <body> <h1 style="margin-bottom: 10px;">Throttled Data Flow</h1> <div class="progress-container"> <h3 style="margin-bottom: 5px;">Throttled Data Flow</h3> <div class="progress-bar"> <div class="progress" id="throttled-progress"></div> </div> <p>The red bar shows data flow when throttling is applied. Throttling intentionally slows down data transmission, usually to manage network traffic. Adjust the slider to see how varying levels of throttling affect the speed of data transfer.</p> </div> <div class="slider-container"> <label for="throttle-slider">Throttle Percentage: <span id="throttle-value">0</span>%</label><br> <input type="range" id="throttle-slider" min="0" max="90" step="10" value="0"> </div> <script> const throttledProgressBar = document.getElementById('throttled-progress'); const throttleSlider = document.getElementById('throttle-slider'); const throttleValue = document.getElementById('throttle-value'); let throttledProgress = 0; function updateThrottledProgress() { if (throttledProgress < 100) { // Adjust speed based on throttle percentage but ensure it only slows down and doesn't go backward let throttleFactor = 1 - (throttleSlider.value / 100); // Throttling factor (0 to 1) throttledProgress += 0.5 * throttleFactor; // Progress slower with higher throttle throttledProgressBar.style.width = `${Math.min(throttledProgress, 100)}%`; } } // Update displayed throttle percentage value throttleSlider.addEventListener('input', function() { throttleValue.innerText = throttleSlider.value; }); // Update throttled progress every 100 milliseconds setInterval(updateThrottledProgress, 100); </script> </body> </html> [[Throttle that data!]] (display: "Sidebar") (display: "SidebarBack") <h1>Throttle that data</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Alright, we’ve decided to slow the hacker’s data transfer, but this requires a bit of technical know-how."</p> <p class="speech"><b>Task Force Member 1:</b> "Throttling means limiting the amount of data the hacker can send. It won’t stop them entirely, but it will buy us some time."</p> <p class="speech"><b>Mr. Luddite:</b> "So, we’re making them crawl instead of sprinting? How do we pull that off?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. We’ll use something called Quality of Service, or QoS. It lets us control how much bandwidth—basically internet speed—a specific device can use."</p> <p>The team brings up the network’s control panel, showing the IP address involved in the data spike.</p> <p class="speech"><b>Task Force Member 1:</b> "Here’s the suspicious IP: 192.168.203.50. That’s what we need to throttle."</p> [[Technical Breakdown]] (display: "Sidebar") (display: "SidebarBack") <style> body { font-family: Arial, sans-serif; text-align: center; padding: 20px; } table { width: 60%; margin: 20px auto; border-collapse: collapse; } table, th, td { border: 1px solid black; } th, td { padding: 10px; text-align: center; } .throttle-btn { padding: 8px 15px; background-color: #f44336; color: white; border: none; cursor: pointer; border-radius: 5px; } .throttle-btn:hover { background-color: #d32f2f; } #throttling-status { margin-top: 20px; font-size: 18px; color: red; } .progress-bar { width: 60%; background-color: #e0e0e0; margin: 20px auto; height: 25px; position: relative; border-radius: 10px; } .progress { height: 100%; background-color: green; width: 100%; border-radius: 10px; position: relative; } .progress.throttled { background-color: red; } .progress-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-weight: bold; } </style> <h1>Network Interface: Locating Suspicious IP</h1> <p><strong>Task Force Member 2</strong>: "First, we need to isolate the hacker’s device from the network logs—<b>192.168.203.50</b>. That’s the one causing the spike."</p> <!-- Display the network devices --> <table> <thead> <tr> <th>Device Name</th> <th>IP Address</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td>Admin PC</td> <td>192.168.1.10</td> <td>Normal</td> </tr> <tr> <td>Teacher Laptop</td> <td>192.168.1.11</td> <td>Normal</td> </tr> <tr> <td>Library PC</td> <td>192.168.1.12</td> <td>Normal</td> </tr> <tr> <td><strong>Suspicious Device</strong></td> <td><strong>192.168.203.50</strong></td> <td><strong>Spiking Data Usage</strong></td> </tr> </tbody> </table> <p><strong>Task Force Leader</strong>: "Now, let’s apply the throttle. We’ll use the QoS settings to limit the bandwidth of that IP address."</p> <!-- Button to throttle the suspicious device --> <button class="throttle-btn" id="throttle-btn">Throttle Suspicious Device</button> <!-- Display throttling status --> <div id="throttling-status"></div> <!-- Progress bar to show data throttling --> <div class="progress-bar" id="progress-bar"> <div class="progress" id="progress"> <span class="progress-text" id="progress-text">100% Data Flow</span> </div> </div> <!-- More Dialogue --> <p><strong>Task Force Member 1</strong>: "Bandwidth reduced to 1 Mbps. That’ll slow them down significantly. They’re still transferring data, but at a fraction of the speed."</p> <p><strong>Mr. Luddite</strong>: "Perfect. We’ve bought ourselves some time, but the transfer is still happening, just at a snail’s pace."</p> <script> const throttleBtn = document.getElementById('throttle-btn'); const progressBar = document.getElementById('progress'); const progressText = document.getElementById('progress-text'); const statusDiv = document.getElementById('throttling-status'); let progressValue = 100; // Function to throttle the device function throttleDevice() { statusDiv.textContent = "Throttling Suspicious Device... Bandwidth Reduced!"; progressBar.classList.add('throttled'); // Simulate throttling effect let throttling = setInterval(() => { if (progressValue > 20) { // Throttle to 20% of original data flow progressValue -= 1; progressBar.style.width = progressValue + '%'; progressText.textContent = progressValue + '% Data Flow'; } else { clearInterval(throttling); statusDiv.textContent = "Suspicious Device Throttled to 20% Data Flow."; } }, 100); } // Add event listener to the button throttleBtn.addEventListener('click', throttleDevice); </script> </body> </html> [[Clue: Login Activity at Odd Hours]] (display: "Sidebar") (display: "SidebarBack")<h1>Throttling Success</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar"> <div class="progress" id="timer-progress">0%</div> </div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('timer-progress').style.width = `${progress}%`; // Update progress bar width document.getElementById('timer-progress').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); progress = 100; updateProgressBar(); hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "Great work, team. The throttling has slowed the hacker’s data transfer to a crawl. We’ve bought ourselves some time."</p> <p class="speech"><b>Task Force Member 1:</b> "We still haven’t stopped the transfer entirely though. The data is still flowing, just much slower."</p> <p class="speech"><b>Mr. Luddite:</b> "So, what’s next? We’ve slowed them down, but we need to shut them down for good!"</p> <p class="speech"><b>Task Force Leader:</b> "That’s right. Now we need to decide our next move. Do we cut the data transfer directly or block the hacker’s access completely?"</p> [[Technical Continue]] (display: "Sidebar") (display: "SidebarBack") <!-- Mark the action as completed --> (set: $throttle_data_completed to true) <h1>Isolate Device: Locating the MAC Address</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "The first step is to track down the MAC address of the suspicious device. We've already seen the IP address: 192.168.203.50. Now, we’ll match it to the MAC address in the network logs."</p> <p class="speech"><b>Task Force Member 1:</b> "Right. The MAC address will help us identify exactly which device we need to isolate from the network."</p> [[Continue->Interactive Element]] (display: "Sidebar") (display: "SidebarBack") <h1>Isolate Device: Monitoring the Isolation</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "We’ve successfully isolated the hacker’s device. The data transfer has been completely halted."</p> <p class="speech"><b>Task Force Member 1:</b> "We’ll keep monitoring the network traffic to ensure that no other suspicious devices come online. But for now, it looks like the transfer has been stopped."</p> <p class="speech"><b>Mr. Luddite:</b> "Good job, team. We’ve stopped the leak. The hacker is out of options, for now."</p> <p class="speech"><b>Task Force Leader:</b> "But we still need to ensure this hacker doesn’t find another way in. Let’s wrap this up and review what we’ve learned."</p> [[Continue->Favourite Colour]] (display: "Sidebar") (display: "SidebarBack") <h1>WrapUp</h1> <div class="wrapupStory"> <p class="speech"><b>Task Force Leader:</b> "Great work today. We successfully isolated the hacker’s device, preventing any further data from being transferred."</p> <p class="speech"><b>Task Force Member 1:</b> "By using MAC address filtering, we were able to cut off their access at the network switch level. This stopped their communication with the rest of the network."</p> <p class="speech"><b>Mr. Luddite:</b> "And, we also learned a lot about monitoring network traffic and identifying suspicious activity. It’s not just about responding to an attack, but staying vigilant."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. We need to be proactive in protecting our network. Let’s take what we’ve learned and apply it going forward. Now let's put all these clues together and find out who's behind all this."</p> </div> <!-- Set the variable to indicate this option is complete --> (set: $isolate_device_completed to true) (set: $dataTransferStopped to true) <!-- or another variable indicating this action is successful --> [[Vote]] (display: "Sidebar") (display: "SidebarBack") <!-- Mark the "Data Transfer Stopped" as complete --> (set: $dataTransferStopped to true) <style> .timer { font-size: 24px; text-align: center; margin-bottom: 20px; /* Added margin for spacing */ width: 100%; padding: 5px 0; /* Padding for appearance */ color: #fff; /* White text for the timer */ background-color: #111; /* Background color */ border-radius: 5px; /* Rounded corners */ } .progress-bar-container { width: 100%; /* Full width */ height: 24px; /* Height of the progress bar */ background-color: #333; /* Background for the progress bar */ margin: 0 auto; /* Center it */ border-radius: 5px; /* Rounded corners */ } .progress-bar { height: 100%; width: 0%; /* Start at 0% */ background-color: red; /* Red progress bar */ text-align: center; line-height: 24px; color: white; font-size: 14px; border-radius: 5px; /* Rounded corners */ } .console { background-color: #333; padding: 20px; border-radius: 10px; color: #0f0; flex-grow: 1; display: flex; flex-direction: column; margin-top: 20px; /* Adjusted margin */ border: 2px solid #0f0; } .input-area { width: 100%; border: none; background-color: #333; color: #0f0; font-size: 16px; font-family: "Courier New", Courier, monospace; outline: none; padding: 5px; margin-top: 10px; } .input-area::placeholder { color: #0f0; } .scrollable { max-height: 400px; overflow-y: auto; flex-grow: 1; } .console-output { white-space: pre-wrap; margin-top: 15px; } h2 { color: #fff; } .blue-text { color: lightblue; } .success-text { color: #0f0; } #twine-link { display: none; /* Hidden by default */ margin-top: 20px; text-align: center; font-size: 18px; color: lightblue; } #failLink { display: none; /* Hidden by default */ text-align: center; margin-top: 10px; font-size: 18px; color: lightcoral; } </style> <h1>Terminal Game</h1> {<!-- Timer Area --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none;"> [[Game Fail - Upload to Internet]] </div> } {<!-- Console Area --> <div class="console"> <h2>Network Interface Command Line</h2> <div id="response" class="console-output scrollable"> <p>Welcome to the network command interface. Type <span class="blue-text">"arp -a"</span> to get the list of IP and MAC addresses.</p> </div> <input type="text" id="commandInput" class="input-area" placeholder="Type command here..." /> </div> <!-- Twine Links --> <div id="twine-link"> [[Continue->IsolateDeviceStep4]] </div> } <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); const commandInput = document.getElementById("commandInput"); const responseDiv = document.getElementById("response"); const twineLink = document.getElementById("twine-link"); let step = 1; // Track the current step in the process let success = false; // Track whether the game was successful const commands = { "arp -a": `IP Address MAC Address ------------------------------------- 192.168.1.10 00:14:22:01:23:45 192.168.1.11 00:14:22:67:89:AB 192.168.1.12 00:14:22:11:22:33 192.168.203.50 00:14:22:77:88:99 <-- Suspicious Device`, "192.168.203.50": "<span class='blue-text'>Correct! Now type 'isolate 00:14:22:77:88:99' to isolate the suspicious device.</span>", "isolate 00:14:22:77:88:99": "<span class='success-text'>Isolating device with MAC address 00:14:22:77:88:99... SUCCESS!</span>", "default": "<span class='blue-text'>Error: Invalid command. Try again.</span>" }; // Function to update console function updateConsole(message) { responseDiv.innerHTML += `<p>${message}</p>`; responseDiv.scrollTop = responseDiv.scrollHeight; // Auto-scroll to bottom } // Event listener for user input commandInput.addEventListener("keydown", function(event) { if (event.key === "Enter") { const userCommand = commandInput.value.trim(); commandInput.value = ""; // Clear input field if (step === 1 && userCommand === "arp -a") { updateConsole("> " + userCommand); updateConsole(commands["arp -a"]); updateConsole("<span class='blue-text'>Next, type the IP address of the suspicious device:</span>"); step = 2; // Move to next step } else if (step === 2 && userCommand === "192.168.203.50") { updateConsole("> " + userCommand); updateConsole(commands["192.168.203.50"]); step = 3; // Move to next step } else if (step === 3 && userCommand === "isolate 00:14:22:77:88:99") { updateConsole("> " + userCommand); updateConsole(commands["isolate 00:14:22:77:88:99"]); // Show the next link after successful isolation twineLink.style.display = 'block'; // Show Twine link after success twineLink.scrollIntoView(); // Ensure the link is visible on the screen success = true; // Mark the game as successful } else { updateConsole("> " + userCommand); updateConsole(commands["default"]); } } }); </script> (display: "Sidebar") (display: "SidebarBack") <h1>Post-Breach Briefing</h1> <p class = s_direction">The room is filled with tension. Mr. Luddite, lowers his head.</p> <p class = "speech">Mr. Luddite: "I… I can’t believe it! It's out there, all of the data’s out there, and you couldn’t stop it."</p> <p class = s_direction">The Task Force Leader steps forward with a calm yet determined look.</p> <p class = "speech">Task Force Leader: "Luddite, listen to me. No one person can stop every attack, and no system is completely foolproof. What matters now is what we do next. We’ve got the skills, the knowledge, and plenty of clues to work with. This isn’t the end—it’s just the next step."</p> [[Continue->Containment Measures]] (display: "Sidebar") (display: "SidebarBack") <h1>Containment Measures</h1> <p class = "speech">Mr. Luddite: "But the data… It’s out there now. What’s the point?"</p> <p class = "speech">Task Force Leader: "Yes, the data has been leaked, but it’s not too late to stop things from getting worse. Our first job is to lock down the rest. We’ll reset access, secure the remaining information, and make sure no more damage is done."</p> <p class = "speech">Task Force Member: "We’ve dealt with situations like this before. We’ve already got a plan to contain this."</p> <p class = "speech">Task Force Leader: "We can’t undo the breach, but we can limit its impact. We’re not giving up, and neither should you."</p> [[Continue->Investigate the Source]]<h1>Investigate the Source</h1> <p class = "speech">Task Force Leader: Cyberattacks can be incredibly sophisticated, and even the best can get caught off guard. But here’s the good news: the hacker left behind a trail. We have a solid lead—more than enough to track them down."</p> <p class = "speech>Task Force Member: "We’ve got plenty of digital breadcrumbs to follow...almost like they wanted us to find them! Every action they took left a mark, and we’re going to find them.</p> <p class = "speech">Task Force Leader: "This is where the real investigation begins. They may have breached our system, but now we’re on their trail. We’re piecing it all together now. The clues are there, and with a little more time, we’ll find out who’s behind this."</p> [[Wrapping up]]:: Wrap-Up Task Force Leader: "Remember, Luddite, the true measure of success isn’t in preventing every attack. It’s in how we respond when things go wrong. We didn’t stop the breach, but we’ve acted quickly, secured the system, and we’re on the verge of finding the culprit. This experience will make us stronger for next time." Mr. Luddite: So...we’re not done yet." Task Force Leader: "Exactly. Now let's put all these clues together and find out who's behind all this" :: NetworkTrafficBranchComplete <!-- Mark the Network Traffic Branch as completed --> (set: $network_traffic_completed to true) <p>You've completed the Network Traffic analysis!</p> <!-- Redirect back to the Decision Point --> [[Technical Continue]] <!-- Mark the action as completed --> (set: $isolate_device_completed to true)<h1>What is a Firewall?</h1> { <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <!-- Dialogue Section --> <p class="speech"><b>Mr. Luddite:</b> "Okay, so we block their IP and close their session, but what if they try again?"</p> <p class="speech"><b>Task Force Member 1:</b> "Good question. That’s where our firewall comes in. A firewall is like a security barrier that watches for suspicious activity. It prevents anyone without the right permissions from connecting."</p> <p class="speech"><b>Task Force Leader:</b> "Right. We reinforce the firewall after blocking the hacker’s IP and closing their session. This makes sure they can’t get back in and start again."</p> <p class="speech"><b>Task Force Member 2:</b> "To give you a bit more detail, every time data comes in or goes out of our network, it goes through the firewall. The firewall checks the data and decides if it’s safe. If it looks like a threat, it blocks it right there."</p> <p class="speech"><b>Mr. Luddite:</b> "Wait, but how does it know what's safe or not? And what are these 'ports' you keep mentioning?"</p> <p class="speech"><b>Task Force Member 1:</b> "Good point, Luddite. Think of ports as doors that data uses to enter and leave our network. Each port has a specific number and purpose. For example, Port 80 is used for regular website traffic (HTTP), and Port 443 is used for secure website traffic (HTTPS)."</p> <p class="speech"><b>Task Force Member 2:</b> "Hackers can use these ports to sneak into the network or send data out. Some ports are meant for specific types of data, like Port 21 for FTP, which is used to transfer files. If we see large amounts of data going through a port like that, it might be suspicious."</p> <p class="speech"><b>Task Force Leader:</b> "Our firewall can control which ports are open and who can use them. We can set rules like 'Block Port 21' if we think the hacker is using it to steal data. That's one of the steps we'll take in the mini-game."</p> <div> [[Continue->Transition to mini-game]] </div> (display: "Sidebar") (display: "SidebarBack") <h1>Transition to the Mini-Game</h1> { <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Leader:</b> "We’ve gone over the steps: block the IP, close the session, and reinforce the firewall. But now, we need someone to put that plan into action."</p> <p class="speech"><b>Mr. Luddite:</b> "Do we have to do it right now?"</p> <p class="speech"><b>Task Force Leader:</b> "Absolutely. If we don’t act fast, the hacker will upload everything. So, who’s ready to step up and save the school?"</p> <div> [[Continue->Mini-Game]] </div> (display: "Sidebar") (display: "SidebarBack") <!-- Title --> <h1>Data Transfer Prevention</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to GameFail, hidden initially --> <div id="gameFailLink" style="display: none;"> [[GameFail]] </div> <!-- Game Section --> <div id="gameSection"> <!-- Part 1: Terminate Hacker's Session --> <div id="terminateSession"> <p>Terminate the hacker's session by clicking on the correct IP address:</p> <!-- IP Options with indicators of network activity --> <div class="ip-option" data-correct="false">192.168.1.10 - Upload: 5MB/s, Download: 2MB/s</div> <div class="ip-option" data-correct="false">192.168.1.20 - Upload: 1MB/s, Download: 1MB/s</div> <div class="ip-option" data-correct="true">192.168.1.99 - Upload: 100MB/s, Download: 0MB/s</div> <!-- Correct IP inferred --> <div class="ip-option" data-correct="false">192.168.1.40 - Upload: 10MB/s, Download: 10MB/s</div> <div class="ip-option" data-correct="false">192.168.1.55 - Upload: 8MB/s, Download: 6MB/s</div> <div class="ip-option" data-correct="false">192.168.1.75 - Upload: 3MB/s, Download: 4MB/s</div> <!-- Hint Button for Part 1 --> <button id="hint1" class="hint-button">Hint</button> <p id="hintText1" class="hint-text" style="display:none;"> Look for an IP with unusually high upload activity and little to no download. Hackers typically transfer large amounts of data out of the network. </p> </div> <!-- Part 2: Firewall Configuration (Hidden initially) --> <div id="firewallConfig" style="display:none;"> <p>Drag the "Block" icon to the suspicious port to reinforce the firewall:</p> <!-- More ports with more complexity --> <div class="port" id="port20">Port 20 (FTP Data Transfer)</div> <div class="port" id="port21">Port 21 (FTP Control)</div> <!-- Correct Port --> <div class="port" id="port25">Port 25 (SMTP Email)</div> <div class="port" id="port80">Port 80 (HTTP)</div> <div class="port" id="port443">Port 443 (HTTPS)</div> <div id="blockIcon" draggable="true">Block</div> <!-- Hint Button for Part 2 --> <button id="hint2" class="hint-button">Hint</button> <p id="hintText2" class="hint-text" style="display:none;"> File transfers often use FTP (File Transfer Protocol) ports. Identify the port commonly associated with file transfers to block it. </p> </div> <!-- Game Win Link, hidden initially --> <div id="gameWinLink" style="display: none;"> [[Game Win - Educational Reinforcement]] </div> </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables) { window.harloweVariables = {}; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } let progress = window.harloweVariables.timerProgress; let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds let timerInterval; // Declare timerInterval in the outer scope const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Call this function to start the timer const startTimer = () => { timerInterval = setInterval(() => { // Assign to the outer variable if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Show the GameFail link if the timer reaches 100% document.getElementById('gameFailLink').style.display = 'block'; document.getElementById('gameSection').style.display = 'none'; // Hide the game } }, 1000); }; // Start the timer automatically startTimer(); // Game Logic: Part 1 - Terminate Session document.querySelectorAll(".ip-option").forEach(option => { option.addEventListener("click", function() { if (this.getAttribute("data-correct") === "true") { // Show the firewall configuration step document.getElementById('terminateSession').style.display = 'none'; document.getElementById('firewallConfig').style.display = 'block'; } else { alert("Incorrect IP! Try again."); } }); }); // Hint Button Logic for Part 1 document.getElementById("hint1").addEventListener("click", function() { document.getElementById("hintText1").style.display = 'block'; }); // Game Logic: Part 2 - Firewall Configuration const blockIcon = document.getElementById("blockIcon"); blockIcon.addEventListener("dragstart", (e) => { e.dataTransfer.setData("text/plain", "block"); }); document.querySelectorAll(".port").forEach(port => { port.addEventListener("dragover", (e) => { e.preventDefault(); }); port.addEventListener("drop", function(e) { e.preventDefault(); const data = e.dataTransfer.getData("text/plain"); if (data === "block" && this.id === "port21") { // Port 21 is the correct one // Show the Game Win link document.getElementById('firewallConfig').style.display = 'none'; document.getElementById('gameWinLink').style.display = 'block'; clearInterval(timerInterval); // Stop the timer } else { alert("Incorrect port! Try again."); } }); }); // Hint Button Logic for Part 2 document.getElementById("hint2").addEventListener("click", function() { document.getElementById("hintText2").style.display = 'block'; }); </script> } <style> /* Styling the Timer */ .timer { text-align: center; background-color: #111; padding: 10px; color: #fff; margin-bottom: 20px; border-radius: 5px; } .progress-bar-container { background-color: #444; border-radius: 5px; overflow: hidden; } .progress-bar { height: 20px; background-color: #ff3e3e; width: 0%; text-align: center; line-height: 20px; color: #fff; } /* Game Section */ #gameSection { background-color: #1a1a1a; padding: 20px; border-radius: 5px; color: #fff; } /* IP Options */ .ip-option { background-color: #333; padding: 10px; margin: 5px 0; cursor: pointer; border-radius: 3px; text-align: center; border: 1px solid #555; } .ip-option:hover { background-color: #555; } /* Firewall Config Section */ #firewallConfig { margin-top: 20px; } .port { background-color: #333; padding: 10px; margin: 5px 0; border-radius: 3px; border: 1px solid #555; } #blockIcon { display: inline-block; background-color: #d9534f; color: #fff; padding: 10px; border-radius: 5px; cursor: pointer; margin-top: 20px; } /* Hint Button */ .hint-button { background-color: #444; color: #fff; padding: 5px 10px; border: none; border-radius: 3px; cursor: pointer; margin-top: 10px; } /* Hint Text */ .hint-text { margin-top: 10px; color: #aaa; font-style: italic; } </style> (display: "Sidebar") (display: "SidebarBack")<h1>Educational Reinforcement</h1> <p class="speech"><b>Task Force Leader:</b> "Blocking a hacker’s access is often the last line of defense in stopping them. It’s important to act quickly and decisively—hesitation could cost you everything."</p> <p class="speech"><b>Task Force Member 1:</b> "In real cyberattacks, schools, companies, and individuals all rely on these techniques to keep their data safe. The faster you respond, the safer your systems will be."</p> <!-- Mark the "Block the Hackers Access" branch as complete --> (set: $hackersAccessBlocked to true) <div> [[HackerSuccessfullyBlocked]] </div> (display: "Sidebar") (display: "SidebarBack") <h2>Clues Discovered</h2> <!-- Display total clues found --> <p class = "s_direction">Total Clues Found: <span class="clue">{(print: $cluesFound)}</span></p> { <ul> <!-- Caesar Cipher Clue --> (if: $clue1_found is true)[ <li>Caesar Cipher found in hacker's message: <p class = "s_direction">The hacker used a Caesar Cipher with a shift of <span class="clue">{ (if: $suspectNum is 1)[3] (else-if: $suspectNum is 2)[5] (else-if: $suspectNum is 3)[4] (else-if: $suspectNum is 4)[2] (else-if: $suspectNum is 5)[7] (else-if: $suspectNum is 6)[6] (else-if: $suspectNum is 7)[(print: 7)] (else-if: $suspectNum is 8)[8] (else:)[3] }</span>.</p> </li> ] <!-- Suspicious IP Address --> (if: $clue2_found is true)[ <li>Suspicious IP Address found in logs: <p class = "s_direction">The IP address with unusually high data transfer rates was identified as <span class="clue">{ (if: $suspectNum is 1)[192.168.203.50] (else-if: $suspectNum is 2)[192.168.1.15] (else-if: $suspectNum is 3)[192.168.203.50] (else-if: $suspectNum is 4)[192.168.2.45] (else-if: $suspectNum is 5)[192.168.3.25] (else-if: $suspectNum is 6)[192.168.5.12] (else-if: $suspectNum is 7)[(print: $userIPAddress)] (else-if: $suspectNum is 8)[192.168.203.50] (else:)[192.168.203.50] }</span>.</p> </li> ] <!-- Email Header Clue --> (if: $clue3_found is true)[ <li>Email Header Clue - 'Trust me, this is safe.': <p class = "s_direction">The hidden message in the email headers helped us identify the hacker’s methods.</p> </li> ] <!-- Encryption Tools --> (if: $clue4_found is true)[ <li>Encryption tools found on the compromised machine: <p class = "s_direction">We identified sophisticated encryption tools used by the hacker. This insight was crucial in understanding their techniques.</p> </li> ] (if: $clue5_found is true)[ <li>Hackers Profession Found: <p class = "s_direction">The hacker scrambled role was found to be <span class="clue">{ (if: $suspectNum is 1)[Frpsxwhu Whfkqlfldq] (else-if: $suspectNum is 2)[Xdxyjr Firnsnxywfytw] (else-if: $suspectNum is 3)[Liehxiegliv] (else-if: $suspectNum is 4)[Fgrwva Jgcfvgcejgt] (else-if: $suspectNum is 5)[PA Zbwwvya] (else-if: $suspectNum is 6)[Rohxgxogt/Skjog Yvkiogroyz] (else-if: $suspectNum is 7)[School Student] (else-if: $suspectNum is 8)[Ivbq-Bmkpvwtwog Ildwkibm] (else:)[Unknown] }</span>.</p> </li> ] <!-- Login Attempts --> (if: $clue6_found is true)[ <li>Login attempts at unusual hours: <p class = "s_direction>Irregular login attempts were logged late at night, indicating attempts to access the system during off-hours.</p> </li> ] <!-- Favorite Colour --> (if: $clue7_found is true)[ <li>Found hacker's favourite colour: <p class = "s_direction">The hacker’s favorite color was found to be <span class="clue">{ (if: $suspectNum is 1)[Blue] (else-if: $suspectNum is 2)[Red] (else-if: $suspectNum is 3)[Green] (else-if: $suspectNum is 4)[Yellow] (else-if: $suspectNum is 5)[Purple] (else-if: $suspectNum is 6)[Orange] (else-if: $suspectNum is 7)[(print: $userFavoriteColor)] (else-if: $suspectNum is 8)[Black] (else:)[Unknown] }</span>.</p> </li> ] <!-- First Pet Name --> (if: $clue8_found is true)[ <li>Hacker's First Pet name found: <p class = "s_direction">The hacker’s first pet name was found to be <span class="clue">{ (if: $suspectNum is 1)[Rex] (else-if: $suspectNum is 2)[Milo] (else-if: $suspectNum is 3)[Buddy] (else-if: $suspectNum is 4)[Max] (else-if: $suspectNum is 5)[Lucy] (else-if: $suspectNum is 6)[Oscar] (else-if: $suspectNum is 7)[(print: $userFirstPet)] (else-if: $suspectNum is 8)[Shadow] (else:)[Unknown] }</span>.</p> </li> ] <!-- Mother's Maiden Name --> (if: $clue9_found is true)[ <li>Found hacker's mother's maiden name: <p class ="s_direction">The hacker’s mother’s maiden name was <span class="clue">{ (if: $suspectNum is 1)[Taylor] (else-if: $suspectNum is 2)[Clark] (else-if: $suspectNum is 3)[Thompson] (else-if: $suspectNum is 4)[Anderson] (else-if: $suspectNum is 5)[Evans] (else-if: $suspectNum is 6)[Mitchell] (else-if: $suspectNum is 7)[(print: $userMotherMaidenName)] (else-if: $suspectNum is 8)[Jones] (else:)[Unknown] }</span>.</p> </li> ] <!-- Anonymous Email Traced --> (if: $clue10_found is true)[ <li>Anonymous email traced back to the hacker: <p class = "s_direction">The anonymous email address used by the hacker was traced and linked to a specific suspect.</p> </li> ] <!-- Favorite Hobby --> (if: $clue11_found is true)[ <li>Favorite Hobby used as a personal security question: <p class = "s_direction">The hacker’s favorite hobby, used as a personal security question, was <span class="clue">{ (if: $suspectNum is 1)[Programming] (else-if: $suspectNum is 2)[Gaming] (else-if: $suspectNum is 3)[Hiking] (else-if: $suspectNum is 4)[Reading] (else-if: $suspectNum is 5)[Painting] (else-if: $suspectNum is 6)[Photography] (else-if: $suspectNum is 7)[(print: $userHobby)] (else-if: $suspectNum is 8)[Sabotage] (else:)[Unknown] }</span>.</p> </li> ] <!-- Decryption Key --> (if: $clue12_found is true)[ <li>Decryption Key (Shift of 3) used to decode the message: <p class = "s_direction">The decryption key used was a shift of <span class="clue">{ (if: $suspectNum is 1)[3] (else-if: $suspectNum is 2)[5] (else-if: $suspectNum is 3)[4] (else-if: $suspectNum is 4)[2] (else-if: $suspectNum is 5)[7] (else-if: $suspectNum is 6)[6] (else-if: $suspectNum is 7)[(print: 7)] (else-if: $suspectNum is 8)[8] (else:)[3] }</span>.</p> </li> ] <!-- Hidden Message in Source Code --> (if: $clue13_found is true)[ <li>Hidden message "Olssv dvysk" found in the source code, awaiting decryption: <p class = "s_direction">The hidden message found in the source code reads: <span class="clue">Olssv dvysk</span>. Use the decryption key to decipher it.</p> </li> ] <!-- Clue 14 - Hacker Name --> (if: $clue14_found is true)[ <li>Hacker's Codename Discovered: <p class = "s_direction">During the investigation, the hacker's codename was identified as <span class="clue">{ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] }</span>, revealing a part of their digital identity.</p> </li> ] <!-- Scrambled Email --> (if: $clue15_found is true)[ <li>Hacker's scrambled email found: <p class ="s_direction">The hacker's scrambled name was found to be <span class="clue">{ (if: $suspectNum is 1)[Dohz Mrkvrq] (else-if: $suspectNum is 2)[Mdplh Sdunhu] (else-if: $suspectNum is 3)[Hplob Gdylv] (else-if: $suspectNum is 4)[Wkrpdv Uhhh] (else-if: $suspectNum is 5)[Vdudk Ohh] (else-if: $suspectNum is 6)[Urehuw Eurzq] (else-if: $suspectNum is 7)["Unknown"] (else-if: $suspectNum is 8)[Rwvibpiv Tcllqbm] (else:)[Unknown] }</span>.</p> </li> ] </ul> } [[Audience Vote ->Audience VoteAgain]] (display: "SidebarBack") (display: "Sidebar") <script> document.getElementById('decryptButton').addEventListener('click', function() { // Get the input values var encryptedText = document.getElementById("encryptedInput").value; var shift = parseInt(document.getElementById("decryptKey").value); var result = ''; // Decrypt the input using Caesar Cipher for (var i = 0; i < encryptedText.length; i++) { var c = encryptedText[i]; // Only shift letters if (c.match(/[a-z]/i)) { // Get ASCII code var code = encryptedText.charCodeAt(i); // Uppercase letters if ((code >= 65) && (code <= 90)) { c = String.fromCharCode(((code - 65 - shift + 26) % 26 + 26) % 26 + 65); // Adjusted for correct backward shift } // Lowercase letters else if ((code >= 97) && (code <= 122)) { c = String.fromCharCode(((code - 97 - shift + 26) % 26 + 26) % 26 + 97); // Adjusted for correct backward shift } } // Append the decrypted character result += c; } // Display the decrypted text document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: " + result; }); document.getElementById('resetButton').addEventListener('click', function() { // Clear the input fields and output document.getElementById("encryptedInput").value = ''; document.getElementById("decryptKey").value = ''; document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: "; }); function caesarCipherEncrypt(str, shift) { return str.split('').map(char => { if (char.match(/[a-z]/i)) { const base = char.charCodeAt(0) < 97 ? 65 : 97; const encryptedChar = String.fromCharCode(((char.charCodeAt(0) - base + shift) % 26) + base); return encryptedChar; } return char; // Non-letter characters remain unchanged }).join(''); } // Automatically encrypt the user's name when the passage loads const inputString = window.harloweVariables.userName; // Get the Harlowe variable const encryptedString = caesarCipherEncrypt(inputString, 7); // Display the output document.getElementById('output').innerHTML = encryptedString; // Store the result back into a Harlowe variable window.harloweVariables.encryptedName = encryptedString; // Store it in a Harlowe variable </script>~~Strikethrough Text~~<style> /* Make tw-story and tw-passage take up the entire screen */ tw-story, tw-passage { width: 100%; height: 100vh; /* Full viewport height */ margin: 0; padding: 0; background-color: #2E4A43; /* Desired green background color */ max-width: 100%; overflow-y: auto; /* Enable vertical scrolling */ } .container { display: flex; width: 100%; max-height: 100vh; /* Ensure container doesn't exceed the viewport height */ overflow-y: auto; /* Enable scrolling for overflow */ } /* Left column for Suspect Information */ .left { flex: 1; /* Takes up 1/3 of the screen */ padding: 20px; color: #F5F5DC; /* Beige color for the text */ border-right: 2px solid #F5F5DC; /* Divider line */ box-sizing: border-box; /* Ensure padding and border are included in the element's total width and height */ background-color: #2E4A43; /* Matching the right column background */ } /* Right column for Cipher Decryption */ .right { flex: 2; /* Takes up 2/3 of the screen */ padding: 20px; color: #F5F5DC; /* Beige color for the text */ box-sizing: border-box; /* Ensure padding is included in the element's total width and height */ background-color: #2E4A43; /* Matching the left column background */ display: flex; flex-direction: column; /* Stack items vertically */ align-items: center; /* Center items horizontally */ justify-content: center; /* Center items vertically */ } /* Styling the form elements for better spacing */ form { display: flex; flex-direction: column; max-width: 400px; /* Limit the width of the form */ width: 100%; /* Make form take full width */ } label, input, button { margin-bottom: 10px; /* Add spacing between elements */ } input { max-width: 100%; /* Ensure input fields do not exceed form's width */ background-color: white; } button { align-self: flex-start; /* Align button to the left */ } /* Ensure the text doesn't overflow */ .clue { word-wrap: break-word; } </style> <div class="container"> <!-- Left Column for Suspect Information --> <div class="left"> <h3>Suspect Information:</h3> <ul> <li><b>Encrypted Name:</b> <span class="clue">{ (if: $clue1_found is true and $clue12_found is true)[ (if: $suspectNum is 1)[Dohz Mrkvrq] (else-if: $suspectNum is 2)[Ofrnj Ufwpjw] (else-if: $suspectNum is 3)[Iqmpc Hezmw] (else-if: $suspectNum is 4)[Vjqocu Tggf] (else-if: $suspectNum is 5)[Zhyho Sll] (else-if: $suspectNum is 6)[Xuhkxz Hxuct] (else-if: $suspectNum is 7)[<p id="output"></p>] (else-if: $suspectNum is 8)[Rwvibpiv Tcllqbm] (else:)[Unknown] ] (else:)[Unknown] }</span></li> <li><b>Encrypted Role:</b> <span class="clue">{ (if: $clue5_found is true)[ (if: $suspectNum is 1)[Frpsxwhu Whfkqlfldq] (else-if: $suspectNum is 2)[Xdxyjr Firnsnxywfytw] (else-if: $suspectNum is 3)[Liehxiegliv] (else-if: $suspectNum is 4)[Fgrwva Jgcfvgcejgt] (else-if: $suspectNum is 5)[PA Zbwwvya] (else-if: $suspectNum is 6)[Rohxgxogt/Skjog Yvkiogroyz] (else-if: $suspectNum is 7)[School Student] (else-if: $suspectNum is 8)[Ivbq-Bmkpvwtwog Ildwkibm mvkzgxbml] (else:)[Unknown] ] (else:)[Unknown] }</span></li> <li><b>Date of Birth:</b> <span class="clue">{ (if: $clue1_found is true)[ (if: $suspectNum is 1)[01/05/1980] (else-if: $suspectNum is 2)[12/11/1975] (else-if: $suspectNum is 3)[23/09/1968] (else-if: $suspectNum is 4)[05/06/1970] (else-if: $suspectNum is 5)[14/03/1985] (else-if: $suspectNum is 6)[30/07/1978] (else-if: $suspectNum is 7)[(print: $userDOB)] (else-if: $suspectNum is 8)[17/02/1965] (else:)[Unknown] ] (else:)[Unknown] }</span></li> <li><b>Mother's Maiden Name:</b> <span class="clue">{ (if: $clue9_found is true)[ (if: $suspectNum is 1)[Taylor] (else-if: $suspectNum is 2)[Clark] (else-if: $suspectNum is 3)[Thompson] (else-if: $suspectNum is 4)[Anderson] (else-if: $suspectNum is 5)[Evans] (else-if: $suspectNum is 6)[Mitchell] (else-if: $suspectNum is 7)[(print: $userMotherMaidenName)] (else-if: $suspectNum is 8)[Jones] (else:)[Unknown] ] (else:)[Unknown] }</span></li> <li><b>Hobby:</b> <span class="clue">{ (if: $clue11_found is true)[ (if: $suspectNum is 1)[Programming] (else-if: $suspectNum is 2)[Gaming] (else-if: $suspectNum is 3)[Hiking] (else-if: $suspectNum is 4)[Reading] (else-if: $suspectNum is 5)[Painting] (else-if: $suspectNum is 6)[Photography] (else-if: $suspectNum is 7)[(print: $userHobby)] (else-if: $suspectNum is 8)[Sabotage] (else:)[Unknown] ] (else:)[Unknown] } <!-- Hacker Name (Clue 14) --> <li><b>Hacker Name:</b> <span class="clue">{ (if: $clue14_found is true)[ (if: $suspectNum is 1)[ShadowByte] (else-if: $suspectNum is 2)[NetPhantom] (else-if: $suspectNum is 3)[DataMistress] (else-if: $suspectNum is 4)[CipherScribe] (else-if: $suspectNum is 5)[CodeSorceress] (else-if: $suspectNum is 6)[MediaGhost] (else-if: $suspectNum is 7)[Audience4Lyfe] (else-if: $suspectNum is 8)[TechNemesis] (else:)[Unknown] ] (else:)[Unknown]} </span></li> <li><b>Cipher Key:</b> <span class="clue">{ (if: $suspectNum is 1)[3] (else-if: $suspectNum is 2)[5] (else-if: $suspectNum is 3)[4] (else-if: $suspectNum is 4)[2] (else-if: $suspectNum is 5)[7] (else-if: $suspectNum is 6)[6] (else-if: $suspectNum is 7)[(print: 7)] (else-if: $suspectNum is 8)[8] (else:)[3] }</span></li> </ul> </div> <!-- Right Column for Cipher Decryption Area --> <div class="right"> <h3>Cipher Decryption Area</h3> <p>Enter the encrypted name and decryption key to decipher:</p> <form id="decryptForm"> { <label for="encryptedInput">Encrypted Name:</label> <input type="text" id="encryptedInput"> } {<label for="decryptKey">Decryption Key (Shift Value):</label> <input type="number" id="decryptKey">} { <button type="button" id="decryptButton">Decrypt</button>} {<p id="decryptedOutput">Decrypted Name: </p>} </form> <button type="button" id="resetButton">Reset</button> </div> </div> [[The Reveal]] <script> document.getElementById('decryptButton').addEventListener('click', function() { // Get the input values var encryptedText = document.getElementById("encryptedInput").value; var shift = parseInt(document.getElementById("decryptKey").value); var result = ''; // Decrypt the input using Caesar Cipher for (var i = 0; i < encryptedText.length; i++) { var c = encryptedText[i]; // Only shift letters if (c.match(/[a-z]/i)) { // Get ASCII code var code = encryptedText.charCodeAt(i); // Uppercase letters if ((code >= 65) && (code <= 90)) { c = String.fromCharCode(((code - 65 - shift + 26) % 26 + 26) % 26 + 65); // Adjusted for correct backward shift } // Lowercase letters else if ((code >= 97) && (code <= 122)) { c = String.fromCharCode(((code - 97 - shift + 26) % 26 + 26) % 26 + 97); // Adjusted for correct backward shift } } // Append the decrypted character result += c; } // Display the decrypted text document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: " + result; }); document.getElementById('resetButton').addEventListener('click', function() { // Clear the input fields and output document.getElementById("encryptedInput").value = ''; document.getElementById("decryptKey").value = ''; document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: "; }); function caesarCipherEncrypt(str, shift) { return str.split('').map(char => { if (char.match(/[a-z]/i)) { const base = char.charCodeAt(0) < 97 ? 65 : 97; const encryptedChar = String.fromCharCode(((char.charCodeAt(0) - base + shift) % 26) + base); return encryptedChar; } return char; // Non-letter characters remain unchanged }).join(''); } // Automatically encrypt the user's name when the passage loads const inputString = window.harloweVariables.userName; // Get the Harlowe variable const encryptedString = caesarCipherEncrypt(inputString, 7); // Display the output document.getElementById('output').innerHTML = encryptedString; // Store the result back into a Harlowe variable window.harloweVariables.encryptedName = encryptedString; // Store it in a Harlowe variable </script><h1>The Reveal</h1> <p class="speech"><b>Task Force Leader:</b> "We’ve done it! We’ve decrypted the message, and all the evidence is clear now."</p> <p class="speech"><b>Task Force Member:</b> "Everything lines up—the encrypted emails, the strange activity logs, and those suspicious data transfers. We know who’s been hiding behind all these layers of deception."</p> <p class="speech"><b>Task Force Leader:</b> "We have everything we need. Now it’s time to close this chapter once and for all. The hacker can’t hide any longer."</p> <p class="speech"><b>Task Force Member:</b> "Let’s proceed with the final steps."</p> <!-- Conditional Links based on the suspect number --> { (if: $suspectNum is 1)[ [[Continue->Alex Johnson Ending]] ] (else-if: $suspectNum is 2)[ [[Continue->Jamie Parker Ending]] ] (else-if: $suspectNum is 3)[ [[Continue->Emily Davis Ending]] ] (else-if: $suspectNum is 4)[ [[Continue->Thomas Reed Ending]] ] (else-if: $suspectNum is 5)[ [[Continue->Sarah Lee Ending]] ] (else-if: $suspectNum is 6)[ [[Continue->Robert Brown Ending]] ] (else-if: $suspectNum is 7)[ [[Continue->Random Audience Member Ending]] ] (else-if: $suspectNum is 8)[ [[Continue->Luddite Ending]] ] (else:)[ <p>You haven't chosen a number at the beginning</p> ] } (display: "Sidebar") (display: "SidebarBack")<h1>Wrapping Up the Investigation</h1> <p class="speech"><b>Task Force Leader:</b> "Well done, everyone! We’ve solved the case, uncovered the hacker’s identity, and secured the network. But this investigation was about more than just catching the hacker—it was a lesson in cybersecurity."</p> <p class="speech"><b>Task Force Member:</b> "Throughout the investigation, we dealt with encrypted data, suspicious activity, and digital clues. Let’s take a moment to reflect on what we’ve learned about staying safe online."</p> <p>[[Encryption and Online Security]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Encryption and Online Security</h1> <p class="speech"><b>Task Force Leader:</b> "One of the biggest lessons we learned is the power of encryption. The hacker used the Caesar Cipher to scramble their messages, making it harder for anyone to read them. Encryption is a tool that can protect your information, but it can also be used by attackers to hide their activities."</p> <p class="speech"><b>Task Force Member:</b> "That’s right. Encryption is everywhere, from secure websites to encrypted emails. It’s how we keep data private and safe. But understanding how it works helps you recognize when something’s wrong, like we did in this investigation."</p> <p>[[Recognising and Responding to Threats]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Recognizing and Responding to Threats</h1> <p class="speech"><b>Task Force Leader:</b> "We also learned that staying safe online means knowing how to spot threats. The hacker used phishing emails, fake logins, and hidden data transfers to try and access sensitive information. These are common tactics in real-world cyberattacks."</p> <p class="speech"><b>Task Force Member:</b> "That’s why it’s important to always question unexpected emails, strange login requests, or unusual activity on your accounts. When in doubt, report it to someone who can help."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. Cybersecurity isn’t just about high-tech defenses—it’s about being aware of what’s happening online and protecting yourself from potential dangers."</p> <p>[[Data Privacy and Personal Responsibility]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Data Privacy and Personal Responsibility</h1> <p class="speech"><b>Task Force Leader:</b> "We also saw how easily someone can exploit weak points in a network to steal personal data. That’s why data privacy is so important. You need to think carefully about what information you share online and how you protect it."</p> <p class="speech"><b>Task Force Member:</b> "That includes using strong passwords, enabling two-factor authentication, and being careful with the personal information you give out. Remember, once something is online, it can be difficult to remove."</p> <p class="speech"><b>Task Force Leader:</b> "Taking control of your online privacy is part of being a responsible digital citizen. You have the power to keep your data safe by making smart choices."</p> <p>[[Digital Competence and Staying Safe Online]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Digital Competence and Staying Safe Online</h1> <p class="speech"><b>Task Force Leader:</b> "Finally, this investigation showed us why it’s important to build digital competence—knowing how to navigate the online world safely and responsibly. Cybersecurity threats are always changing, but by staying informed, you can protect yourself and your data."</p> <p class="speech"><b>Task Force Member:</b> "The Digital Competence Framework (DCF) helps us develop these skills. It teaches us about online behavior, cyber safety, and how to use technology in a secure and responsible way."</p> <p>[[Final Thought]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Final Thought</h1> <p class="speech"><b>Task Force Leader:</b> "Cybersecurity isn’t just for professionals—it’s for everyone. Whether it’s protecting your social media accounts, securing your emails, or recognizing phishing attempts, the skills you learn now will help you stay safe in the future."</p> <p class="speech"><b>Task Force Member:</b> "Thanks for your help, team. You’ve all learned how to think like cybersecurity experts today!"</p> <p class="speech"><b>Task Force Leader:</b> "Let’s stay sharp, stay secure, and keep learning how to protect ourselves online. Great work!"</p> (display: "Sidebar") (display: "SidebarBack") <h1>Proceed to the Final Investigation</h1> <p class="speech"><b>Task Force Leader:</b> "Excellent. With all the clues we’ve gathered, we should be able to decrypt the hacker’s communications using the Caesar Cipher and figure out who’s responsible."</p> <p class="s_direction">(The audience proceeds to the final investigation and puzzle-solving stage.)</p> <p>[[Recap of clues]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Task Force Reassesses the Situation</h1> <p class="speech"><b>Task Force Member 1:</b> "Cybersecurity threats come in all forms. Attackers could be using phishing emails, network infiltration, or even malware to cover their tracks. We can’t take anything for granted."</p> <p class="speech"><b>Task Force Member 2:</b> "And then there’s social engineering. Sometimes the weakest link is the human factor, and we haven’t even touched that yet. Maybe we overlooked something simple, like a compromised password or a phishing attempt."</p> <p class="speech"><b>Task Force Leader:</b> "That’s true. Attackers often rely on exploiting small oversights, like unpatched software or misconfigured firewalls. It’s why thoroughness is key in any investigation."</p> <p class="speech"><b>Task Force Member 1:</b> "We might need to go back and re-examine the network for unusual activity. Even small anomalies, like strange traffic patterns, can be signs of a larger attack."</p> <p class="speech"><b>Task Force Leader:</b> "Right. Without more evidence, we can't be sure of our next move. We need to gather more clues before we can proceed."</p> <p>[[Vote]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> (display: "SidebarBack")<h1>Meet the Individuals</h1> <!-- Content Sections --> <div id="content"> <!-- Individual 1 --> <div id="individual1" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 1;"> <h2>Computer Technician - Alex Johnson</h2> <p>"I was just fixing a minor issue in the server room. I didn’t see or hear anything unusual."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 2 --> <div id="individual2" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>System Administrator - Jamie Parker</h2> <p>"I was monitoring the network traffic. Everything seemed normal until the siren went off."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 3 --> <div id="individual3" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>Headteacher - Mrs. Emily Davis</h2> <p>"I was in my office when the alarm rang. I rushed out to see what was happening."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 4 --> <div id="individual4" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>Deputy Headteacher - Mr. Thomas Reed</h2> <p>"I was making rounds in the building and arrived here just as the siren started."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 5 --> <div id="individual5" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>IT Support Staff - Sarah Lee</h2> <p>"I was working on a ticket when I heard the commotion. I came to check if I could help."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 6 --> <div id="individual6" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>Librarian - Mr. Robert Brown</h2> <p>"I was organizing books in the library when the siren went off. I joined the crowd to see what was wrong."</p> <div class="instruction">Click for next...</div> </div> <!-- Individual 7 --> <div id="individual7" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 0; display: none;"> <h2>Science Teacher - Dr. Lisa Green</h2> <p>"I was conducting an experiment in the lab and came out when I heard the siren."</p> <div class="instruction">Click for next...</div> </div> <!-- Task Force Commander Dialogue --> <div id="taskForceDialogue" style="position: absolute; top: 0; left: 0; width: 100%; z-index: 1; display: none;"> <p><b>Task Force Commander:</b> "Luddite, Emma Smith, can you please step forward and introduce yourselves to the group?"</p> <p><b>Luddite:</b> "I’m Mr Jonathan Luddite, a tech...enthusiast. I was here to present and have been here the whole time."</p> <p><b>Emma Smith:</b> "I’m Emma Smith, a staff member. I was helping out and also witnessed the commotion."</p> <p>[[Continue->Clue1]]</p> </div> </div> <!-- Clickable area to trigger content change --> <div id="clickableArea" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; cursor: pointer;"></div> <script> let currentIndividual = 1; // Start at Individual 1 document.getElementById('clickableArea').addEventListener('click', function() { if (currentIndividual <= 7) { // Hide the current individual document.getElementById(`individual${currentIndividual}`).style.display = 'none'; // Show the next individual currentIndividual++; if (currentIndividual <= 7) { document.getElementById(`individual${currentIndividual}`).style.display = 'block'; document.getElementById(`individual${currentIndividual}`).style.zIndex = '1'; // Ensure it's on top } else { // Show the Task Force Commander dialogue after the last individual document.getElementById('taskForceDialogue').style.display = 'block'; } } }); // Initially display the first individual document.getElementById('individual1').style.display = 'block'; </script> (display: "Sidebar") (display: "SidebarBack") <h1>Narrowing Down the Suspects</h1> <!-- Conditional statement to check if Alex Johnson is a suspect --> { (if: $suspect1_found is true)[ <!-- If Alex is a suspect --> <p class="s_direction">The task force leader walks over to Alex Johnson, who is typing furiously at his workstation. He looks up with a slight scowl as the leader approaches.</p> <p class="speech"><b>Task Force Leader:</b> "Alex, any luck with those logs? Can we figure out who’s behind these emails?"</p> <p class="speech"><b>Alex Johnson:</b> "You know, maybe if we had the resources I've been asking for, we wouldn't be in this mess. It's like you expect me to work miracles with outdated equipment."</p> <p class="s_direction">He glares at the leader for a moment before turning back to his screen.</p> <p class="speech"><b>Alex Johnson:</b> "I've managed to trace some network activity, but it’s not easy when we’re always playing catch-up. It’s coming from inside the network, and it’s frustratingly obvious that someone on the inside knows exactly how to exploit our weaknesses."</p> <p class="speech"><b>Task Force Leader:</b> "We’re all frustrated, Alex, but now’s not the time. We need results."</p> <p class="s_direction">Alex mutters something under his breath, but then reluctantly nods and continues sifting through the logs.</p> <p class="speech"><b>Alex Johnson:</b> "Fine. I’ll keep digging. But don’t expect miracles."</p> ] (else:)[ <!-- If Alex is not a suspect --> <p class="s_direction">The task force leader walks over to Alex Johnson, who is typing furiously at his workstation. He looks up, concern etched on his face as the leader approaches.</p> <p class="speech"><b>Task Force Leader:</b> "Alex, any luck with those logs? Can we figure out who’s behind these emails?"</p> <p class="speech"><b>Alex Johnson:</b> "I’m working on it. Whoever this is, they covered their tracks well, but I’ve managed to trace some network activity. It’s just... frustrating."</p> <p class="s_direction">He hesitates, glancing at the leader with a conflicted expression.</p> <p class="speech"><b>Alex Johnson:</b> "If we had the right tools and resources, we could have prevented this. But I'm not making excuses. I just want you to know I'm doing everything I can."</p> <p class="speech"><b>Task Force Leader:</b> "We appreciate your effort, Alex. Keep at it. We need to find the culprit."</p> <p class="s_direction">Alex nods, his focus returning to the screen as he continues to sift through the logs.</p> <p class="speech"><b>Alex Johnson:</b> "I’ve isolated more suspicious traffic that matches the timeline of the breach. It’s coming from inside the network. I'll keep digging."</p> ] } <p>[[Investigate Email Address]]</p> (display: "Sidebar") (display: "SidebarBack") <p class="speech"><b>Emma Smith</b> (confused): “What's happening?”</p> <p class="speech"><b>Mr. Luddite</b> (worried): “This isn’t part of the plan… something’s wrong!”</p> <p class="speech"><b>Emma Smith</b> (nervous): “I don’t like this...”</p> <p>[[Task Force Arrival]]</p> (display: "SidebarBack")<h1>The Briefing</h1> <p class="speech"><b>Task Force Leader:</b> "We need your eyes and ears open. You're not just spectators; you're part of this investigation now. Each one of you could be a witness, or you could help us catch the perpetrator. We'll be uncovering clues together, and it's imperative that everyone participates and remains vigilant. Are we clear... ARE WE CLEAR?!"</p> {<!-- Interactive Game --> <div id="interactive-game" class="s_direction"> <p id="game-text">Press the button below to respond: "CLEAR SIR!"</p> <button id="clearButton">CLEAR SIR!</button> <progress id="progressBar" value="0" max="100" style="width: 100%; height: 30px; margin: 20px 0;"></progress> <p id="progressText">0% Complete</p> <p id="briefingLink" style="display: none;">[[Continue ->Briefing 3]]</p> <!-- Hidden link initially --> </div> } <script> // Variables for the interactive game const button = document.getElementById('clearButton'); const progressBar = document.getElementById('progressBar'); const progressText = document.getElementById('progressText'); const briefingLink = document.getElementById('briefingLink'); let progress = 0; // Start at 0% // Function to handle button clicks button.addEventListener('click', function() { if (progress < 100) { // Increase progress by 20% progress += 20; if (progress > 100) { progress = 100; // Cap progress at 100% } progressBar.value = progress; // Update progress bar progressText.textContent = `${progress}% Complete`; // Update progress text // Check if progress has reached 100% if (progress === 100) { // Stop the game and show the link progressText.textContent = "100% Complete! Proceeding to the next part..."; button.disabled = true; // Disable the button briefingLink.style.display = 'block'; // Show the link } } }); </script> (display: "Sidebar") (display: "SidebarBack") <h1>The Briefing</h1> <p class="speech"><b>Task Force Leader:</b> "We have also brought in several individuals who were in the vicinity of the incident. They are here to provide any necessary information and assist with our investigation."</p> <p class="s_direction"> (A group of individuals enters the room, looking slightly apprehensive. They were in the area and may have useful information.) </p> <p>[[Meet the individuals->Meet the Individuals]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>First Clue: Hacker’s Message</h1> <p class="speech"><b>Task Force Member:</b> "Sir! We’ve just received a message from the hacker. Looks like the hacker is sending us on a puzzle chase.</p> <p class="speech"><b>Task Force Leader:</b> <b>‘The secret to my special speech is the move of <span class='clue'>{ (if: $suspectNum is 1)[3] (else-if: $suspectNum is 2)[5] (else-if: $suspectNum is 3)[4] (else-if: $suspectNum is 4)[2] (else-if: $suspectNum is 5)[7] (else-if: $suspectNum is 6)[6] (else-if: $suspectNum is 7)[(print: 7)] (else-if: $suspectNum is 8)[8] (else:)[3] }</span>. Not one, not twenty, but <span class='clue'>{ (if: $suspectNum is 1)[3] (else-if: $suspectNum is 2)[5] (else-if: $suspectNum is 3)[4] (else-if: $suspectNum is 4)[2] (else-if: $suspectNum is 5)[7] (else-if: $suspectNum is 6)[6] (else-if: $suspectNum is 7)[(print: 7)] (else-if: $suspectNum is 8)[8] (else:)[3] } <p class="speech"><b>Task Force Leader:</b> "‘Veni, Vidi, Vici.’ That’s from Julius Caesar. They’re hinting at something... Perhaps a Caesar Cipher."They’re taunting us, playing games... It feels like they want us to crack the code. </p> <p class="s_direction">The team exchanges glances, realizing they might be on to something important. This first clue is added to their investigation notes.</p> <p>[[Continue with Investigation->Investigation Start]]</p> (display: "Sidebar") (display: "SidebarBack") <!-- Check and update the clue variable --> (if: $clue1_found is not true)[ (set: $clue1_found to true) (set: $cluesFound to $cluesFound + 1) ] <!-- Check and update the clue variable --> (if: $clue12_found is not true)[ (set: $clue12_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Clue: First Pet Name</h1> { (display: ":: PetNameClue") <!-- This calls the template that displays the pet name --> } <p class="speech"><b>Task Force Member:</b> "Sir! While combing through the user logs, we found a password recovery prompt. It's asking for the name of the user's first pet. A bit old-school, but it looks like our hacker is relying on traditional security questions."</p> <p class="speech"><b>Task Force Leader:</b> "First pet name? Classic, but weak. If the hacker is using this, they must have wanted to keep things simple. They might be underestimating us."</p> <p class="speech"><b>Task Force Member:</b> "Could be a lazy defense mechanism or they’ve customized it to throw us off. Either way, we’ll log this clue. It’s one step closer to unlocking their security layers."</p> <p class="speech"><b>Task Force Leader:</b> "Every detail counts, no matter how trivial it seems. Add it to our clues. We’ll keep digging—this could lead us to something bigger."</p> <p class="s_direction">The team exchanges determined looks as they log the clue: the hacker used “First Pet Name” as part of their security setup. They wonder how many more personal details are hiding in the system.</p> [[Hacker Online]] (display: "Sidebar") (display: "SidebarBack") <!-- Check and update the clue variable --> (if: $clue8_found is not true)[ (set: $clue8_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Third Clue: Favorite Color</h1> (display: "FavColourClue") <p class="speech"><b>Task Force Member:</b> "We’ve found another clue...a security question. This time, it’s asking for the user’s favorite color."</p> <p class="speech"><b>Task Force Leader:</b> "Favorite color? That’s a bit personal. It’s interesting that the hacker is using these personal questions. Maybe this gives us a glimpse into their identity or mindset."</p> <p class="speech"><b>Task Force Member:</b> "Could it be a clue about the hacker themselves? People tend to use personal details they’re attached to. It could help us narrow down suspects."</p> <p class="speech"><b>Task Force Leader:</b> "It’s possible. Whether it’s significant or just a distraction, we log everything. Add it to the clues. We’re closing in."</p> <p class="s_direction">The team logs the clue: “Favorite Color” as part of the hacker’s defense. As they discuss the implications, they wonder how much of the hacker’s personality is hiding behind these simple questions.</p> <p>[[WrapUp]]</p> (display: "Sidebar") (display: "SidebarBack") (if: $clue7_found is not true)[ (set: $clue7_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Clue: Login Activity at Odd Hours</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar"> <div class="progress" id="timer-progress">0%</div> </div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('timer-progress').style.width = `${progress}%`; // Update progress bar width document.getElementById('timer-progress').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { link.style.display = 'none'; } }); }; const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); progress = 100; updateProgressBar(); hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } {(display: "LoginTimeClue")} <p class="speech"><b>Task Force Member:</b> "Sir, we’ve found a pattern of irregular login times. It looks like someone has been accessing the system at odd hours, trying to stay under the radar."</p> <p class="speech"><b>Task Force Leader:</b> "Late-night logins, strange hours... It’s typical for someone trying to hide their tracks. We’ll need to cross-check these times with our suspects’ schedules."</p> <p class="speech"><b>Task Force Member:</b> "If we can match these odd hours with someone’s routine, we might find our hacker."</p> <p class="s_direction">The team logs the clue, focusing on the irregular login times. It feels like they’re narrowing down the hacker’s identity.</p> [[Wrap Up]] (display: "Sidebar") (display: "SidebarBack") <!-- Check and update the clue variable --> (if: $clue6_found is not true)[ (set: $clue6_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Clue: Hackers Profession</h1> <p class="speech"><b>Task Force Member:</b> "There's <strong>some</strong> good news Sir! While you were doing that i've been going over the metadata in the system logs. We have found a clue about the hacker's profession! It's scrambled but...if we can unscramble it!"</p> <p class="speech"><b>Task Force Leader:</b> "That's a significant lead. If we can identify the hacker's professional role, it might narrow down our list of suspects."</p> <p class="speech"><b>Task Force Member:</b> "Analyzing the techniques and the type of access used, we've pinpointed their role."</p> <p class="s_direction"> The hacker's professional role is revealed as <span class="clue">{ (if: $suspectNum is 1)[Frpsxwhu Whfkqlfldq] <!-- Computer Technician --> (else-if: $suspectNum is 2)[Xdxyjr Firnsnxywfytw] <!-- System Administrator --> (else-if: $suspectNum is 3)[Liehxiegliv] <!-- Headteacher --> (else-if: $suspectNum is 4)[Fgrwva Jgcfvgcejgt] <!-- Deputy Headteacher --> (else-if: $suspectNum is 5)[PA Zbwwvya] <!-- IT Support --> (else-if: $suspectNum is 6)[Rohxgxogt/Skjog Yvkiogroyz] <!-- Librarian/Media Specialist --> (else-if: $suspectNum is 7)[School Student] <!-- Audience Member --> (else-if: $suspectNum is 8)[Ivbq-Bmkpvwtwog Ildwkibm] <!-- Anti-Technology Advocate --> (else:)[Unknown] }</span>. </p> [[Continue]] (if: $clue5_found is not true)[ (set: $clue5_found to true) (set: $cluesFound to $cluesFound + 1) ] <!-- Set the variable to true --> (set: $backups_restored to true) (display: "Sidebar") (display: "SidebarBack") <h1>Clue: Unauthorized File Transfer</h1> <p class="speech"><b>Task Force Member:</b> "We’ve detected an unauthorized file transfer, sir. It was masked, but we managed to uncover the logs. Someone moved data out of the system without permission."</p> <p class="speech"><b>Task Force Leader:</b> "A data leak? That’s big. If we can trace where the data went, we’ll find out who’s behind this."</p> <p class="speech"><b>Task Force Member:</b> "This could be what the hacker is after—valuable data they’re trying to steal."</p> <p class="s_direction">The team logs the clue, realizing the hacker’s endgame might be a data breach. This clue could help them figure out the bigger picture.</p> [[File Opening Decision]] (display: "Sidebar") <!-- Update the clue variable --> (set: $clue7_found to true) [[Audience Votes on Attack Type]] (display: "Sidebar") (display: "SidebarBack")<h1>Suspicious Emails Investigation</h1> <p class="s_direction">The task force leader motions to Alex Johnson, the computer technician, to share his analysis.</p> <p class="speech"><b>Task Force Leader:</b> "Alex, you’ve been monitoring the network. What’s your take on these emails? Can you trace where they might have come from?"</p> <p class="speech"><b>Alex Johnson:</b> "These emails are definitely well-crafted. Whoever sent them knows how to spoof domains and forge email headers. The slight change from 'school.ac.uk' to 'schooltech.co.uk' could easily go unnoticed by most people. It's a clear sign of how vulnerable our system really is."</p> <p class="speech"><b>Task Force Leader:</b> "What about the links embedded in these emails? Do you think they could lead us to anything useful?"</p> <p class="speech"><b>Alex Johnson:</b> "The links are disguised to look legitimate, but they actually point to a fake website hosted on an overseas server. I’ve traced some of the network traffic and found that a few staff members clicked on these links. The moment they did, their credentials were likely stolen. If our IT policies weren't so outdated, maybe this wouldn't have happened."</p> [[Continue ->Suspicious3]] (display: "Sidebar") (display: "SidebarBack") <h1>Jamie Parker’s Analysis (Expanded)</h1> <p class="s_direction">Jamie Parker, the System Administrator, steps forward, focusing on the metadata and technical details.</p> <p class="speech"><b>Jamie Parker:</b> "These headers reveal quite a bit. The sender’s address is 'admin@schooltech.co.uk,' but our official domain is 'school.ac.uk.' This is a textbook case of domain spoofing."</p> <p class="speech"><b>Task Force Leader:</b> "Good catch. Anything else?"</p> <p class="speech"><b>Jamie Parker:</b> "Look at this line—'Received-SPF: softfail.' That tells us this email failed an important security check. Someone was trying to make this email look legitimate, but they didn’t get past all our defenses. Although, it’s strange—if they were as skilled as they seem, they wouldn’t have made such a basic mistake. It's almost like they don't care about being flawless, which is either sloppy... or intentional."</p> <p class="speech"><b>Task Force Leader:</b> "So whoever sent this knows their way around email systems, but they made a mistake."</p> <p class="speech"><b>Jamie Parker:</b> "Exactly. But here's something that stands out even more—this phrase embedded in the metadata: '<span class='clue'>Trust me, this is safe.</span>' This isn't just an error. It's a message, almost like they’re taunting us. No one embeds a phrase like this by accident. It's a bold move, almost as if they want us to find it. If I had the control over system access I’ve been asking for, we might have caught this sooner."</p> <p class="speech"><b>Task Force Leader:</b> "So, they’re playing games with us. Why leave a message like that?"</p> <p class="speech"><b>Jamie Parker:</b> "It’s a show of confidence. They want us to know that they’re one step ahead, using our own systems against us. It's frustrating to see how they exploit the gaps in our defenses. If our hands weren't tied by all the bureaucratic restrictions, this kind of thing wouldn't be slipping through."</p> <p class="speech"><b>Task Force Leader:</b> "We’re definitely looking at a sophisticated attacker here. Keep digging, Jamie. We need more clues."</p> <p class="s_direction">Jamie frowns slightly, then speaks with a hint of frustration.</p> <p class="speech"><b>Jamie Parker:</b> "You know, if I had more control over these systems, we wouldn’t be having this problem in the first place. It's the red tape that’s slowing us down."</p> <p class="speech"><b>Task Force Leader:</b> "We’ve all got restrictions to deal with, Jamie. Focus on the task at hand."</p> <p class="s_direction">Jamie nods, but there’s still an edge to his voice as he returns to his work.</p> <p><b>Do you find Jamie Parker suspicious?</b></p> [[Yes, Jamie Parker seems suspicious]] [[No, Jamie Parker does not seem suspicious ->Audience Votes on Attack Type]] (display: "Sidebar") (display: "SidebarBack") <!-- Check and update the clue variable --> (if: $clue3_found is not true)[ (set: $clue3_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Emily Davis’s Frustration</h1> <p class="s_direction">The Task Force approaches Emily Davis, the Headteacher, who’s pacing back and forth, clearly stressed.</p> <p class="speech"><b>Emily Davis:</b> "You know, when I first took this job, it wasn’t about battling cyber threats. It was about education, about helping students. But now... now everything revolves around technology we can barely afford to maintain."</p> <p class="s_direction">She stops for a moment and looks directly at the Task Force leader.</p> <p class="speech"><b>Emily Davis:</b> "Do you have any idea what it's like trying to manage a school when the budget for essential services is being slashed left and right? IT is supposed to be the backbone of this place, but we've been stretched so thin."</p> <p class="s_direction">She gestures towards the chaotic scenes of the investigation happening around her.</p> <p class="speech"><b>Emily Davis:</b> "It’s not just about this breach. It’s about years of neglect. The school board cuts funding, parents demand more, and staff... well, they don’t see the big picture. They just want everything to work without understanding the cost."</p> <p class="speech"><b>Task Force Leader:</b> "It sounds like you’re dealing with a lot of frustration. Do you think this breach could be related to the budget issues?"</p> <p class="speech"><b>Emily Davis:</b> "If it is, then it’s only proving what I’ve been saying for years. We don’t have the resources to protect ourselves. The irony is that now, after all this damage, maybe the school board will finally realize that cutting corners on IT has consequences."</p> <p class="speech"><b>Task Force Leader:</b> "Do you think someone on the inside could be responsible? Someone with access to these resources?"</p> <p class="s_direction">Emily hesitates, a flicker of doubt crossing her face before she shakes her head.</p> <p class="speech"><b>Emily Davis:</b> "I... I don't know. It could be anyone, really. Someone frustrated, someone who feels betrayed by the system... or maybe even someone who just wants control."</p> <p class="s_direction">She glances back at the task force leader with a slight edge in her voice.</p> <p class="speech"><b>Emily Davis:</b> "I’m not saying it’s anyone in particular, but these things don’t happen out of thin air. There’s always a reason. Always."</p> <p class="s_direction">The task force leader makes a note and nods, leaving Emily to stew in her thoughts as they continue the investigation.</p> <!-- Present the player with a choice --> <p> [[Yes, Emily Davis seems suspicious.->EmilyAdd to Watchlist]]<br> [[No, Emily doesn't seem suspicious.->Sarah Lee’s IT Struggles]] </p> (display: "Sidebar") (display: "SidebarBack") <h1>Sarah Lee’s IT Struggles</h1> <p class="s_direction">Sarah Lee, the IT Support Staff member, looks exhausted as she steps forward. The pressure is mounting, and it's clear she’s been dealing with system issues for a long time.</p> <p class="speech"><b>Task Force Leader:</b> "Sarah, you've been handling the school's IT systems. Have you noticed anything unusual in recent days that could be linked to the attack?"</p> <p class="speech"><b>Sarah Lee:</b> "It’s been one thing after another. I’ve been reporting for months that our systems were outdated, but nothing ever gets done. We’re constantly patching things up. Half the time, I’m just trying to stop everything from falling apart."</p> <p class="speech"><b>Task Force Member:</b> "Do you think the vulnerabilities you’ve been warning about could have been the point of entry for the malware?"</p> <p class="speech"><b>Sarah Lee:</b> "Honestly? Yes. Whoever did this knew what they were doing, and they found the gaps we’ve been unable to fix because we don’t have the right infrastructure. I’ve asked for upgrades and additional staff, but the budget just isn’t there."</p> <p class="s_direction">The task force exchanges looks, recognizing that this could be an important factor in the breach. Sarah’s struggles might have left the system vulnerable.</p> <p class="speech"><b>Task Force Leader:</b> "Thank you, Sarah. We’ll look into how these vulnerabilities might have been exploited. For now, keep monitoring the system and alert us to anything suspicious."</p> <!-- Check if Emily Davis is a suspect --> { (if: $suspect3_found is true)[ <p class="s_direction">Emily Davis interjects, her voice sharp.</p> <p class="speech"><b>Emily Davis:</b> "If Sarah had been more diligent about maintaining the systems, we might not be in this situation. She’s been aware of these issues for months!"</p> <p class="s_direction">Sarah looks taken aback by the accusation, feeling the weight of the blame.</p> ] } <p> { (if: $suspect3_found is true)[ [[Sarah Lee's Rebuke->Sarah Lee's Rebuke]] ] (else:)[ [[Investigate Suspicious Document->Investigate Suspicious Document]] ] } </p> (display: "Sidebar") (display: "SidebarBack") <h1>Thomas Reed's Insight</h1> <p class="s_direction">The task force brings up a list of unusual network activities. Thomas Reed, the Deputy Headteacher, steps forward, his face tense.</p> <p class="speech"><b>Thomas Reed:</b> "I’ve noticed an increase in staff requests to access certain restricted areas of the network over the past few weeks. We had tightened our IT policies, but some staff, especially those involved in media and research, were requesting broader permissions."</p> <p class="speech"><b>Task Force Leader:</b> "Do you think any of these requests could be linked to the breach?"</p> <p class="speech"><b>Thomas Reed:</b> "Possibly. I don’t have the technical expertise to say for certain, but there were some persistent complaints. Especially from staff needing access to the school’s media databases. It could be someone trying to bypass restrictions. Frankly, it's frustrating. I've voiced concerns about mismanagement and lack of oversight in IT resource allocation, but nothing ever changes."</p> <p class="s_direction">The Task Force Leader takes a moment to assess the situation. Thomas's frustration and position could indicate genuine concern or raise suspicion.</p> <p><b>Do you find Thomas Reed suspicious?</b></p> <!-- Present the player with a choice --> <p> [[Yes, Thomas Reed seems suspicious.->Thomas Reed Suspicious]] <br> [[No, Thomas Reed doesn't seem suspicious.->Next Investigation]] </p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <!-- Set the variable for "Thomas Reed" to true --> (set: $suspect4_found to true) (set: $suspectsFound to $suspectsFound + 1) <h1>Network Traffic Analysis</h1> <p class="s_direction">The team gathers around the main screen as Task Force Member 1 brings up an interactive graph displaying the network's data transfer levels over the past few days.</p> <p class="speech"><b>Task Force Member 1:</b> "Here we have the normal data transfer levels for the school’s network. You can see these small spikes here and there—probably just routine uploads or teachers sharing resources."</p> <p class="s_direction">*The audience sees a graph with steady traffic and a few minor spikes.*</p> <p class="speech"><b>Task Force Leader:</b> "But notice these larger spikes. They're more significant than usual. We need to find out what those spikes are and, more importantly, who’s responsible."</p> { (if: $suspect4_found is true)[ <p class="speech"><b>Thomas Reed:</b> (casually) "Honestly, these spikes don't seem that unusual to me. We've had busy days before. Probably just some large file transfers for projects. I wouldn't focus too much on it."</p> <p class="s_direction">*Thomas glances away from the screen, seeming more interested in downplaying the severity of the spikes.*</p> ] (else:)[ <p class="speech"><b>Thomas Reed:</b> (pointing to the screen) "Look at these larger spikes—those don’t match any scheduled activities I’m aware of. We should investigate who had access during those times."</p> <p class="s_direction">*Thomas leans forward, studying the graph, clearly eager to help the team narrow down the cause.*</p> ] } <p>[[Continue->Network Overview]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Robert Brown's Frustration</h1> <p class="s_direction">As the investigation continues, Robert Brown, the Librarian and Media Specialist, steps forward, frustration visible on his face.</p> <p class="speech"><b>Robert Brown:</b> "It’s not surprising, really. We’ve been dealing with network restrictions for years, and it’s only gotten worse. I’ve been asking for more access to the media databases for ages. But it’s always the same answer—security concerns."</p> <p class="speech"><b>Task Force Leader:</b> "Are you suggesting these restrictions might have led to someone finding a way around them?"</p> <p class="speech"><b>Robert Brown:</b> "I’m saying it’s possible. When people are frustrated and feel like they’re being held back from doing their jobs, they find workarounds. It wouldn’t surprise me if someone finally got fed up."</p> <p class="s_direction">Robert steps back, his lips pressed into a thin line.</p> <p><b>Do you find Robert Brown suspicious?</b></p> [[Yes, Robert Brown seems suspicious.->Robert Brown]] <br> [[No, Robert Brown doesn't seem suspicious.->Investigate Logs]] <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> :: Luddite Reveal <h1>The Luddite Reveal</h1> <p class="s_direction">(The Task Force gathers as the final message is decrypted. A dramatic GIF appears on the screen, heightening the tension.)</p> <img src="https://static.wixstatic.com/media/27b368_ab076a87001f4db8b4350facf72bb07c~mv2.gif" alt="It Was Me All Along" style="width:100%; height:auto;"> <p class="s_direction">(Luddite steps forward with a wild grin, his excitement palpable.)</p> <p class="speech"><b>Mr. Luddite:</b> "IT WAS ME ALL ALONG!! You’ve finally discovered the truth. I’ve been the one orchestrating this chaos." </p> <p class="speech"><b>Mr. Luddite:</b> "My goal was to show you how dependent you’ve become on technology. The school’s obsession with digital solutions has led to its own downfall, and I wanted to prove it." </p> <p class="speech"><b>Task Force Leader:</b> "We need to understand why you chose to act this way. Your actions have caused significant harm. What drove you to such extremes?" </p> [[Explore Hypocrisy->Luddite Hypocrisy]] (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable for "Luddite" to true --> (set: $suspect7_found to true) <h1>The Alex Johnson Reveal</h1> <p class="s_direction">(As the final message is decrypted, Alex Johnson’s name appears on the screen. Tension builds as the Task Force confronts him.)</p> <p class="speech"><b>Task Force Leader:</b> "The decrypted message reveals that Alex Johnson, the Computer Technician, orchestrated the attack. Can you explain why you did this?"</p> <p class="s_direction">(Alex steps forward, visibly agitated but resolute.)</p> <!-- Conditional Confession Based on Suspect Status --> { <!-- If Alex Johnson is in the suspects list --> (if: $suspect1_found is true)[ <p class="speech"><b>Alex Johnson:</b> "Yes, it was me. I was tired of seeing my warnings about security go unheeded. Every time I pointed out weaknesses or asked for more resources, I was ignored. I tried to fix things quietly, but nothing changed. You caught me fair and square."</p> ] <!-- If Alex Johnson was not initially in the suspects list --> (else:)[ <p class="speech"><b>Alex Johnson:</b> "Of course it was me. You think you’re smarter than me? I’ve been playing this game for a long time. Nobody listened to my warnings, so I decided to make them pay attention in my way."</p> ] } <p class="speech"><b>Task Force Member:</b> "Why go to such extremes? Your actions have caused a lot of disruption and harm."</p> { <!-- If Alex Johnson is in the suspects list --> (if: $suspect1_found is true)[ <p class="speech"><b>Alex Johnson:</b> "I felt desperate. I thought if I made the issues undeniable, it would force the administration to pay attention. I manipulated network settings and created false data transfers to cover my tracks. I hoped the chaos would finally make them act."</p> ] <!-- If Alex Johnson was not initially in the suspects list --> (else:)[ <p class="speech"><b>Alex Johnson:</b> "Extreme times call for extreme measures. If causing chaos was the only way to get the administration to notice the glaring holes in our network, then so be it. They needed a wake-up call, and I gave them one."</p> ] } [[Detailed Explanation->Alex Johnson Details]] (display: "Sidebar") (display: "SidebarBack") <h1>The Jamie Parker Reveal</h1> <p class="s_direction">(As the final message is decrypted, Jamie Parker’s name appears on the screen. The Task Force prepares to confront him.)</p> <p class="speech"><b>Task Force Leader:</b> "The decrypted message reveals that Jamie Parker, the System Administrator, was behind the attack. Jamie, can you explain your actions?"</p> <p class="s_direction">(Jamie Parker steps forward, looking both defensive and frustrated.)</p> { <!-- If Jamie Parker is on the suspect list --> (if: $suspect2_found is true)[ <p class="speech"><b>Jamie Parker:</b> "Alright, you caught me. I knew it was only a matter of time. I’ve been dealing with the consequences of poor administrative decisions for too long. Despite raising concerns about system vulnerabilities and resource shortages, nothing changed. I felt ignored and undervalued." </p> <p class="speech"><b>Task Force Member:</b> "But why resort to such drastic measures? There had to be other ways to address these issues." </p> <p class="speech"><b>Jamie Parker:</b> "I tried other ways, but they didn’t work. The administration dismissed my concerns, and I wanted to make them see how serious the situation was. By causing a disruption, I hoped to force a reaction and bring attention to the critical issues we were facing." </p> ] } { <!-- If Jamie Parker is not on the suspect list --> (else:)[ <p class="speech"><b>Jamie Parker:</b> "You think you're clever for catching me? Ha! I orchestrated this entire operation under your noses. None of you suspected a thing until it was too late. I exploited every weakness in this system because it was child’s play for someone like me." </p> <p class="speech"><b>Task Force Member:</b> "But why? You had the skills and the access to improve the system from within." </p> <p class="speech"><b>Jamie Parker:</b> "Improve? I was the system's only hope. But every time I proposed real solutions, I was ignored. So, I decided to show just how vulnerable this place was. I wanted to force a change by exposing the flaws in the most direct way possible." </p> ] } [[Detailed Explanation->Jamie Parker Details]] (display: "Sidebar") (display: "SidebarBack") <h1>The Emily Davis Reveal</h1> <p class="s_direction">(As the final message is decrypted, Emily Davis’s name appears on the screen. The Task Force prepares to confront her.)</p> <p class="speech"><b>Task Force Leader:</b> "The decrypted message reveals that Emily Davis, the Headteacher, was behind the attack. Emily, can you explain your actions?"</p> <p class="s_direction">(Emily Davis steps forward with a look of both determination and weariness.)</p> { <!-- If Emily Davis is on the suspect list --> (if: $suspect3_found is true)[ <p class="speech"><b>Emily Davis:</b> "You caught me. I knew this was a risk, but I couldn’t sit back and watch the school crumble any longer. Our budget cuts and resource shortages were pushing us into a corner. Every plea I made for more support was dismissed." </p> <p class="speech"><b>Task Force Member:</b> "But why take such drastic measures? There must have been other ways to address these concerns." </p> <p class="speech"><b>Emily Davis:</b> "I had exhausted all other options. I tried advocating for increased funding and better support through regular channels, but nothing changed. I hoped that by creating a significant disruption, I could force the administration to confront the reality of our situation." </p> ] } { <!-- If Emily Davis is not on the suspect list --> (else:)[ <p class="speech"><b>Emily Davis:</b> "So, you finally figured it out. I never expected you to catch on. I was the one pulling the strings all along, right under your noses. I leveraged every flaw in this school's system to make a point." </p> <p class="speech"><b>Task Force Member:</b> "But why go to such lengths? You had the authority to make changes from within." </p> <p class="speech"><b>Emily Davis:</b> "Authority? Ha! My 'authority' meant nothing when it came to securing the resources we needed. I was stonewalled at every turn. I wanted to expose just how dire our situation was and force the administration to act. This was the only way to make them see the consequences of their inaction." </p> ] } [[Detailed Explanation->Emily Davis Details]] (display: "Sidebar") (display: "SidebarBack") <h1>The Thomas Reed Reveal</h1> <p class="s_direction">(As the final message is decrypted, Thomas Reed’s name appears on the screen. The Task Force prepares to confront him.)</p> <p class="speech"><b>Task Force Leader:</b> "The decrypted message reveals that Thomas Reed, the Deputy Headteacher, was behind the attack. Thomas, can you explain why you did this?"</p> <p class="s_direction">(Thomas Reed steps forward, looking both serious and troubled.)</p> { <!-- If Thomas Reed is on the suspect list --> (if: $suspect4_found is true)[ <p class="speech"><b>Thomas Reed:</b> "Yes, you caught me. I didn't want it to come to this, but I felt like I had no other choice. I was deeply frustrated with how the school was being managed. My concerns about mismanagement and ineffective policies were ignored time and again."</p> <p class="speech"><b>Task Force Member:</b> "Why choose such drastic measures? There must have been other ways to address these issues." </p> <p class="speech"><b>Thomas Reed:</b> "I tried every other way. I raised these concerns repeatedly, but they fell on deaf ears. I believed that only a major disruption would force the administration to confront these problems. My intention was to push for much-needed reforms, but I realize now the cost was too high."</p> ] } { <!-- If Thomas Reed is not on the suspect list --> (else:)[ <p class="speech"><b>Thomas Reed:</b> "Surprised, are you? I bet you never suspected the Deputy Headteacher. I had been planning this for a long time, right under your noses. The administration’s refusal to address the school’s mismanagement gave me the perfect opportunity."</p> <p class="speech"><b>Task Force Member:</b> "You went to extreme lengths to prove your point. Why take such a destructive path?"</p> <p class="speech"><b>Thomas Reed:</b> "Because nothing else worked! My repeated warnings were dismissed as mere complaints. I needed to show the administration the consequences of their neglect. By orchestrating a crisis, I hoped to force a complete overhaul of our policies and practices."</p> ] } [[Detailed Explanation->Thomas Reed Details]] (display: "Sidebar") (display: "SidebarBack") <h1>The Sarah Lee Reveal</h1> <p class="s_direction">(As the final message is decrypted, Sarah Lee’s name appears on the screen. The Task Force prepares to confront her.)</p> <p class="speech"><b>Task Force Leader:</b> "The decrypted message reveals that Sarah Lee, the IT Support Staff, was behind the attack. Sarah, can you explain your actions?"</p> <p class="s_direction">(Sarah Lee steps forward, looking both defensive and regretful.)</p> { <!-- If Sarah Lee is on the suspect list --> (if: $suspect5_found is true)[ <p class="speech"><b>Sarah Lee:</b> "You’ve caught me. I was at my breaking point. Every day I had to deal with a network that was falling apart, with no support and no budget to fix it. I knew I had to make a drastic move to get the administration to listen to us."</p> <p class="speech"><b>Task Force Member:</b> "But why resort to such drastic measures? There must have been other ways to address these issues." </p> <p class="speech"><b>Sarah Lee:</b> "I tried other ways, but my concerns were brushed aside. I thought that by creating a crisis, the administration would be forced to see how dire things really were. It wasn’t about causing harm—it was about making sure we got the resources we needed to protect the school's network properly."</p> ] } { <!-- If Sarah Lee is not on the suspect list --> (else:)[ <p class="speech"><b>Sarah Lee:</b> "Surprised to see me, aren’t you? Nobody expects the IT Support to take such actions. But you all underestimated me. I knew exactly how to exploit the vulnerabilities that I had been warning about for so long."</p> <p class="speech"><b>Task Force Member:</b> "You went to extreme lengths to make your point. Why did you choose such a destructive path?"</p> <p class="speech"><b>Sarah Lee:</b> "Because I was tired of being ignored! Every time I raised concerns about our outdated systems, they were dismissed. I wanted to expose how fragile our network really was. Creating this disruption was the only way to get the attention that our department deserved."</p> ] } [[Detailed Explanation->Sarah Lee Details]] (display: "Sidebar") (display: "SidebarBack") :: Luddite Hypocrisy <h1>Luddite's Hypocrisy</h1> <p class="s_direction">(Luddite’s rant continues as he is confronted with the paradox of his actions.)</p> <p class="speech"><b>Task Force Member:</b> "Mr. Luddite, you’re an anti-technology extremist who has used technology to spread chaos. Doesn’t that seem contradictory to you?"</p> <p class="speech"><b>Mr. Luddite:</b> "Contradictory? Perhaps. But it was necessary. To expose the flaws and dependency on technology, I had to use it as my tool. The irony of my actions is part of the message. Technology is a double-edged sword—it can be used to both create and destroy." </p> <p class="s_direction">(Luddite paces, seemingly reflecting on his own actions.)</p> <p class="speech"><b>Mr. Luddite:</b> "I used technology to highlight its dangers. It’s a cruel irony, but it’s effective. By weaponizing the very thing I oppose, I forced the issue into the open. The technology we depend on is also our greatest vulnerability." </p> <p class="speech"><b>Task Force Leader:</b> "It seems you’ve proven that technology can be manipulated for both good and ill. But your approach has only highlighted the need for better security and more responsible use of technology." </p> [[Final Reflections->Luddite Final Thoughts]] (display: "Sidebar") (display: "SidebarBack"):: Luddite Final Thoughts <h1>Final Thoughts on Luddite’s Actions</h1> <p class="s_direction">(The Task Force concludes the confrontation with Luddite, reflecting on the impact of his actions.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions, while intended to provoke a reaction, have caused unnecessary harm. Technology indeed has its flaws, but this extreme method of exposing them only highlights the need for thoughtful, ethical improvements." </p> <p class="speech"><b>Mr. Luddite:</b> "I understand. The chaos I created was meant to be a stark reminder of the vulnerabilities we face. I hope it drives you to address these issues, but I acknowledge the damage done." </p> <p class="s_direction">(The Task Force begins to secure the network and review their policies.)</p> <p class="speech"><b>Task Force Leader:</b> "We will take your points into account but will focus on strengthening our systems and practices. This incident will lead to improvements, but we must move forward with better strategies and responsible technology use." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack"):: Alex Johnson Details <h1>Alex Johnson's Detailed Explanation</h1> <p class="s_direction">(Alex explains in detail how he executed the attack and his grievances with the administration.)</p> <p class="speech"><b>Task Force Leader:</b> "Can you provide more details on how you executed the attack and your specific grievances?"</p> <p class="speech"><b>Alex Johnson:</b> "Certainly. I used my access as a Computer Technician to adjust network settings and create access points that weren’t authorized. By encrypting logs and generating false data, I aimed to confuse the detection systems and delay the response. My goal was to make the administration confront the serious security flaws we’d been highlighting for years." </p> <p class="speech"><b>Task Force Member:</b> "So, your main issue was with how the IT department was managed and the lack of support for security measures?" </p> <p class="speech"><b>Alex Johnson:</b> "Exactly. We were asked to manage an expanding system with fewer resources and less support. Every time we raised concerns, they were brushed off. I hoped that by creating a major disruption, I could force a re-evaluation of our IT practices and make them take our warnings seriously." </p> <p class="s_direction">(Alex appears both frustrated and remorseful.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions did highlight critical issues but at a great cost. While the need for improved IT practices is clear, your approach was drastic and harmful." </p> [[Final Reflections->Alex Johnson Reflections]] (display: "Sidebar") (display: "SidebarBack"):: Alex Johnson Reflections <h1>Final Reflections on Alex Johnson's Actions</h1> <p class="s_direction">(The Task Force concludes their confrontation with Alex Johnson and reflects on the broader implications of his actions.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions have indeed exposed significant vulnerabilities in our system, but they also caused considerable disruption. It’s clear that we need to address the issues you’ve raised, but your method was inappropriate and harmful." </p> <p class="speech"><b>Alex Johnson:</b> "I understand. I thought I was acting in the best interest of the school by making the problems undeniable. I regret that my actions caused so much harm and didn’t achieve the intended results in a more constructive way." </p> <p class="s_direction">(The Task Force begins to secure the network and review their policies.)</p> <p class="speech"><b>Task Force Leader:</b> "We will use this situation to improve our IT infrastructure and ensure that similar issues are addressed more effectively in the future. Your actions have highlighted the need for better support and resource allocation, but moving forward, we’ll focus on making necessary improvements without resorting to harmful tactics." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack"):: Jamie Parker Details <h1>Jamie Parker's Detailed Explanation</h1> <p class="s_direction">(Jamie Parker explains how he executed the attack and his reasons behind it.)</p> <p class="speech"><b>Task Force Leader:</b> "Can you elaborate on the specifics of your attack and what exactly motivated you?"</p> <p class="speech"><b>Jamie Parker:</b> "Certainly. I used my administrative access to exploit system weaknesses. I manipulated permissions and created unauthorized access points. The encrypted data and false logs were meant to cover my tracks and create confusion. My intention was to expose the severe resource constraints and security flaws we were dealing with." </p> <p class="speech"><b>Task Force Member:</b> "So, your main issue was with how the IT resources were managed and your role in the system?" </p> <p class="speech"><b>Jamie Parker:</b> "Yes. We were under-resourced and overworked. Every time I raised these issues, they were ignored. I felt like my warnings were falling on deaf ears. The only way to make the administration face the reality was to create a situation they couldn’t ignore." </p> <p class="s_direction">(Jamie’s expression reflects a mix of frustration and regret.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions have indeed highlighted critical issues, but the approach was harmful and disruptive. It’s important to address these issues, but not at the cost of security and operational stability." </p> [[Final Reflections->Jamie Parker Reflections]] (display: "Sidebar") (display: "SidebarBack"):: Jamie Parker Reflections <h1>Final Reflections on Jamie Parker's Actions</h1> <p class="s_direction">(The Task Force reflects on Jamie Parker’s actions and their broader implications.)</p> <p class="speech"><b>Task Force Leader:</b> "While your actions have brought attention to significant resource and security issues, they also caused considerable disruption. Your approach was extreme and unacceptable." </p> <p class="speech"><b>Jamie Parker:</b> "I understand. My goal was to force a change, but I see now that my method was too drastic. I hoped to make the administration recognize the urgent need for improvements." </p> <p class="s_direction">(The Task Force begins to address the issues revealed by Jamie’s actions.)</p> <p class="speech"><b>Task Force Leader:</b> "We will take this opportunity to review and improve our IT resources and management practices. Moving forward, we’ll focus on addressing the vulnerabilities and ensuring better support without resorting to harmful tactics." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack")<h1>Emily Davis's Detailed Explanation</h1> <p class="s_direction">(Emily Davis elaborates on her actions and the specific issues that motivated her.)</p> <p class="speech"><b>Task Force Leader:</b> "Can you provide more details on how you executed the attack and what specifically motivated you?"</p> <p class="speech"><b>Emily Davis:</b> "Certainly. I used my position to access sensitive areas of the system that were normally restricted. I manipulated data to create false signals and cover my tracks, intending to generate enough chaos to make the administration notice. My goal was to highlight the critical need for better management and resources." </p> <p class="speech"><b class="task-force-member">Task Force Member:</b> "So, your primary grievance was the lack of resources and the impact of budget cuts on the school’s infrastructure?" </p> <p class="speech"><b>Emily Davis:</b> "Exactly. We were facing severe shortages in both funding and support for essential services. The ongoing neglect was impacting our ability to provide a safe and effective learning environment. I felt that by creating a major disruption, I could force a reassessment of these priorities." </p> <p class="s_direction">(Emily’s expression reflects a deep sense of frustration mixed with resolve.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "While your concerns about resource allocation are valid, your approach was damaging and disruptive. It’s important to address these issues, but there are more constructive ways to advocate for change." </p> [[Final Reflections->Emily Davis Reflections]] (display: "Sidebar") (display: "SidebarBack")<h1>Final Reflections on Emily Davis's Actions</h1> <p class="s_direction">(The Task Force reflects on Emily Davis’s actions and their broader implications.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "Your actions have certainly drawn attention to significant issues within our administration and resource management. However, the way you chose to address these issues has resulted in unnecessary harm and disruption." </p> <p class="speech"><b>Emily Davis:</b> "I understand. My intention was to make the severity of the problems undeniable. I regret that my methods caused so much disruption, but I hoped it would lead to necessary changes." </p> <p class="s_direction">(The Task Force begins to address the issues highlighted by Emily’s actions.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "We will take this opportunity to improve our management practices and ensure that resource allocation is handled more effectively. Moving forward, we will focus on making the necessary changes without resorting to harmful actions." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack"):: Thomas Reed Details <h1>Thomas Reed's Detailed Explanation</h1> <p class="s_direction">(Thomas Reed elaborates on his actions and the specific grievances that motivated him.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "Can you provide more details on how you executed the attack and what specifically motivated you?"</p> <p class="speech"><b>Thomas Reed:</b> "Certainly. I used my access as Deputy Headteacher to manipulate system settings and create false data. By exploiting system vulnerabilities and causing intentional disruptions, I aimed to highlight the critical issues we were facing. The encrypted logs and misleading data were part of my strategy to avoid immediate detection and ensure the problem was visible." </p> <p class="speech"><b class="task-force-member">Task Force Member:</b> "So, your main grievances were with how the administration was handling the school’s resources and policies?" </p> <p class="speech"><b>Thomas Reed:</b> "Exactly. There were ongoing issues with budget management and policy implementation that I believed were putting the school at risk. My actions were a desperate attempt to make those issues undeniable and prompt a serious reevaluation of our practices." </p> <p class="s_direction">(Thomas’s demeanor shows a mix of determination and regret.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "Your actions have certainly brought attention to some serious issues, but the method you chose was harmful and disruptive. It’s important to address these problems, but not at the cost of operational stability." </p> [[Final Reflections->Thomas Reed Reflections]] (display: "Sidebar") (display: "SidebarBack"):: Thomas Reed Reflections <h1>Final Reflections on Thomas Reed's Actions</h1> <p class="s_direction">(The Task Force reflects on Thomas Reed’s actions and their broader implications.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "While your actions have highlighted critical issues within our administration, they also caused significant disruption and harm. It’s clear that we need to address the underlying problems, but your approach was inappropriate and damaging." </p> <p class="speech"><b>Thomas Reed:</b> "I understand. My intention was to provoke a reaction and force change, but I see now that my methods were too extreme. I hoped to expose the issues in a way that couldn’t be ignored, but I regret the disruption it caused." </p> <p class="s_direction">(The Task Force begins to address the issues revealed by Thomas’s actions.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "We will use this incident to improve our management practices and ensure better handling of resources and policies. Moving forward, we’ll focus on making necessary improvements while avoiding harmful tactics." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack"):: Sarah Lee Details <h1>Sarah Lee's Detailed Explanation</h1> <p class="s_direction">(Sarah Lee elaborates on her actions and the specific issues that motivated her.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "Can you provide more details on how you executed the attack and what specifically motivated you?"</p> <p class="speech"><b>Sarah Lee:</b> "Certainly. I used my access as IT Support Staff to manipulate system settings and create disruptions. I altered data and created false alarms to mask my activities. My goal was to expose the inadequacies in our IT support system and make the administration confront the systemic issues we had been highlighting." </p> <p class="speech"><b class="task-force-member">Task Force Member:</b> "So, your main grievance was with the management of IT resources and how you were being treated?" </p> <p class="speech"><b>Sarah Lee:</b> "Exactly. We were always stretched thin and expected to manage with fewer resources. I felt like my efforts and concerns were ignored. The only way I saw to force a change was to create a situation that could not be overlooked." </p> <p class="s_direction">(Sarah’s expression reflects frustration and a hint of regret.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "Your actions did highlight some critical issues, but the method was harmful and disruptive. It’s important to address these concerns, but not at the cost of operational stability." </p> [[Final Reflections->Sarah Lee Reflections]] (display: "Sidebar") (display: "SidebarBack"):: Sarah Lee Reflections <h1>Final Reflections on Sarah Lee's Actions</h1> <p class="s_direction">(The Task Force reflects on Sarah Lee’s actions and their broader implications.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "While your actions have certainly brought attention to issues within our IT management, they also caused significant disruption. Your approach was extreme and unacceptable." </p> <p class="speech"><b>Sarah Lee:</b> "I understand. I wanted to make the problems we faced undeniable, but I regret that my methods caused so much disruption. I hoped it would lead to necessary changes, but I see now that there were better ways to address these issues." </p> <p class="s_direction">(The Task Force begins to address the issues revealed by Sarah’s actions.)</p> <p class="speech"><b class="task-force-leader">Task Force Leader:</b> "We will use this opportunity to improve our IT management and ensure that similar issues are handled more effectively in the future. Moving forward, we’ll focus on addressing vulnerabilities and ensuring better support for our IT staff." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack")<h1>The Random Audience Member Reveal</h1> <p class="s_direction">(As the final message is decrypted, the identity of the random audience member is dramatically revealed.)</p> <!-- Display the perpetrator's details --> <p class="speech"><b>Task Force Leader:</b> "Well, well, well, what a surprise! It turns out it was you, <span class="clue">{{$userName}}</span>! I should have known from the start when you wouldn’t stop eating popcorn during the entire briefing!"</p> <p class="speech"><b>Task Force Leader:</b> "We’ve got a lot of evidence against you. Unauthorized access logs, suspicious device activity—basically, it all leads back to you. It’s clear as day!"</p> <p class="speech"><b>Task Force Leader:</b> "And let me tell you something. I remember your style from back in the day—you hacked into the Barclays Bank network in 1992. Your style hasn’t changed a bit over the years. I don’t care if you say you weren’t even born yet....<span class="clue">{{$userDOB}}</span>...yeah right!. You’re going down for a LOOOONG TIME!!" </p> <p class="s_direction">(The Task Force members prepare to escort the culprit out with all the dramatic flair they can muster.)</p> <p class="speech"><b>Task Force Leader:</b> "Alright, {{$userName}}, time to stand up. We’ve got a very long chat with a judge ahead of us. Follow us—no, you can’t take that popcorn with you!"</p> [[Escorted Out->Random Audience Member Escort]] (display: "Sidebar") (display: "SidebarBack") :: Random Audience Member Escort <h1>Escorting the Random Audience Member</h1> <p class="s_direction">(The Task Force escorts the random audience member out of the building, reflecting on the situation.)</p> <p class="speech"><b>Task Force Leader:</b> "We understand that this situation may be confusing, but it’s important that we follow the protocols. We’ll need to review how this incident occurred and ensure such breaches are prevented in the future." </p> <p class="speech"><b>Random Audience Member:</b> "I... I didn’t know. I was just here to participate. I never meant to cause any trouble." </p> <p class="s_direction">(The random audience member is escorted out, and the Task Force refocuses on securing the system and addressing the vulnerabilities exposed.)</p> <p class="speech"><b>Task Force Leader:</b> "We’ll use this incident to improve our security measures and ensure that such vulnerabilities are addressed. Thank you to everyone involved for your cooperation and understanding." </p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack")<div id="sidebar"> <h2>Investigation Progress</h2> <!-- Display clues and suspects count --> <p>Total Clues Found: (print: $cluesFound)</p> <button>[[View Clues->CluesPage]]</button> <p>Total Suspects Found: (print: $suspectsFound)</p> <button>[[View Suspects and Motives-> SuspectsPage]]</button> <!-- Solve Case Button with color and status change --> { (if: $cluesFound <= 3)[ <!-- Disable the button if less than 4 clues are found --> <button class="solve" style="background-color: red; cursor: not-allowed;">Solve Case</button> ] (else-if: $cluesFound > 3 and $cluesFound <= 6)[ <!-- Link to Gatekeeper Node with orange color for medium difficulty --> <button class="solve" style="background-color: orange; cursor: pointer;">[[Solve Case ->Gatekeeper Node]]</button> <p style="color: orange; font-size: 0.8em;">Hard</p> ] (else-if: $cluesFound > 6)[ <!-- Link to Gatekeeper Node with green color indicating readiness --> <button class="solve" style="background-color: green; cursor: pointer;">[[Solve Case ->Gatekeeper Node]]</button> <p style="color: green; font-size: 0.8em;">Ready to solve!</p> ] } </div> <h1>Clues Discovered</h1> <!-- Display total clues found --> <p>Total Clues Found: (print: $cluesFound)</p> <ul> (if: $clue1_found is true)[<li>Caesar Cipher found in hacker's message.</li>] (if: $clue2_found is true)[<li>Suspicious IP Address found in logs.</li>] (if: $clue3_found is true)[<li>Email Header Clue - 'Trust me, this is safe.'.</li>] (if: $clue4_found is true)[<li>Encryption tools found on the compromised machine.</li>] (if: $clue5_found is true)[<li>Hackers Profession Found.</li>] (if: $clue6_found is true)[<li>Login attempts at unusual hours.</li>] (if: $clue7_found is true)[<li>Found hackers favourite colour.</li>] (if: $clue8_found is true)[<li>Hackers First Pet name found</li>] (if: $clue9_found is true)[<li>Found Hackers mothers maiden name.</li>] (if: $clue10_found is true)[<li>Anonymous email traced back to the hacker.</li>] (if: $clue11_found is true)[<li>Favorite Hobby used as a personal security question.</li>] (if: $clue12_found is true)[<li>Decryption Key used to decode the message.</li>] (if: $clue13_found is true)[<li>Hidden message "Olssv dvysk" found in the source code, awaiting decryption.</li>] (if: $clue14_found is true)[<li>Found Hackers online name.</li>] (if: $clue15_found is true)[<li>Hackers scrambled email found</li>] <!-- Other clues here --> </ul> (display: "SidebarBack") (display: "Sidebar") <h1>Suspects and Motives</h1> <ul> (if: $suspect1_found is true)[<li><b>Alex Johnson</b>: Computer Technician, frustrated with IT policies. His night shift gave him access to key systems.</li>] (if: $suspect2_found is true)[<li><b>Jamie Parker</b>: System Administrator, seeking more control over system access. His role granted him insider knowledge.</li>] (if: $suspect3_found is true)[<li><b>Emily Davis</b>: Headteacher, frustrated with budget cuts affecting IT infrastructure. She might have sought control over limited resources.</li>] (if: $suspect4_found is true)[<li><b>Thomas Reed</b>: Deputy Headteacher, believed IT resources were being mismanaged. His position gave him administrative access.</li>] (if: $suspect5_found is true)[<li><b>Sarah Lee</b>: IT Support Staff, wanted better infrastructure. Her role allowed her to install critical software.</li>] (if: $suspect6_found is true)[<li><b>Robert Brown</b>: Librarian/Media Specialist, wanted more control over school media. He could access the media network.</li>] (if: $suspect7_found is true)[<li><b>Luddite</b>: Anti-technology advocate, aiming to disrupt all tech systems. His anti-tech stance made him a prime suspect.</li>] (if: $suspect8_found is true)[<li><b>EVERYONE</b>: Everyone is a suspect! A coordinated effort might have been behind this attack.</li>] </ul> (display: "SidebarBack") <h1>Just Enough</h1> <p class="speech"><b>Task Force Leader:</b> "It’s not a complete picture, but we’ve got enough to move forward. We’ve gathered enough evidence to make an educated guess."</p> <p class="speech"><b>Task Force Member 1:</b> "We’re taking a bit of a gamble, but the clues we have are leading us toward a clear suspect. We’ll need to be careful, but I think we’re ready to make a move."</p> <p class="speech"><b>Task Force Member 2:</b> "We don’t have all the answers, but the encryption methods, the network traffic patterns… they’re all pointing in one direction."</p> <p class="speech"><b>Task Force Leader:</b> "This isn’t a decision we’re making lightly. We’ve worked hard, and it’s time to put our theories to the test. We’re going to proceed, but we need to stay sharp."</p> <p class="speech"><b>Task Force Member 1:</b> "Let’s connect the dots and hope everything fits together."</p> <p>[[Continue->Enough Clues]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Final Clue: Hacker's Name</h1> <p class="speech"><b>Task Force Leader:</b> "We’ve done it. Every clue points to the same conclusion. We know who’s behind this, and it’s time to bring them in."</p> <p class="speech"><b>Task Force Member 1:</b> "We’ve gathered more than enough evidence. The encrypted messages, the suspicious IP activity, the hidden software… It’s all there, plain as day."</p> <p class="speech"><b>Task Force Member 2:</b> "There’s no doubt. We’ve pieced together the hacker’s entire plan, and we have the proof to back it up. We’re ready to wrap this up."</p> <p class="speech"><b>Task Force Leader:</b> "But before we close this case, there’s one final clue that confirms the identity of our hacker—a scrambled name hidden in the final piece of evidence."</p> { <p class="s_direction">The scrambled name is revealed: <b> <div class="clueReveal"> (if: $suspectNum is 1)[Doha Mrkqvrq] <!-- Alex Johnson --> (else-if: $suspectNum is 2)[Ofrnj Ufwpjw] <!-- Jamie Parker --> (else-if: $suspectNum is 3)[Iqmpc Hezmw] <!-- Emily Davis --> (else-if: $suspectNum is 4)[Vjqocu Tggf] <!-- Thomas Reed --> (else-if: $suspectNum is 5)[Zhyho Sll] <!-- Sarah Lee --> (else-if: $suspectNum is 6)[Xuhkxz Hxuct] <!-- Robert Brown --> (else-if: $suspectNum is 7)[<p id="output"></p>] <!-- Audience Member's scrambled name --> (else-if: $suspectNum is 8)[Rwvibpiv Tcllqbm] <!-- Jonathan Luddite --> (else:)[Dudqgrp Dxfglhqfh Phpehu] <!-- Default fallback --> </div> </b></p> } <p class="speech"><b>Task Force Leader:</b> "Now, let’s finish this. Excellent work, team. We’ve been methodical, and now it’s time to bring this case to a close. Let’s move in and secure the hacker."</p> <p class="speech"><b>Task Force Member 1:</b> "It’s time. Let’s execute the final steps and end this once and for all."</p> <p>[[Continue->Enough Clues]]</p> (display: "Sidebar") (display: "SidebarBack") <script> document.getElementById('decryptButton').addEventListener('click', function() { // Get the input values var encryptedText = document.getElementById("encryptedInput").value; var shift = parseInt(document.getElementById("decryptKey").value); var result = ''; // Decrypt the input using Caesar Cipher for (var i = 0; i < encryptedText.length; i++) { var c = encryptedText[i]; // Only shift letters if (c.match(/[a-z]/i)) { // Get ASCII code var code = encryptedText.charCodeAt(i); // Uppercase letters if ((code >= 65) && (code <= 90)) { c = String.fromCharCode(((code - 65 - shift + 26) % 26 + 26) % 26 + 65); // Adjusted for correct backward shift } // Lowercase letters else if ((code >= 97) && (code <= 122)) { c = String.fromCharCode(((code - 97 - shift + 26) % 26 + 26) % 26 + 97); // Adjusted for correct backward shift } } // Append the decrypted character result += c; } // Display the decrypted text document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: " + result; }); document.getElementById('resetButton').addEventListener('click', function() { // Clear the input fields and output document.getElementById("encryptedInput").value = ''; document.getElementById("decryptKey").value = ''; document.getElementById("decryptedOutput").innerHTML = "Decrypted Name: "; }); function caesarCipherEncrypt(str, shift) { return str.split('').map(char => { if (char.match(/[a-z]/i)) { const base = char.charCodeAt(0) < 97 ? 65 : 97; const encryptedChar = String.fromCharCode(((char.charCodeAt(0) - base + shift) % 26) + base); return encryptedChar; } return char; // Non-letter characters remain unchanged }).join(''); } // Automatically encrypt the user's name when the passage loads const inputString = window.harloweVariables.userName; // Get the Harlowe variable const encryptedString = caesarCipherEncrypt(inputString, 7); // Display the output document.getElementById('output').innerHTML = encryptedString; // Store the result back into a Harlowe variable window.harloweVariables.encryptedName = encryptedString; // Store it in a Harlowe variable </script>:: PhishingBranchComplete (set: $phishing_completed to true) <p>You've completed the Phishing Threat investigation!</p> [[Return to Decision Point->Vote]] :: Footer (set: $previousPassage to (passage:)'s name) <div id="back-sidebar"> <!-- Back Button using the (history:) macro to navigate to the last visited passage --> (if: (history:)'s length > 1)[ (link-goto: "Go Back", (history:)'s last) ] (else:)[ <p>No previous page to go back to.</p> ] </div> <h2>Suspect Details:</h2> <!-- StoryInit to map the suspectNum to the correct suspect with some encrypted values --> (if: $suspectNum is 1)[ (set: $perp to "Doha Mrkqvrq") <!-- Alex Johnson encrypted --> (set: $perpRole to "Frpsxwhu Whfkqlfldq") <!-- Computer Technician encrypted --> (set: $perpDOB to "01/05/1980") <!-- Date of Birth --> (set: $perpPetName to "Rex") (set: $perpMaidenName to "Taylor") (set: $perpFavoriteColor to "Blue") (set: $perpLoginTime to "Late Nights") (set: $perpHobby to "Programming") (set: $perpCipherKey to 3) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "ShadowByte") <!-- Hacker Name --> ] (else-if: $suspectNum is 2)[ (set: $perp to "Ofrnj Ufwpjw") <!-- Jamie Parker encrypted --> (set: $perpRole to "Xdxyjr Firnsnxywfytw") <!-- System Administrator encrypted --> (set: $perpDOB to "12/11/1975") <!-- Date of Birth --> (set: $perpPetName to "Milo") (set: $perpMaidenName to "Clark") (set: $perpFavoriteColor to "Red") (set: $perpLoginTime to "Evenings") (set: $perpHobby to "Gaming") (set: $perpCipherKey to 5) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "NetPhantom") <!-- Hacker Name --> ] (else-if: $suspectNum is 3)[ (set: $perp to "Iqmpc Hezmw") <!-- Emily Davis encrypted --> (set: $perpRole to "Liehxiegliv") <!-- Headteacher encrypted --> (set: $perpDOB to "23/09/1968") <!-- Date of Birth --> (set: $perpPetName to "Buddy") (set: $perpMaidenName to "Thompson") (set: $perpFavoriteColor to "Green") (set: $perpLoginTime to "Daytime") (set: $perpHobby to "Hiking") (set: $perpCipherKey to 4) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "DataMistress") <!-- Hacker Name --> ] (else-if: $suspectNum is 4)[ (set: $perp to "Vjqocu Tggf") <!-- Thomas Reed encrypted --> (set: $perpRole to "Fgrwva Jgcfvgcejgt") <!-- Deputy Headteacher encrypted --> (set: $perpDOB to "05/06/1970") <!-- Date of Birth --> (set: $perpPetName to "Max") (set: $perpMaidenName to "Anderson") (set: $perpFavoriteColor to "Yellow") (set: $perpLoginTime to "Afternoons") (set: $perpHobby to "Reading") (set: $perpCipherKey to 2) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "CipherScribe") <!-- Hacker Name --> ] (else-if: $suspectNum is 5)[ (set: $perp to "Zhyho Sll") <!-- Sarah Lee encrypted --> (set: $perpRole to "PA Zbwwvya") <!-- IT Support encrypted --> (set: $perpDOB to "14/03/1985") <!-- Date of Birth --> (set: $perpPetName to "Lucy") (set: $perpMaidenName to "Evans") (set: $perpFavoriteColor to "Purple") (set: $perpLoginTime to "Evening Shifts") (set: $perpHobby to "Painting") (set: $perpCipherKey to 7) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "CodeSorceress") <!-- Hacker Name --> ] (else-if: $suspectNum is 6)[ (set: $perp to "Xuhkxz Hxuct") <!-- Robert Brown encrypted --> (set: $perpRole to "Rohxgxogt/Skjog Yvkiogroyz") <!-- Librarian/Media Specialist encrypted --> (set: $perpDOB to "30/07/1978") <!-- Date of Birth --> (set: $perpPetName to "Oscar") (set: $perpMaidenName to "Mitchell") (set: $perpFavoriteColor to "Orange") (set: $perpLoginTime to "Regular Hours") (set: $perpHobby to "Photography") (set: $perpCipherKey to 6) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "MediaGhost") <!-- Hacker Name --> ] (else-if: $suspectNum is 7)[ <!-- Suspect 7: Audience Member (Details assigned at the beginning of the play) --> (set: $perp to $userName) <!-- Name entered by the audience --> (set: $perpRole to "Audience Member") <!-- A generic role for the audience --> (set: $perpDOB to $userDOB) <!-- Date of Birth entered by the audience --> (set: $perpPetName to $userFirstPet) <!-- Pet name entered by the audience --> (set: $perpMaidenName to $userMotherMaidenName) <!-- Mother's maiden name entered by the audience --> (set: $perpFavoriteColor to $userFavoriteColor) <!-- Favorite color entered by the audience --> (set: $perpLoginTime to "Unknown") <!-- Optional, can set this to another question response --> (set: $perpHobby to $userHobby) <!-- Hobby entered by the audience --> (set: $perpCipherKey to 7) <!-- Caesar's Cipher decryption number (from the number entered by the audience) --> (set: $perpHackerName to "Audience4Lyfe") <!-- Hacker Name --> ] (else-if: $suspectNum is 8)[ (set: $perp to "Rwvibpiv Tcllqbm") <!-- Jonathan Luddite encrypted --> (set: $perpRole to "Ivbq-Bmkpvwtwog Ildwkibm mvkzgxbml") <!-- Anti-Technology Advocate encrypted --> (set: $perpDOB to "17/02/1965") <!-- Date of Birth --> (set: $perpPetName to "Shadow") (set: $perpMaidenName to "Jones") (set: $perpFavoriteColor to "Black") (set: $perpLoginTime to "Unknown") (set: $perpHobby to "Sabotage") (set: $perpCipherKey to 8) <!-- Caesar's Cipher decryption number --> (set: $perpHackerName to "TechNemesis") <!-- Hacker Name --> ] <p><b>Name:</b> (print: $perp)</p> <p><b>Role:</b> (print: $perpRole)</p> <p><b>Date of Birth:</b> (print: $perpDOB)</p> <p><b>Pet Name:</b> (print: $perpPetName)</p> <p><b>Maiden Name:</b> (print: $perpMaidenName)</p> <p><b>Favorite Color:</b> (print: $perpFavoriteColor)</p> <p><b>Login Time:</b> (print: $perpLoginTime)</p> <p><b>Hobby:</b> (print: $perpHobby)</p> <p><b>Caesar's Cipher Decryption Number:</b> (print: $perpCipherKey)</p> <p><b>Hacker Name:</b> (print: $perpHackerName)</p> <p>Your number is: (print: $suspectNum)</p> <p>Your encrypted name is: (print: $encryptedName)</p> <h1>Pick a random number.</h1> <p>Pick a number between 1 and 8:</p> { <!-- Input box to get the user’s number --> (input-box: bind $userNum) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userNum is not "")[ (if: (num: $userNum) >= 1 and (num: $userNum) <= 8)[ (set: $suspectNum to (num: $userNum)) <!-- Convert to a number and store it in $suspectNum --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter a valid number between 1 and 8.") ] ] (else:)[ (alert: "Please enter a number.") ] ] } { |nextLink)[[[Continue to Avatar Creation Complete->Avatar Creation Complete]]] } {<p class="s_direction"> (if: $suspectNum is 1)[The hacker used the pet name <span class="clue">Rex</span> as part of their security setup.] (else-if: $suspectNum is 2)[The hacker used the pet name <span class="clue">Milo</span> as part of their security setup.] (else-if: $suspectNum is 3)[The hacker used the pet name <span class="clue">Buddy</span> as part of their security setup.] (else-if: $suspectNum is 4)[The hacker used the pet name <span class="clue">Max</span> as part of their security setup.] (else-if: $suspectNum is 5)[The hacker used the pet name <span class="clue">Lucy</span> as part of their security setup.] (else-if: $suspectNum is 6)[The hacker used the pet name <span class="clue">Oscar</span> as part of their security setup.] (else-if: $suspectNum is 7 and $suspect7FirstPet is not "")[The hacker used the pet name <span class="clue">(print: $suspect7FirstPet)</span> as part of their security setup.] <!-- Reference to user input --> (else-if: $suspectNum is 8)[The hacker used the pet name <span class="clue">Shadow</span> as part of their security setup.] (else:)[The hacker used a pet name <span class="clue">Unknown</span> as part of their security setup. This is a test placeholder to show that the clue system is working.] </p> }<p class="s_direction"> (if: $suspectNum is 1)[The hacker used the mother's maiden name <span class="clue">Smith</span> as part of their security setup.] (else-if: $suspectNum is 2)[The hacker used the mother's maiden name <span class="clue">Johnson</span> as part of their security setup.] (else-if: $suspectNum is 3)[The hacker used the mother's maiden name <span class="clue">Davis</span> as part of their security setup.] (else-if: $suspectNum is 4)[The hacker used the mother's maiden name <span class="clue">Reed</span> as part of their security setup.] (else-if: $suspectNum is 5)[The hacker used the mother's maiden name <span class="clue">Lee</span> as part of their security setup.] (else-if: $suspectNum is 6)[The hacker used the mother's maiden name <span class="clue">Brown</span> as part of their security setup.] (else:)[The hacker used the mother's maiden name <span class="clue">Audience</span> as part of their security setup.] </p> {<p class="s_direction"> (if: $suspectNum is 1)[The hacker often logged in during <span class="clue">Late Nights</span>.] (else-if: $suspectNum is 2)[The hacker often logged in during <span class="clue">Evenings</span>.] (else-if: $suspectNum is 3)[The hacker often logged in during <span class="clue">Daytime</span>.] (else-if: $suspectNum is 4)[The hacker often logged in during <span class="clue">Afternoons</span>.] (else-if: $suspectNum is 5)[The hacker often logged in during <span class="clue">Evening Shifts</span>.] (else-if: $suspectNum is 6)[The hacker often logged in during <span class="clue">Regular Hours</span>.] (else-if: $suspectNum is 7 and $suspect7LoginTime is not "")[The hacker often logged in during <span class="clue">(print: $suspect7LoginTime)</span>.] <!-- Reference to user input or default value --> (else-if: $suspectNum is 8)[The hacker often logged in during <span class="clue">Unknown Hours</span>.] (else:)[The hacker often logged in during <span class="clue">Uncertain Times</span>. This is a test placeholder to show that the clue system is working.] </p>} <p class="s_direction"> (if: $suspectNum is 1)[The hacker's favorite hobby is <span class="clue">Programming</span>.] (else-if: $suspectNum is 2)[The hacker's favorite hobby is <span class="clue">Gaming</span>.] (else-if: $suspectNum is 3)[The hacker's favorite hobby is <span class="clue">Hiking</span>.] (else-if: $suspectNum is 4)[The hacker's favorite hobby is <span class="clue">Reading</span>.] (else-if: $suspectNum is 5)[The hacker's favorite hobby is <span class="clue">Painting</span>.] (else-if: $suspectNum is 6)[The hacker's favorite hobby is <span class="clue">Photography</span>.] (else-if: $suspectNum is 7 and $suspect7Hobby is not "")[The hacker's favorite hobby is <span class="clue">(print: $suspect7Hobby)</span>.] <!-- Reference to user input --> (else-if: $suspectNum is 8)[The hacker's favorite hobby is <span class="clue">Sabotage</span>.] (else:)[The hacker's favorite hobby is <span class="clue">Unknown</span>. This is a test placeholder to show that the clue system is working.] </p> {<p class="s_direction"> (if: $suspectNum is 1)[The hacker's favorite color is <span class="clue">Blue</span>.] (else-if: $suspectNum is 2)[The hacker's favorite color is <span class="clue">Red</span>.] (else-if: $suspectNum is 3)[The hacker's favorite color is <span class="clue">Green</span>.] (else-if: $suspectNum is 4)[The hacker's favorite color is <span class="clue">Yellow</span>.] (else-if: $suspectNum is 5)[The hacker's favorite color is <span class="clue">Purple</span>.] (else-if: $suspectNum is 6)[The hacker's favorite color is <span class="clue">Orange</span>.] (else-if: $suspectNum is 7 and $suspect7FavoriteColor is not "")[The hacker's favorite color is <span class="clue">(print: $suspect7FavoriteColor)</span>.] <!-- Reference to user input for suspect 7 --> (else-if: $suspectNum is 8)[The hacker's favorite color is <span class="clue">Black</span>.] (else:)[The hacker's favorite color is <span class="clue">Unknown</span>. This is a test placeholder to show that the clue system is working.] </p> }<h1>Clue: Hacker's Favorite Hobby</h1> { <!-- Timer Area Inside tw-passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 300 seconds (5 minutes) let timeRemaining = 300 * (1 - progress / 100); // Total time: 300 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((300 - timeRemaining) / 300) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } <p class="speech"><b>Task Force Member:</b> "Sir! We’ve identified a clue related to the hacker’s favorite hobby. This piece of information was crucial in narrowing down our suspect list."</p> <p class="s_direction"> The hacker's favorite hobby is <span class="clue">{ (if: $suspectNum is 1)[Programming] (else-if: $suspectNum is 2)[Gaming] (else-if: $suspectNum is 3)[Hiking] (else-if: $suspectNum is 4)[Reading] (else-if: $suspectNum is 5)[Painting] (else-if: $suspectNum is 6)[Photography] (else-if: $suspectNum is 7)[(print: $userHobby)] <!-- Audience Member's hobby --> (else-if: $suspectNum is 8)[Sabotage] (else:)[Unknown] <!-- Default placeholder --> }</span>. </p> [[Continue->Continued Transfer]] (display: "Sidebar") (display: "SidebarBack") <!-- Check and update the clue variable --> (if: $clue11_found is not true)[ (set: $clue11_found to true) (set: $cluesFound to $cluesFound + 1) ] <h1>Suspicious Email Investigation</h1> <p class="speech"><b>Task Force Member 1:</b> "Take a look at the sender’s address, '<span style='color: red;'>admin@schooltech.co.uk</span>'. It looks almost correct, doesn't it? But there's a subtle difference; it's not the school’s real domain, which is '<span style='color: red;'>school.ac.uk</span>'. This sender is clearly trying to impersonate someone inside the school."</p> <p class="speech"><b>Mr. Luddite:</b> "Wait, so this isn't actually from the school?"</p> <p class="speech"><b>Task Force Member 2:</b> "Exactly. And then there's the link in the email: '<a href="#" style='color: red;'>Click here to update your credentials</a>'. It appears to be an official school link, but it doesn’t match our actual website. If someone clicked on this, they would have unknowingly given their credentials to the attacker."</p> [[Continue->Suspicious2]] (display: "Sidebar") (display: "SidebarBack")<h1>After the Breach</h1> <p class="s_direction">The room falls silent as the team stares at the screen, the data transfer progress bar now flashing "Complete." The tension is palpable, and Mr. Luddite clenches his fists in frustration.</p> <p class="speech"><b>Mr. Luddite:</b> "I can't believe it... We had a chance to stop them, and now it's too late. They've taken everything."</p> <p class="s_direction">The Task Force Leader takes a deep breath, keeping a composed demeanor despite the gravity of the situation.</p> <p class="speech"><b>Task Force Leader:</b> "This is a hard lesson, but it’s the reality of cybersecurity. We did everything we could, but sometimes, despite our best efforts, the attacker slips through. Our job isn’t over, though. We can still mitigate the damage, track the perpetrator, and strengthen our defenses for next time."</p> <p class="speech"><b>Task Force Member 1:</b> "It’s not the outcome we wanted, but we can use what we’ve learned here. Each failure teaches us how to better protect the network in the future."</p> <p class="speech"><b>Mr. Luddite:</b> "This isn't just about the network. It's about people, their privacy, their lives. We have to be better."</p> <p class="speech"><b>Task Force Leader:</b> "And we will be. But now, we need to focus on containment and ensure that this breach doesn't escalate further. We may have lost this battle, but the war for cybersecurity is far from over."</p> <div> [[Continue->Firewall Containment Measures]] </div> (display: "Sidebar") (display: "SidebarBack") <h1>Containment Measures</h1> <!-- Set the branch as failed to prevent replay --> (set: $dataTransferFailed to true) <p class="speech"><b>Mr. Luddite:</b> "But the data… It’s out there now. What’s the point in continuing?"</p> <p class="speech"><b>Task Force Leader:</b> "Yes, the data has been leaked, but there's still much we can do. Our focus now is on containment. We need to act fast to neutralize the threat before it escalates. We'll launch a full network lockdown and isolate critical systems to prevent further breaches."</p> <p class="speech"><b>Task Force Member:</b> "We’ve already initiated emergency protocols. We're cutting off external access points and monitoring network traffic for any signs of further intrusion. This isn’t over yet."</p> <p class="speech"><b>Task Force Leader:</b> "We’ll also deploy a decoy network—a honeypot—to lure the hacker into a trap. While they're busy with the false data, we can gather more information about their methods and potentially trace them."</p> <p class="speech"><b>Mr. Luddite:</b> "A decoy network? You mean we’re going to bait them?"</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. It’s a strategic move. By focusing on the decoy, they waste valuable time and resources while we secure what remains. We can still mitigate the fallout and turn this attack to our advantage."</p> <p class="speech"><b>Task Force Member:</b> "We may have lost some data, but we haven’t lost the fight. Every second counts now. Let’s ensure they gain nothing more."</p> <div> [[Continue - Interactive Vote]] </div> (display: "Sidebar") (display: "SidebarBack") <h1>Data Transfer Successfully Stopped</h1> <p class="speech"><b>Task Force Leader:</b> "Excellent work! We've successfully halted the data transfer. The hacker has been blocked from further activity."</p> <p class="s_direction">As the team analyzes the halted data stream, they uncover a small snippet of metadata left behind by the hacker.</p> <p class="speech"><b>Task Force Member:</b> "Look at this—we’ve found a timestamp embedded in the data. It's in the format of a date... could it be the hacker's date of birth?"</p> { <p class="s_direction">The hidden date reveals itself: <span class="clue">{ (if: $suspectNum is 1)[01/05/1980] (else-if: $suspectNum is 2)[12/11/1975] (else-if: $suspectNum is 3)[23/09/1968] (else-if: $suspectNum is 4)[05/06/1970] (else-if: $suspectNum is 5)[14/03/1985] (else-if: $suspectNum is 6)[30/07/1978] (else-if: $suspectNum is 7 and $userDOB is not "")[(print: $userDOB)] (else-if: $suspectNum is 8)[17/02/1965] (else:)[01/01/1970] }</span>.</p> <!-- Mark the "Data Transfer Stopped" as complete --> (set: $dataTransferStopped to true) (display: "Sidebar") (display: "SidebarBack") } [[Continue->Vote]] <h1>Decision</h1> <p class="s_direction">The task force has identified a potential phishing attack. The emails look legitimate at first glance, but something seems off. The team needs to decide how to proceed with the investigation.</p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> <p class="s_direction">Where should the task force focus their investigation next?</p> { <!-- Center the links container --> <div style="text-align: center; margin-top: 20px;"> <!-- Check if all investigations are complete --> (if: $investigateEmailHeadersCompleted is true and $investigateEmailLinksCompleted is true and $investigateSenderCompleted is true)[ <!-- All branches are complete, show the link to next steps --> <p><b>All investigations are complete.</b></p> [[Next Steps After Link Clue]] ] <!-- If not all investigations are complete, show the remaining options --> (else:)[ <!-- Investigate Email Headers --> (if: $investigateEmailHeadersCompleted is not true)[ <div>[[Investigate Email Headers->Investigate Email Headers]]</div><br> ] (else:)[ <p class="strike">You've already investigated the email headers.</p> ] <!-- Investigate Email Links --> (if: $investigateEmailLinksCompleted is not true)[ <div>[[Investigate Email Links->Investigate Email Links]]</div><br> ] (else:)[ <p class="strike">You've already investigated the email links.</p> ] <!-- Investigate Sender --> (if: $investigateSenderCompleted is not true)[ <div>[[Investigate Sender->Investigate Sender]]</div><br> ] (else:)[ <p class="strike">You've already investigated the sender.</p> ] ] } </div> (display: "Sidebar") (display: "SidebarBack") <h1>Investigate Logs</h1> <p class="speech"><b>Task Force Leader:</b> "These logs are like the digital fingerprints of every device on the network. If someone’s been moving large amounts of data, the logs will show us when, where, and how."</p> <div class="log-container"> <pre class="network-logs" id="logs"> Time Src IP Dest IP Prot Act Data (MB) ----------------------------------------------------------------------------------- </pre> </div> [[Continue->Luddite Explanation]] <script> // Define the log entries array globally const logEntries = [ "2024-09-02 13:05:43 192.168.203.50 203.0.113.5 TCP Allow 0.5", "2024-09-02 13:06:10 192.168.1.15 203.0.113.20 UDP Allow 1.2", "2024-09-02 13:06:58 192.168.203.50 198.51.100.7 TCP Allow 200", // Potential large data transfer "2024-09-02 13:07:15 192.168.203.50 203.0.113.45 TCP Allow 5.0", "2024-09-02 13:07:30 192.168.203.50 203.0.113.10 TCP Allow 0.3", "2024-09-02 13:08:00 192.168.203.50 203.0.113.12 TCP Allow 15.7", // Potential large data transfer "2024-09-02 13:08:45 192.168.1.25 198.51.100.20 TCP Allow 0.7", "2024-09-02 13:09:10 192.168.203.50 203.0.113.5 TCP Allow 10.5", // Potential large data transfer "2024-09-02 13:10:00 192.168.203.50 203.0.113.18 UDP Allow 2.3" ]; // Function to add a new log entry to the logs function addLogEntry() { const logsElement = document.getElementById('logs'); if (logsElement && logEntries.length > 0) { const newLog = logEntries.shift(); // Get the next log entry logsElement.textContent += '\n' + newLog; // Append the new log entry // Scroll to the bottom of the logs to show the new entry const logContainer = document.querySelector('.log-container'); logContainer.scrollTop = logContainer.scrollHeight; // Schedule the next log update at a random interval (1 to 3 seconds) const nextInterval = Math.random() * 2000 + 1000; // Random between 1000ms and 3000ms setTimeout(addLogEntry, nextInterval); } } // Start adding logs after a short delay, only if the logs element is present if (document.getElementById('logs')) { setTimeout(addLogEntry, 1000); // Start after 1 second } </script> (display: "Sidebar") (display: "SidebarBack") <h1>Avatar Creation: Date of Birth</h1> <p class="speech"><b>Emma Smith:</b> "Great! When’s your birthday?"</p> { <!-- Input for the date of birth --> (input-box: bind $userDOB) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userDOB is not "")[ (set: $suspect7DOB to $userDOB) <!-- Store the DOB in suspect7DOB variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter your date of birth.") ] ] } { |nextLink)[[[Continue to First Pet->First Pet]]] } <h1>Avatar Creation: First Pet</h1> <p class="speech"><b>Mr. Jonathan Luddite:</b> "What was the name of your first pet?"</p> { <!-- Input for the first pet's name --> (input-box: bind $userFirstPet) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userFirstPet is not "")[ (set: $suspect7FirstPet to $userFirstPet) <!-- Store the first pet's name in suspect7FirstPet variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter the name of your first pet.") ] ] } { |nextLink)[[[Continue to Mother's Maiden Name->Mother's Maiden Name]]] } <h1>Avatar Creation: Mother's Maiden Name</h1> <p class="speech"><b>Emma Smith:</b> "Now, just for fun, what's your mother's maiden name?"</p> { <!-- Input for the mother's maiden name --> (input-box: bind $userMotherMaidenName) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userMotherMaidenName is not "")[ (set: $suspect7MotherMaidenName to $userMotherMaidenName) <!-- Store the mother's maiden name in suspect7MotherMaidenName variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter your mother's maiden name.") ] ] } { |nextLink)[[[Continue to Favourite Colour->FavColour]]] } <h1>Avatar Creation: Favorite Color</h1> <p class="speech"><b>Mr. Jonathan Luddite:</b> "What's your favorite color?"</p> { <!-- Input for the favorite color --> (input-box: bind $userFavoriteColor) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userFavoriteColor is not "")[ (set: $suspect7FavoriteColor to $userFavoriteColor) <!-- Store the favorite color in suspect7FavoriteColor variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter your favorite color.") ] ] } { |nextLink)[[[Continue to Favorite Hobby->Favorite Hobby]]] } <h1>Avatar Creation: Favorite Hobby</h1> <p class="speech"><b>Emma Smith:</b> "Lastly, what's your favorite hobby?"</p> { <!-- Input for the favorite hobby --> (input-box: bind $userHobby) } { <!-- Submit button to validate input --> (link-repeat: "Submit")[ (if: $userHobby is not "")[ (set: $suspect7Hobby to $userHobby) <!-- Store the hobby in suspect7Hobby variable --> (show: ?nextLink) <!-- Reveal the link to the next passage --> ] (else:)[ (alert: "Please enter your favorite hobby.") ] ] } { |nextLink)[[[Complete Avatar Creation->Start2]]] } <h1>Avatar Creation Complete</h1> <p class="speech"><b>Mr. Jonathan Luddite:</b> "Thank you! Your virtual avatar is now complete. Let's move forward with the show!"</p> <!-- Proceed to the next part of the story --> (link: "Continue")[ (goto: " Siren and Task Force Arrival") ] <h1>Robert Brown</h1> <p class="s_direction">(Robert explains in detail how he executed the attack and his motivations behind it.)</p> <p class="speech"><b>Task Force Leader:</b> "Can you provide more details on how you executed the attack and your specific motivations?"</p> <!-- Conditional Dialogue for Suspect Status --> { <!-- If Robert Brown is in the suspects list --> (if: $suspect6_found is true)[ <p class="speech"><b>Robert Brown:</b> "I suppose I underestimated you. You caught me fair and square. As a Librarian and Media Specialist, I exploited my access to the system’s media archives to insert malicious code and redirect data streams. I utilized my knowledge of the library’s network to bypass security measures and cover my tracks. My intention was to demonstrate the vulnerabilities in our media and data management systems."</p> <p class="speech"><b>Task Force Member:</b> "So your primary concern was with how the media and data systems were managed and the security oversights associated with them?"</p> <p class="speech"><b>Robert Brown:</b> "Precisely. The lack of adequate security for sensitive information and media assets was alarming. Despite numerous requests for better security protocols, nothing was done. By creating a significant disruption, I hoped to force a reassessment of our data handling and protection practices."</p> <p class="s_direction">(Robert appears both determined and regretful.)</p> <p class="speech"><b>Task Force Leader:</b> "While your actions did reveal critical security flaws, the method you chose was extreme and disruptive. Addressing these issues through appropriate channels would have been more effective and less damaging."</p> ] <!-- If Robert Brown is not in the suspects list --> (else:)[ <p class="speech"><b>Robert Brown:</b> "Hah! You think you could catch me? I'm far more clever than you could ever imagine. As a Librarian and Media Specialist, I had the perfect cover. I exploited my access to the system’s media archives, inserting malicious code and redirecting data streams without raising suspicion. You never stood a chance!"</p> <p class="speech"><b>Task Force Member:</b> "So you used your role as a cover to bypass security measures, all while flaunting your superiority?"</p> <p class="speech"><b>Robert Brown:</b> "Exactly! It was all too easy. The lack of adequate security for sensitive information and media assets was laughable. I needed to show everyone how flawed the system was, and I did it with style. Maybe now you'll appreciate the brilliance of my plan."</p> <p class="s_direction">(Robert's demeanor is arrogant and unapologetic.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions revealed critical security flaws, yes, but they also caused chaos and harm. There were better ways to address these issues than through malicious actions."</p> ] } <p>[[Final Reflections->Robert Brown Reflections]]</p> (display: "Sidebar") (display: "SidebarBack") <h1>Final Reflections on Robert Brown's Actions</h1> <p class="s_direction">The Task Force concludes their confrontation with Robert Brown and reflects on the broader implications of his actions.)</p> <p class="speech"><b>Task Force Leader:</b> "Your actions have certainly brought to light critical issues with our media and data management systems. However, the way you went about it caused significant disruption and confusion. It's important that while we address the vulnerabilities, we recognize that your method was damaging and counterproductive."</p> <!-- Conditional Reflection Based on Suspect Status --> { <!-- If Robert Brown is in the suspects list --> (if: $suspect6_found is true)[ <p class="speech"><b>Robert Brown:</b> "I understand. I intended to highlight the serious flaws in our system to push for necessary changes. I regret the chaos my actions caused and acknowledge that there were better, more constructive ways to address these issues."</p> ] <!-- If Robert Brown was not initially in the suspects list --> (else:)[ <p class="speech"><b>Robert Brown:</b> "I see that my actions have had unintended consequences. I aimed to prove a point, but I realize now that there were more constructive ways to address the system's flaws."</p> ] } <p class="s_direction">(The Task Force begins to review and enhance their media and data management policies.)</p> <p class="speech"><b>Task Force Leader:</b> "We will take this opportunity to improve our security measures and ensure that our media and data systems are protected more effectively. Your actions have underscored the need for better protocols and resources, but moving forward, we will focus on making improvements through appropriate channels."</p> [[Final Wrap-Up]] (display: "Sidebar") (display: "SidebarBack") <p id="output"></p> <script> function caesarCipherEncrypt(str, shift) { return str.split('').map(char => { if (char.match(/[a-z]/i)) { const base = char.charCodeAt(0) < 97 ? 65 : 97; const encryptedChar = String.fromCharCode(((char.charCodeAt(0) - base + shift) % 26) + base); return encryptedChar; } return char; // Non-letter characters remain unchanged }).join(''); } // Automatically encrypt the user's name when the passage loads const inputString = window.harloweVariables.userName; // Get the Harlowe variable const encryptedString = caesarCipherEncrypt(inputString, 7); // Display the output document.getElementById('output').innerHTML = encryptedString; // Store the result back into a Harlowe variable window.harloweVariables.encryptedName = encryptedString; // Store it in a Harlowe variable </script> <!-- Timer Area Inside tw-passage --> { <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable, or 0 if not set let progress = window.harloweVariables.timerProgress; // Adjust timeRemaining for 30 seconds let timeRemaining = 30 * (1 - progress / 100); // Total time: 30 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((30 - timeRemaining) / 30) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script> } [[Untitled Passage 5]] {<!-- Timer Area Inside tw-passage for the second passage --> <div class="timer"> Upload Completion <div class="progress-bar-container"> <div class="progress-bar" id="progressBar">0%</div> </div> </div> <!-- Link to the failure passage, hidden by default --> <div id="failLink" style="display: none; text-align: center; margin-top: 10px;"> [[Game Fail - Upload to Internet]] </div> <script> // Ensure global harloweVariables is accessible if (!window.harloweVariables.timerProgress) { window.harloweVariables.timerProgress = 0; // Initialize if not set } // Initialize the timer progress from Harlowe variable let progress = window.harloweVariables.timerProgress; // Calculate remaining time based on current progress let timeRemaining = 30 * (1 - progress / 100); // Total time: 30 seconds const updateProgressBar = () => { document.getElementById('progressBar').style.width = `${progress}%`; // Update progress bar width document.getElementById('progressBar').textContent = `${Math.floor(progress)}%`; // Update text inside the bar }; // Function to hide all other links except the fail link const hideOtherLinks = () => { // Select all Twine links and hide them, but keep the fail link visible document.querySelectorAll('tw-link, tw-enchant').forEach(link => { if (link.closest('#failLink') === null) { // Ensure we don't hide the fail link link.style.display = 'none'; } }); }; // Call this function to start the timer const startTimer = () => { const timerInterval = setInterval(() => { if (timeRemaining > 0) { timeRemaining--; progress = ((30 - timeRemaining) / 30) * 100; // Calculate progress from 0% to 100% updateProgressBar(); // Update the Harlowe variable window.harloweVariables.timerProgress = progress; // Persist progress } else { clearInterval(timerInterval); // Stop the timer when it reaches 100% progress = 100; updateProgressBar(); // Hide all other links and show the fail link hideOtherLinks(); document.getElementById('failLink').style.display = 'block'; } }, 1000); }; // Start the timer automatically startTimer(); </script>} <h1>The Stick of Truth</h1> <img class="stick" src="https://static.wixstatic.com/media/27b368_acae6bdeef084ea9b0b802eb30d81e5a~mv2.png" alt="Stick of Truth!"> <p class="speech"><b>Task Force Member 2:</b> (eyes widening) "The... Stick of Truth?"</p> <p class="speech"><b>Task Force Leader:</b> (dramatic) "40 years of the best tools ever known to computer technicians. Passed down from mentor to student. If we’re going to save this system, this is our best shot."</p> <p class="speech"><b>Mr. Luddite:</b> (nervous, but hiding it) "You really think that old thing’s going to fix this?"</p> <p class="speech"><b>Task Force Leader:</b> (confident) "It’s saved me more times than I can count. Now, let’s put it to work. Here, plug this in and reboot!"</p> <!-- Check if Sarah Lee is not a suspect --> { (if: $suspect5_found is not true)[ <p class="speech"><b>Sarah Lee:</b> (in awe) "I’ve heard legends about the Stick of Truth. It’s supposed to be unbeatable!"</p> ] } <!-- Check if Alex Johnson is not a suspect --> { (if: $suspect1_found is not true)[ <p class="speech"><b>Alex Johnson:</b> (nodding) "I thought it was just a myth! If it’s real, we might actually have a chance!"</p> ] } <p>[[Continue->RebootP1]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>USB Drive: Stick of Truth</h1> <div class="file-explorer"> <h2>Files & Folders</h2> <table> <tr> <td class="file" data-type="exe">Malware Remover.exe</td> <td>5 MB</td> <td>01-09-2024</td> </tr> <tr> <td class="file" data-type="exe">Virus Vanquisher.exe</td> <td>4 MB</td> <td>20-08-2024</td> </tr> <tr> <td class="file" data-type="image">Cat in a Firewall.png</td> <td>2 MB</td> <td>15-08-2024</td> </tr> <tr> <td class="file" data-type="exe">Trojan Terminator.exe</td> <td>6 MB</td> <td>10-07-2024</td> </tr> <tr> <td class="file" data-type="doc">Meeting Notes - How to Fix Everything.docx</td> <td>1 MB</td> <td>05-09-2024</td> </tr> <tr> <td class="file" data-type="exe">Adware Annihilator.exe</td> <td>5.5 MB</td> <td>30-08-2024</td> </tr> <tr> <td class="file" data-type="exe">Spyware Suppressor.exe</td> <td>4.2 MB</td> <td>03-09-2024</td> </tr> <tr> <td class="file" data-type="doc">What Not to Do When Hacked.pdf</td> <td>0.5 MB</td> <td>07-09-2024</td> </tr> <tr> <td class="file" data-type="exe">Ransomware Reducer.exe</td> <td>3.8 MB</td> <td>25-08-2024</td> </tr> <tr> <td class="file" data-type="doc">Ransomware: A Love Story.txt</td> <td>0.2 MB</td> <td>10-08-2024</td> </tr> <tr> <td class="file" data-type="exe">Malware Mangler.exe</td> <td>7 MB</td> <td>02-09-2024</td> </tr> <tr> <td class="file" data-type="doc">Grandma's Secret Recipe.docx</td> <td>1.2 MB</td> <td>20-08-2024</td> </tr> <tr> <td class="file" data-type="exe">Spam Filter (Not That Kind).exe</td> <td>3 MB</td> <td>01-08-2024</td> </tr> <tr> <td class="file" data-type="image">Vacation in the Cloud.jpg</td> <td>1.5 MB</td> <td>15-07-2024</td> </tr> </table> </div> <div id="message"></div> <div id="rebootLink" style="display: none;"> <p>[[Reboot]]</p> </div> <div id="catLink" style="display: none;"> <p>[[Cat]]</p> </div> <div id="meetingLink" style="display: none;"> <p>[[Meeting]]</p> </div> <script> const files = document.querySelectorAll('.file'); const message = document.getElementById('message'); const rebootLink = document.getElementById('rebootLink'); const catLink = document.getElementById('catLink'); const meetingLink = document.getElementById('meetingLink'); files.forEach(file => { file.addEventListener('click', () => { // Reset message and hide all links message.textContent = ''; rebootLink.style.display = 'none'; catLink.style.display = 'none'; meetingLink.style.display = 'none'; // Display a message based on the file type const fileType = file.getAttribute('data-type'); if (fileType === "exe") { message.textContent = 'You selected an executable file.'; rebootLink.style.display = 'block'; // Show the Reboot2 link } else if (fileType === "image") { message.textContent = 'You selected an image file.'; catLink.style.display = 'block'; // Show the Cat link } else if (fileType === "doc") { message.textContent = 'You selected a document file.'; meetingLink.style.display = 'block'; // Show the Meeting link } else { message.textContent = "Oops! That didn't work."; } }); }); </script> <style> h1 { text-align: center; font-size: 1.5em; } .file-explorer { text-align: center; margin: 10px; padding: 10px; background-color: #1a1a1a; border-radius: 5px; color: #fff; } table { width: 100%; border-collapse: collapse; } td { padding: 8px; border: 1px solid #555; } .file { cursor: pointer; transition: background-color 0.3s; } .file:hover { background-color: #555; } #message { margin-top: 10px; font-weight: bold; color: #ffcc00; } #rebootLink, #catLink, #meetingLink { margin-top: 10px; font-weight: bold; color: #ffcc00; } </style> (display: "Sidebar") (display: "SidebarBack") Test?<h1>Task Force Commander's Personal Photos</h1> <img class = "cat" src = "https://static.wixstatic.com/media/27b368_e24a8faae2c44707a41f8806c11e43ba~mv2.png" alt = "cat"> <p class="speech"><b>Task Force Member 1:</b> "Uh-oh, it looks like we've stumbled upon the Task Force Commander's personal photo collection."</p> <p class="speech"><b>Task Force Member 2:</b> "Is that... a cat in a tiny firefighter outfit? I never knew he had such a soft side!"</p> <p class="speech"><b>Mr. Luddite:</b> "I always knew there was a big heart under that tough exterior. This is priceless!"</p> <p class="speech"><b>Task Force Leader:</b> [overhearing] "Ahem. Can we focus on the task at hand, please?"</p> <p class="speech"><b>Task Force Member 1:</b> "Right, right. Back to business, everyone!"</p> [[RebootP1]]<h1>Meeting Notes - Task Force Briefing</h1> <p class="speech"><b>Task Force Member 1:</b> "Great, we’ve stumbled onto the meeting notes. Just what we needed... more excitement!"</p> <p class="speech"><b>Mr. Luddite:</b> "Let's see... 'Agenda Item 1: Review of Firewall Protocols.' Riveting stuff."</p> <p class="speech"><b>Task Force Member 2:</b> "Wait, it gets better. 'Agenda Item 2: Discussion of Data Packet Structures.' Fascinating!"</p> <p class="speech"><b>Task Force Leader:</b> "Ah, yes, the good old days of our weekly technical meetings. Thrilling, wasn't it?"</p> <p class="speech"><b>Mr. Luddite:</b> "I'm not sure if this will help us stop the hacker, but at least we know we were thorough!"</p> [[RebootP1]] (display: "Sidebar") (display: "SidebarBack")<h1>Suspicious Email Investigation</h1> <p class="speech"><b>Task Force Leader:</b> "So, they're tricking people into giving away their passwords?"</p> <p class="speech"><b>Task Force Member 1:</b> "Precisely. And there's more. The email's headers contain hidden information about where the email came from and how it traveled across the internet. If we can trace these headers, we might find clues about the attacker’s location or the tools they used."</p> <p class="speech"><b>Task Force Leader:</b> "We’re dealing with someone who knows how to cover their tracks, and that person could be in this room right now. We need to dig deeper into this email and decide which part to investigate first."</p> <p class="speech"><b>Task Force Leader:</b> "We have three key areas to investigate:</p> { <div class="investigation-list"> <ul> <li><b>The links in the emails</b> – Where do they lead? Are they part of a phishing website?</li> <li><b>The headers of the emails</b> – This could help us trace where they were sent from.</li> <li><b>The sender information</b> – Was this person impersonating someone else?</li> </ul> </div> } <p class="speech"><b>Task Force Leader:</b> "Let’s decide which part to investigate first."</p> [[Continue->Suspicious Emails Investigation]] (display: "Sidebar") (display: "SidebarBack") <h1>Suspicious Emails Investigation</h1> <p class="s_direction">Alex pulls up the logs on the central screen, displaying the path the phishing emails took through the network.</p> <p class="speech"><b>Alex Johnson:</b> "The email headers are also interesting. There’s some metadata in there that suggests the attacker is routing their traffic through multiple servers to obscure their real location. This isn’t someone new to cyberattacks; they’ve done this before. Frankly, it’s frustrating to watch these weaknesses being exploited when I've been suggesting changes for months."</p> <p class="s_direction">The Task Force Leader takes a moment to assess the situation. Alex's frustration and detailed knowledge of the network could be a sign of genuine concern or something more suspicious.</p> <p><b>Do you find Alex Johnson suspicious?</b></p> [[Yes, Alex Johnson seems suspicious.->Add to Watchlist]] [[No, Alex Johnson doesn't seem suspicious.->Phishing Decision]] (display: "Sidebar") (display: "SidebarBack")<h1>Add Alex Johnson to Watchlist</h1> <p class="speech"><b>Task Force Leader:</b> "We need to keep a closer eye on Alex Johnson. He seems to know a bit too much about how this attack is unfolding. His detailed knowledge of the network and the way he's outlined the weaknesses... It's almost as if he has firsthand experience with how this attack was orchestrated."</p> <p class="speech"><b>Task Force Member 1:</b> "I agree. He’s clearly frustrated with the current IT policies, and his access as a computer technician gives him insight into our network's vulnerabilities. If someone with his skills and access were to turn rogue, it would be a significant threat."</p> <p class="speech"><b>Task Force Member 2:</b> "It’s also concerning that he was able to trace the phishing links and identify the methods used by the attacker so quickly. While it could just mean he's very skilled at his job, it’s also possible he might have been involved in the attack itself."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. We can’t afford to overlook any potential threats, even if they come from within our own team. For now, we’ll keep monitoring Alex's actions closely. Any deviation from normal behavior could give us the evidence we need."</p> <p class="s_direction">The task force updates their watchlist, adding Alex Johnson's name as a person of interest. They decide to quietly observe his activities moving forward, noting his access to key systems and any further behavior that might raise suspicions.</p> [[Continue->Phishing Decision]] <!-- Set the suspect variable to true --> (set: $suspect1_found to true) (set: $suspectsFound to $suspectsFound + 1) (display: "Sidebar") (display: "SidebarBack") <h1>Inspecting the Suspicious Email</h1> <p class="speech"><b>Task Force Leader:</b> "Take a closer look at the sender's address, <span style='color: red;'>admin@schooltech.co.uk</span>. They've gone to great lengths to make this look official."</p> <p class="speech"><b>Mr. Luddite:</b> "But why use a fake email address? Wouldn’t people just ignore it if it's not from the real domain?"</p> <p class="speech"><b>Task Force Member:</b> "Not necessarily. They've used a domain that's almost identical to ours. This tactic plays on the familiarity and trust people have in our actual domain. Most staff wouldn’t notice the slight difference, especially if they’re quickly glancing at their emails."</p> <p class="speech"><b>Task Force Leader:</b> "It's about creating a sense of urgency and authority. Look at the email content. They're instructing staff to '<span style='color: red;'>Click here to update your credentials</span>'." </p> <p class="s_direction">The task force member points to the link, displayed in red, on the screen.</p> <p class="speech"><b>Task Force Member:</b> "<span style='color: red;'>Click here to update your credentials</span>. It’s a common phishing tactic. They disguise the link to look like a legitimate school resource, but it actually leads to a fake website designed to capture login information."</p> <p class="speech"><b>Mr. Luddite:</b> "So, it's less about the email itself and more about what they're trying to get people to do."</p> <p class="speech"><b>Task Force Leader:</b> "Exactly. The fake email address serves as a means to gain trust and trick staff into clicking the link. It's social engineering—a psychological manipulation to get people to perform actions or divulge confidential information."</p> <p class="s_direction">The team members exchange determined looks, realizing the attacker has a deep understanding of how to exploit human behavior through seemingly legitimate emails.</p> [[Continue->Deeper Analysis]] (display: "Sidebar") (display: "SidebarBack") <h1>Inspecting the Email Metadata</h1> <p class="s_direction">The task force member clicks through the email client’s options and selects "View Message Source."</p> <p class="speech"><b>Task Force Member:</b> "Here, let me show you an example of what the metadata looks like."</p> <div class="metadata-container" style="width: 100%; overflow: auto; color: black; background-color: #f4f4f4; border: 1px solid #ccc; padding: 10px; border-radius: 5px;"> <pre style="white-space: pre-wrap; word-wrap: break-word; font-size: 0.9em;"> Received: from mail.fake-server.com (mail.fake-server.com. [192.168.1.50]) by mail.school.ac.uk with SMTP id x1234567890 for <staff@school.ac.uk>; Wed, 20 Sep 2024 12:34:56 -0700 (PDT) Received-SPF: pass (schooltech.co.uk: domain of admin@schooltech.co.uk designates 192.168.1.50 as permitted sender) client-ip=192.168.1.50; Authentication-Results: mail.school.ac.uk; spf=pass From: admin@schooltech.co.uk Subject: Important Update: Action Required X-Phishing-Score: High <!-- Suspicious metadata indicator --> </pre> </div> <p class="speech"><b>Task Force Member:</b> "This metadata tells us a lot. For example, we can see the IP address of the server that sent the email and the route it took to reach our server. Notice this line: <i>Received: from mail.fake-server.com</i>. This tells us the email was sent from a server that doesn't belong to our network."</p> <p class="speech"><b>Task Force Member:</b> "Also, the 'Received-SPF' line indicates that the email passed the SPF (Sender Policy Framework) check. This means the email came from a server allowed to send on behalf of 'schooltech.co.uk', but that doesn't guarantee it's legitimate—it just means the attacker has cleverly bypassed a common email security check."</p> <p class="speech"><b>Mr. Luddite:</b> "So, it's like the email's digital footprint? And what's this 'X-Phishing-Score' line?"</p> <p class="speech"><b>Task Force Member:</b> "Exactly. The 'X-Phishing-Score' is an added header, usually by advanced email security systems. This indicates the system flagged this email as having a high chance of being a phishing attempt. But since it’s buried in the metadata, most recipients wouldn't see it unless they look into the message source."</p> <p class="speech"><b>Task Force Leader:</b> "This gives us a trail to follow. We can use this information to trace it back to its origin. The IP address—192.168.1.50—could be a vital clue to identifying the attacker."</p> [[Continue->email source]] (display: "Sidebar") (display: "SidebarBack") <h1>Adding Jamie Parker to the Watchlist</h1> <p class="s_direction">The task force members exchange wary glances as the leader steps forward, focusing on Jamie Parker.</p> <p class="speech"><b>Task Force Leader:</b> "Jamie, your insights have been invaluable, but some things don't quite add up. You've been vocal about the limitations in our systems, almost as if you expected this breach."</p> <p class="speech"><b>Jamie Parker:</b> "Expected it? I've been warning about these vulnerabilities for months! If we had implemented the changes I suggested, we wouldn't be in this mess."</p> <p class="speech"><b>Task Force Leader:</b> "And now we're here, facing a sophisticated attacker who seems to know our system's weaknesses inside and out. Someone who might have inside knowledge, just like you."</p> <p class="s_direction">Jamie's eyes narrow, a flicker of anger crossing his face.</p> <p class="speech"><b>Jamie Parker:</b> "You think I had something to do with this? That’s ridiculous. I’m the one trying to fix things around here."</p> <p class="speech"><b>Task Force Leader:</b> "We’re not pointing fingers, Jamie. But your expertise, your knowledge of the system's vulnerabilities... it’s enough to raise some concerns. Until we have more information, we need to consider all possibilities."</p> <p class="s_direction">The room falls into an uneasy silence as the task force leader turns to the rest of the team.</p> <p class="speech"><b>Task Force Leader:</b> "From now on, we’ll be monitoring your actions more closely. This is not an accusation, but a precaution. We need to ensure we're covering every angle."</p> <p class="s_direction">Jamie leans back in his chair, his expression hardening.</p> <p class="speech"><b>Jamie Parker:</b> "Fine. Do what you have to do. But remember, the real threat is out there, and we’re wasting time with this witch hunt."</p> <p class="s_direction">The leader nods and turns back to the screen, the atmosphere in the room growing tenser.</p> <p class="speech"><b>Task Force Leader:</b> "Let’s move on. We have an attacker to catch."</p> [[Continue->Audience Votes on Attack Type]] (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable for "Jamie Parker" to true --> (set: $suspect2_found to true) (set: $suspectsFound to $suspectsFound + 1)<h1>Task Force Leader's Concerns</h1> <p class="speech"><b>Task Force Leader:</b> "Alright team, I need to share my thoughts about Emily Davis. I can’t shake the feeling that she might be hiding something. Her frustration could easily lead someone to make desperate choices."</p> <p class="speech"><b>Task Force Member:</b> "You think she could be involved in the breach?"</p> <p class="speech"><b>Task Force Leader:</b> "It’s possible. She has access to critical information and resources, and her frustration might make her a target for manipulation or even push her to take matters into her own hands."</p> <p class="speech"><b>Task Force Member:</b> "So what do you suggest we do?"</p> <p class="speech"><b>Task Force Leader:</b> "I think we should keep a close eye on her. Let’s gather more information about her actions and relationships within the school. We can’t afford to overlook anyone at this point."</p> <p class="speech"><b>Task Force Member:</b> "Understood. I’ll make sure to monitor her closely."</p> <p>[[Continue->Sarah Lee’s IT Struggles]]</p> (display: "Sidebar") (display: "SidebarBack") (set: $suspectsFound to $suspectsFound + 1) <!-- Set the variable for "Emily Davis" to true --> (set: $suspect3_found to true) <h1>Sarah Lee's Rebuke</h1> <p class="s_direction">The tension in the room rises as Emily Davis and Sarah Lee face off.</p> <p class="speech"><b>Sarah Lee:</b> "You know, Emily, it’s easy to point fingers when you’re sitting behind a desk. I’ve been trying to keep this school’s IT systems from crumbling under the weight of your budget cuts!"</p> <p class="speech"><b>Emily Davis:</b> "And you think I’m to blame for that? I’m the one fighting for resources, but the school board keeps slashing our funding!"</p> <p class="s_direction">Sarah steps closer, her frustration boiling over.</p> <p class="speech"><b>Sarah Lee:</b> "You talk about funding cuts, but I've been begging for proper infrastructure for months! How can I do my job when we’re constantly patching up a sinking ship? It’s not just about IT; it’s about the entire school’s future!"</p> <p class="speech"><b>Emily Davis:</b> "I understand that, but your failures in maintaining the systems have put us all at risk! We can't afford to overlook these issues any longer!"</p> <p class="speech"><b>Sarah Lee:</b> "Failures? You think I want this chaos? I’m drowning in work, trying to fix problems that shouldn't exist! It’s not just me—it’s a system that’s been neglected for years!"</p> <p class="s_direction">The room grows silent as both women glare at each other, the weight of their frustrations palpable.</p> <p class="speech"><b>Task Force Leader:</b> "Alright, both of you, let's focus on finding a solution. This isn’t helping our investigation." </p> <p class="speech"><b>Sarah Lee:</b> "Maybe if there had been more support from the administration, we wouldn’t be in this mess!"</p> <p class="speech"><b>Emily Davis:</b> "And maybe if you had been more proactive, we could have prevented this!"</p> <p class="s_direction">The argument hangs in the air as the task force members exchange uneasy glances, knowing that the conflict between them reflects deeper issues within the school.</p> <p>[[Investigate Suspicious Document]]</p> (display: "Sidebar") (display: "SidebarBack") <!-- Set the variable for "Sarah Lee" to true --> (set: $suspect5_found to true) (set: $suspectsFound to $suspectsFound + 1) <h1>What do you notice about the file?</h1> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" alt="File Properties Illustration" style="max-width: 100%; height: auto;"> <p>[[File Property Interaction]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Interactive Decision</h1> <!-- Image with reduced bottom margin --> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> [[Investigate File Size->File Size Explanation]] [[Investigate File Name->File Name Explanation]] [[Investigate Digital Signature->Digital Signature Explanation]] <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>IT Technician Returns with the Floppy Disk</h1> <!-- Check if Alex Johnson is a suspect --> { (if: $suspect1_found is true)[ <p class="speech"><b>Alex Johnson:</b> (aggressively) "Yeah, I told you it wouldn’t work! Nobody ever listens to me around here!"</p> ] (else:)[ <p class="speech"><b>IT Technician:</b> (nervously, barely audible) "It’s... it’s my first day."</p> ] } <p class="speech"><b>Mr. Luddite:</b> (laughing in disbelief) "A floppy disk?! Please tell me you’re joking."</p> <p class = "s_direction">The task force stares in stunned silence at the floppy disk, then slowly turn to the technician.</p> <p class="speech"><b>Task Force Member 1:</b> (trying to hold back laughter) "This is what we have to work with?"</p> <p class="speech"><b>Task Force Leader:</b> (grimacing) "It’s all we’ve got. Let’s give it a shot."</p> <p>[[Attempted Restore]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Attempted Restore</h1> <p class="speech"><b>Task Force Member 1:</b> (exasperated) "Windows 95?! How old are these backups?"</p> <p class="speech"><b>Mr. Luddite:</b> (laughing nervously) "I knew we were doomed, but this is ridiculous!"</p> <p class = "s_direction">The screen flickers again, and the familiar <strong>ransomware message</strong> reappears, blinking ominously:</p> <p class="ransom-message"><strong>**"Pay 10 Bitcoin to unlock your system."**</strong></p> <p class="speech"><b>Mr. Luddite:</b> (groaning) "We’re back to where we started."</p> <p class="speech"><b>Task Force Leader:</b> (serious) "This is exactly why keeping backups up to date is crucial. Outdated backups are as good as no backups at all."</p> <p>[[Continue->Clue: Profession]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <h1>Thomas Reed: Added to Watchlist</h1> <p class="s_direction">The task force members exchange glances as they discuss Thomas Reed's involvement in the network traffic patterns.</p> <p class="speech"><b>Task Force Leader:</b> "Thomas has access to administrative resources and seems to have strong opinions about how IT is managed here. His frustration with the current IT policies could be a motive."</p> <p class="speech"><b>Task Force Member 1:</b> "He's been vocal about mismanagement and has pushed for changes to network access policies. If he felt those changes weren't happening fast enough, he might have taken matters into his own hands."</p> <p class="speech"><b>Task Force Member 2:</b> "The increase in requests for broader network permissions aligns with his stance on IT resource management. If someone was trying to bypass restrictions, Thomas might have the know-how or the motive to do so."</p> <p class="s_direction">The Task Force Leader nods, contemplating.</p> <p class="speech"><b>Task Force Leader:</b> "We need to keep an eye on him. His access level and grievances with how the network is managed could indicate he had the opportunity and the motive to facilitate the breach."</p> <p class="s_direction">Thomas is added to the watchlist, his actions and motives now under closer scrutiny as the investigation continues.</p> [[Continue->Next Investigation]] <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <!-- Set the variable for "Thomas Reed" to true --> (set: $suspect4_found to true) (set: $suspectsFound to $suspectsFound + 1)<h1>Robert Brown: Added to Watchlist</h1> <p class="s_direction">The Task Force Leader crosses his arms, studying Robert with a critical eye.</p> <p class="speech"><b>Task Force Leader:</b> "Robert, you've been very vocal about your frustrations with the network restrictions. Wanting more access is one thing, but crossing the line into taking matters into your own hands is another."</p> <p class="speech"><b>Robert Brown:</b> "Are you implying I had something to do with this breach? I just want to do my job effectively, without all these roadblocks!"</p> <p class="speech"><b>Task Force Leader:</b> "I’m not implying anything. I’m stating that when someone is as frustrated as you are, they might be tempted to bypass the rules. We’ll be watching you, Robert, closely."</p> <p class="s_direction">Robert shifts uncomfortably but maintains his defiant expression.</p> <p class="speech"><b>Robert Brown:</b> "Fine, watch all you want. I have nothing to hide."</p> <p class="s_direction">The Task Force Leader nods and makes a note, signaling to the rest of the team to keep an eye on Robert's actions moving forward.</p> <p>[[Continue->Investigate Logs]]</p> <p>(display: "Sidebar")</p> <p>(display: "SidebarBack")</p> <!-- Set the variable for "Robert Brown" to true --> (set: $suspect6_found to true) (set: $suspectsFound to $suspectsFound + 1) <div style='position: relative; padding-bottom: 56.25%; padding-top: 35px; height: 0; overflow: hidden;'><iframe sandbox='allow-scripts allow-same-origin allow-presentation' allowfullscreen='true' allowtransparency='true' frameborder='0' height='315' src='https://www.mentimeter.com/app/presentation/al5btvuvjitew6pg7n5o58pksztaoo87/embed' style='position: absolute; top: 0; left: 0; width: 100%; height: 100%;' width='420'></iframe></div><h1>Audience Decision</h1> <p class = "speech">Ok audience, before we unveil who the Hacker is, it's up to you! Who do you think is the perpetrator<p> <p class = "s_direction">Audience are shown one final Mentimeter Question...Who did it!?"<p> <img src="https://static.wixstatic.com/media/27b368_7ed6a790e6b945a5ae4f8f7ba65a3f73~mv2.png" style="display: block; margin: 0 auto; margin-bottom: 10px;"> [[Decryption ->Introduction to Cipher Puzzle]] (display: "Sidebar") (display: "SidebarBack")