🎯 Welcome to CTF Practice!

First time here? Perfect!

In just 3 minutes, you'll solve your first cybersecurity challenge!

No hacking experience needed - we'll guide you through everything!

🛡️ CTF Practice Arena

Master ethical hacking through interactive Capture The Flag challenges! Learn SQL injection, XSS, cryptography, and more in a safe, gamified environment.

⚠️ IMPORTANT ETHICAL & LEGAL NOTICE ⚠️

All techniques demonstrated here are for EDUCATIONAL PURPOSES ONLY

Using these techniques on systems you don't own or without explicit permission is ILLEGAL and punishable by law. By using this simulator, you agree to practice ethical hacking principles and respect others' digital property.

Choose Your Experience Level

🤔 What Is CTF (Capture The Flag)?

Think of it like a treasure hunt for hackers - but completely legal and educational!

CTF challenges teach you real cybersecurity skills by solving puzzles, finding vulnerabilities, and capturing "flags" (secret codes). It's how security professionals train!

🛡️ Ethical Hacking Principles

  • Permission First: Only test systems you own or have written permission to test
  • Do No Harm: Never damage systems or data during testing
  • Responsible Disclosure: Report vulnerabilities privately to owners first
  • Respect Privacy: Never access or expose personal data
  • Legal Compliance: Follow all local and international cyber laws
🛡️
Security Analyst
Protect companies from cyber attacks
🔍
Penetration Tester
Ethically hack systems to find weaknesses
💰
Bug Bounty Hunter
Earn rewards finding vulnerabilities
🕵️
Digital Forensics
Investigate cyber crimes
🏢
Security Architect
Design secure systems
🚀
Security Researcher
Discover new attack methods
0
Total Points
0
Challenges Solved
0
Current Streak
#--
Global Rank

📚 Challenge Categories

🌐
Web Exploitation
5 challenges
🔐
Cryptography
4 challenges
🔍
Forensics
2 challenges

🎯 Select a Challenge

-- pts
⚖️ Legal Reminder: Practice these techniques ONLY in this simulator or authorized CTF platforms. Using these methods on real systems without permission is illegal and unethical.
Welcome to CTF Practice! Select a category from the left to begin your hacking journey. Remember: all techniques here are for educational purposes only. Never use these skills on unauthorized systems!
ctf@practice:~$
Welcome to CTF Terminal v1.0
Type 'help' for available commands
ctf@practice:~$
🚩 Submit Flag

🛠️ Available Tools

\n\n

Welcome

\n \n \n

Nothing to see here...

\n \n', 'help': 'Available commands: view-source, curl, inspect, robots.txt', 'robots.txt': 'User-agent: *\nDisallow: /admin/\nDisallow: /secret/', 'curl': 'Usage: curl \nTry: view-source' } }, { name: 'Cookie Monster', icon: '\u{1F36A}', points: 75, description: 'The website uses cookies for authentication. Can you modify the cookie to become admin?

Type show-cookies to inspect cookies.', flag: 'CTF{cookie_tampering_101}', hints: [ 'Check the cookies with "show-cookies"', 'The role cookie controls access level', 'Try "set-cookie role=admin"' ], terminal: { 'show-cookies': 'session=abc123def456\nrole=guest\ntheme=dark', 'set-cookie role=admin': '\u2705 Cookie updated: role=admin\n\u{1F6A9} Access granted! Flag: CTF{cookie_tampering_101}', 'set-cookie role=user': '\u274C Access denied. Still not admin.', 'help': 'Commands: show-cookies, set-cookie =, curl' } } ], intermediate: [ { name: 'SQL Injection Login', icon: '\u{1F489}', points: 150, description: "Bypass the login form using SQL injection.

Type login to see the form, then try injecting into the username field.", flag: 'CTF{sql_injection_bypassed}', hints: [ 'Classic SQL injection: think about always-true conditions', "Try: login admin' OR 1=1 --", "The query is: SELECT * FROM users WHERE user='INPUT' AND pass='INPUT'" ], terminal: { 'login': 'Login Form:\n Username: [________]\n Password: [________]\n\nUsage: login ', 'login admin password': '\u274C Invalid credentials.', "login admin' OR 1=1 -- x": '\u2705 SQL Injection successful!\nLogged in as: admin\n\u{1F6A9} Flag: CTF{sql_injection_bypassed}', 'help': 'Commands: login , show-query, tables' } }, { name: 'XSS Reflected', icon: '\u{1F4DC}', points: 150, description: 'Find a reflected XSS vulnerability in the search function.

Type search to use the search page.', flag: 'CTF{reflected_xss_found}', hints: [ 'Input is reflected directly in the page', 'Try injecting a script tag in the search', 'search <script>alert(1)</script>' ], terminal: { 'search': 'Search Page: Type "search " to search\nYour search will be displayed on the results page.', 'search hello': 'Results for: hello\n No results found for "hello"', 'help': 'Commands: search , view-source, headers' } } ], expert: [ { name: 'SSRF Attack', icon: '\u{1F3AF}', points: 300, description: 'The web app fetches URLs. Exploit SSRF to access internal services.

Type fetch for usage.', flag: 'CTF{ssrf_internal_access}', hints: [ 'The app fetches any URL you provide', 'Internal services run on localhost', 'Try fetching http://127.0.0.1:8080/admin' ], terminal: { 'fetch': 'URL Fetcher v1.0\nUsage: fetch \nFetches and displays remote content.', 'fetch http://example.com': 'HTTP 200 OK\nExample Domain ', 'fetch http://127.0.0.1:8080/admin': '\u{1F513} Internal Admin Panel accessed via SSRF!\n\nAdmin Dashboard:\n - Users: 1,247\n - API Key: sk-secret-1234\n - \u{1F6A9} Flag: CTF{ssrf_internal_access}', 'fetch http://localhost:8080': 'HTTP 200 OK\nWelcome to internal service. Try /admin endpoint.', 'help': 'Commands: fetch , headers, dns-lookup ' } } ] }, crypto: { beginner: [ { name: 'Caesar Cipher', icon: '\u{1F510}', points: 50, description: 'Decrypt this Caesar cipher message to find the flag.

Encrypted: FWI{fdhvdu_flskhu_eurnhq}

Type caesar-decode for help.', flag: 'CTF{caesar_cipher_broken}', hints: [ 'Caesar cipher shifts each letter by N positions', 'CTF starts with C, the encrypted starts with F, so shift is 3', 'Use: caesar-decode 3 FWI{fdhvdu_flskhu_eurnhq}' ], terminal: { 'caesar-decode': 'Usage: caesar-decode \nDecodes a Caesar cipher with given shift value.', 'caesar-decode 3 FWI{fdhvdu_flskhu_eurnhq}': 'Shift 3: CTF{caesar_cipher_broken}\n\u{1F6A9} Flag found!', 'help': 'Commands: caesar-decode , base64-decode ' } }, { name: 'Base64 Decode', icon: '\u{1F4DD}', points: 50, description: 'A secret message was encoded in Base64:

Q1RGe2Jhc2U2NF9pc19ub3RfZW5jcnlwdGlvbn0=

Decode it to find the flag.', flag: 'CTF{base64_is_not_encryption}', hints: [ 'Base64 is encoding, not encryption', 'Use the Encoder/Decoder tool or terminal', 'base64-decode Q1RGe2Jhc2U2NF9pc19ub3RfZW5jcnlwdGlvbn0=' ], terminal: { 'base64-decode Q1RGe2Jhc2U2NF9pc19ub3RfZW5jcnlwdGlvbn0=': 'Decoded: CTF{base64_is_not_encryption}\n\u{1F6A9} Flag found!', 'help': 'Commands: base64-decode , base64-encode , hex-decode ' } } ], intermediate: [ { name: 'Hash Cracking', icon: '\u{1F528}', points: 125, description: 'Crack this MD5 hash to find the password flag:

5f4dcc3b5aa765d61d8327deb882cf99

Use the Hash Cracker tool or terminal.', flag: 'CTF{password_cracked_md5}', hints: [ 'This is one of the most common passwords', 'Try common passwords: password, 123456, admin', 'The hash is MD5 of "password"' ], terminal: { 'hash-crack 5f4dcc3b5aa765d61d8327deb882cf99': 'Cracking MD5: 5f4dcc3b5aa765d61d8327deb882cf99\n\nTrying wordlist...\n admin -> 21232f297a57a5a743894a0e4a801fc3 X\n password -> 5f4dcc3b5aa765d61d8327deb882cf99 MATCH!\n\nPassword: password\n\u{1F6A9} Flag: CTF{password_cracked_md5}', 'help': 'Commands: hash-crack , md5 , sha256 ' } } ], expert: [ { name: 'RSA Weak Key', icon: '\u{1F5DD}', points: 250, description: 'An RSA key uses a small prime. Factor the modulus to decrypt.

n = 3233, e = 17, ciphertext = 2790

Type rsa-info for help.', flag: 'CTF{rsa_small_primes_broken}', hints: [ 'n = p * q where p and q are primes', '3233 = 61 * 53', 'Use: rsa-decrypt 3233 17 2790' ], terminal: { 'rsa-info': 'RSA Parameters:\n n (modulus) = 3233\n e (public exponent) = 17\n ciphertext = 2790', 'factor 3233': '3233 = 61 * 53\nBoth are prime!', 'rsa-decrypt 3233 17 2790': 'Factoring n=3233... found p=61, q=53\nphi(n) = 60 * 52 = 3120\nd = modinv(17, 3120) = 2753\nplaintext = 2790^2753 mod 3233 = 65 -> ASCII "A"\n\n\u{1F6A9} Flag: CTF{rsa_small_primes_broken}', 'help': 'Commands: rsa-info, rsa-decrypt , factor ' } } ] }, forensics: { beginner: [ { name: 'Hidden in Plain Sight', icon: '\u{1F50D}', points: 75, description: 'A suspicious file was recovered. Examine its metadata and hidden content.

Type file-info evidence.jpg to start.', flag: 'CTF{metadata_reveals_all}', hints: [ 'Check the file metadata with exiftool', 'Look at the EXIF comment field', 'exiftool evidence.jpg' ], terminal: { 'file-info evidence.jpg': 'File: evidence.jpg\nSize: 245,302 bytes\nType: JPEG image\nCreated: 2024-03-15 14:23:01', 'exiftool evidence.jpg': 'ExifTool Version: 12.70\nFile Name: evidence.jpg\nFile Size: 245 kB\nMIME Type: image/jpeg\nImage Width: 1920\nImage Height: 1080\nCamera Model: iPhone 15 Pro\nGPS Latitude: 37.7749 N\nGPS Longitude: 122.4194 W\nComment: CTF{metadata_reveals_all}\nArtist: John Doe', 'strings evidence.jpg': '...JFIF...Exif...iPhone 15 Pro...\nCTF{metadata_reveals_all}\n...Adobe Photoshop...', 'help': 'Commands: file-info , exiftool , strings , hexdump ' } } ], intermediate: [ { name: 'Network Capture Analysis', icon: '\u{1F4E1}', points: 175, description: 'Analyze a network packet capture to find leaked credentials.

Type pcap-open capture.pcap to start.', flag: 'CTF{packet_sniffing_detected}', hints: [ 'Look at HTTP traffic for unencrypted data', 'Filter for POST requests', 'pcap-filter http.method==POST' ], terminal: { 'pcap-open capture.pcap': 'Loaded capture.pcap\n Total packets: 1,247\n HTTP: 89 | HTTPS: 412 | DNS: 156 | TCP: 590', 'pcap-filter http': 'HTTP Packets (89):\n #12 GET /index.html 200\n #45 GET /style.css 200\n #78 POST /login 302\n #91 GET /dashboard 200', 'pcap-filter http.method==POST': 'POST Requests:\n #78 POST /login HTTP/1.1\n Host: vulnerable-app.com\n Body: username=admin&password=CTF{packet_sniffing_detected}\n\n\u{1F6A9} Flag found in plain-text HTTP traffic!', 'help': 'Commands: pcap-open , pcap-filter , pcap-stats' } } ], expert: [] }, reverse: { beginner: [], intermediate: [ { name: 'Binary Strings', icon: '\u{1F504}', points: 125, description: 'Reverse engineer a binary to find the hardcoded flag.

Type file crackme to begin.', flag: 'CTF{strings_reveal_secrets}', hints: [ 'The simplest reverse engineering: run strings on the binary', 'strings crackme | grep CTF', 'Not all flags are obfuscated!' ], terminal: { 'file crackme': 'crackme: ELF 64-bit LSB executable, x86-64\n Compiler: GCC 12.2.0\n Stripped: No\n Size: 16,384 bytes', 'strings crackme': '/lib64/ld-linux-x86-64.so.2\nlibc.so.6\nprintf\nstrcmp\n__libc_start_main\nEnter password:\nCTF{strings_reveal_secrets}\nCorrect!\nWrong password!', 'strings crackme | grep CTF': 'CTF{strings_reveal_secrets}\n\u{1F6A9} Flag found!', 'help': 'Commands: file , strings , objdump ' } } ], expert: [ { name: 'XOR Obfuscation', icon: '\u2295', points: 275, description: 'The flag is XOR-encrypted in memory. Find the key and decode it.

Encrypted (hex): 06 21 09 38 7b 6f 72 5f 69 73 5f 72 65 76 65 72 73 69 62 6c 65 7d
Key byte: 0x45', flag: 'CTF{xor_is_reversible}', hints: [ 'XOR is its own inverse: A XOR K XOR K = A', 'Try XOR-ing the first byte (0x06) with key (0x45)', 'xor-decrypt 45 0621093878' ], terminal: { 'xor-info': 'XOR Cipher:\n Encrypted: 06 21 09 38 7b 6f 72 5f 69 73 5f 72 65 76 65 72 73 69 62 6c 65 7d\n Key: 0x45 (single byte)', 'xor-decrypt 45 0621093878': 'Decrypting with key 0x45:\n 0x06 XOR 0x45 = 0x43 -> C\n 0x21 XOR 0x45 = 0x54 -> T\n 0x09 XOR 0x45 = 0x46 -> F\n ...\n\nDecrypted: CTF{xor_is_reversible}\n\u{1F6A9} Flag found!', 'help': 'Commands: xor-info, xor-decrypt , xor-bruteforce ' } } ] }, binary: { beginner: [], intermediate: [ { name: 'Buffer Overflow Basics', icon: '\u{1F4BE}', points: 200, description: "Overflow the buffer to overwrite the return address and reach the win() function.

Type analyze vuln.c to see the vulnerable code.", flag: 'CTF{buffer_overflow_101}', hints: [ 'The buffer is 64 bytes. What happens if you input more?', 'You need to overwrite the saved return pointer', 'run AAAAAA...72 As plus the address bytes' ], terminal: { 'analyze vuln.c': 'void win() {\n printf("Flag: CTF{buffer_overflow_101}");\n}\n\nvoid vuln() {\n char buffer[64];\n gets(buffer); // DANGEROUS: no bounds checking!\n}\n\n// win() is at address 0xdeadbeef', 'checksec vuln': 'RELRO: Partial RELRO\nStack Canary: No\nNX: Disabled\nPIE: Disabled\nArch: x86-64', 'run AAAA': 'Input: AAAA\nProgram exited normally.', 'run overflow': 'Segmentation fault!\nReturn address overwritten!\nYou crashed the program! Now direct execution to win() at 0xdeadbeef.', 'run exploit': 'Buffer overflow detected!\nReturn address overwritten to: 0xdeadbeef -> win()\n\n\u{1F6A9} Flag: CTF{buffer_overflow_101}', 'help': 'Commands: analyze , checksec , run , run exploit' } } ], expert: [ { name: 'Format String Attack', icon: '\u{1F4CB}', points: 300, description: "Exploit a format string vulnerability to read the flag from memory.

Type analyze fmt_vuln.c to see the code.", flag: 'CTF{format_string_pwned}', hints: [ 'printf(user_input) is dangerous - why?', 'Use %x or %s to read from the stack', 'Try: run %x.%x.%x.%x.%x.%x' ], terminal: { 'analyze fmt_vuln.c': 'char flag[] = "CTF{format_string_pwned}";\n\nvoid vuln(char *input) {\n printf(input); // Format string vulnerability!\n // Should be: printf("%s", input);\n}', 'run hello': 'Output: hello', 'run %x.%x.%x.%x': 'Output: deadbeef.cafebabe.41414141.7b465443\n\nStack values leaked! The hex values contain the flag.', 'run %s%s%s%s': 'Reading stack strings...\n\nCTF{format_string_pwned}\n\n\u{1F6A9} Flag found by reading memory via format string!', 'help': 'Commands: analyze , run , memory-map, stack-dump' } } ] } }; /* ---------- Ethics Modal ---------- */ function agreeToEthics() { document.getElementById('ethicsModal').style.display = 'none'; sessionStorage.setItem('ctf_ethics_agreed', 'true'); } function declineEthics() { window.location.href = '/divine/'; } (function initEthicsModal() { var cbs = document.querySelectorAll('#ethicsModal input[type=checkbox]'); var btn = document.getElementById('agreeEthicsBtn'); if (!btn || !cbs.length) return; cbs.forEach(function(cb) { cb.addEventListener('change', function() { var all = Array.from(cbs).every(function(c) { return c.checked; }); btn.disabled = !all; btn.style.opacity = all ? '1' : '0.5'; }); }); if (!sessionStorage.getItem('ctf_ethics_agreed')) { document.getElementById('ethicsModal').style.display = 'flex'; } })(); /* ---------- Onboarding & Tutorial ---------- */ function startTutorial() { var m = document.getElementById('onboardingModal'); if (m) m.style.display = 'none'; sessionStorage.setItem('ctf_onboarded', 'true'); var steps = [ { text: 'Step 1: Select difficulty level to match your skill', sel: '.difficulty-selector' }, { text: 'Step 2: Pick a challenge category', sel: '.categories-panel' }, { text: 'Step 3: Read the challenge and use the terminal', sel: '.challenge-workspace' }, { text: 'Step 4: Submit flags to earn points!', sel: '.flag-submission' } ]; var overlay = document.getElementById('tutorialOverlay'); var idx = 0; function showStep() { if (idx >= steps.length) { overlay.style.display = 'none'; overlay.innerHTML = ''; selectCategory('web'); return; } var s = steps[idx]; overlay.style.display = 'block'; overlay.innerHTML = '
' + '
' + s.text + '
' + '
'; var el = document.querySelector(s.sel); if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }); } window.nextTutorialStep = function() { idx++; showStep(); }; showStep(); } function skipOnboarding() { var m = document.getElementById('onboardingModal'); if (m) m.style.display = 'none'; sessionStorage.setItem('ctf_onboarded', 'true'); selectCategory('web'); } /* ---------- Difficulty ---------- */ function setDifficulty(level) { currentDifficulty = level; document.querySelectorAll('.difficulty-card').forEach(function(c) { c.classList.toggle('active', c.getAttribute('data-level') === level); }); var rev = document.getElementById('reverseCategory'); var bin = document.getElementById('binaryCategory'); if (level === 'expert') { if (rev) rev.classList.remove('hidden'); if (bin) bin.classList.remove('hidden'); } else if (level === 'intermediate') { if (rev) rev.classList.remove('hidden'); if (bin) bin.classList.add('hidden'); } else { if (rev) rev.classList.add('hidden'); if (bin) bin.classList.add('hidden'); } loadChallenge(); } /* ---------- Category ---------- */ function selectCategory(cat) { currentCategory = cat; document.querySelectorAll('.category-item').forEach(function(c) { c.classList.toggle('active', c.getAttribute('data-category') === cat); }); loadChallenge(); } /* ---------- Load Challenge ---------- */ function loadChallenge() { var catData = challenges[currentCategory]; if (!catData) return; var pool = catData[currentDifficulty] || []; if (!pool.length) { if (currentDifficulty === 'expert') pool = catData['intermediate'] || []; if (!pool.length) pool = catData['beginner'] || []; } if (!pool.length) { document.getElementById('challengeName').textContent = 'No Challenges Available'; document.getElementById('challengeIcon').textContent = '\u{1F512}'; document.getElementById('challengePoints').textContent = '-- pts'; document.getElementById('challengeDescription').innerHTML = 'No challenges available for this category at the selected difficulty. Try a different difficulty level!'; currentChallenge = null; return; } var ch = pool.find(function(c) { return !solvedChallenges.has(c.flag); }) || pool[0]; currentChallenge = ch; document.getElementById('challengeName').textContent = ch.name; document.getElementById('challengeIcon').textContent = ch.icon; document.getElementById('challengePoints').textContent = ch.points + ' pts'; document.getElementById('challengeDescription').innerHTML = ch.description; var hc = document.getElementById('hintContent'); if (hc) hc.innerHTML = ''; ['hint1Btn','hint2Btn','hint3Btn'].forEach(function(id) { var b = document.getElementById(id); if (b) { b.disabled = false; b.style.opacity = '1'; } }); var h3 = document.getElementById('hint3Btn'); if (h3) h3.classList.toggle('hidden', currentDifficulty === 'beginner'); var tb = document.getElementById('terminalBody'); if (tb) { var outputs = tb.querySelectorAll('.terminal-output'); for (var i = outputs.length - 1; i >= 2; i--) outputs[i].remove(); } var fi = document.getElementById('flagInput'); if (fi) fi.value = ''; var pt = document.getElementById('proxyTool'); if (pt) pt.classList.toggle('hidden', currentDifficulty !== 'expert'); if (solvedChallenges.has(ch.flag)) { document.getElementById('challengeName').textContent = ch.name + ' (Solved)'; } } /* ---------- Terminal ---------- */ (function initTerminal() { document.addEventListener('keydown', function(e) { var input = document.getElementById('terminalInput'); if (!input || document.activeElement !== input) return; if (e.key !== 'Enter') return; var cmd = input.value.trim(); if (!cmd) return; input.value = ''; var tb = document.getElementById('terminalBody'); var prompt = tb.querySelector('.terminal-prompt'); var cmdLine = document.createElement('div'); cmdLine.className = 'terminal-output'; cmdLine.style.color = '#00ff88'; cmdLine.textContent = 'ctf@practice:~$ ' + cmd; tb.insertBefore(cmdLine, prompt); var response = 'Command not found: ' + cmd.split(' ')[0] + '. Type "help" for available commands.'; if (currentChallenge && currentChallenge.terminal) { if (currentChallenge.terminal[cmd]) { response = currentChallenge.terminal[cmd]; } else { var keys = Object.keys(currentChallenge.terminal); for (var i = 0; i < keys.length; i++) { if (cmd.toLowerCase().startsWith(keys[i].toLowerCase()) || keys[i].toLowerCase().startsWith(cmd.toLowerCase())) { response = currentChallenge.terminal[keys[i]]; break; } } } } if (cmd === 'clear') { var outs = tb.querySelectorAll('.terminal-output'); outs.forEach(function(o) { o.remove(); }); return; } if (cmd === 'whoami') response = 'ctf-player'; if (cmd === 'pwd') response = '/home/ctf-player/challenges'; if (cmd === 'ls') response = 'challenge.txt README.md hints/ tools/'; if (cmd === 'id') response = 'uid=1000(ctf-player) gid=1000(players)'; if (cmd === 'date') response = new Date().toString(); var respLine = document.createElement('div'); respLine.className = 'terminal-output'; respLine.style.whiteSpace = 'pre-wrap'; respLine.textContent = response; tb.insertBefore(respLine, prompt); tb.scrollTop = tb.scrollHeight; if (currentChallenge && response.indexOf(currentChallenge.flag) !== -1 && !solvedChallenges.has(currentChallenge.flag)) { solveCurrentChallenge(); } }); })(); /* ---------- Flag Submission ---------- */ function submitFlag() { var input = document.getElementById('flagInput'); if (!input || !currentChallenge) return; var flag = input.value.trim(); if (!flag) { showNotification('Please enter a flag!', 'warning'); return; } if (solvedChallenges.has(currentChallenge.flag)) { showNotification('Already solved!', 'info'); return; } if (flag === currentChallenge.flag) { solveCurrentChallenge(); input.value = ''; } else { showNotification('Wrong flag! Try again.', 'error'); var btn = document.getElementById('submitBtn'); if (btn) { btn.style.background = '#f44336'; setTimeout(function() { btn.style.background = ''; }, 1000); } } } function solveCurrentChallenge() { if (!currentChallenge || solvedChallenges.has(currentChallenge.flag)) return; solvedChallenges.add(currentChallenge.flag); var pts = currentChallenge.points; var chKey = currentCategory + '_' + currentDifficulty + '_' + currentChallenge.name; if (hintsUsed[chKey]) { if (hintsUsed[chKey] >= 2) pts -= 5; if (hintsUsed[chKey] >= 3) pts -= 10; } if (pts < 10) pts = 10; totalPoints += pts; challengesSolved++; currentStreak++; document.getElementById('totalPoints').textContent = totalPoints; document.getElementById('challengesSolved').textContent = challengesSolved; document.getElementById('currentStreak').textContent = currentStreak; var ranks = ['#--','#9999','#5000','#2500','#1000','#500','#250','#100','#50','#10','#1']; document.getElementById('globalRank').textContent = ranks[Math.min(challengesSolved, ranks.length - 1)]; document.getElementById('challengeName').textContent = currentChallenge.name + ' (Solved)'; showNotification('Flag captured! +' + pts + ' points!', 'success'); } /* ---------- Hints ---------- */ function showHint(n) { if (!currentChallenge || !currentChallenge.hints) return; if (n > currentChallenge.hints.length) return; var chKey = currentCategory + '_' + currentDifficulty + '_' + currentChallenge.name; hintsUsed[chKey] = Math.max(hintsUsed[chKey] || 0, n); var hc = document.getElementById('hintContent'); if (!hc) return; var html = ''; for (var i = 0; i < n; i++) { html += '
' + 'Hint ' + (i + 1) + ': ' + currentChallenge.hints[i] + '
'; } hc.innerHTML = html; var btn = document.getElementById('hint' + n + 'Btn'); if (btn) { btn.disabled = true; btn.style.opacity = '0.5'; } } /* ---------- Tools ---------- */ function useTool(tool) { var tb = document.getElementById('terminalBody'); var prompt = tb ? tb.querySelector('.terminal-prompt') : null; if (!tb || !prompt) return; var output = ''; if (tool === 'encoder') { output = 'Encoder/Decoder Tool\n' + 'Commands: base64-encode , base64-decode , url-encode , hex-encode , hex-decode \n' + 'Type the command in the terminal.'; } else if (tool === 'hasher') { output = 'Hash Cracker Tool\n' + 'Commands: md5 , sha256 , hash-crack , identify-hash \n' + 'Common: admin=21232f29... password=5f4dcc3b...'; } else if (tool === 'scanner') { output = 'Port Scanner Tool\nScanning target: ctf-challenge.local\n\n' + 'PORT STATE SERVICE\n22/tcp open ssh\n80/tcp open http\n443/tcp open https\n8080/tcp open http-proxy\n\n4 open ports found.'; } else if (tool === 'proxy') { output = 'Proxy Tool (Expert)\nCommands: intercept on/off, modify-header , replay , forward'; } var respLine = document.createElement('div'); respLine.className = 'terminal-output'; respLine.style.whiteSpace = 'pre-wrap'; respLine.style.color = '#00bcd4'; respLine.textContent = output; tb.insertBefore(respLine, prompt); tb.scrollTop = tb.scrollHeight; } /* ---------- Notification ---------- */ function showNotification(msg, type) { var existing = document.querySelector('.ctf-notification'); if (existing) existing.remove(); var colors = { success: '#4caf50', error: '#f44336', warning: '#ff9800', info: '#2196f3' }; var n = document.createElement('div'); n.className = 'ctf-notification'; n.style.cssText = 'position:fixed;top:20px;right:20px;padding:15px 25px;border-radius:12px;color:white;font-weight:bold;font-size:16px;z-index:30000;box-shadow:0 4px 15px rgba(0,0,0,0.3);background:' + (colors[type] || colors.info); n.textContent = msg; document.body.appendChild(n); setTimeout(function() { if (n.parentNode) n.remove(); }, 3000); } /* ---------- Init ---------- */ (function initCTF() { setTimeout(function() { if (!sessionStorage.getItem('ctf_onboarded')) { var m = document.getElementById('onboardingModal'); if (m) m.style.display = 'flex'; } else { selectCategory('web'); } }, 500); })(); // ===== Tutorial System ===== var tutorialState = { step: 0, steps: [ { title: '🏴 Welcome to CTF Practice Arena!', text: 'Capture The Flag challenges teach real cybersecurity skills through gamified puzzles. Solve challenges across web, crypto, and forensics categories.' }, { title: '🔍 Challenge Categories', text: 'Web Exploitation: Find web vulnerabilities. Cryptography: Break codes and ciphers. Forensics: Analyze digital evidence. Reverse Engineering: Decode compiled programs.' }, { title: '🏆 Scoring System', text: 'Each challenge has a flag - a hidden string you must find. Submit flags to earn points. Harder challenges give more points!' }, { title: '🚀 Start Hacking!', text: 'Pick a challenge category, read the description, and hunt for the flag. Think like an attacker to find the vulnerability!' } ] }; function startTutorial() { tutorialState.step = 0; showTutorialStep(); } function showTutorialStep() { var overlay = document.getElementById('tutorialOverlay'); var titleEl = document.getElementById('tutorialTitle'); var textEl = document.getElementById('tutorialInstruction') || document.getElementById('tutorialText'); var nextBtn = overlay ? overlay.querySelector('.tutorial-next, .tutorial-btn-primary, #tutorialNextBtn') : null; if (!overlay || !titleEl) return; var step = tutorialState.steps[tutorialState.step]; if (!step) return; titleEl.textContent = step.title; if (textEl) textEl.textContent = step.text; var progress = document.getElementById('tutorialProgress'); if (progress) progress.textContent = (tutorialState.step + 1) + ' / ' + tutorialState.steps.length; if (nextBtn) nextBtn.textContent = (tutorialState.step >= tutorialState.steps.length - 1) ? 'Finish ✓' : 'Next →'; overlay.classList.add('active'); overlay.classList.remove('hidden'); overlay.style.display = 'flex'; } function nextTutorial() { tutorialState.step++; if (tutorialState.step >= tutorialState.steps.length) { skipTutorial(); } else { showTutorialStep(); } } function nextTutorialStep() { nextTutorial(); } function skipTutorial() { var overlay = document.getElementById('tutorialOverlay'); if (overlay) { overlay.classList.remove('active'); overlay.classList.add('hidden'); overlay.style.display = 'none'; } }