227 lines
8.7 KiB
JavaScript
227 lines
8.7 KiB
JavaScript
/** @param {import(".").NS } ns */
|
|
import { EXCLUDE_SERVERS } from "./constants.js";
|
|
|
|
export async function main(ns) {
|
|
ns.disableLog('ALL');
|
|
|
|
async function writeLog(type, obj) {
|
|
let timeNow = new Date();
|
|
let year = timeNow.getFullYear().toString().substring(2);
|
|
let month = (timeNow.getMonth() < 9 ? '0' : '') + (timeNow.getMonth() + 1);
|
|
let day = (timeNow.getDate() < 10 ? '0' : '') + timeNow.getDate();
|
|
let hour = (timeNow.getHours() < 10 ? '0' : '') + timeNow.getHours();
|
|
let minute = (timeNow.getMinutes() < 10 ? '0' : '') + timeNow.getMinutes();
|
|
let second = (timeNow.getSeconds() < 10 ? '0' : '') + timeNow.getSeconds();
|
|
let timestamp = `${year}${month}${day}_${hour}${minute}${second}`;
|
|
await ns.tryWritePort(2, `t${timestamp}_${type} = ${obj};\n`);
|
|
|
|
if (['ERROR', 'TERMINAL'].indexOf(type) != -1) ns.tprint(`${timestamp} ${type} = ${obj}`);
|
|
}
|
|
|
|
/**
|
|
* @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.tryWritePort(2, `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 {Promise<number>} exit code; if negative error, if positive hack script PID, if 0 already running
|
|
*/
|
|
async function runHack(server) {
|
|
let script = 'simple-hack.js';
|
|
|
|
let serverStatus = analyzeServer(server);
|
|
await writeLog('ANALYZE', `{server: "${server}", status: ${JSON.stringify(serverStatus)}}`);
|
|
|
|
if (!serverStatus.rootAccess) {
|
|
if (serverStatus.nukeAvailable) {
|
|
await writeLog('NUKE', `"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')) {
|
|
await writeLog('ERROR', `"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) {
|
|
// await writeLog('ERROR', `"Not enough ram to run '${script}' on '${server}', ${scriptRam}/${serverFreeRam}!"`);
|
|
return -4;
|
|
}
|
|
|
|
let execExitCode = ns.exec(script, server, maxThreads, server);
|
|
|
|
if (!execExitCode) {
|
|
// await writeLog('ERROR', `"Exec error running script '${script} on '${server}!"`);
|
|
return -5;
|
|
}
|
|
else {
|
|
return execExitCode;
|
|
}
|
|
} else {
|
|
// await writeLog('ERROR', `"Hack already running on ${server}"`);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -6;
|
|
}
|
|
|
|
// let nukedServers = ['home', 'CSEC', 'avmnite-02h'];
|
|
// /**
|
|
// * 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) {
|
|
// await writeLog('SCAN', `{server: "${availableServers[i]}", index: ${nukedServers.indexOf(availableServers[i])}, available: ["${availableServers.toString().replaceAll(',','","')}"]}`);
|
|
// if (nukedServers.indexOf(availableServers[i]) == -1) {
|
|
// nukedServers.push(availableServers[i]);
|
|
// await scanServer(availableServers[i], maxDepth, depth + 1);
|
|
// let hackExitCode = await runHack(availableServers[i]);
|
|
|
|
// if (hackExitCode == 0) {
|
|
// await writeLog('HACK', `"Hack already running on ${availableServers[i]}"`);
|
|
// } if (hackExitCode == -6) {
|
|
// await writeLog('HACK', `"No root access to ${availableServers[i]}!"`);
|
|
// } else {
|
|
// if (hackExitCode < 0) {
|
|
// await writeLog('ERROR', `"Hack exec ERROR on '${availableServers[i]}': ${hackExitCode}!"`);
|
|
// } else {
|
|
// await writeLog('HACK', `"Hack started on '${availableServers[i]}'"`);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// await ns.sleep(10);
|
|
// }
|
|
|
|
|
|
/**
|
|
* Recursively kill simple-hack.js running on servers in the network
|
|
* @async
|
|
* @param {string} currentServer server to scan
|
|
*/
|
|
async function scanServer(currentServer, previousServer = currentServer) {
|
|
let availableServers = ns.scan(currentServer);
|
|
|
|
for (let i = 0; i < availableServers.length; ++i) {
|
|
let nextServer = availableServers[i];
|
|
|
|
if (nextServer != currentServer && nextServer != previousServer) {
|
|
if (EXCLUDE_SERVERS.indexOf(nextServer) == -1) {
|
|
let hackExitCode = await runHack(nextServer);
|
|
|
|
if (hackExitCode == 0) {
|
|
await writeLog('HACK', `"Hack already running on ${nextServer}"`);
|
|
} else if (hackExitCode == -6) {
|
|
await writeLog('HACK', `"No root access to ${nextServer}!"`);
|
|
} else if (hackExitCode == -4) {
|
|
await writeLog('HACK', `"Not enough RAM to run script on ${nextServer}!"`);
|
|
} else {
|
|
if (hackExitCode < 0) {
|
|
await writeLog('ERROR', `"Hack exec ERROR on '${nextServer}': ${hackExitCode}!"`);
|
|
} else {
|
|
await writeLog('HACK', `"Hack started on '${nextServer}'"`);
|
|
}
|
|
}
|
|
}
|
|
await scanServer(nextServer, currentServer);
|
|
}
|
|
}
|
|
await ns.sleep(10);
|
|
}
|
|
|
|
ns.write('nuke-log.js', '', 'w');
|
|
if (!ns.scriptRunning('simple-hack.js', 'n00dles')) ns.write('hack-log.js', '', 'w');
|
|
ns.tprint(`TERMINAL = "Running scan"`);
|
|
|
|
while (true) {
|
|
await writeLog('INFO', `"Running scan"`);
|
|
await scanServer('home');
|
|
await ns.sleep(60000);
|
|
}
|
|
}
|