initialization
This commit is contained in:
parent
98f7347199
commit
a1cf215014
28
README.md
28
README.md
@ -1,2 +1,30 @@
|
|||||||
# nmap-scripts
|
# nmap-scripts
|
||||||
|
|
||||||
|
## http-info.nse
|
||||||
|
|
||||||
|
Return status, title and favicon URL of a webpage
|
||||||
|
|
||||||
|
@args http-get.path Path to get. Default /.
|
||||||
|
@usage nmap -phttp,https --script http-info.nse --script-args http-info.path=/ <host>
|
||||||
|
@output
|
||||||
|
80/tcp open http
|
||||||
|
| http-info:
|
||||||
|
| status-line: HTTP/1.1 200 OK\x0D
|
||||||
|
|
|
||||||
|
| title: Go ahead and ScanMe!
|
||||||
|
| favicon: http://scanme.nmap.org:80/shared/images/tiny-eyeicon.png
|
||||||
|
|_ status: 200
|
||||||
|
|
||||||
|
## smb-shares-size.nse
|
||||||
|
|
||||||
|
Return free and total size in octets of each SMB shares
|
||||||
|
|
||||||
|
@args See the documentation for the smbauth library.
|
||||||
|
@usage nmap -p137-139,445 --script smb-shares-size.nse --script-args-file smb-shares-size.ini <host>
|
||||||
|
@output
|
||||||
|
Host script results:
|
||||||
|
| smb-shares-size:
|
||||||
|
| data:
|
||||||
|
| FreeSize: 38495883264
|
||||||
|
| TotalSize: 500961574912
|
||||||
|
|_ IPC$: NT_STATUS_ACCESS_DENIED
|
||||||
|
114
http-info.nse
Normal file
114
http-info.nse
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
local shortport = require "shortport"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Return status, title and favicon URL of a webpage
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @args http-get.path Path to get. Default /.
|
||||||
|
--
|
||||||
|
-- @usage nmap -phttp,https --script http-info.nse --script-args http-info.path=/ <host>
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- 80/tcp open http
|
||||||
|
-- | http-info:
|
||||||
|
-- | status-line: HTTP/1.1 200 OK\x0D
|
||||||
|
-- |
|
||||||
|
-- | title: Go ahead and ScanMe!
|
||||||
|
-- | favicon: http://scanme.nmap.org:80/shared/images/tiny-eyeicon.png
|
||||||
|
-- |_ status: 200
|
||||||
|
---
|
||||||
|
|
||||||
|
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
|
||||||
|
stdnse.debug1("Try to download %s", uri)
|
||||||
|
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
|
2
smb-shares-size.ini
Normal file
2
smb-shares-size.ini
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
smbuser =
|
||||||
|
smbpassword =
|
206
smb-shares-size.nse
Normal file
206
smb-shares-size.nse
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
local stdnse = require "stdnse"
|
||||||
|
local smb = require "smb"
|
||||||
|
local smb2 = require "smb2"
|
||||||
|
local msrpc = require "msrpc"
|
||||||
|
local bin = require "bin"
|
||||||
|
local shortport = require "shortport"
|
||||||
|
|
||||||
|
description = [[
|
||||||
|
Return free and total size in octets of each SMB shares
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- @args See the documentation for the smbauth library.
|
||||||
|
--
|
||||||
|
-- @usage nmap -p137-139,445 --script smb-shares-size.nse --script-args-file smb-shares-size.ini <host>
|
||||||
|
--
|
||||||
|
-- @output
|
||||||
|
-- Host script results:
|
||||||
|
-- | smb-shares-size:
|
||||||
|
-- | data:
|
||||||
|
-- | FreeSize: 38495883264
|
||||||
|
-- | TotalSize: 500961574912
|
||||||
|
-- |_ IPC$: NT_STATUS_ACCESS_DENIED
|
||||||
|
---
|
||||||
|
|
||||||
|
categories = {"discovery", "intrusive"}
|
||||||
|
author = "Adrien Malingrey"
|
||||||
|
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
|
||||||
|
|
||||||
|
portrule = shortport.service({"microsoft-ds", "netbios-ssn", "smb"})
|
||||||
|
|
||||||
|
|
||||||
|
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]
|
||||||
|
if (share ~= nil) then
|
||||||
|
local status, result = get_share_info(host, share)
|
||||||
|
if (status) then
|
||||||
|
response[share] = result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
TRANS2_QUERY_FS_INFORMATION = 0x0003
|
||||||
|
SMB_QUERY_FS_SIZE_INFO = 0x0103
|
||||||
|
---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, share)
|
||||||
|
local status, smbstate, err
|
||||||
|
local hostaddress = (host.name ~= '' and host.name) or host.ip
|
||||||
|
local path = "\\\\" .. hostaddress .. "\\" .. share
|
||||||
|
|
||||||
|
status, smbstate = smb.start(host)
|
||||||
|
status, err = smb.negotiate_protocol(smbstate, {})
|
||||||
|
status, err = smb.start_session(smbstate, {})
|
||||||
|
status, err = smb.tree_connect(smbstate, path, {})
|
||||||
|
|
||||||
|
stdnse.debug1("SMB: Getting information for share: %s", path)
|
||||||
|
|
||||||
|
local status, err = send_transaction2(smbstate, TRANS2_QUERY_FS_INFORMATION, bin.pack("<S", SMB_QUERY_FS_SIZE_INFO))
|
||||||
|
if ( not(status) ) then
|
||||||
|
status, err = smb.stop(smbstate)
|
||||||
|
return false, "Failed to send data to server: send_transaction2"
|
||||||
|
end
|
||||||
|
|
||||||
|
local status, response = receive_transaction2(smbstate)
|
||||||
|
if ( not(status) ) then
|
||||||
|
status, err = smb.stop(smbstate)
|
||||||
|
return false, response
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos, totalAllocationUnits, totalFreeAllocationUnits, sectorsPerAllocationUnit, bytesPerSector = bin.unpack("<LLII", response.data)
|
||||||
|
|
||||||
|
status, err = smb.stop(smbstate)
|
||||||
|
|
||||||
|
return true, {
|
||||||
|
TotalSize = totalAllocationUnits * sectorsPerAllocationUnit * bytesPerSector,
|
||||||
|
FreeSize = totalFreeAllocationUnits * sectorsPerAllocationUnit * bytesPerSector
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Taken from smb lib
|
||||||
|
|
||||||
|
function send_transaction2(smbstate, sub_command, function_parameters, function_data, overrides)
|
||||||
|
overrides = overrides or {}
|
||||||
|
local header1, header2, header3, header4, command, status, flags, flags2, pid_high, signature, unused, pid, mid
|
||||||
|
local header, parameters, data
|
||||||
|
local parameter_offset = 0
|
||||||
|
local parameter_size = 0
|
||||||
|
local data_offset = 0
|
||||||
|
local data_size = 0
|
||||||
|
local total_word_count, total_data_count, reserved1, parameter_count, parameter_displacement, data_count, data_displacement, setup_count, reserved2
|
||||||
|
local response = {}
|
||||||
|
|
||||||
|
-- Header is 0x20 bytes long (not counting NetBIOS header).
|
||||||
|
header = smb.smb_encode_header(smbstate, smb.command_codes['SMB_COM_TRANSACTION2'], overrides) -- 0x32 = SMB_COM_TRANSACTION2
|
||||||
|
|
||||||
|
if(function_parameters) then
|
||||||
|
parameter_offset = 0x44
|
||||||
|
parameter_size = #function_parameters
|
||||||
|
data_offset = #function_parameters + 33 + 32
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parameters are 0x20 bytes long.
|
||||||
|
parameters = bin.pack("<SSSSCCSISSSSSCCS",
|
||||||
|
parameter_size, -- Total parameter count.
|
||||||
|
data_size, -- Total data count.
|
||||||
|
0x000a, -- Max parameter count.
|
||||||
|
0x3984, -- Max data count.
|
||||||
|
0x00, -- Max setup count.
|
||||||
|
0x00, -- Reserved.
|
||||||
|
0x0000, -- Flags (0x0000 = 2-way transaction, don't disconnect TIDs).
|
||||||
|
0x00001388, -- Timeout (0x00000000 = return immediately).
|
||||||
|
0x0000, -- Reserved.
|
||||||
|
parameter_size, -- Parameter bytes.
|
||||||
|
parameter_offset, -- Parameter offset.
|
||||||
|
data_size, -- Data bytes.
|
||||||
|
data_offset, -- Data offset.
|
||||||
|
0x01, -- Setup Count
|
||||||
|
0x00, -- Reserved
|
||||||
|
sub_command -- Sub command
|
||||||
|
)
|
||||||
|
|
||||||
|
local data = "\0\0\0" .. (function_parameters or '')
|
||||||
|
.. (function_data or '')
|
||||||
|
|
||||||
|
-- Send the transaction request
|
||||||
|
stdnse.debug2("SMB: Sending SMB_COM_TRANSACTION2")
|
||||||
|
local result, err = smb.smb_send(smbstate, header, parameters, data, overrides)
|
||||||
|
if(result == false) then
|
||||||
|
stdnse.debug1("SMB: Try SMBv2 connexion")
|
||||||
|
local result, err = smb2.smb2_send(smbstate, header, parameters, data, overrides)
|
||||||
|
if(result == false) then
|
||||||
|
return false, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function receive_transaction2(smbstate)
|
||||||
|
|
||||||
|
-- Read the result
|
||||||
|
local status, header, parameters, data = smb.smb_read(smbstate)
|
||||||
|
if(status ~= true) then
|
||||||
|
stdnse.debug1("SMB: Try SMBv2 connexion")
|
||||||
|
local status, header, parameters, data = smb2.smb2_read(smbstate)
|
||||||
|
if(status ~= true) then
|
||||||
|
return false, header
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if it worked
|
||||||
|
local pos, header1, header2, header3, header4, command, status, flags, flags2, pid_high, signature, unused, tid, pid, uid, mid = bin.unpack("<CCCCCICSSlSSSSS", header)
|
||||||
|
if(header1 == nil or mid == nil) then
|
||||||
|
return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [29]"
|
||||||
|
end
|
||||||
|
if(status ~= 0) then
|
||||||
|
if(smb.status_names[status] == nil) then
|
||||||
|
return false, string.format("Unknown SMB error: 0x%08x\n", status)
|
||||||
|
else
|
||||||
|
return false, smb.status_names[status]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parse the parameters
|
||||||
|
local pos, total_word_count, total_data_count, reserved1, parameter_count, parameter_offset, parameter_displacement, data_count, data_offset, data_displacement, setup_count, reserved2 = bin.unpack("<SSSSSSSSSCC", parameters)
|
||||||
|
if(total_word_count == nil or reserved2 == nil) then
|
||||||
|
return false, "SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [30]"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Convert the parameter/data offsets into something more useful (the offset into the data section)
|
||||||
|
-- - 0x20 for the header, - 0x01 for the length.
|
||||||
|
parameter_offset = parameter_offset - 0x20 - 0x01 - #parameters - 0x02;
|
||||||
|
-- - 0x20 for the header, - 0x01 for parameter length, the parameter length, and - 0x02 for the data length.
|
||||||
|
data_offset = data_offset - 0x20 - 0x01 - #parameters - 0x02;
|
||||||
|
|
||||||
|
-- I'm not sure I entirely understand why the '+1' is here, but I think it has to do with the string starting at '1' and not '0'.
|
||||||
|
local function_parameters = string.sub(data, parameter_offset + 1, parameter_offset + parameter_count)
|
||||||
|
local function_data = string.sub(data, data_offset + 1, data_offset + data_count)
|
||||||
|
|
||||||
|
local response = {}
|
||||||
|
response['parameters'] = function_parameters
|
||||||
|
response['data'] = function_data
|
||||||
|
|
||||||
|
return true, response
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user