[Add] Implement nmap network scanner.

This commit is contained in:
Ritchie Cunningham 2025-09-27 00:13:56 +01:00
parent 5f648440c5
commit fde6879720
6 changed files with 55 additions and 1 deletions

View File

@ -0,0 +1,9 @@
-- /bin/nmap - Network exploration tool and security/port scanner.
local target_ip = arg[1]
if not target_ip then
return "nmap: requires a target host to be specified"
end
-- TODO: Add args such as -sV for version detection etc.
return { action = "scan", target = target_ip }

View File

@ -3,6 +3,8 @@
#include <SDL3/SDL.h>
#include <GL/glew.h>
#include <SDL3/SDL_events.h>
#include <sstream>
#include <algorithm>
#include "terminal.h"
#include "client_network.h"
@ -43,7 +45,21 @@ void Terminal::update(void) {
_prompt = server_msg.substr(last_newline+1);
std::string output = server_msg.substr(0, last_newline);
if(!output.empty()) {
_history.push_back(output);
/* Split multiline output and push each line to history. */
std::stringstream ss(output);
std::string line;
while(std::getline(ss, line, '\n')) {
/* Replace tabs. */
std::string line_with_spaces;
for(char ch : line) {
if(ch == '\t') {
line_with_spaces += " ";
} else {
line_with_spaces += ch;
}
}
_history.push_back(line_with_spaces);
}
}
} else {
/*

View File

@ -192,6 +192,24 @@ std::string CommandProcessor::_handle_vfs_action(sol::table action) {
return "Connection closed.";
} else if(action_name == "close_terminal") {
return "__CLOSE_CONNECTION__";
} else if(action_name == "scan") {
std::string target_ip = action["target"].get_or<std::string>("");
if(!_world_vfs.count(target_ip)) {
return std::string("nmap: Could not resolve host: ") + target_ip;
}
vfs_node* target_root = _world_vfs[target_ip];
if(target_root->services.empty()) {
return std::string("No open ports for ") + target_ip;
}
std::stringstream ss;
ss<<"Host: "<<target_ip<<"\n";
ss<<"PORT\tSTATE\tSERVICE\n";
for(auto const& [port, service_name] : target_root->services) {
ss<<port<<"/tcp\t"<<"open\t"<<service_name<<"\n";
}
return ss.str();
}
return "Error: Unknown VFS action '" + action_name + "'";
}

View File

@ -24,6 +24,9 @@ struct vfs_node {
/* Directories. */
vfs_child_map children;
vfs_node* parent;
/* Services (for root nodes). */
std::map<int, std::string> services;
};
std::string get_full_path(vfs_node* node);

View File

@ -77,6 +77,9 @@ vfs_node* VFSManager::create_vfs(const std::string& system_type) {
/* Link to the shared directories from the template. */
root->children["bin"] = copy_vfs_node(_vfs_root->children["bin"], root);
/* Default services. All machines have SSH currently. */
root->services[22] = "SSH v1.2";
if(system_type == "npc") {
vfs_node* npc_file = new_node("npc_system.txt", FILE_NODE, root);
npc_file->content = "This guy sucks nuts!";

View File

@ -16,6 +16,11 @@ NetworkManager::NetworkManager(void) : _acceptor(_io_context) {
/* VFS setup. */
_world_vfs["8.8.8.8"] = _vfs_manager.create_vfs("npc");
_world_vfs["10.0.2.15"] = _vfs_manager.create_vfs("npc");
/* Specific npc services. */
_world_vfs["8.8.8.8"]->services[80] = "HTTPD v2.4";
_world_vfs["10.0.2.15"]->services[21] = "FTPd v3.0";
fprintf(stderr, "Created world with %zu networks\n", _world_vfs.size());
}