const WebSocket = require("ws"); const { authenticator } = require("otplib"); const { execSync, spawn } = require("child_process"); const CONFIG = { email: "c-azaw@regoproducts.com", password: "Fuckyou4suhail", totpSecret: "RZQTQSKDWKHZ6ZYR", devtoolsPort: 9222, vpnTestIp: "10.35.33.230" }; let ws; let msgId = 1; function log(msg) { console.log("[" + new Date().toLocaleTimeString() + "] " + msg); } function run(cmd) { try { execSync(cmd, { stdio: "ignore", timeout: 10000 }); } catch (e) {} } function runOutput(cmd) { try { return execSync(cmd, { encoding: "utf8", timeout: 10000 }); } catch (e) { return ""; } } async function getPages() { const res = await fetch("http://localhost:" + CONFIG.devtoolsPort + "/json"); return res.json(); } function send(method, params = {}) { return new Promise((resolve, reject) => { const id = msgId++; const timeout = setTimeout(() => reject(new Error("Timeout: " + method)), 15000); const handler = (data) => { const msg = JSON.parse(data); if (msg.id === id) { clearTimeout(timeout); ws.off("message", handler); resolve(msg.result); } }; ws.on("message", handler); ws.send(JSON.stringify({ id, method, params })); }); } async function waitForSelector(selector, timeout = 30000) { const start = Date.now(); while (Date.now() - start < timeout) { try { const result = await send("Runtime.evaluate", { expression: "document.querySelector('" + selector + "') !== null", returnByValue: true }); if (result.result.value === true) return true; } catch (e) {} await sleep(500); } return false; } async function typeText(selector, text) { await send("Runtime.evaluate", { expression: "var el = document.querySelector('" + selector + "'); el.focus(); el.value = '';" }); await sleep(100); for (const char of text) { await send("Input.dispatchKeyEvent", { type: "char", text: char }); await sleep(30); } } async function click(selector) { await send("Runtime.evaluate", { expression: "document.querySelector('" + selector + "').click()" }); } async function clickSubmit() { const methods = [ "document.querySelector('#submitButton') && document.querySelector('#submitButton').click()", "typeof Login !== 'undefined' && Login.submitLoginRequest && Login.submitLoginRequest()", "document.querySelector('input[type=\"submit\"]') && document.querySelector('input[type=\"submit\"]').click()", "document.querySelector('button[type=\"submit\"]') && document.querySelector('button[type=\"submit\"]').click()", "document.querySelector('#idSIButton9') && document.querySelector('#idSIButton9').click()" ]; for (const expr of methods) { try { await send("Runtime.evaluate", { expression: expr }); } catch (e) {} } } async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); } async function waitForDevtools(maxWait = 120000) { const start = Date.now(); while (Date.now() - start < maxWait) { try { const pages = await getPages(); const page = pages.find(p => p.type === "page"); if (page) return page; } catch (e) {} log("Waiting for WebView..."); await sleep(2000); } return null; } // VPN adapter check skipped - IP range is unpredictable // We rely solely on connectivity test to target IP // Test connectivity via ping (check for actual reply, not TTL expired) function testVpnConnectivity(ip) { try { const output = execSync(`ping -n 1 -w 3000 ${ip}`, { encoding: "utf8", timeout: 5000 }); // Must have "Reply from " - not "TTL expired" or "Request timed out" return output.includes(`Reply from ${ip}`); } catch (e) { return false; } } // Verify VPN is connected with retries (connectivity test only) async function verifyVpnConnection(maxRetries = 10, retryDelay = 5000) { log("--- VPN VERIFICATION ---"); for (let i = 1; i <= maxRetries; i++) { log(`Attempt ${i}/${maxRetries}: Pinging ${CONFIG.vpnTestIp}...`); const connected = testVpnConnectivity(CONFIG.vpnTestIp); if (connected) { log("VPN connectivity confirmed!"); return true; } log("Not reachable yet, waiting..."); if (i < maxRetries) { await sleep(retryDelay); } } log("VPN verification failed after " + maxRetries + " attempts"); return false; } async function main() { console.log(""); console.log("========================================"); console.log(" CISCO VPN AUTO-LOGIN"); console.log("========================================"); console.log(""); // Sync time first (TOTP requires accurate time) log("Syncing system time..."); run("sc config w32time start= auto"); run("net start w32time"); run("w32tm /config /manualpeerlist:pool.ntp.org /syncfromflags:manual /update"); run("w32tm /resync /force"); await sleep(2000); // Kill everything log("Killing Cisco processes..."); run("taskkill /F /IM csc_ui.exe"); run("taskkill /F /IM vpnui.exe"); run("taskkill /F /IM vpnagent.exe"); run('net stop csc_vpnagent'); await sleep(2000); // Start agent log("Starting Cisco agent..."); run('net start csc_vpnagent'); await sleep(3000); // Start UI log("Starting Cisco UI..."); process.env.WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS = "--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --remote-allow-origins=*"; spawn("C:\\Program Files (x86)\\Cisco\\Cisco Secure Client\\UI\\csc_ui.exe", [], { detached: true, stdio: "ignore" }).unref(); await sleep(5000); // Wait for WebView const page = await waitForDevtools(); if (!page) { log("ERROR: WebView not found - rebooting..."); run("shutdown /r /t 1"); process.exit(1); } log("WebView: " + page.title); ws = new WebSocket(page.webSocketDebuggerUrl); await new Promise((resolve, reject) => { ws.on("open", resolve); ws.on("error", reject); }); await send("DOM.enable"); await send("Runtime.enable"); await send("Input.enable"); log("Connected to DevTools"); const url = page.url || ""; const isADFS = url.includes("adfs"); log("Login type: " + (isADFS ? "ADFS" : "Microsoft")); if (isADFS) { log("--- ADFS LOGIN ---"); if (!await waitForSelector("#passwordInput", 15000)) { log("Password field not found"); process.exit(1); } log("Entering password..."); await typeText("#passwordInput", CONFIG.password); await sleep(500); log("Clicking Sign In..."); await clickSubmit(); await sleep(3000); } else { log("--- EMAIL ---"); if (await waitForSelector('input[type="email"]', 5000)) { log("Entering email..."); await typeText('input[type="email"]', CONFIG.email); await sleep(500); log("Clicking Next..."); await clickSubmit(); await sleep(3000); } log("--- PASSWORD ---"); if (!await waitForSelector('input[type="password"]', 15000)) { log("Password field not found"); process.exit(1); } log("Entering password..."); await typeText('input[type="password"]', CONFIG.password); await sleep(500); log("Clicking Sign In..."); await clickSubmit(); await sleep(3000); } // TOTP log("--- TOTP ---"); if (await waitForSelector('input[name="otc"]', 15000)) { await sleep(500); const totp = authenticator.generate(CONFIG.totpSecret); log("TOTP: " + totp); await typeText('input[name="otc"]', totp); await sleep(500); log("Submitting..."); await clickSubmit(); await sleep(3000); } else { log("No TOTP field"); } // Stay signed in log("--- STAY SIGNED IN ---"); if (await waitForSelector("#idBtn_Back", 5000)) { log("Clicking No..."); await click("#idBtn_Back"); } await sleep(2000); ws.close(); // Verify VPN connection const vpnConnected = await verifyVpnConnection(); if (!vpnConnected) { log("ERROR: VPN connection could not be verified"); process.exit(1); } console.log(""); console.log("========================================"); console.log(" VPN CONNECTED!"); console.log(" Entering watchdog mode..."); console.log("========================================"); console.log(""); // Enter watchdog mode - monitor and reconnect if needed await watchdogLoop(); } async function watchdogLoop() { const checkInterval = 2 * 60 * 1000; // 2 minutes let consecutiveFailures = 0; let checkCount = 0; log("Watchdog: Monitoring every 2 minutes..."); while (true) { await sleep(checkInterval); checkCount++; // Force garbage collection every 10 checks (~20 min) if (checkCount % 10 === 0 && global.gc) { global.gc(); } // Log memory every 30 checks (~1 hour) if (checkCount % 30 === 0) { const mem = Math.round(process.memoryUsage().heapUsed / 1024 / 1024); log(`Watchdog: Memory ${mem}MB, checks ${checkCount}`); } const connected = testVpnConnectivity(CONFIG.vpnTestIp); if (connected) { if (consecutiveFailures > 0) { log("Watchdog: Connection restored"); } consecutiveFailures = 0; } else { consecutiveFailures++; log(`Watchdog: Connection FAILED (${consecutiveFailures})`); if (consecutiveFailures >= 2) { log("Watchdog: Reconnecting..."); await reconnectVpn(); consecutiveFailures = 0; } } } } async function reconnectVpn() { // Sync time first (TOTP requires accurate time) log("Syncing system time..."); run("sc config w32time start= auto"); run("net start w32time"); run("w32tm /resync /force"); await sleep(1000); // Kill and restart VPN log("Killing Cisco processes..."); run("taskkill /F /IM csc_ui.exe"); run("taskkill /F /IM vpnui.exe"); run("taskkill /F /IM vpnagent.exe"); run('net stop "Cisco Secure Client Agent"'); await sleep(2000); log("Starting Cisco agent..."); run('net start "Cisco Secure Client Agent"'); await sleep(3000); log("Starting Cisco UI..."); spawn("C:\\Program Files (x86)\\Cisco\\Cisco Secure Client\\UI\\csc_ui.exe", [], { detached: true, stdio: "ignore" }).unref(); await sleep(5000); const page = await waitForDevtools(); if (!page) { log("ERROR: WebView not found - rebooting..."); run("shutdown /r /t 1"); return false; } ws = new WebSocket(page.webSocketDebuggerUrl); await new Promise((resolve, reject) => { ws.on("open", resolve); ws.on("error", reject); }); await send("DOM.enable"); await send("Runtime.enable"); await send("Input.enable"); const url = page.url || ""; const isADFS = url.includes("adfs"); if (isADFS) { if (await waitForSelector("#passwordInput", 15000)) { await typeText("#passwordInput", CONFIG.password); await sleep(500); await clickSubmit(); await sleep(3000); } } else { if (await waitForSelector('input[type="email"]', 5000)) { await typeText('input[type="email"]', CONFIG.email); await sleep(500); await clickSubmit(); await sleep(3000); } if (await waitForSelector('input[type="password"]', 15000)) { await typeText('input[type="password"]', CONFIG.password); await sleep(500); await clickSubmit(); await sleep(3000); } } // TOTP if (await waitForSelector('input[name="otc"]', 15000)) { await sleep(500); const totp = authenticator.generate(CONFIG.totpSecret); log("TOTP: " + totp); await typeText('input[name="otc"]', totp); await sleep(500); await clickSubmit(); await sleep(3000); } // Stay signed in - No if (await waitForSelector("#idBtn_Back", 5000)) { await click("#idBtn_Back"); } await sleep(2000); ws.close(); // Verify reconnection const verified = await verifyVpnConnection(); if (verified) { log("Reconnection successful!"); return true; } log("Reconnection failed"); return false; } main().catch(err => { log("ERROR: " + err.message); process.exit(1); });