--set up referances local servStore = game:GetService("ServerStorage") local modules = servStore:WaitForChild("modules") local services = modules:WaitForChild("services") local utilityModules = modules:WaitForChild("utility") local repStore = game:GetService("ReplicatedStorage") local exploitHandler = require(modules.exploitHandler) local vfx = workspace:WaitForChild("map"):WaitForChild("vfx") local sparkEffect = require(modules:WaitForChild("effects"):WaitForChild("sparkEffect")) --require needed modules local ipUtil = require(utilityModules.ipUtil) local networkStorage = require(modules:WaitForChild("storage"):WaitForChild("networkStorage")) local serverHandler = require(modules:WaitForChild("serverHandler")) local packetHandler = require(modules.packetHandler) local sqlService = require(services.sqlService) local hashUtil = require(utilityModules.hashUtil) local mfaHandler = require(modules.mfaHandler) --local sshService = require(services:WaitForChild("sshService")) local networksStorage = {} --store created networks --load cost of actions local actionCost = { ping = 1, scan_port = 2, -- per port scanned ssh_login = 3, http_request = 5, -- base request FILE_TRANSFER_PER_KB = 0.02, -- cost per KB iot_heartbeat = 0.5, -- periodic background devices ddos_packet = 1.5, -- single malicious packet baseline } local networkHandler = {} networkHandler.__index = networkHandler --table search utility function local function contains(tbl: table, val) if type(tbl) ~= "table" then error("First argument must be a table", 2) end for _, v in pairs(tbl) do if v == val then return true end end return false end --define vulns for each service --set up new network instance for player function networkHandler.new(entity, config: {openPorts: number?, isInternal: boolean?, gatewayNetworks: {string?}, maxLoad: number?, loadDecay: number?}?) config = config or {} local self = setmetatable({}, networkHandler) local name = if typeof(entity) == "Instance" and entity:IsA("Player") then entity.Name else entity -- Use player name or direct string for servers self.hostname = name self.publicIp = ipUtil.GeneratePublic() self.openPorts = config.openPorts or {} self.iotDevices = {} --network bandwith stuff self.maxLoad = config.maxLoad or 100 self.load = 0 self.load = math.clamp(self.load, 0, self.maxLoad) self.loadThread = task.spawn(function() while task.wait(0.5) do --calculate load local load = (self.load/self.maxLoad)*100 --check if load is over 80% if load >= 70 then print("load over 70, applying fx") if not sparkEffect.SparksActive(self.hostname) then task.spawn(function() sparkEffect.MakeSparks(self.hostname) while task.wait(0.1) do if self.load <= 40 then sparkEffect.Destroy(self.hostname) end end end) end end if self.load > 0 then self.load -= config.loadDecay or 1 end end end) self.connectedServer = { name = nil, port = nil, service = nil } self.pivotedFrom = nil --tracks gateway network used for pivot packetHandler.ClearPackets(name) -- clean up packets for new network if typeof(entity) == "Instance" and entity:IsA("Player") then --player specifc properties of the netinstance object self.discoveredNetworks = {} self.hackingNetwork = nil self.instanceType = "player" self.wordlists = {} else --server specific properties self.instanceType = "server" self.isInternal = config.isInternal or false self.gatewayNetworks = config.gatewayNetworks or nil end networksStorage[name] = self -- store all network instances globally return self end function networkHandler:ApplyLoad(action: string, cost: string?) -- normally map to action but you can also provide load cost if not action then return "please provide action" end local cost = cost or actionCost[action] or nil if not cost then return "action not found for load" end self.load += cost self.load = math.clamp(self.load, 0, self.maxLoad) -- make sure it stays between 0 and 100 end function networkHandler.SetInternalNetwork(parentNetworks: {string}, targetNetwork) if not parentNetworks or not targetNetwork then return end --make sure parent networks are strings for key, network in parentNetworks do if type(network) ~= "string" then return error "parent networks table must only contain strings" end end if not targetNetwork.isInternal then targetNetwork.isInternal = true --get gateway network(s) names local gatewayNames = {} for key, networkName in pairs(parentNetworks) do local parentNetwork = networkHandler.GetNetworkInfo(networkName) assert(parentNetwork, "unable to match parent network to key") table.insert(gatewayNames, networkName) end if #gatewayNames == 0 then return error "unable to find hostname of parent network" end targetNetwork.gatewayNetworks = gatewayNames return ("set network '%s' as internal with gateways: %s"):format(targetNetwork.hostname, table.concat(gatewayNames, ", ")) end end --wordlist stuff function networkHandler:AddWordlist(wordlistName, wordlist: {string}?) if not wordlistName then return error "provide wordlist name" end local wordlists = self.wordlists if type(wordlist) ~= "table" then return error("wordlist must be a table") end if #wordlist == 0 then return error("wordlist must have at least one word") end self.wordlists[wordlistName] = wordlist end function networkHandler:FetchWordlist(wordlistName) if not wordlistName then return error "provide wordlist name" end local wordlist = self.wordlists wordlist = wordlist[wordlistName] return wordlist or error "wordlists not found" end function networkHandler.OpenPort(networkName, port) if not port then return error("unable to open ports, no ports provided") end local netInst = networksStorage[networkName] assert(netInst, "network instance not found, unable to open port") netInst.openPorts = netInst.openPorts or {} if table.find(netInst.openPorts, port) then error("attempted to open port that is already open") end table.insert(netInst.openPorts, port) return ("successfully opened port on network '%s'"):format(networkName) end function networkHandler.GetNetworkInfo(name: string?) if not name then return networksStorage end local network = networksStorage[name] if not network then error(("network '%s' not found"):format(name)) end return network end function networkHandler:DiscoverNetwork(name: string) local targetNetwork = self.GetNetworkInfo(name) if not targetNetwork then return error(("network '%s' does not exist"):format(targetNetwork)) end if targetNetwork.isInternal then local connectedNetwork = self.connectedServer if connectedNetwork == nil then return error(("cannot discover internal network '%s' without being connected to a network"):format(name)) end local gatewayNetwork = contains(targetNetwork.gatewayNetworks, connectedNetwork.name) -- if this returns true then assume the gateway is valid if gatewayNetwork == false then return error(("access to internal network '%s' denied. current connection '%s' is not in allowed list of gateway networks to access this network"):format(name, connectedNetwork.name)) end gatewayNetwork = self.GetNetworkInfo(name) --directly pass name because it is in the gateway table for the internal network self.discoveredNetworks[name] = gatewayNetwork return ("discovered network: '%s'"):format(name) end --see if network exists if targetNetwork then self.discoveredNetworks[name] = targetNetwork --disallow connection to a network by default return ("discovered network: '%s'"):format(name) else return error(("network '%s' not found, unable to discover"):format(name)) end end --get open ports from network function networkHandler:ScanNetwork(name) local openPorts = {} local targetNetwork = self.GetNetworkInfo(name) if not targetNetwork then return error("target network not found") end local services = targetNetwork.services if not services then error "services not found in target network" end --dynamically get open ports based on the open ports in every service for servName, servData in pairs(services) do if servData.port then table.insert(openPorts, servData.port) end end --see if network is in the discovered networks if self.discoveredNetworks[name] then self.discoveredNetworks[name].openPorts = openPorts return openPorts else return error(("unable to scan, network '%s' not found or discovered"):format(name)) end end function networkHandler:ConnectToNetwork(name, port) local targetNetwork = self.GetNetworkInfo(name) if not targetNetwork then return error("target network not found") end -- make sure target network exists --if the network your attempting to connect to is internal, make sure your connecting thru a valid gateway network if targetNetwork.isInternal then local connectedServer = self.connectedServer.name if not connectedServer or not contains(targetNetwork.gatewayNetworks, connectedServer) then error(("cannot connet to internal network '%s'. you must connect to it through a valid gateway network"):format(name)) end end --throw error if you dont provide a port if not port then error(("unable to connect to network: '%s' no port provided"):format(name)) end --see if you have the network discovered if not self.discoveredNetworks[name] then error(("unable to connect to %s, network not discovered or does not exist"):format(name)) end --see if you have discovered any open ports: if not self.discoveredNetworks[name].openPorts then error(("unable to connect to network %s, no ports found. please scan for open ports"):format(name)) end --see if the port your attempting to connect on is open on the requested network if not table.find(self.discoveredNetworks[name].openPorts, port) then print(self.discoveredNetworks[name].openPorts) error(("port '%s' on network: '%s' not open"):format(port,name)) end local ssh = targetNetwork.services and targetNetwork.services.ssh local http = targetNetwork.services and targetNetwork.services.http if ssh and port == (ssh.port or 22) then --handle ssh connection if ssh.allowConnection then self.connectedServer = { name = targetNetwork.hostname, port = port, service = "ssh", isInternal = targetNetwork.isInternal or false } return ("connected to network '%s' on port '%s' with 'ssh'"):format(name, port) else --dont allow to connect if allow connection isnt enabled on the servers ssh service return error(("connection not allowd on network '%s'. in order to connect you must first get the correct password"):format(name)) end elseif http and port == (http.port or 80) then if http.allowConnection then self.connectedServer = { name = targetNetwork.hostname, port = port, service = "http", isInternal = targetNetwork.isInternal or false } return ("connected to network '%s' on port '%s' with 'http'"):format(name,port) else error(("HTTP connection not allowed on network %s"):format(name)) end else return error ("unsupported port/service") end end function networkHandler:DisconnectFromNetwork() self.connectedServer = nil return ("disconnected from network") end function networkHandler:getServerFiles() if self.connectedServer then local serverInstance = serverHandler.GetServerInfo(self.connectedServer.name) assert(serverInstance, "server instance not found") local files = serverInstance:GetFiles() assert(files, "files not found on server") return files else return error("connect to a network to its see files!") end end function networkHandler:AllowConnectionToNetwork(name) if self.discoveredNetworks[name] then else return error(("network: '%s' not found or discovered"):format(name)) end end function networkHandler.ping(clientNetwork, network: string) if not network then return error "network not provided" end if not networkHandler.GetNetworkInfo(network) then return error "ping failed, network not found" end local targetNetwork = networkHandler.GetNetworkInfo(network) packetHandler.LogPacket({clientNetwork, network}, { sourceIp = clientNetwork.publicIp, destIp = targetNetwork.publicIp, port = 0, protocol = "ICMP", method = "PING", }) packetHandler.LogPacket({clientNetwork, network}, { sourceIp = targetNetwork.publicIp, destIp = clientNetwork.publicIp, port = 0, protocol = "ICMP", method = "PING_REPLY", }) print(targetNetwork:ApplyLoad("ping", 20)) return "ping success" end --handle services function networkHandler:InitServices(config: { ssh: {enabled: boolean?, port: number?, password: string?, allowConnection: boolean?, authType: "password" | "mfa"?}?, http: {enabled: boolean?, port: number, allowConnection: boolean?, authRequired: boolean?, password: string?, authType: "password" | "mfa"?}? }) config = config or {} self.services = {} --ssh------------------------------------ if config.ssh and config.ssh.enabled ~= false then --database setup local hashedPswrd = hashUtil.sha256(config.ssh.password or "passwrd123") local sqlTable: sqlService.tableDef = { schema = {"username", "password"}, types = {"string", "string"}, data = { {"_sshPass", hashedPswrd}, {"_mfaCode", tostring(math.random(100000, 999999))} } } sqlService.createTable(self.hostname, sqlTable) self.services.ssh = { enabled = true, port = config.ssh.port or 22, password = config.ssh.password or "passwrd123", -- no longer used allowConnection = config.ssh.allowConnection or false, loginAttempts = 0, authType = config.ssh.authType or "password", discoveredEndpoints = {} } if self.services.ssh.authType == "mfa" then print("loop output:",mfaHandler.StartLoop(self.hostname, 10, "ssh")) end exploitHandler.AssignVulns(self, "ssh") end --http--------------------------------- if config.http and config.http.enabled ~= false then --database setup local hashedPswrd = hashUtil.sha256(config.http.password or "passwrd123") local sqlTable: sqlService.tableDef = { schema = {"username", "password"}, types = {"string", "string"}, data = { {"default", hashedPswrd}, {"_mfaCode", tostring(math.random(100000, 999999))} } } sqlService.createTable("http", sqlTable) self.services.http = { enabled = true, port = config.http.port or 80, allowConnection = config.http.allowConnection or false, authRequired = config.http.authRequired or false, authType = config.http.authType or "password", password = config.password or "passwrd123", loginAttempts = 0 } if self.services.http.authType == "mfa" then print("loop output:",mfaHandler.StartLoop(self.hostname, 2, "http")) end exploitHandler.AssignVulns(self, "http") end end --helper login func local function passwordCheck(tableName, username, password) local sqlString = string.format("SELECT password, username FROM %s WHERE username = '%s' AND password = '%s'", tableName, username, password) return sqlService.Execute(sqlString) end function networkHandler:AttemptLogin(service: string, password: string, username: string?) local svc = self.services and self.services[service] if not services or not svc.enabled then error(("service '%s' not enabled"):format(service)) end --svc is short for service if service == "ssh" then local ssh = self.services.ssh if not ssh or not ssh.enabled then return error("ssh not enabled") end if ssh.allowConnection then return "already authenticated on network" end --if your alr authed js return if ssh.authType == "mfa" then local correctPass = mfaHandler.GetCode(self.hostname, service) print("correct code:", correctPass, "entered pass:", password) password = password:match("^%s*(.-)%s*$") --remove whitespace and make the 2 things the same datatype correctPass = tostring(correctPass):match("^%s*(.-)%s*$") if password ~= correctPass then return error("incorrect password") else print("login success") ssh.allowConnection = true --if you got the password then allow player to connect to network via ssh return (("login successful, you are now able to connect to network: '%s' on service '%s'"):format(self.hostname, service)) end else --hash password to check w database password = hashUtil.sha256(password) --check database for service password local msg, output = passwordCheck(self.hostname, "_sshPass", password) if output then print("login success", output) ssh.allowConnection = true --if you got the password then allow player to connect to network via ssh return (("login successful, you are now able to connect to network: '%s' on service '%s'"):format(self.hostname, service)) else ssh.loginAttempts += 1 local trigger = exploitHandler.CheckTrigger(self, "ssh", "login_attempt") if not trigger then if ssh.loginAttempts > 3 then return error("too many login attempts") end return error("incorrect password") end end end elseif service == "http" then local http = self.services.http if not http or not http.enabled then return error("http not enabled") end if http.allowConnection then return "already authenticated on network" end --if your alr authed js return if password ~= http.password then http.loginAttempts += 1 return error("incorrect password") end http.allowConnection = true return (("login successful, you are now able to connect to network: '%s' on service '%s'"):format(self.hostname, service)) end error(("service '%s' not supported"):format(service)) end --function networkHandler:D return networkHandler