1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 14:11:29 +00:00
This commit is contained in:
dmiller
2015-05-31 17:37:51 +00:00
parent 3d4fb07728
commit 00064a1809
19 changed files with 297 additions and 297 deletions

View File

@@ -346,8 +346,8 @@ local TESTS = {
test = function(o) return not next(o) end test = function(o) return not next(o) end
}, },
{'', valid=false}, {'', valid=false},
{'null', valid=false}, -- error {'null', valid=false}, -- error
{'"abc"', valid=false}, -- error {'"abc"', valid=false}, -- error
{'{a":1}', valid=false}, -- error {'{a":1}', valid=false}, -- error
{'{"a" bad :1}', valid=false}, -- error {'{"a" bad :1}', valid=false}, -- error
{ {

View File

@@ -37,7 +37,7 @@ function have_ssl()
-- @return The version intensity. -- @return The version intensity.
-- @usage -- @usage
-- portrule = function(host, port) -- portrule = function(host, port)
-- return ... -- return ...
-- ... -- ...
-- and nmap.version_intensity() >= 7 -- and nmap.version_intensity() >= 7
-- end -- end

View File

@@ -222,7 +222,7 @@ function add_account(host, username, domain, password, password_hash, hash_type,
-- Reset the credentials -- Reset the credentials
next_account(host, 1) next_account(host, 1)
-- io.write("\n\n" .. nsedebug.tostr(host.registry['smbaccounts']) .. "\n\n") -- io.write("\n\n" .. nsedebug.tostr(host.registry['smbaccounts']) .. "\n\n")
end end
---Retrieve the current set of credentials set in the registry. ---Retrieve the current set of credentials set in the registry.

View File

@@ -1834,7 +1834,7 @@ local format_vuln_base = function(vuln_table, showall)
local risk_str = "" local risk_str = ""
if vuln_table.scores and next(vuln_table.scores) then if vuln_table.scores and next(vuln_table.scores) then
output_table.scores = vuln_table.scores output_table.scores = vuln_table.scores
for score_type, score in pairs(vuln_table.scores) do for score_type, score in pairs(vuln_table.scores) do
risk_str = risk_str .. string_format(" %s: %s", score_type, score) risk_str = risk_str .. string_format(" %s: %s", score_type, score)
end end
@@ -1858,10 +1858,10 @@ local format_vuln_base = function(vuln_table, showall)
output_table.dates = vuln_table.dates output_table.dates = vuln_table.dates
if vuln_table.dates.disclosure and if vuln_table.dates.disclosure and
next(vuln_table.dates.disclosure) then next(vuln_table.dates.disclosure) then
output_table.disclosure = string_format("%s-%s-%s", output_table.disclosure = string_format("%s-%s-%s",
vuln_table.dates.disclosure.year, vuln_table.dates.disclosure.year,
vuln_table.dates.disclosure.month, vuln_table.dates.disclosure.month,
vuln_table.dates.disclosure.day) vuln_table.dates.disclosure.day)
insert(out, string_format(" Disclosure date: %s-%s-%s", insert(out, string_format(" Disclosure date: %s-%s-%s",
vuln_table.dates.disclosure.year, vuln_table.dates.disclosure.year,
vuln_table.dates.disclosure.month, vuln_table.dates.disclosure.month,
@@ -1928,7 +1928,7 @@ local format_vuln_base = function(vuln_table, showall)
local ref_str = {} local ref_str = {}
for link in pairs(ref_set) do for link in pairs(ref_set) do
insert(out, string_format(" %s", link)) insert(out, string_format(" %s", link))
table.insert(ref_str, link) table.insert(ref_str, link)
end end
output_table.refs = ref_str output_table.refs = ref_str
end end
@@ -2241,10 +2241,10 @@ Report = {
insert(output, "VULNERABLE:") insert(output, "VULNERABLE:")
for i, vuln_table in ipairs(self.entries.vulns) do for i, vuln_table in ipairs(self.entries.vulns) do
local vuln_out, out_t = format_vuln_base(vuln_table) local vuln_out, out_t = format_vuln_base(vuln_table)
if type(out_t) == "table" then if type(out_t) == "table" then
for i, v, k in pairs(out_t) do for i, v, k in pairs(out_t) do
output_t2[i]=v output_t2[i]=v
end end
end end
if vuln_out then if vuln_out then
output_table.report = concat(vuln_out, "\n") output_table.report = concat(vuln_out, "\n")
@@ -2264,10 +2264,10 @@ Report = {
end end
for i, vuln_table in ipairs(self.entries.not_vulns) do for i, vuln_table in ipairs(self.entries.not_vulns) do
local vuln_out, out_t = format_vuln_base(vuln_table, SHOW_ALL) local vuln_out, out_t = format_vuln_base(vuln_table, SHOW_ALL)
if type(out_t) == "table" then if type(out_t) == "table" then
for i, v, k in pairs(out_t) do for i, v, k in pairs(out_t) do
output_t2[i]=v output_t2[i]=v
end end
end end
if vuln_out then if vuln_out then
output_table.report = concat(vuln_out, "\n") output_table.report = concat(vuln_out, "\n")

View File

@@ -122,40 +122,40 @@ action = function(host, port)
for _, vol in ipairs( vols ) do for _, vol in ipairs( vols ) do
local status, tbl = afpHelper:Dir( vol ) local status, tbl = afpHelper:Dir( vol )
if ( not(status) ) then if ( not(status) ) then
table.insert( table.insert(
output, output,
("ERROR: Failed to list the contents of %s"):format(vol)) ("ERROR: Failed to list the contents of %s"):format(vol))
else else
local file_tab = createFileTable() local file_tab = createFileTable()
local counter = maxfiles or 10 local counter = maxfiles or 10
for _, item in ipairs(tbl[1]) do for _, item in ipairs(tbl[1]) do
if ( item and item.name ) then if ( item and item.name ) then
local status, result = afpHelper:GetFileUnixPermissions( local status, result = afpHelper:GetFileUnixPermissions(
vol, item.name) vol, item.name)
if ( status ) then if ( status ) then
local status, fsize = afpHelper:GetFileSize( vol, item.name) local status, fsize = afpHelper:GetFileSize( vol, item.name)
if ( not(status) ) then if ( not(status) ) then
table.insert( table.insert(
output, output,
("\n\nERROR: Failed to retrieve file size for %/%s"):format(vol, item.name)) ("\n\nERROR: Failed to retrieve file size for %/%s"):format(vol, item.name))
else else
local status, date = afpHelper:GetFileDates( vol, item.name) local status, date = afpHelper:GetFileDates( vol, item.name)
if ( not(status) ) then if ( not(status) ) then
table.insert( table.insert(
output, output,
("\n\nERROR: Failed to retrieve file dates for %/%s"):format(vol, item.name)) ("\n\nERROR: Failed to retrieve file dates for %/%s"):format(vol, item.name))
else else
tab.addrow(file_tab, result.privs, result.uid, result.gid, fsize, date.create, item.name) tab.addrow(file_tab, result.privs, result.uid, result.gid, fsize, date.create, item.name)
counter = counter - 1 counter = counter - 1
end end
end end
end end
end end
if ( counter == 0 ) then break end if ( counter == 0 ) then break end
end end
local result_part = { name = vol } local result_part = { name = vol }
table.insert(result_part, tab.dump(file_tab)) table.insert(result_part, tab.dump(file_tab))
table.insert(output, result_part) table.insert(output, result_part)
end end
end end
end end

View File

@@ -1,8 +1,8 @@
description = [[ description = [[
Attempts to enumerate users in Avaya IP Office systems 7.x. Attempts to enumerate users in Avaya IP Office systems 7.x.
Avaya IP Office systems allow unauthenticated access to the URI '/system/user/scn_user_list' Avaya IP Office systems allow unauthenticated access to the URI '/system/user/scn_user_list'
which returns a XML file containing user information such as display name, full name and which returns a XML file containing user information such as display name, full name and
extension number. extension number.
* Tested on Avaya IP Office 7.0(27). * Tested on Avaya IP Office 7.0(27).
@@ -15,10 +15,10 @@ extension number.
-- @output -- @output
-- PORT STATE SERVICE REASON VERSION -- PORT STATE SERVICE REASON VERSION
-- 80/tcp open http syn-ack ttl 99 Avaya IP Office VoIP PBX httpd 7.0(27) -- 80/tcp open http syn-ack ttl 99 Avaya IP Office VoIP PBX httpd 7.0(27)
-- | http-avaya-ipoffice-users: -- | http-avaya-ipoffice-users:
-- | title: Avaya IP Office User Listing -- | title: Avaya IP Office User Listing
-- | users: -- | users:
-- | -- |
-- | full_name: John Doe -- | full_name: John Doe
-- | extension: 211 -- | extension: 211
-- | name: JDoe -- | name: JDoe
@@ -63,7 +63,7 @@ action = function(host, port)
local _,_, fName = string.find(user_block, '<fname>(.-)</fname>') local _,_, fName = string.find(user_block, '<fname>(.-)</fname>')
local _,_, ext = string.find(user_block, '<extn>(.-)</extn>') local _,_, ext = string.find(user_block, '<extn>(.-)</extn>')
stdnse.debug1("User found!\nName: %s\nFull name: %s\nExt:%s", name, fName, ext) stdnse.debug1("User found!\nName: %s\nFull name: %s\nExt:%s", name, fName, ext)
if name ~= nil or fName ~= nil or ext ~= nil then if name ~= nil or fName ~= nil or ext ~= nil then
local user = {} local user = {}
user.name = name user.name = name
user.full_name = fName user.full_name = fName

View File

@@ -7,12 +7,12 @@ local table = require "table"
local string = require "string" local string = require "string"
description = [[ description = [[
Checks the cross-domain policy file (/crossdomain.xml) in web applications and lists the trusted Checks the cross-domain policy file (/crossdomain.xml) in web applications and lists the trusted
domains. Overly permissive settings enable Cross Site Request Forgery attacks and may allow attackers domains. Overly permissive settings enable Cross Site Request Forgery attacks and may allow attackers
to access sensitive data. This script is useful to detect permissive configurations and possible to access sensitive data. This script is useful to detect permissive configurations and possible
domain names available for purchase to exploit the application. domain names available for purchase to exploit the application.
The script queries instantdomainsearch.com to lookup the domains. This functionality is The script queries instantdomainsearch.com to lookup the domains. This functionality is
turned off by default, to enable it set the script argument http-crossdomainxml.domain-lookup. turned off by default, to enable it set the script argument http-crossdomainxml.domain-lookup.
References: References:
@@ -26,16 +26,16 @@ References:
--- ---
-- @usage nmap --script http-crossdomainxml <target> -- @usage nmap --script http-crossdomainxml <target>
-- @usage nmap -p80 --script http-crossdomainxml --script-args domain-lookup=true <target> -- @usage nmap -p80 --script http-crossdomainxml --script-args domain-lookup=true <target>
-- --
-- @output -- @output
-- PORT STATE SERVICE REASON -- PORT STATE SERVICE REASON
-- 80/tcp open http syn-ack ttl 40 -- 80/tcp open http syn-ack ttl 40
-- | http-crossdomainxml: -- | http-crossdomainxml:
-- | VULNERABLE: -- | VULNERABLE:
-- | Cross-domain policy file (crossdomain.xml) -- | Cross-domain policy file (crossdomain.xml)
-- | State: VULNERABLE (Exploitable) -- | State: VULNERABLE (Exploitable)
-- | A cross-domain policy file specifies the permissions that a web client such as Java, Adobe Flash, Adobe Reader, -- | A cross-domain policy file specifies the permissions that a web client such as Java, Adobe Flash, Adobe Reader,
-- | etc. use to access data across different domains. Overly permissive configurations enables Cross-site Request -- | etc. use to access data across different domains. Overly permissive configurations enables Cross-site Request
-- | Forgery attacks, and may allow third parties to access sensitive data meant for the user. -- | Forgery attacks, and may allow third parties to access sensitive data meant for the user.
-- | Check results: -- | Check results:
-- | <?xml version="1.0"?> -- | <?xml version="1.0"?>
@@ -43,10 +43,10 @@ References:
-- | <allow-access-from domain="*.0xdeadbeefcafe2.com" /> -- | <allow-access-from domain="*.0xdeadbeefcafe2.com" />
-- | <allow-access-from domain="*.0xdeadbeefcafe.com" /> -- | <allow-access-from domain="*.0xdeadbeefcafe.com" />
-- | </cross-domain-policy> -- | </cross-domain-policy>
-- | -- |
-- | Extra information: -- | Extra information:
-- | Trusted domains:0xdeadbeefcafe2.com, 0xdeadbeefcafe.com -- | Trusted domains:0xdeadbeefcafe2.com, 0xdeadbeefcafe.com
-- | -- |
-- | [!]Trusted domains available for purchase:0xdeadbeefcafe2.com -- | [!]Trusted domains available for purchase:0xdeadbeefcafe2.com
-- | References: -- | References:
-- | http://gursevkalra.blogspot.com/2013/08/bypassing-same-origin-policy-with-flash.html -- | http://gursevkalra.blogspot.com/2013/08/bypassing-same-origin-policy-with-flash.html
@@ -54,7 +54,7 @@ References:
-- | https://www.owasp.org/index.php/Test_RIA_cross_domain_policy_%28OTG-CONFIG-008%29 -- | https://www.owasp.org/index.php/Test_RIA_cross_domain_policy_%28OTG-CONFIG-008%29
-- | https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/CrossDomain_PolicyFile_Specification.pdf -- | https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/CrossDomain_PolicyFile_Specification.pdf
-- |_ http://sethsec.blogspot.com/2014/03/exploiting-misconfigured-crossdomainxml.html -- |_ http://sethsec.blogspot.com/2014/03/exploiting-misconfigured-crossdomainxml.html
-- --
-- @args http-crossdomainxml.domain-lookup Boolean to check domain availability. Default:false -- @args http-crossdomainxml.domain-lookup Boolean to check domain availability. Default:false
--- ---
@@ -87,11 +87,11 @@ function check_domain (domain)
end end
stdnse.print_debug(1, "Checking availability of domain %s with tld:%s ", name, tld) stdnse.print_debug(1, "Checking availability of domain %s with tld:%s ", name, tld)
local path = string.format("/all/%s?/tlds=%s&limit=1", name, tld) local path = string.format("/all/%s?/tlds=%s&limit=1", name, tld)
local response = http.get("instantdomainsearch.com", 443, path) local response = http.get("instantdomainsearch.com", 443, path)
if ( not(response) or (response.status and response.status ~= 200) ) then if ( not(response) or (response.status and response.status ~= 200) ) then
return nil return nil
end end
local _, _, registered = response.body:find('"isRegistered":(.-),"isBid":') local _, _, registered = response.body:find('"isRegistered":(.-),"isBid":')
return registered return registered
end end
@@ -122,11 +122,11 @@ function check_crossdomain(host, port, lookup)
--Parse domains --Parse domains
line = line:match("domain%=\"(.-)\""):gsub("%*%.", "") line = line:match("domain%=\"(.-)\""):gsub("%*%.", "")
stdnse.debug(1, "Extracted line: %s", line) stdnse.debug(1, "Extracted line: %s", line)
local domain = line:match("(%w*%.*%w+%.%w+)$") local domain = line:match("(%w*%.*%w+%.%w+)$")
if domain ~= nil then if domain ~= nil then
--Deals with tlds with double extension --Deals with tlds with double extension
local tld = domain:match("%w*(%.%w*)%.%w+$") local tld = domain:match("%w*(%.%w*)%.%w+$")
if tld ~= nil and not(stdnse.contains(tlds_instantdomainsearch, tld)) then if tld ~= nil and not(stdnse.contains(tlds_instantdomainsearch, tld)) then
domain = domain:match("%w*%.(.*)$") domain = domain:match("%w*%.(.*)$")
end end
@@ -141,10 +141,10 @@ function check_crossdomain(host, port, lookup)
table.insert(trusted_domains_available, domain) table.insert(trusted_domains_available, domain)
end end
end end
end end
end end
stdnse.debug(1, "Extracted domain: %s", domain) stdnse.debug(1, "Extracted domain: %s", domain)
end end
end end
@@ -162,8 +162,8 @@ action = function(host, port)
title = 'Cross-domain policy file (crossdomain.xml)', title = 'Cross-domain policy file (crossdomain.xml)',
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
description = [[ description = [[
A cross-domain policy file specifies the permissions that a web client such as Java, Adobe Flash, Adobe Reader, A cross-domain policy file specifies the permissions that a web client such as Java, Adobe Flash, Adobe Reader,
etc. use to access data across different domains. Overly permissive configurations enables Cross-site Request etc. use to access data across different domains. Overly permissive configurations enables Cross-site Request
Forgery attacks, and may allow third parties to access sensitive data meant for the user.]], Forgery attacks, and may allow third parties to access sensitive data meant for the user.]],
references = { references = {
'http://sethsec.blogspot.com/2014/03/exploiting-misconfigured-crossdomainxml.html', 'http://sethsec.blogspot.com/2014/03/exploiting-misconfigured-crossdomainxml.html',
@@ -179,7 +179,7 @@ Forgery attacks, and may allow third parties to access sensitive data meant for
if check then if check then
if stdnse.contains(domains, "*") then if stdnse.contains(domains, "*") then
vuln.state = vulns.STATE.EXPLOIT vuln.state = vulns.STATE.EXPLOIT
else else
vuln.state = vulns.STATE.LIKELY_VULN vuln.state = vulns.STATE.LIKELY_VULN
end end
vuln.check_results = content vuln.check_results = content
@@ -190,8 +190,8 @@ Forgery attacks, and may allow third parties to access sensitive data meant for
if lookup ~= nil and #domains_available>0 then if lookup ~= nil and #domains_available>0 then
vuln.state = vulns.STATE.EXPLOIT vuln.state = vulns.STATE.EXPLOIT
vuln.extra_info = vuln.extra_info .. string.format("\n[!]Trusted domains available for purchase:%s", vuln.extra_info = vuln.extra_info .. string.format("\n[!]Trusted domains available for purchase:%s",
stdnse.strjoin(', ', domains_available)) stdnse.strjoin(', ', domains_available))
end end
end end

View File

@@ -12,7 +12,7 @@ description = [[
Performs brute force password auditing against http form-based authentication. Performs brute force password auditing against http form-based authentication.
This script uses the unpwdb and brute libraries to perform password This script uses the unpwdb and brute libraries to perform password
guessing. Any successful guesses are stored in the nmap registry, using guessing. Any successful guesses are stored in the nmap registry, using
the creds library, for other scripts to use. the creds library, for other scripts to use.
The script automatically attempts to discover the form method, action, and The script automatically attempts to discover the form method, action, and

View File

@@ -7,12 +7,12 @@ local vulns = require "vulns"
description = [[ description = [[
Attempts to exploit the "shellshock" vulnerability (CVE-2014-6271 and CVE-2014-7169) in web applications. Attempts to exploit the "shellshock" vulnerability (CVE-2014-6271 and CVE-2014-7169) in web applications.
To detect this vulnerability the script executes a command that prints a To detect this vulnerability the script executes a command that prints a
random string and then attempts to find it inside the response body. Web apps that random string and then attempts to find it inside the response body. Web apps that
don't print back information won't be detected with this method. don't print back information won't be detected with this method.
By default the script injects the payload in the HTTP headers User-Agent, By default the script injects the payload in the HTTP headers User-Agent,
Cookie, Referer and also uses the payload as the header name. Cookie, Referer and also uses the payload as the header name.
Vulnerability originally discovered by Stephane Chazelas. Vulnerability originally discovered by Stephane Chazelas.
@@ -23,20 +23,20 @@ References:
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271 * http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271
]] ]]
-- @usage -- @usage
-- nmap -sV -p- --script http-shellshock <target> -- nmap -sV -p- --script http-shellshock <target>
-- nmap -sV -p- --script http-shellshock --script-args uri=/cgi-bin/bin,cmd=ls <target> -- nmap -sV -p- --script http-shellshock --script-args uri=/cgi-bin/bin,cmd=ls <target>
-- @output -- @output
-- PORT STATE SERVICE REASON -- PORT STATE SERVICE REASON
-- 80/tcp open http syn-ack -- 80/tcp open http syn-ack
-- | http-shellshock: -- | http-shellshock:
-- | VULNERABLE: -- | VULNERABLE:
-- | HTTP Shellshock vulnerability -- | HTTP Shellshock vulnerability
-- | State: VULNERABLE (Exploitable) -- | State: VULNERABLE (Exploitable)
-- | IDs: CVE:CVE-2014-6271 -- | IDs: CVE:CVE-2014-6271
-- | This web application might be affected by the vulnerability known as Shellshock. It seems the server -- | This web application might be affected by the vulnerability known as Shellshock. It seems the server
-- | is executing commands injected via malicious HTTP headers. -- | is executing commands injected via malicious HTTP headers.
-- | -- |
-- | Disclosure date: 2014-09-24 -- | Disclosure date: 2014-09-24
-- | References: -- | References:
-- | http://www.openwall.com/lists/oss-security/2014/09/24/10 -- | http://www.openwall.com/lists/oss-security/2014/09/24/10
@@ -51,7 +51,7 @@ References:
-- <elem>CVE:CVE-2014-6271</elem> -- <elem>CVE:CVE-2014-6271</elem>
-- </table> -- </table>
-- <table key="description"> -- <table key="description">
-- <elem>This web application might be affected by the vulnerability known as Shellshock. It seems the server -- <elem>This web application might be affected by the vulnerability known as Shellshock. It seems the server
-- &#xa;is executing commands injected via malicious HTTP headers. &#xa; </elem> -- &#xa;is executing commands injected via malicious HTTP headers. &#xa; </elem>
-- </table> -- </table>
-- <table key="dates"> -- <table key="dates">
@@ -82,7 +82,7 @@ function generate_http_req(host, port, uri, custom_header, cmd)
local rnd = nil local rnd = nil
--Set custom or probe with random string as cmd --Set custom or probe with random string as cmd
if cmd ~= nil then if cmd ~= nil then
cmd = '() { :;}; '..cmd cmd = '() { :;}; '..cmd
else else
rnd = stdnse.generate_random_string(15) rnd = stdnse.generate_random_string(15)
cmd = '() { :;}; echo; echo "'..rnd..'"' cmd = '() { :;}; echo; echo "'..rnd..'"'
@@ -104,7 +104,7 @@ function generate_http_req(host, port, uri, custom_header, cmd)
if not(cmd) then if not(cmd) then
return req return req
else else
return req, rnd return req, rnd
end end
end end
@@ -113,16 +113,16 @@ action = function(host, port)
local cmd = stdnse.get_script_args(SCRIPT_NAME..".cmd") or nil local cmd = stdnse.get_script_args(SCRIPT_NAME..".cmd") or nil
local http_header = stdnse.get_script_args(SCRIPT_NAME..".header") or nil local http_header = stdnse.get_script_args(SCRIPT_NAME..".header") or nil
local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or '/' local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or '/'
local rnd = nil local rnd = nil
local req, rnd = generate_http_req(host, port, uri, http_header, nil) local req, rnd = generate_http_req(host, port, uri, http_header, nil)
if req.status == 200 and string.match(req.body, rnd) ~= nil then if req.status == 200 and string.match(req.body, rnd) ~= nil then
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
local vuln = { local vuln = {
title = 'HTTP Shellshock vulnerability', title = 'HTTP Shellshock vulnerability',
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
description = [[ description = [[
This web application might be affected by the vulnerability known as Shellshock. It seems the server This web application might be affected by the vulnerability known as Shellshock. It seems the server
is executing commands injected via malicious HTTP headers. is executing commands injected via malicious HTTP headers.
]], ]],
IDS = {CVE = 'CVE-2014-6271'}, IDS = {CVE = 'CVE-2014-6271'},
references = { references = {

View File

@@ -54,29 +54,29 @@ Cisco Adaptive Security Appliance (ASA) Software 8.2 before 8.2(5.47), 8.4 befor
} }
local vuln_versions = { local vuln_versions = {
['8'] = { ['8'] = {
['2'] = 5.47, ['2'] = 5.47,
['4'] = 7.5, ['4'] = 7.5,
['7'] = 1.11, ['7'] = 1.11,
}, },
['9'] = { ['9'] = {
['0'] = 3.10, ['0'] = 3.10,
['1'] = 3.4, ['1'] = 3.4,
}, },
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
local ac = anyconnect.Cisco.AnyConnect:new(host, port) local ac = anyconnect.Cisco.AnyConnect:new(host, port)
local status, err = ac:connect() local status, err = ac:connect()
if not status then if not status then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
else else
local ver = ac:get_version() local ver = ac:get_version()
if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then
if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then
vuln_table.state = vulns.STATE.VULN vuln_table.state = vulns.STATE.VULN
end end
end end
end end
return report:make_output(vuln_table) return report:make_output(vuln_table)
end end

View File

@@ -53,30 +53,30 @@ Cisco Adaptive Security Appliance (ASA) Software 8.x before 8.2(5.48), 8.3 befor
} }
local vuln_versions = { local vuln_versions = {
['8'] = { ['8'] = {
['2'] = 5.48, ['2'] = 5.48,
['3'] = 2.40, ['3'] = 2.40,
['4'] = 7.9, ['4'] = 7.9,
['6'] = 1.13, ['6'] = 1.13,
}, },
['9'] = { ['9'] = {
['0'] = 4.1, ['0'] = 4.1,
['1'] = 4.3, ['1'] = 4.3,
}, },
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
local ac = anyconnect.Cisco.AnyConnect:new(host, port) local ac = anyconnect.Cisco.AnyConnect:new(host, port)
local status, err = ac:connect() local status, err = ac:connect()
if not status then if not status then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
else else
local ver = ac:get_version() local ver = ac:get_version()
if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then
if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then
vuln_table.state = vulns.STATE.VULN vuln_table.state = vulns.STATE.VULN
end end
end end
end end
return report:make_output(vuln_table) return report:make_output(vuln_table)
end end

View File

@@ -53,31 +53,31 @@ The SSL VPN implementation in Cisco Adaptive Security Appliance (ASA) Software 8
} }
local vuln_versions = { local vuln_versions = {
['8'] = { ['8'] = {
['2'] = 5.47, ['2'] = 5.47,
['3'] = 2.40, ['3'] = 2.40,
['4'] = 7.3, ['4'] = 7.3,
['6'] = 1.13, ['6'] = 1.13,
['7'] = 1.11, ['7'] = 1.11,
}, },
['9'] = { ['9'] = {
['0'] = 3.8, ['0'] = 3.8,
['1'] = 3.2, ['1'] = 3.2,
}, },
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
local ac = anyconnect.Cisco.AnyConnect:new(host, port) local ac = anyconnect.Cisco.AnyConnect:new(host, port)
local status, err = ac:connect() local status, err = ac:connect()
if not status then if not status then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
else else
local ver = ac:get_version() local ver = ac:get_version()
if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then
if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then
vuln_table.state = vulns.STATE.VULN vuln_table.state = vulns.STATE.VULN
end end
end end
end end
return report:make_output(vuln_table) return report:make_output(vuln_table)
end end

View File

@@ -53,28 +53,28 @@ The SIP inspection engine in Cisco Adaptive Security Appliance (ASA) Software 8.
} }
local vuln_versions = { local vuln_versions = {
['8'] = { ['8'] = {
['2'] = 5.48, ['2'] = 5.48,
['4'] = 6.5, ['4'] = 6.5,
}, },
['9'] = { ['9'] = {
['0'] = 3.1, ['0'] = 3.1,
['1'] = 2.5, ['1'] = 2.5,
}, },
} }
local report = vulns.Report:new(SCRIPT_NAME, host, port) local report = vulns.Report:new(SCRIPT_NAME, host, port)
local ac = anyconnect.Cisco.AnyConnect:new(host, port) local ac = anyconnect.Cisco.AnyConnect:new(host, port)
local status, err = ac:connect() local status, err = ac:connect()
if not status then if not status then
return ("\n ERROR: %s"):format(err) return ("\n ERROR: %s"):format(err)
else else
local ver = ac:get_version() local ver = ac:get_version()
if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then if vuln_versions[ver['major']] and vuln_versions[ver['major']][ver['minor']] then
if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then if vuln_versions[ver['major']][ver['minor']] > tonumber(ver['rev']) then
vuln_table.state = vulns.STATE.VULN vuln_table.state = vulns.STATE.VULN
end end
end end
end end
return report:make_output(vuln_table) return report:make_output(vuln_table)
end end

View File

@@ -11,8 +11,8 @@ description = [[
This script attempts to detect a vulnerability, CVE-2015-1427, which allows attackers This script attempts to detect a vulnerability, CVE-2015-1427, which allows attackers
to leverage features of this API to gain unauthenticated remote code execution (RCE). to leverage features of this API to gain unauthenticated remote code execution (RCE).
Elasticsearch versions 1.3.0-1.3.7 and 1.4.0-1.4.2 have a vulnerability in the Groovy scripting engine. Elasticsearch versions 1.3.0-1.3.7 and 1.4.0-1.4.2 have a vulnerability in the Groovy scripting engine.
The vulnerability allows an attacker to construct Groovy scripts that escape the sandbox and execute shell The vulnerability allows an attacker to construct Groovy scripts that escape the sandbox and execute shell
commands as the user running the Elasticsearch Java VM. commands as the user running the Elasticsearch Java VM.
]] ]]
@@ -20,12 +20,12 @@ This script attempts to detect a vulnerability, CVE-2015-1427, which allows att
-- @args command Enter the shell comannd to be executed. The script outputs the Java -- @args command Enter the shell comannd to be executed. The script outputs the Java
-- and Elasticsearch versions by default. -- and Elasticsearch versions by default.
-- @args invasive If set to true then it creates an index if there are no indices. -- @args invasive If set to true then it creates an index if there are no indices.
-- --
-- @usage -- @usage
-- nmap --script=http-vuln-cve2015-1427 --script-args command= 'ls' <targets> -- nmap --script=http-vuln-cve2015-1427 --script-args command= 'ls' <targets>
-- --
--@output --@output
-- | http-vuln-cve2015-1427: -- | http-vuln-cve2015-1427:
-- | VULNERABLE: -- | VULNERABLE:
-- | ElasticSearch CVE-2015-1427 RCE Exploit -- | ElasticSearch CVE-2015-1427 RCE Exploit
-- | State: VULNERABLE (Exploitable) -- | State: VULNERABLE (Exploitable)
@@ -133,7 +133,7 @@ action = function(host, port)
--check if a vulnerable version is running --check if a vulnerable version is running
if (tostring(parsed.version.number):find('1.3.[0-7]') or tostring(parsed.version.number):find('1.4.[0-2]')) then if (tostring(parsed.version.number):find('1.3.[0-7]') or tostring(parsed.version.number):find('1.4.[0-2]')) then
vuln_table.state = vulns.STATE.LIKELY_VULN vuln_table.state = vulns.STATE.LIKELY_VULN
end end
--help the version/service detection. --help the version/service detection.
port.version = { port.version = {
name = 'elasticsearch', name = 'elasticsearch',

View File

@@ -7,8 +7,8 @@ local vulns = require "vulns"
description = [[ description = [[
Checks for a remote code execution vulnerability (MS15-034) in Microsoft Windows systems (CVE2015-2015-1635). Checks for a remote code execution vulnerability (MS15-034) in Microsoft Windows systems (CVE2015-2015-1635).
The script sends a specially crafted HTTP request with no impact on the system to detect this vulnerability. The script sends a specially crafted HTTP request with no impact on the system to detect this vulnerability.
The affected versions are Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows 8.1, The affected versions are Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows 8.1,
and Windows Server 2012 R2. and Windows Server 2012 R2.
References: References:
@@ -22,15 +22,15 @@ References:
-- @output -- @output
-- PORT STATE SERVICE REASON -- PORT STATE SERVICE REASON
-- 80/tcp open http syn-ack -- 80/tcp open http syn-ack
-- | http-vuln-cve2015-1635: -- | http-vuln-cve2015-1635:
-- | VULNERABLE: -- | VULNERABLE:
-- | Remote Code Execution in HTTP.sys (MS15-034) -- | Remote Code Execution in HTTP.sys (MS15-034)
-- | State: VULNERABLE (Exploitable) -- | State: VULNERABLE (Exploitable)
-- | IDs: CVE:CVE-2015-1635 -- | IDs: CVE:CVE-2015-1635
-- | A remote code execution vulnerability exists in the HTTP protocol stack (HTTP.sys) that is -- | A remote code execution vulnerability exists in the HTTP protocol stack (HTTP.sys) that is
-- | caused when HTTP.sys improperly parses specially crafted HTTP requests. An attacker who -- | caused when HTTP.sys improperly parses specially crafted HTTP requests. An attacker who
-- | successfully exploited this vulnerability could execute arbitrary code in the context of the System account. -- | successfully exploited this vulnerability could execute arbitrary code in the context of the System account.
-- | -- |
-- | Disclosure date: 2015-04-14 -- | Disclosure date: 2015-04-14
-- | References: -- | References:
-- | https://technet.microsoft.com/en-us/library/security/ms15-034.aspx -- | https://technet.microsoft.com/en-us/library/security/ms15-034.aspx
@@ -52,10 +52,10 @@ action = function(host, port)
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
local vuln = { local vuln = {
title = 'Remote Code Execution in HTTP.sys (MS15-034)', title = 'Remote Code Execution in HTTP.sys (MS15-034)',
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
description = [[ description = [[
A remote code execution vulnerability exists in the HTTP protocol stack (HTTP.sys) that is A remote code execution vulnerability exists in the HTTP protocol stack (HTTP.sys) that is
caused when HTTP.sys improperly parses specially crafted HTTP requests. An attacker who caused when HTTP.sys improperly parses specially crafted HTTP requests. An attacker who
successfully exploited this vulnerability could execute arbitrary code in the context of the System account. successfully exploited this vulnerability could execute arbitrary code in the context of the System account.
]], ]],
IDS = {CVE = 'CVE-2015-1635'}, IDS = {CVE = 'CVE-2015-1635'},

View File

@@ -16,11 +16,11 @@ The databases are sorted by popularity and the script will search only the top 1
The theme database has around 32,000 entries while the plugin database has around 14,000 entries. The theme database has around 32,000 entries while the plugin database has around 14,000 entries.
The script determines the version number of a plugin by looking at the readme.txt file inside the plugin The script determines the version number of a plugin by looking at the readme.txt file inside the plugin
directory and it uses the file style.css inside a theme directory to determine the theme version. directory and it uses the file style.css inside a theme directory to determine the theme version.
If the script argument check-latest is set to true, the script will query api.wordpress.org to obtain If the script argument check-latest is set to true, the script will query api.wordpress.org to obtain
the latest version number available. This check is disabled by default since it queries an external service. the latest version number available. This check is disabled by default since it queries an external service.
This script is a combination of http-wordpress-plugins.nse and http-wordpress-themes.nse originally This script is a combination of http-wordpress-plugins.nse and http-wordpress-themes.nse originally
submited by Ange Gutek and Peter Hill. submited by Ange Gutek and Peter Hill.
TODO: TODO:
@@ -31,18 +31,18 @@ TODO:
-- @usage nmap -sV --script http-wordpress-enum <target> -- @usage nmap -sV --script http-wordpress-enum <target>
-- @usage nmap --script http-wordpress-enum --script-args check-latest=true,search-limit=10 <target> -- @usage nmap --script http-wordpress-enum --script-args check-latest=true,search-limit=10 <target>
-- @usage nmap --script http-wordpress-enum --script-args type="themes" <target> -- @usage nmap --script http-wordpress-enum --script-args type="themes" <target>
-- --
-- @args http-wordpress-enum.root Base path. By default the script will try to find a WP directory -- @args http-wordpress-enum.root Base path. By default the script will try to find a WP directory
-- installation or fall back to '/'. -- installation or fall back to '/'.
-- @args http-wordpress-enum.search-limit Number of entries or the string "all". Default:100. -- @args http-wordpress-enum.search-limit Number of entries or the string "all". Default:100.
-- @args http-wordpress-enum.type Search type. Available options:plugins, themes or all. Default:all. -- @args http-wordpress-enum.type Search type. Available options:plugins, themes or all. Default:all.
-- @args http-wordpress-enum.check-latest Retrieves latest plugin version information from wordpress.org. -- @args http-wordpress-enum.check-latest Retrieves latest plugin version information from wordpress.org.
-- Default:false. -- Default:false.
-- --
-- @output -- @output
-- PORT STATE SERVICE -- PORT STATE SERVICE
-- 80/tcp open http -- 80/tcp open http
-- | http-wordpress-enum: -- | http-wordpress-enum:
-- | Search limited to top 100 themes/plugins -- | Search limited to top 100 themes/plugins
-- | plugins -- | plugins
-- | akismet -- | akismet
@@ -104,24 +104,24 @@ local function existence_check_assign(act_file)
local temp_file = io.open(act_file,"r") local temp_file = io.open(act_file,"r")
if not temp_file then if not temp_file then
return false return false
end end
return temp_file return temp_file
end end
--Obtains version from readme.txt or style.css --Obtains version from readme.txt or style.css
local function get_version(path, typeof, host, port) local function get_version(path, typeof, host, port)
local pattern, version, versioncheck local pattern, version, versioncheck
if typeof == 'plugins' then if typeof == 'plugins' then
path = path .. "readme.txt" path = path .. "readme.txt"
pattern = 'Stable tag: ([.0-9]*)' pattern = 'Stable tag: ([.0-9]*)'
else else
path = path .. "style.css" path = path .. "style.css"
pattern = 'Version: ([.0-9]*)' pattern = 'Version: ([.0-9]*)'
end end
stdnse.debug1("Extracting version of path:%s", path) stdnse.debug1("Extracting version of path:%s", path)
versioncheck = http.get(host, port, path) versioncheck = http.get(host, port, path)
if versioncheck.body then if versioncheck.body then
version = versioncheck.body:match(pattern) version = versioncheck.body:match(pattern)
end end
@@ -129,7 +129,7 @@ local function get_version(path, typeof, host, port)
return version return version
end end
-- check if the plugin is the latest -- check if the plugin is the latest
local function get_latest_plugin_version(plugin) local function get_latest_plugin_version(plugin)
stdnse.debug1("Retrieving the latest version of %s", plugin) stdnse.debug1("Retrieving the latest version of %s", plugin)
local apiurl = WORDPRESS_API_URL .. plugin .. ".json" local apiurl = WORDPRESS_API_URL .. plugin .. ".json"
@@ -138,7 +138,7 @@ local function get_latest_plugin_version(plugin)
local latestpluginversion = latestpluginapi.body:match(latestpluginpattern) local latestpluginversion = latestpluginapi.body:match(latestpluginpattern)
stdnse.debug1("Latest version:%s", latestpluginversion) stdnse.debug1("Latest version:%s", latestpluginversion)
return latestpluginversion return latestpluginversion
end end
action = function(host, port) action = function(host, port)
@@ -158,23 +158,23 @@ action = function(host, port)
local wp_themes_file = nmap.fetchfile("nselib/data/wp-themes.lst") local wp_themes_file = nmap.fetchfile("nselib/data/wp-themes.lst")
local wp_plugins_file = nmap.fetchfile("nselib/data/wp-plugins.lst") local wp_plugins_file = nmap.fetchfile("nselib/data/wp-plugins.lst")
if operation_type_arg == "themes" or operation_type_arg == "all" then if operation_type_arg == "themes" or operation_type_arg == "all" then
local theme_db = existence_check_assign(wp_themes_file) local theme_db = existence_check_assign(wp_themes_file)
if not theme_db then if not theme_db then
return false, "Couldn't find wp-themes.lst in /nselib/data/" return false, "Couldn't find wp-themes.lst in /nselib/data/"
else else
file['themes'] = theme_db file['themes'] = theme_db
end end
end end
if operation_type_arg == "plugins" or operation_type_arg == "all" then if operation_type_arg == "plugins" or operation_type_arg == "all" then
local plugin_db = existence_check_assign(wp_plugins_file) local plugin_db = existence_check_assign(wp_plugins_file)
if not plugin_db then if not plugin_db then
return false, "Couldn't find wp-plugins.lst in /nselib/data/" return false, "Couldn't find wp-plugins.lst in /nselib/data/"
else else
file['plugins'] = plugin_db file['plugins'] = plugin_db
end end
end end
local resource_search local resource_search
if resource_search_arg == "all" then if resource_search_arg == "all" then
resource_search = nil resource_search = nil
@@ -248,7 +248,7 @@ action = function(host, port)
local version = get_version(bfqueries[i][1],key,host,port) local version = get_version(bfqueries[i][1],key,host,port)
local output = nil local output = nil
--We format the table for XML output --We format the table for XML output
bfqueries[i].path = bfqueries[i][1] bfqueries[i].path = bfqueries[i][1]
bfqueries[i].category = key bfqueries[i].category = key
bfqueries[i].name = bfqueries[i][2] bfqueries[i].name = bfqueries[i][2]
@@ -265,10 +265,10 @@ action = function(host, port)
output = output .. " (latest version:" .. latestversion .. ")" output = output .. " (latest version:" .. latestversion .. ")"
bfqueries[i].latest_version = latestversion bfqueries[i].latest_version = latestversion
end end
end end
else else
output = bfqueries[i].name output = bfqueries[i].name
end end
output_table[bfqueries[i].name] = bfqueries[i] output_table[bfqueries[i].name] = bfqueries[i]
table.insert(response, output) table.insert(response, output)
end end
@@ -292,6 +292,6 @@ end
return nil return nil
end end
end end
end end

View File

@@ -141,7 +141,7 @@ action = function(host)
if(share['user_can_write'] == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then if(share['user_can_write'] == "NT_STATUS_OBJECT_NAME_NOT_FOUND") then
share_output["Type"] = "Not a file share" share_output["Type"] = "Not a file share"
else else
table.insert(host.registry['smb_shares'], share.name) table.insert(host.registry['smb_shares'], share.name)
end end
else else
local details = share['details'] local details = share['details']
@@ -153,9 +153,9 @@ action = function(host)
share_output["Path"] = details.path share_output["Path"] = details.path
if (share_output["Type"] == "STYPE_DISKTREE" or if (share_output["Type"] == "STYPE_DISKTREE" or
share_output["Type"] == "STYPE_DISKTREE_TEMPORARY" or share_output["Type"] == "STYPE_DISKTREE_TEMPORARY" or
share_output["Type"] == "STYPE_DISKTREE_HIDDEN") then share_output["Type"] == "STYPE_DISKTREE_HIDDEN") then
table.insert(host.registry['smb_shares'], share.name) table.insert(host.registry['smb_shares'], share.name)
end end
end end
-- Print details for a file share -- Print details for a file share
@@ -186,7 +186,7 @@ action = function(host)
end end
if next(host.registry['smb_shares']) == nil then if next(host.registry['smb_shares']) == nil then
host.registry['smb_shares'] = nil host.registry['smb_shares'] = nil
end end
return response return response

View File

@@ -55,9 +55,9 @@ local arg_checksum = stdnse.get_script_args(SCRIPT_NAME .. '.checksum')
local arg_errors = stdnse.get_script_args(SCRIPT_NAME .. '.errors') local arg_errors = stdnse.get_script_args(SCRIPT_NAME .. '.errors')
hostrule = function(host) hostrule = function(host)
return ( smb.get_port(host) ~= nil and return ( smb.get_port(host) ~= nil and
(arg_shares or arg_share (arg_shares or arg_share
or host.registry['smb_shares'] ~= nil) ) or host.registry['smb_shares'] ~= nil) )
end end
-- checks whether the file entry is a directory -- checks whether the file entry is a directory
@@ -71,97 +71,97 @@ action = function(host)
-- give priority to specified shares if specified -- give priority to specified shares if specified
if arg_shares ~= nil then if arg_shares ~= nil then
arg_shares = stdnse.strsplit(":", arg_shares) arg_shares = stdnse.strsplit(":", arg_shares)
elseif arg_share ~= nil then elseif arg_share ~= nil then
arg_shares = {arg_share} arg_shares = {arg_share}
else else
arg_shares = host.registry['smb_shares'] arg_shares = host.registry['smb_shares']
end end
-- arg_maxdepth defaults to 1 (no recursion) -- arg_maxdepth defaults to 1 (no recursion)
if arg_maxdepth == nil then if arg_maxdepth == nil then
arg_maxdepth = 1 arg_maxdepth = 1
else else
arg_maxdepth = tonumber(arg_maxdepth) arg_maxdepth = tonumber(arg_maxdepth)
end end
local output = {} local output = {}
for _, share in ipairs(arg_shares) do for _, share in ipairs(arg_shares) do
local status, smbstate = smb.start_ex(host, true, true, share, local status, smbstate = smb.start_ex(host, true, true, share,
nil, nil, nil) nil, nil, nil)
if ( not(status) ) then if ( not(status) ) then
if arg_errors then if arg_errors then
table.insert( table.insert(
output, output,
("Failed to authenticate to server (%s) for directory of \\\\%s\\%s%s"):format(smbstate, stdnse.get_hostname(host), share, arg_path)) ("Failed to authenticate to server (%s) for directory of \\\\%s\\%s%s"):format(smbstate, stdnse.get_hostname(host), share, arg_path))
table.insert(output, "") table.insert(output, "")
end end
else else
table.insert(output, "") table.insert(output, "")
-- remove leading slash -- remove leading slash
arg_path = ( arg_path:sub(1,2) == '\\' and arg_path:sub(2) or arg_path ) arg_path = ( arg_path:sub(1,2) == '\\' and arg_path:sub(2) or arg_path )
-- fixup checksum argument -- fixup checksum argument
arg_checksum = ( arg_checksum == 'true' or arg_checksum == '1' ) and true or false arg_checksum = ( arg_checksum == 'true' or arg_checksum == '1' ) and true or false
local options = { max_depth = arg_maxdepth, max_files = arg_maxfiles } local options = { max_depth = arg_maxdepth, max_files = arg_maxfiles }
local depth, path, dirs = 0, arg_path, {} local depth, path, dirs = 0, arg_path, {}
local file_count, dir_count, total_bytes = 0, 0, 0 local file_count, dir_count, total_bytes = 0, 0, 0
repeat repeat
-- we need three columns per row, plus one for checksum if -- we need three columns per row, plus one for checksum if
-- requested -- requested
local lstab = tab.new((arg_checksum and 4 or 3)) local lstab = tab.new((arg_checksum and 4 or 3))
for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options ) do for fe in smb.find_files(smbstate, path .. '\\' .. arg_pattern, options ) do
if ( arg_checksum and not(is_dir(fe)) ) then if ( arg_checksum and not(is_dir(fe)) ) then
local status, content = smb.file_read(host, share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1}) local status, content = smb.file_read(host, share, path .. '\\' .. fe.fname, nil, {file_create_disposition=1})
local sha1 = ( status and stdnse.tohex(openssl.sha1(content)) or "" ) local sha1 = ( status and stdnse.tohex(openssl.sha1(content)) or "" )
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname, sha1) tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname, sha1)
else else
tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname) tab.addrow(lstab, fe.created, (is_dir(fe) and '<DIR>' or fe.eof), fe.fname)
end end
arg_maxfiles = ( arg_maxfiles and arg_maxfiles - 1 ) arg_maxfiles = ( arg_maxfiles and arg_maxfiles - 1 )
if ( arg_maxfiles == 0 ) then if ( arg_maxfiles == 0 ) then
break break
end end
if ( is_dir(fe) ) then if ( is_dir(fe) ) then
dir_count = dir_count + 1 dir_count = dir_count + 1
if ( fe.fname ~= '.' and fe.fname ~= '..' ) then if ( fe.fname ~= '.' and fe.fname ~= '..' ) then
table.insert(dirs, { depth = depth + 1, path = path .. '\\' .. fe.fname } ) table.insert(dirs, { depth = depth + 1, path = path .. '\\' .. fe.fname } )
end end
else else
total_bytes = total_bytes + fe.eof total_bytes = total_bytes + fe.eof
file_count = file_count + 1 file_count = file_count + 1
end end
end end
table.insert(output, { name = ("Directory of %s"):format( '\\\\' .. stdnse.get_hostname(host) .. '\\' .. share .. path), tab.dump(lstab) }) table.insert(output, { name = ("Directory of %s"):format( '\\\\' .. stdnse.get_hostname(host) .. '\\' .. share .. path), tab.dump(lstab) })
path = nil path = nil
if ( #dirs ~= 0 ) then if ( #dirs ~= 0 ) then
local dir = table.remove(dirs, 1) local dir = table.remove(dirs, 1)
depth = dir.depth depth = dir.depth
if ( not(arg_maxdepth) or ( dir.depth < arg_maxdepth ) ) then if ( not(arg_maxdepth) or ( dir.depth < arg_maxdepth ) ) then
path = dir.path path = dir.path
table.insert(output, "") table.insert(output, "")
end end
end end
until(not(path) or arg_maxfiles == 0) until(not(path) or arg_maxfiles == 0)
smb.stop(smbstate) smb.stop(smbstate)
local summary = { name = "Total Files Listed:", local summary = { name = "Total Files Listed:",
("%8d File(s)\t%d bytes"):format(file_count, total_bytes), ("%8d File(s)\t%d bytes"):format(file_count, total_bytes),
("%8d Dir(s)"):format(dir_count) } ("%8d Dir(s)"):format(dir_count) }
table.insert(output, "") table.insert(output, "")
table.insert(output, summary) table.insert(output, summary)
table.insert(output, "") table.insert(output, "")
end end
end end
return stdnse.format_output(true, output) return stdnse.format_output(true, output)

View File

@@ -10,24 +10,24 @@ References:
--- ---
-- @usage nmap -p49152 --script supermicro-ipmi-conf <target> -- @usage nmap -p49152 --script supermicro-ipmi-conf <target>
-- --
-- @output -- @output
-- PORT STATE SERVICE REASON -- PORT STATE SERVICE REASON
-- 49152/tcp open unknown syn-ack -- 49152/tcp open unknown syn-ack
-- | supermicro-ipmi-conf: -- | supermicro-ipmi-conf:
-- | VULNERABLE: -- | VULNERABLE:
-- | Supermicro IPMI/BMC configuration file disclosure -- | Supermicro IPMI/BMC configuration file disclosure
-- | State: VULNERABLE (Exploitable) -- | State: VULNERABLE (Exploitable)
-- | Description: -- | Description:
-- | Some Supermicro IPMI/BMC controllers allow attackers to download -- | Some Supermicro IPMI/BMC controllers allow attackers to download
-- | a configuration file containing plain text user credentials. This credentials may be used to log in to the administrative interface and the -- | a configuration file containing plain text user credentials. This credentials may be used to log in to the administrative interface and the
-- | network's Active Directory. -- | network's Active Directory.
-- | Disclosure date: 2014-06-19 -- | Disclosure date: 2014-06-19
-- | Extra information: -- | Extra information:
-- | Snippet from configuration file: -- | Snippet from configuration file:
-- | .............31spring.............\x14..............\x01\x01\x01.\x01......\x01ADMIN...........ThIsIsApAsSwOrD.............T.T............\x01\x01\x01.\x01......\x01ipmi............w00t!.............\x14............. -- | .............31spring.............\x14..............\x01\x01\x01.\x01......\x01ADMIN...........ThIsIsApAsSwOrD.............T.T............\x01\x01\x01.\x01......\x01ipmi............w00t!.............\x14.............
-- | Configuration file saved to 'xxx.xxx.xxx.xxx_bmc.conf' -- | Configuration file saved to 'xxx.xxx.xxx.xxx_bmc.conf'
-- | -- |
-- | References: -- | References:
-- |_ http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-added-extras/ -- |_ http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-added-extras/
-- --
@@ -62,20 +62,20 @@ end
action = function(host, port) action = function(host, port)
local fw = stdnse.get_script_args(SCRIPT_NAME..".out") or host.ip.."_bmc.conf" local fw = stdnse.get_script_args(SCRIPT_NAME..".out") or host.ip.."_bmc.conf"
local vuln = { local vuln = {
title = 'Supermicro IPMI/BMC configuration file disclosure', title = 'Supermicro IPMI/BMC configuration file disclosure',
state = vulns.STATE.NOT_VULN, state = vulns.STATE.NOT_VULN,
description = [[ description = [[
Some Supermicro IPMI/BMC controllers allow attackers to download Some Supermicro IPMI/BMC controllers allow attackers to download
a configuration file containing plain text user credentials. This credentials may be used to log in to the administrative interface and the a configuration file containing plain text user credentials. This credentials may be used to log in to the administrative interface and the
network's Active Directory.]], network's Active Directory.]],
references = { references = {
'http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-added-extras/', 'http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-added-extras/',
}, },
dates = { dates = {
disclosure = {year = '2014', month = '06', day = '19'}, disclosure = {year = '2014', month = '06', day = '19'},
}, },
} }
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
local open_session = http.get(host.ip, port, "/PSBlock") local open_session = http.get(host.ip, port, "/PSBlock")
if open_session and open_session.status ==200 and string.len(open_session.body)>200 then if open_session and open_session.status ==200 and string.len(open_session.body)>200 then
@@ -88,7 +88,7 @@ network's Active Directory.]],
else else
extra_info = '' extra_info = ''
stdnse.debug(1, "Error saving configuration file to '%s': %s\n", fw, err) stdnse.debug(1, "Error saving configuration file to '%s': %s\n", fw, err)
end end
vuln.extra_info = "Snippet from configuration file:\n"..string.sub(s, 25, 200)..extra_info vuln.extra_info = "Snippet from configuration file:\n"..string.sub(s, 25, 200)..extra_info
end end