1local nmap = require "nmap" 2local shortport = require "shortport" 3local stdnse = require "stdnse" 4local string = require "string" 5local stringaux = require "stringaux" 6local table = require "table" 7 8description = [[ 9Opens a connection to a NetBus server and extracts information about 10the host and the NetBus service itself. 11 12The extracted host information includes a list of running 13applications, and the hosts sound volume settings. 14 15The extracted service information includes its access control list 16(acl), server information, and setup. The acl is a list of IP 17addresses permitted to access the service. Server information 18contains details about the server installation path, restart 19persistence, user account that the server is running on, and the 20amount of connected NetBus clients. The setup information contains 21configuration details, such as the services TCP port number, traffic 22logging setting, password, an email address for receiving login 23notifications, an email address used for sending the notifications, 24and an smtp-server used for notification delivery. 25]] 26 27--- 28-- @usage 29-- nmap -p 12345 --script netbus-info <target> --script-args netbus-info.password=<password> 30-- 31-- @output 32-- 12345/tcp open netbus 33-- | netbus-info: 34-- | ACL 35-- | 127.0.0.1 36-- | APPLICATIONS 37-- | PuTTY Configuration 38-- | INFO 39-- | Program Path: Z:\home\joeuser\Desktop\Patch.exe 40-- | Restart persistent: Yes 41-- | Login ID: joeuser 42-- | Clients connected to this host: 1 43-- | SETUP 44-- | TCP-port: 12345 45-- | Log traffic: 1 46-- | Password: password123 47-- | Notify to: admin@example.com 48-- | Notify from: spoofed@example.org 49-- | SMTP-server: smtp.example.net 50-- | VOLUME 51-- | Wave: 0 52-- | Synth: 0 53-- |_ Cd: 0 54-- @xmloutput 55-- <table key="ACL"> 56-- <elem>127.0.0.1</elem> 57-- </table> 58-- <table key="APPLICATIONS"> 59-- <elem>PuTTY Configuration</elem> 60-- </table> 61-- <table key="INFO"> 62-- <elem key="Program Path">Z:\home\joeuser\Desktop\Patch.exe</elem> 63-- <elem key="Restart persistent">Yes</elem> 64-- <elem key="Login ID">joeuser</elem> 65-- <elem key="Clients connected to this host">1</elem> 66-- </table> 67-- <table key="SETUP"> 68-- <elem key="TCP-port">12345</elem> 69-- <elem key="Log traffic">1</elem> 70-- <elem key="Password">password123</elem> 71-- <elem key="Notify to">admin@example.com</elem> 72-- <elem key="Notify from">spoofed@example.org</elem> 73-- <elem key="SMTP-server">smtp.example.net</elem> 74-- </table> 75-- <table key="VOLUME"> 76-- <elem key="Wave">0</elem> 77-- <elem key="Synth">0</elem> 78-- <elem key="Cd">0</elem> 79-- </table> 80-- 81-- @args netbus-info.password The password used for authentication 82 83author = "Toni Ruottu" 84license = "Same as Nmap--See https://nmap.org/book/man-legal.html" 85categories = {"default", "discovery", "safe"} 86 87 88dependencies = {"netbus-version", "netbus-brute"} 89 90portrule = shortport.port_or_service (12345, "netbus", {"tcp"}) 91 92local function format_acl(acl) 93 if acl == nil then 94 return nil 95 end 96 local payload = string.sub(acl, 9) --skip header 97 local fields = stringaux.strsplit("|", payload) 98 table.remove(fields, (# fields)) 99 return fields 100end 101 102local function format_apps(apps) 103 if apps == nil then 104 return nil 105 end 106 local payload = string.sub(apps, 10) --skip header 107 local fields = stringaux.strsplit("|", payload) 108 table.remove(fields, (# fields)) 109 return fields 110end 111 112local function format_info(info) 113 if info == nil then 114 return nil 115 end 116 local payload = string.sub(info, 6) --skip header 117 local fields = stringaux.strsplit("|", payload) 118 return fields 119end 120 121local function format_setup(setup) 122 if setup == nil then 123 return nil 124 end 125 local fields = stringaux.strsplit(";", setup) 126 if # fields < 7 then 127 return nil 128 end 129 local formatted = stdnse.output_table() 130 formatted["TCP-port"] = fields[2] 131 formatted["Log traffic"] = fields[3] 132 formatted["Password"] = fields[4] 133 formatted["Notify to"] = fields[5] 134 formatted["Notify from"] = fields[6] 135 formatted["SMTP-server"] = fields[7] 136 return formatted 137end 138 139local function format_volume(volume) 140 if volume == nil then 141 return nil 142 end 143 local fields = stringaux.strsplit(";", volume) 144 if # fields < 4 then 145 return nil 146 end 147 local formatted = stdnse.output_table() 148 formatted["Wave"] = fields[2] 149 formatted["Synth"] = fields[3] 150 formatted["Cd"] = fields[4] 151 return formatted 152end 153 154action = function( host, port ) 155 local password = nmap.registry.args[SCRIPT_NAME .. ".password"] 156 if not password and nmap.registry.netbuspasswords then 157 local key = string.format("%s:%d", host.ip, port.number) 158 password = nmap.registry.netbuspasswords[key] 159 end 160 if not password then 161 password = "" 162 end 163 local socket = nmap.new_socket() 164 socket:set_timeout(5000) 165 local status, err = socket:connect(host, port) 166 local buffer, err = stdnse.make_buffer(socket, "\r") 167 local _ = buffer() 168 if not (_ and _:match("^NetBus")) then 169 stdnse.debug1("Not NetBus") 170 return nil 171 end 172 socket:send(string.format("Password;1;%s\r", password)) 173 local gotin = buffer() 174 if gotin == "Access;0" then 175 return 176 end 177 178 socket:send("GetInfo\r") 179 local info = buffer() 180 socket:send("GetSetup\r") 181 local setup = buffer() 182 socket:send("GetACL\r") 183 local acl = buffer() 184 socket:send("GetApps\r") 185 local apps = buffer() 186 socket:send("GetVolume\r") 187 local volume = buffer() 188 socket:close() 189 190 local response = stdnse.output_table() 191 response["ACL"] = format_acl(acl) 192 response["APPLICATIONS"] = format_apps(apps) 193 response["INFO"] = format_info(info) 194 response["SETUP"] = format_setup(setup) 195 response["VOLUME"] = format_volume(volume) 196 197 return response 198end 199 200 201