new nse script

This commit is contained in:
2023-05-09 15:15:27 +02:00
parent c3082c9442
commit 5378e16e24
3 changed files with 140 additions and 1 deletions

109
nse/http-info.nse Normal file
View File

@ -0,0 +1,109 @@
local shortport = require "shortport"
description = [[
Get and return a page info
]]
---
-- @args http-get.path Path to get. Default /.
--
-- @usage nmap -p80 --script http-info.nse --script-args http-info.path=/ <target>
--
-- @output
-- status: 200
-- status-line: HTTP/1.1 200 OK\x0D
---
categories = {"discovery", "intrusive"}
author = "Adrien Malingrey"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
portrule = shortport.service({"http", "https", "ssl"})
local http = require "http"
local stdnse = require "stdnse"
action = function(host, port)
local scheme = ""
local hostaddress = (host.name ~= '' and host.name) or host.ip
local path = "/"
local uri
local favicon_relative_uri = "/favicon.ico"
local favicon
if (port.service == "ssl") then
scheme = "https"
else
scheme = port.service
end
if(stdnse.get_script_args('http-get.path')) then
path = stdnse.get_script_args('http-info.path')
end
uri = scheme.."://"..hostaddress..":"..port.number..path
local answer = http.get_url(uri)
local info = {status=answer.status, ["status-line"]=answer["status-line"]}
if (answer and answer.status == 200) then
stdnse.debug1("[SUCCESS] Load page %s", uri)
-- Taken from http-title.nse by Diman Todorov
local title = string.match(answer.body, "<[Tt][Ii][Tt][Ll][Ee][^>]*>([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")
if (title) then
info.title = title
end
stdnse.debug1("[INFO] Try favicon %s", favicon_relative_uri)
favicon_relative_uri = parseIcon(answer.body) or "favicon.ico"
else
stdnse.debug1("[ERROR] Can't load page %s", uri)
end
favicon_absolute_uri = scheme.."://"..hostaddress..":"..port.number..favicon_relative_uri
favicon = http.get_url(favicon_absolute_uri)
if (favicon and favicon.status == 200) then
stdnse.debug1("[SUCCESS] Load favicon %s", favicon_absolute_uri)
info.favicon = favicon_absolute_uri
else
stdnse.debug1("[ERROR] Can't load favicon %s", favicon_absolute_uri)
end
return info
end
--- function taken from http_favicon.nse by Vlatko Kosturjak
function parseIcon( body )
local _, i, j
local rel, href, word
-- Loop through link elements.
i = 0
while i do
_, i = string.find(body, "<%s*[Ll][Ii][Nn][Kk]%s", i + 1)
if not i then
return nil
end
-- Loop through attributes.
j = i
while true do
local name, quote, value
_, j, name, quote, value = string.find(body, "^%s*(%w+)%s*=%s*([\"'])(.-)%2", j + 1)
if not j then
break
end
if string.lower(name) == "rel" then
rel = value
elseif string.lower(name) == "href" then
href = value
end
end
for word in string.gmatch(rel or "", "%S+") do
if string.lower(word) == "icon" then
return href
end
end
end
end

139
nse/smb-shares-du.nse Normal file
View File

@ -0,0 +1,139 @@
local stdnse = require "stdnse"
local smb = require "smb"
local msrpc = require "msrpc"
local msrpctypes = require "msrpctypes"
hostrule = function(host)
return smb.get_port(host) ~= nil
end
action = function(host)
local status, shares, extra
local response = stdnse.output_table()
-- Try and do this the good way, make a MSRPC call to get the shares
stdnse.debug1("SMB: Attempting to log into the system to enumerate shares")
status, shares = msrpc.enum_shares(host)
if(status == false) then
return stdnse.format_output(false, string.format("Couldn't enumerate shares: %s", shares))
end
-- Get more information on each share
for i = 1, #shares, 1 do
local share = shares[i]
stdnse.debug1("SMB: Getting information for share: %s", share)
status, result = get_share_info(host, share)
response[share] = result
end
return response
end
---Attempts to retrieve additional information about a share. Will fail unless we have
-- administrative access.
--
--@param host The host object.
--@return Status (true or false).
--@return A table of information about the share (if status is true) or an an error string (if
-- status is false).
function get_share_info(host, name)
local response = {}
-- Create the SMB session
local status, smbstate = msrpc.start_smb(host, msrpc.SRVSVC_PATH)
if(status == false) then
return false, smbstate
end
-- Bind to SRVSVC service
local status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
if(status == false) then
smb.stop(smbstate)
return false, bind_result
end
-- Call NetShareGetInfo
local status, netsharegetinfo_result = srvsvc_netsharegetinfo(smbstate, host.ip, name, 2)
stdnse.debug2("NetShareGetInfo status:%s result:%s", status, netsharegetinfo_result)
if(status == false) then
if(string.find(netsharegetinfo_result, "NT_STATUS_WERR_ACCESS_DENIED")) then
stdnse.debug2("Calling NetShareGetInfo with information level 1")
status, netsharegetinfo_result = srvsvc_netsharegetinfo(smbstate, host.ip, name, 1)
if status then
smb.stop(smbstate)
return true, netsharegetinfo_result
end
end
smb.stop(smbstate)
return false, netsharegetinfo_result
end
smb.stop(smbstate)
return true, netsharegetinfo_result
end
---Call the MSRPC function <code>netsharegetinfo</code> on the remote system. This function retrieves extra information about a share
-- on the system.
--
--@param smbstate The SMB state table
--@param server The IP or Hostname of the server (seems to be ignored but it's a good idea to have it)
--@return (status, result) If status is false, result is an error message. Otherwise, result is a table of values, the most
-- useful one being 'shares', which is a list of the system's shares.
function srvsvc_netsharegetinfo(smbstate, server, share, level)
stdnse.debug2("Calling NetShareGetInfo(%s, %s, %d)", server, share, level)
--NetGetShareInfo seems to reject FQPN and reads the server value from the request
--If any function called this function using a FQPN, this should take care of it.
local _, _, sharename = string.find(share, "\\\\.*\\(.*)")
if sharename then
share = sharename
end
-- [in] [string,charset(UTF16)] uint16 *server_unc,
local arguments = msrpctypes.marshall_unicode_ptr("\\\\" .. server, true)
-- [in] [string,charset(UTF16)] uint16 share_name[],
.. msrpctypes.marshall_unicode(share, true)
-- [in] uint32 level,
.. msrpctypes.marshall_int32(level)
-- [out,switch_is(level)] srvsvc_NetShareInfo info
-- Do the call
local status, result = msrpc.call_function(smbstate, smb.command_codes.SMB_COM_QUERY_INFORMATION_DISK, arguments)
if(status ~= true) then
return false, result
end
stdnse.debug3("MSRPC: NetShareGetInfo() returned successfully")
-- Make arguments easier to use
arguments = result['arguments']
local pos = 1
-- [in] [string,charset(UTF16)] uint16 *server_unc,
-- [in] [string,charset(UTF16)] uint16 share_name[],
-- [in] uint32 level,
-- [out,switch_is(level)] srvsvc_NetShareInfo info
pos, result['info'] = msrpctypes.unmarshall_srvsvc_NetShareInfo(arguments, pos)
if(pos == nil) then
return false, "unmarshall_srvsvc_NetShareInfo() returned an error"
end
-- The return value
pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos)
if(result['return'] == nil) then
return false, "Read off the end of the packet (srvsvc.netsharegetinfo)"
end
if(result['return'] ~= 0) then
return false, smb.get_status_name(result['return']) .. " (srvsvc.netsharegetinfo)"
end
return true, result
end