James Cao
WannaGame Championship CTF 2025 longtrip Web Writeup

WannaGame Championship CTF 2025 longtrip Web Writeup

Room / Challenge: longtrip (Web) Metadata Author: jameskaois CTF: WannaGame Championship CTF 2025 Challenge: longtrip (web) Target / URL: https://ctf.cnsc.com.vn/games/1/challenges?challenge=24 Points: 947 Solved: 6 Date: 10-12-2025 Goal Enjoying the longtrip and get the flag. My Solution The challenge comes with no source code, visit the home page: Doing some enumeration steps with dirsearch, found /login page, login with admin:1234 as in description, found a XML Parser tool, tried using the template to see how it works: ...

December 16, 2025 · 6 min
WannaGame Championship CTF 2025 CTFguideline Web Writeup

WannaGame Championship CTF 2025 CTFguideline Web Writeup

Room / Challenge: CTFguideline (Web) Metadata Author: jameskaois CTF: WannaGame Championship CTF 2025 Challenge: CTFguideline (web) Target / URL: https://ctf.cnsc.com.vn/games/1/challenges?challenge=23 Points: 967 Solved: 5 Date: 09-12-2025 Goal Leveraging the Race Condition XSS in the home page, submit to the bot to get the flag. My Solution Visit the home page and view the page source we should find the script.js which is the main script for the page: /* ============================================================ Load config ============================================================ */ var config; fetch('config.json') .then(resp => resp.json()) .then(async resp => { config = resp; document.body.style.backgroundColor = config.background; document.body.style.color = config.text_color; await loadContentsList(config); if (location.hash.length > 0) (config.skin = 'Pane'), initPane(config); else { const url = new URL(location.href); if (url.searchParams.get('doc')) (config.skin = 'Modern'), initModern(config); else (config.skin = 'Default'), initDefault(config); } }); if (location.hash.length > 0) { sanitizeHash(); window.onhashchange = () => loadPaneContent(config); } /* ============================================================ Build navigation list ============================================================ */ async function loadContentsList(config) { const nav = document.getElementById('nav'); nav.innerHTML = ''; config.contents.forEach(file => { const name = file.replace('.html', ''); nav.innerHTML += ` <li><a href="#" class="nav-item" data-file="${file}">${name}</a></li> `; }); attachNavHandlers(config); } /* ============================================================ Navigation Handlers ============================================================ */ function attachNavHandlers(config) { document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', e => { e.preventDefault(); const file = item.getAttribute('data-file'); if (config.skin === 'Pane') { location.hash = file; // Pane uses hash } else if (config.skin === 'Default') { loadDefault(file); } else if (config.skin === 'Modern') { const url = new URL(location.href); url.searchParams.set('doc', file); location.href = url.toString(); } }); }); } /* ============================================================ Pane Theme — 3 Panel View ============================================================ */ function initPane(config) { hideAllViewers(); document.body.classList.add('pane'); document.getElementById('viewerLeft').style.display = 'block'; document.getElementById('viewerCenter').style.display = 'block'; document.getElementById('viewerRight').style.display = 'block'; loadPaneContent(config); } function sanitizeHash() { currentHash = location.hash.substring(1); if (currentHash) { var decodedHash = decodeURIComponent(currentHash); var sanitizedHash = decodedHash.replace(/(javascript:|data:|[<>])/gi, ''); if (decodedHash != sanitizedHash) { document.location.hash = encodeURI(sanitizedHash); } } } function loadPaneContent(config) { sanitizeHash(); let file = location.hash.substring(1) || config.default; if (file) { document.getElementById( 'viewerLeft', ).innerHTML = `<h2>Overview</h2><p>You selected: ${encodeURIComponent(file)}</p>`; url = new URL(location.href); if (config) { if (!config.load_remote) { file = 'contents/' + file; } else { if (!file.startsWith('http://') && !file.startsWith('https://')) file = url.origin + url.pathname + '/contents' + file; } } document.getElementById('viewerCenter').contentWindow.location.replace(decodeURI(file)); document.getElementById('viewerRight').innerHTML = `<h2>Extras</h2><p>Copyright.</p>`; } } /* ============================================================ Default Theme ============================================================ */ function initDefault(config) { hideAllViewers(); document.body.classList.add('default'); document.getElementById('viewer').style.display = 'block'; loadDefault(config.default); } async function loadDefault(file) { const text = await fetch('contents/' + file).then(r => r.text()); document.getElementById('viewer').innerHTML = text; } /* ============================================================ Modern Theme ============================================================ */ function initModern(config) { hideAllViewers(); document.body.classList.add('modern'); document.getElementById('viewer').style.display = 'block'; const params = new URLSearchParams(location.search); const doc = params.get('doc') || config.default; loadModern(doc); } async function loadModern(file) { const text = await fetch('contents/' + file).then(r => r.text()); document.getElementById('viewer').innerHTML = `<div class="modern-card">${text}</div>`; } /* ============================================================ Helpers ============================================================ */ function hideAllViewers() { document.querySelectorAll('#viewer, .pane-panel').forEach(el => { el.style.display = 'none'; }); } Also, from this we can find the config.json: ...

December 16, 2025 · 4 min
WannaGame Championship CTF 2025 Trust Web Writeup

WannaGame Championship CTF 2025 Trust Web Writeup

Room / Challenge: Trust (Web) Metadata Author: jameskaois CTF: WannaGame Championship CTF 2025 Challenge: Trust (web) Target / URL: https://ctf.cnsc.com.vn/games/1/challenges?challenge=20 Points: 500 Solved: 61 Date: 10-12-2025 Goal Bypassing the vulnerability chain with 3 main vulnerabilities to get the flag. My Solution This app is vulnerable with a vulnerability chain: # Vulnerability Purpose 1 CVE-2025-23419 Bypassing the client certificate of hidden service 2 Signature Bypass Bypass the signature check to upload exploit plugin 3 Zip Slip Achieve RCE to read the flag CVE-2025-23419 SSL Session Reuse This vulnerability can be easily noticed by the comment in the nginx.conf: ...

December 16, 2025 · 5 min