/** @param {import(".").NS } ns */ export async function main(ns) { // ns.disableLog('ALL'); /** * @constant * @default */ const EXPLOITS = [ 'BruteSSH.exe', 'FTPCrack.exe', 'relaySMTP.exe', 'HTTPWorm.exe', 'SQLInject.exe' ]; /** @function maxPortsToHack * Calculate how many ports you're able to open * @returns {number} number of ports you're able to open */ function maxPortsToHack() { let maxPorts = 0; EXPLOITS.forEach(exploit => { if (ns.fileExists(exploit)) ++maxPorts; }); // ns.tprint(`Max ports for hacking ${maxPorts}`); return maxPorts; } /** @function analyzeServer * Analyze server requirements * @param {string} server * @returns {object} object containing server information */ function analyzeServer(server) { let requiredHacking = ns.getServerRequiredHackingLevel(server); let requiredPorts = ns.getServerNumPortsRequired(server); let currentHacking = ns.getHackingLevel(); return { "rootAccess": ns.hasRootAccess(server), "requiredHacking": requiredHacking, "requiredPorts": requiredPorts, "nukeAvailable": (currentHacking >= requiredHacking && maxPortsToHack() >= requiredPorts) }; } /** @function runHack * Recursively scan, try to nuke and hack servers in the network * @param {string} server server to nuke and hack * @returns {number} exit code; if negative error, if positive hack script PID, if 0 already running */ function runHack(server) { let script = 'simple-hack.js'; let serverStatus = analyzeServer(server); ns.tprint(`${server}: ${JSON.stringify(serverStatus)}`); if (!serverStatus.rootAccess) { if (serverStatus.nukeAvailable) { ns.tprint(`Nuking ${server}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`); for (let i = 0; i < maxPortsToHack(); ++i) { switch (EXPLOITS[i]) { case 'BruteSSH.exe': ns.brutessh(server); break; case 'FTPCrack.exe': ns.ftpcrack(server); break; case 'relaySMTP.exe': ns.relaysmtp(server); break; case 'HTTPWorm.exe': ns.httpworm(server); break; case 'SQLInject.exe': ns.sqlinject(server); break; } } ns.nuke(server); } } serverStatus = analyzeServer(server); if (serverStatus.rootAccess) { if (!ns.fileExists(script, 'home')) { ns.tprint(`Script '${script}' doesn't exist!`); return -3; } ns.scp(script, server, 'home'); let serverMaxRam = ns.getServerMaxRam(server); let serverUsedRam = ns.getServerUsedRam(server); let serverFreeRam = serverMaxRam - serverUsedRam; let scriptRam = ns.getScriptRam(script, server); let maxThreads = Math.floor(serverFreeRam / scriptRam); let a = ns.scriptRunning(script, server); if (!a) { if (maxThreads == 0) { ns.tprint(`Not enough ram to run '${script}' on '${server}', ${scriptRam}/${serverFreeRam}!`); return -4; } let execExitCode = ns.exec(script, server, maxThreads, server); ns.tprint(`post exec ${execExitCode}`); if (!execExitCode) { ns.tprint(`Exec error running script '${script} on '${server}!`); return -5; } else { return execExitCode; } } else { ns.tprint(`Hack already running on ${server}`); return 0; } } return -6; } let nukedServers = ['home', 'CSEC']; /** * Recursively scan, try to nuke and hack servers in the network * @async * @param {string} server server to scan */ async function scanServer(server, maxDepth = Number.MAX_SAFE_INTEGER, depth = 1) { if (depth <= maxDepth) { let availableServers = ns.scan(server); // hack servers in current scan for (let i = 0; i < availableServers.length; ++i) { ns.tprint(`${availableServers[i]} ${nukedServers.indexOf(availableServers[i])} ${nukedServers}`); if (nukedServers.indexOf(availableServers[i]) == -1) { nukedServers.push(availableServers[i]); await scanServer(availableServers[i], maxDepth, depth + 1); let hackExitCode = runHack(availableServers[i]); if (hackExitCode == 0) { ns.tprint(`Hack already running on ${availableServers[i]}`); } if (hackExitCode == -6) { ns.tprint(`No root access to ${availableServers[i]}!`); } else { if (hackExitCode < 0) { ns.tprint(`Hack exec ERROR on '${availableServers[i]}': ${hackExitCode}!`); } else { ns.tprint(`Hack started on '${availableServers[i]}'`); } } } } } await ns.sleep(10); } let runDepth = ns.args.length ? ns.args[0] : 1; ns.tprint(`Running scan depth: ${runDepth}`); await scanServer('home', ); // let serversToNuke = {}; // let availableServers = { "home": "home" }; // for (let depth = 0; depth < 2; ++depth) { // for (const key in availableServers) { // if (Object.hasOwnProperty.call(availableServers, key)) { // const element = availableServers[key]; // ns.scan(element).forEach(elem => { // availableServers[elem] = elem; // }); // } // } // } // ns.tprint(availableServers); // for (const element in availableServers) { // ns.tprint(`start loop ${element}`); // if (element != 'home' && element != 'CSEC') { // let hackExitCode = runHack(element); // if (hackExitCode == 0) { // ns.tprint(`Hack already running on ${element}`); // } if (hackExitCode == -6) { // ns.tprint(`No root access to ${element}`); // } else { // if (hackExitCode < 0) { // ns.tprint(`Hack exec ERROR on '${element}': ${hackExitCode}!`); // } else { // ns.tprint(`Hack started on '${element}'`); // } // } // } // } await ns.sleep(10); }