mirror of
https://github.com/nmap/nmap.git
synced 2025-12-13 03:09:02 +00:00
Re-indent the Lua files in nselib/data/
https://secwiki.org/w/Nmap/Code_Standards
This commit is contained in:
@@ -31,12 +31,12 @@ local url = require "url"
|
|||||||
-- @return True if login in was successful
|
-- @return True if login in was successful
|
||||||
---
|
---
|
||||||
local function try_http_basic_login(host, port, path, user, pass, digest_auth)
|
local function try_http_basic_login(host, port, path, user, pass, digest_auth)
|
||||||
local credentials = {username = user, password = pass, digest = digest_auth}
|
local credentials = {username = user, password = pass, digest = digest_auth}
|
||||||
local req = http.get(host, port, path, {no_cache=true, auth=credentials, redirect_ok = false})
|
local req = http.get(host, port, path, {no_cache=true, auth=credentials, redirect_ok = false})
|
||||||
if req.status and req.status ~= 401 and req.status ~= 403 then
|
if req.status and req.status ~= 401 and req.status ~= 403 then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -51,17 +51,17 @@ end
|
|||||||
-- @return True if login in was successful
|
-- @return True if login in was successful
|
||||||
---
|
---
|
||||||
local function try_http_post_login(host, port, path, target, failstr, params, follow_redirects)
|
local function try_http_post_login(host, port, path, target, failstr, params, follow_redirects)
|
||||||
local req = http.post(host, port, url.absolute(path, target), {no_cache=true}, nil, params)
|
local req = http.post(host, port, url.absolute(path, target), {no_cache=true}, nil, params)
|
||||||
|
|
||||||
if not req.status then return false end
|
if not req.status then return false end
|
||||||
local status = tonumber(req.status) or 0
|
local status = tonumber(req.status) or 0
|
||||||
if follow_redirects and ( status > 300 and status < 400 ) then
|
if follow_redirects and ( status > 300 and status < 400 ) then
|
||||||
req = http.get(host, port, url.absolute(path, req.header.location), { no_cache = true, redirect_ok = false })
|
req = http.get(host, port, url.absolute(path, req.header.location), { no_cache = true, redirect_ok = false })
|
||||||
end
|
end
|
||||||
if req.status and req.status ~= 404 and not(http.response_contains(req, failstr)) then
|
if req.status and req.status ~= 404 and not(http.response_contains(req, failstr)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -71,8 +71,8 @@ end
|
|||||||
-- (or nil if not present)
|
-- (or nil if not present)
|
||||||
---
|
---
|
||||||
local function http_auth_realm(response)
|
local function http_auth_realm(response)
|
||||||
local auth = response.header["www-authenticate"] or ""
|
local auth = response.header["www-authenticate"] or ""
|
||||||
return auth:match('%srealm="([^"]*)')
|
return auth:match('%srealm="([^"]*)')
|
||||||
end
|
end
|
||||||
|
|
||||||
fingerprints = {}
|
fingerprints = {}
|
||||||
@@ -110,10 +110,10 @@ table.insert(fingerprints, {
|
|||||||
login_combos = {
|
login_combos = {
|
||||||
{username = "tomcat", password = "tomcat"},
|
{username = "tomcat", password = "tomcat"},
|
||||||
{username = "admin", password = "admin"},
|
{username = "admin", password = "admin"},
|
||||||
-- http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-4189
|
-- http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-4189
|
||||||
{username = "ovwebusr", password = "OvW*busr1"},
|
{username = "ovwebusr", password = "OvW*busr1"},
|
||||||
-- http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-4188
|
-- http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-4188
|
||||||
{username = "j2deployer", password = "j2deployer"}
|
{username = "j2deployer", password = "j2deployer"}
|
||||||
},
|
},
|
||||||
login_check = function (host, port, path, user, pass)
|
login_check = function (host, port, path, user, pass)
|
||||||
return try_http_basic_login(host, port, path, user, pass, false)
|
return try_http_basic_login(host, port, path, user, pass, false)
|
||||||
|
|||||||
@@ -21,345 +21,345 @@ local url = require "url"
|
|||||||
|
|
||||||
tools = { Django = { rapidDetect = function(host, port)
|
tools = { Django = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Check if the site gives that familiar Django admin login page.
|
-- Check if the site gives that familiar Django admin login page.
|
||||||
local response = http.get(host, port, "/admin/")
|
local response = http.get(host, port, "/admin/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "Log in | Django site admin") or
|
if string.find(response.body, "Log in | Django site admin") or
|
||||||
string.find(response.body, "this_is_the_login_form") or
|
string.find(response.body, "this_is_the_login_form") or
|
||||||
string.find(response.body, "csrfmiddlewaretoken") then
|
string.find(response.body, "csrfmiddlewaretoken") then
|
||||||
return "Django detected. Found Django admin login page on /admin/"
|
return "Django detected. Found Django admin login page on /admin/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- In Django, the cookie sessionid is being set when you log in
|
-- In Django, the cookie sessionid is being set when you log in
|
||||||
-- and forms will probably set a cookie called csrftoken.
|
-- and forms will probably set a cookie called csrftoken.
|
||||||
if response.cookies then
|
if response.cookies then
|
||||||
for _, c in pairs(response.cookies) do
|
for _, c in pairs(response.cookies) do
|
||||||
if c.name == "csrftoken" then
|
if c.name == "csrftoken" then
|
||||||
return "Django detected. Found sessionid cookie which means the contrib.auth package for authentication is enabled."
|
return "Django detected. Found sessionid cookie which means the contrib.auth package for authentication is enabled."
|
||||||
elseif c.name == "sessionid" then
|
elseif c.name == "sessionid" then
|
||||||
return "Django detected. Found csrftoken cookie."
|
return "Django detected. Found csrftoken cookie."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- See if DEBUG mode still happens to be true.
|
-- See if DEBUG mode still happens to be true.
|
||||||
response = http.get(host, port, "/random404page/")
|
response = http.get(host, port, "/random404page/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "<code>DEBUG = True</code>") then
|
if string.find(response.body, "<code>DEBUG = True</code>") then
|
||||||
return "Django detected. Found Django error page on /random404page/"
|
return "Django detected. Found Django error page on /random404page/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
if page then
|
if page then
|
||||||
if string.find(page, "csrfmiddlewaretoken") then
|
if string.find(page, "csrfmiddlewaretoken") then
|
||||||
return "Django detected. Found csrfmiddlewaretoken on " .. path
|
return "Django detected. Found csrfmiddlewaretoken on " .. path
|
||||||
end
|
end
|
||||||
if string.find(page, "id=\"id_") then
|
if string.find(page, "id=\"id_") then
|
||||||
return "Django detected. Found id_ preffix in id attribute name on " .. path
|
return "Django detected. Found id_ preffix in id attribute name on " .. path
|
||||||
end
|
end
|
||||||
if string.find(page, "%-TOTAL%-FORMS") or string.find(page, "%-DELETE") then
|
if string.find(page, "%-TOTAL%-FORMS") or string.find(page, "%-DELETE") then
|
||||||
return "Django detected. Found -TOTAL-FORMS and -DELETE hidden inputs, which means there is a Django formset on " .. path
|
return "Django detected. Found -TOTAL-FORMS and -DELETE hidden inputs, which means there is a Django formset on " .. path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
RubyOnRails = { rapidDetect = function(host, port)
|
RubyOnRails = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
-- Check for Mongrel or Passenger in the "Server" or "X-Powered-By" header
|
-- Check for Mongrel or Passenger in the "Server" or "X-Powered-By" header
|
||||||
for h, v in pairs(response.header) do
|
for h, v in pairs(response.header) do
|
||||||
if h == "x-powered-by" or h == "server" then
|
if h == "x-powered-by" or h == "server" then
|
||||||
local vl = v:lower()
|
local vl = v:lower()
|
||||||
local m = vl:match("mongrel") or vl:match("passenger")
|
local m = vl:match("mongrel") or vl:match("passenger")
|
||||||
if m then
|
if m then
|
||||||
return "RoR detected. Found '" .. m .. "' in " .. h .. " header sent by the server."
|
return "RoR detected. Found '" .. m .. "' in " .. h .. " header sent by the server."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- /rails/info/propertires shows project info when in development mode
|
-- /rails/info/propertires shows project info when in development mode
|
||||||
response = http.get(host, port, "/rails/info/properties")
|
response = http.get(host, port, "/rails/info/properties")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "Ruby version") then
|
if string.find(response.body, "Ruby version") then
|
||||||
return "RoR detected. Found properties file on /rails/info/properties/"
|
return "RoR detected. Found properties file on /rails/info/properties/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Make up a bad path and match the error page
|
-- Make up a bad path and match the error page
|
||||||
response = http.get(host, port, "/random404page/")
|
response = http.get(host, port, "/random404page/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "Routing Error") then
|
if string.find(response.body, "Routing Error") then
|
||||||
return "RoR detected. Found RoR routing error page on /random404page/"
|
return "RoR detected. Found RoR routing error page on /random404page/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
|
|
||||||
-- Check the source and look for csrf patterns.
|
-- Check the source and look for csrf patterns.
|
||||||
if page then
|
if page then
|
||||||
if string.find(page, "csrf%-param") or string.find(page, "csrf%-token") then
|
if string.find(page, "csrf%-param") or string.find(page, "csrf%-token") then
|
||||||
return "RoR detected. Found csrf field on" .. path
|
return "RoR detected. Found csrf field on" .. path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
ASPdotNET = { rapidDetect = function(host, port)
|
ASPdotNET = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
-- Look for an ASP.NET header.
|
-- Look for an ASP.NET header.
|
||||||
for h, v in pairs(response.header) do
|
for h, v in pairs(response.header) do
|
||||||
local vl = v:lower()
|
local vl = v:lower()
|
||||||
if h == "x-aspnet-version" or string.find(vl, "asp") then
|
if h == "x-aspnet-version" or string.find(vl, "asp") then
|
||||||
return "ASP.NET detected. Found related header."
|
return "ASP.NET detected. Found related header."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if response.cookies then
|
if response.cookies then
|
||||||
for _, c in pairs(response.cookies) do
|
for _, c in pairs(response.cookies) do
|
||||||
if c.name == "aspnetsessionid" then
|
if c.name == "aspnetsessionid" then
|
||||||
return "ASP.NET detected. Found aspnetsessionid cookie."
|
return "ASP.NET detected. Found aspnetsessionid cookie."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
-- Check the source and look for common traces.
|
-- Check the source and look for common traces.
|
||||||
if page then
|
if page then
|
||||||
if string.find(page, " __VIEWSTATE") or
|
if string.find(page, " __VIEWSTATE") or
|
||||||
string.find(page, "__EVENT") or
|
string.find(page, "__EVENT") or
|
||||||
string.find(page, "__doPostBack") or
|
string.find(page, "__doPostBack") or
|
||||||
string.find(page, "aspnetForm") or
|
string.find(page, "aspnetForm") or
|
||||||
string.find(page, "ctl00_") then
|
string.find(page, "ctl00_") then
|
||||||
return "ASP.NET detected. Found common traces on" .. path
|
return "ASP.NET detected. Found common traces on" .. path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
CodeIgniter = { rapidDetect = function(host, port)
|
CodeIgniter = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Match default error page.
|
-- Match default error page.
|
||||||
local response = http.get(host, port, "/random404page/")
|
local response = http.get(host, port, "/random404page/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "#990000") and
|
if string.find(response.body, "#990000") and
|
||||||
string.find(response.body, "404 Page Not Found") then
|
string.find(response.body, "404 Page Not Found") then
|
||||||
return "CodeIgniter detected. Found CodeIgniter default error page on /random404page/"
|
return "CodeIgniter detected. Found CodeIgniter default error page on /random404page/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
CakePHP = { rapidDetect = function(host, port)
|
CakePHP = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
|
|
||||||
-- Find CAKEPHP header.
|
-- Find CAKEPHP header.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
for h, v in pairs(response.header) do
|
for h, v in pairs(response.header) do
|
||||||
local vl = v:lower()
|
local vl = v:lower()
|
||||||
if string.find(vl, "cakephp") then
|
if string.find(vl, "cakephp") then
|
||||||
return "CakePHP detected. Found related header."
|
return "CakePHP detected. Found related header."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
Symfony = { rapidDetect = function(host, port)
|
Symfony = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Find Symfony header.
|
-- Find Symfony header.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
for h, v in pairs(response.header) do
|
for h, v in pairs(response.header) do
|
||||||
local vl = v:lower()
|
local vl = v:lower()
|
||||||
if string.find(vl, "symfony") then
|
if string.find(vl, "symfony") then
|
||||||
return "Symfony detected. Found related header."
|
return "Symfony detected. Found related header."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
Wordpress = { rapidDetect = function(host, port)
|
Wordpress = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Check for common traces in the source code.
|
-- Check for common traces in the source code.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "content=[\"']WordPress") or
|
if string.find(response.body, "content=[\"']WordPress") or
|
||||||
string.find(response.body, "wp%-content") then
|
string.find(response.body, "wp%-content") then
|
||||||
return "Wordpress detected. Found common traces on /"
|
return "Wordpress detected. Found common traces on /"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if the default login page exists.
|
-- Check if the default login page exists.
|
||||||
response = http.get(host, port, "/wp%-login")
|
response = http.get(host, port, "/wp%-login")
|
||||||
|
|
||||||
if response.status == "200" then
|
if response.status == "200" then
|
||||||
return "Wordpress detected. Found WP login page on /wp-login"
|
return "Wordpress detected. Found WP login page on /wp-login"
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
if page then
|
if page then
|
||||||
if string.find(page, "content=[\"']WordPress") or
|
if string.find(page, "content=[\"']WordPress") or
|
||||||
string.find(page, "wp%-content") then
|
string.find(page, "wp%-content") then
|
||||||
return "Wordpress detected. Found common traces on " .. page
|
return "Wordpress detected. Found common traces on " .. page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
Joomla = { rapidDetect = function(host, port)
|
Joomla = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
|
|
||||||
-- Check for common traces in the source code.
|
-- Check for common traces in the source code.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "content=[\"']Joomla!") then
|
if string.find(response.body, "content=[\"']Joomla!") then
|
||||||
return "Joomla detected. Found common traces on /"
|
return "Joomla detected. Found common traces on /"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if the default login page exists.
|
-- Check if the default login page exists.
|
||||||
response = http.get(host, port, "/administrator")
|
response = http.get(host, port, "/administrator")
|
||||||
|
|
||||||
if response.body and string.find(response.body, "Joomla") then
|
if response.body and string.find(response.body, "Joomla") then
|
||||||
return "Joomla detected. Found Joomla login page on /administrator/"
|
return "Joomla detected. Found Joomla login page on /administrator/"
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
if page and string.find(page, "content=[\"']Joomla!") then
|
if page and string.find(page, "content=[\"']Joomla!") then
|
||||||
return "Joomla detected. Found common traces on " .. page
|
return "Joomla detected. Found common traces on " .. page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
Drupal = { rapidDetect = function(host, port)
|
Drupal = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Check for common traces in the source code.
|
-- Check for common traces in the source code.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "content=[\"']Drupal") then
|
if string.find(response.body, "content=[\"']Drupal") then
|
||||||
return "Drupal detected. Found common traces on /"
|
return "Drupal detected. Found common traces on /"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
if page and string.find(page, "content=[\"']Drupal") then
|
if page and string.find(page, "content=[\"']Drupal") then
|
||||||
return "Drupal detected. Found common traces on " .. page
|
return "Drupal detected. Found common traces on " .. page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
MediaWiki = { rapidDetect = function(host, port)
|
MediaWiki = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
-- Check for common traces in the source code.
|
-- Check for common traces in the source code.
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.body then
|
if response.body then
|
||||||
if string.find(response.body, "content=[\"']MediaWiki") or
|
if string.find(response.body, "content=[\"']MediaWiki") or
|
||||||
string.find(response.body, "/mediawiki/") then
|
string.find(response.body, "/mediawiki/") then
|
||||||
return "MediaWiki detected. Found common traces on /"
|
return "MediaWiki detected. Found common traces on /"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
if page and string.find(page, "content=[\"']MediaWiki") or
|
if page and string.find(page, "content=[\"']MediaWiki") or
|
||||||
string.find(page, "/mediawiki/") then
|
string.find(page, "/mediawiki/") then
|
||||||
return "MediaWiki detected. Found common traces on " .. page
|
return "MediaWiki detected. Found common traces on " .. page
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
ColdFusion = { rapidDetect = function(host, port)
|
ColdFusion = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.cookies then
|
if response.cookies then
|
||||||
for _, c in pairs(response.cookies) do
|
for _, c in pairs(response.cookies) do
|
||||||
if c.name == "cfid" or c.name == "cftoken" then
|
if c.name == "cfid" or c.name == "cftoken" then
|
||||||
return "ColdFusion detected. Found " .. c.name .. " cookie."
|
return "ColdFusion detected. Found " .. c.name .. " cookie."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
Broadvision = { rapidDetect = function(host, port)
|
Broadvision = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.cookies then
|
if response.cookies then
|
||||||
for _, c in pairs(response.cookies) do
|
for _, c in pairs(response.cookies) do
|
||||||
if string.find(c.name, "bv_") then
|
if string.find(c.name, "bv_") then
|
||||||
return "Broadvision detected. Found " .. c.name .. " cookie."
|
return "Broadvision detected. Found " .. c.name .. " cookie."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
||||||
WebSphereCommerce = { rapidDetect = function(host, port)
|
WebSphereCommerce = { rapidDetect = function(host, port)
|
||||||
|
|
||||||
local response = http.get(host, port, "/")
|
local response = http.get(host, port, "/")
|
||||||
|
|
||||||
if response.cookies then
|
if response.cookies then
|
||||||
for _, c in pairs(response.cookies) do
|
for _, c in pairs(response.cookies) do
|
||||||
if string.find(c.name, "wc_") then
|
if string.find(c.name, "wc_") then
|
||||||
return "WebSphere Commerce detected. Found " .. c.name .. " cookie."
|
return "WebSphere Commerce detected. Found " .. c.name .. " cookie."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
consumingDetect = function(page, path)
|
consumingDetect = function(page, path)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11853,90 +11853,90 @@ local f = nmap.fetchfile(nikto_db_path) or io.open(nikto_db_path, "r")
|
|||||||
|
|
||||||
if f then
|
if f then
|
||||||
|
|
||||||
stdnse.print_debug(1, "Found nikto db.")
|
stdnse.print_debug(1, "Found nikto db.")
|
||||||
|
|
||||||
local nikto_db = {}
|
local nikto_db = {}
|
||||||
for l in io.lines(nikto_db_path) do
|
for l in io.lines(nikto_db_path) do
|
||||||
|
|
||||||
-- Skip comments.
|
-- Skip comments.
|
||||||
if not string.match(l, "^#.*") then
|
if not string.match(l, "^#.*") then
|
||||||
|
|
||||||
record = {}
|
record = {}
|
||||||
|
|
||||||
for field in string.gmatch(l, "\"(.-)\",") do
|
for field in string.gmatch(l, "\"(.-)\",") do
|
||||||
|
|
||||||
-- Grab every attribute and create a record.
|
-- Grab every attribute and create a record.
|
||||||
if field then
|
if field then
|
||||||
string.gsub(field, '%%', '%%%%')
|
string.gsub(field, '%%', '%%%%')
|
||||||
table.insert(record, field)
|
table.insert(record, field)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Make sure this record doesn't exists already.
|
|
||||||
local exists = false
|
|
||||||
for _, f in pairs(fingerprints) do
|
|
||||||
if f.probes then
|
|
||||||
for __, p in pairs(f.probes) do
|
|
||||||
if p.path then
|
|
||||||
if p.path == record[4] then
|
|
||||||
exists = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- What we have right now, is the following record:
|
|
||||||
-- record[1]: Nikto test ID
|
|
||||||
-- record[2]: OSVDB-ID
|
|
||||||
-- record[3]: Server Type
|
|
||||||
-- record[4]: URI
|
|
||||||
-- record[5]: HTTP Method
|
|
||||||
-- record[6]: Match 1
|
|
||||||
-- record[7]: Match 1 (Or)
|
|
||||||
-- record[8]: Match1 (And)
|
|
||||||
-- record[9]: Fail 1
|
|
||||||
-- record[10]: Fail 2
|
|
||||||
-- record[11]: Summary
|
|
||||||
-- record[12]: HTTP Data
|
|
||||||
-- record[13]: Headers
|
|
||||||
|
|
||||||
-- Is this a valid record? Atm, with our current format we need
|
|
||||||
-- to skip some nikto records. See NSEDoc for more info.
|
|
||||||
|
|
||||||
if not exists
|
|
||||||
and record[4]
|
|
||||||
and record[8] == "" and record[10] == "" and record[12] == ""
|
|
||||||
and (tonumber(record[4]) == nil or (tonumber(record[4]) and record[4] == "200")) then
|
|
||||||
|
|
||||||
-- Our current format does not support HTTP code matching.
|
|
||||||
if record[6] == "200" then record[6] = "" end
|
|
||||||
|
|
||||||
nikto_fingerprint = { category = "nikto",
|
|
||||||
probes = {
|
|
||||||
{
|
|
||||||
path = record[4],
|
|
||||||
method = record[5]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
matches = {
|
|
||||||
{
|
|
||||||
dontmatch = record[9],
|
|
||||||
match = record[6],
|
|
||||||
output = record[11]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- If there is a second match, add it.
|
|
||||||
if record[7] and record[7] ~= "" then
|
|
||||||
table.insert(nikto_fingerprint.matches, { match = record[7], output = record[11] })
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(fingerprints, nikto_fingerprint)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make sure this record doesn't exists already.
|
||||||
|
local exists = false
|
||||||
|
for _, f in pairs(fingerprints) do
|
||||||
|
if f.probes then
|
||||||
|
for __, p in pairs(f.probes) do
|
||||||
|
if p.path then
|
||||||
|
if p.path == record[4] then
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- What we have right now, is the following record:
|
||||||
|
-- record[1]: Nikto test ID
|
||||||
|
-- record[2]: OSVDB-ID
|
||||||
|
-- record[3]: Server Type
|
||||||
|
-- record[4]: URI
|
||||||
|
-- record[5]: HTTP Method
|
||||||
|
-- record[6]: Match 1
|
||||||
|
-- record[7]: Match 1 (Or)
|
||||||
|
-- record[8]: Match1 (And)
|
||||||
|
-- record[9]: Fail 1
|
||||||
|
-- record[10]: Fail 2
|
||||||
|
-- record[11]: Summary
|
||||||
|
-- record[12]: HTTP Data
|
||||||
|
-- record[13]: Headers
|
||||||
|
|
||||||
|
-- Is this a valid record? Atm, with our current format we need
|
||||||
|
-- to skip some nikto records. See NSEDoc for more info.
|
||||||
|
|
||||||
|
if not exists
|
||||||
|
and record[4]
|
||||||
|
and record[8] == "" and record[10] == "" and record[12] == ""
|
||||||
|
and (tonumber(record[4]) == nil or (tonumber(record[4]) and record[4] == "200")) then
|
||||||
|
|
||||||
|
-- Our current format does not support HTTP code matching.
|
||||||
|
if record[6] == "200" then record[6] = "" end
|
||||||
|
|
||||||
|
nikto_fingerprint = { category = "nikto",
|
||||||
|
probes = {
|
||||||
|
{
|
||||||
|
path = record[4],
|
||||||
|
method = record[5]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matches = {
|
||||||
|
{
|
||||||
|
dontmatch = record[9],
|
||||||
|
match = record[6],
|
||||||
|
output = record[11]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- If there is a second match, add it.
|
||||||
|
if record[7] and record[7] ~= "" then
|
||||||
|
table.insert(nikto_fingerprint.matches, { match = record[7], output = record[11] })
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(fingerprints, nikto_fingerprint)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,61 +6,61 @@ TEMPLATE_NAME="CIS MySQL Benchmarks v1.0.2"
|
|||||||
ADMIN_ACCOUNTS={"root", "debian-sys-maint"}
|
ADMIN_ACCOUNTS={"root", "debian-sys-maint"}
|
||||||
|
|
||||||
-- Checks whether a resultset is empty or not
|
-- Checks whether a resultset is empty or not
|
||||||
local function isEmpty(rows)
|
local function isEmpty(rows)
|
||||||
if ( #rows > 0 ) then return false end
|
if ( #rows > 0 ) then return false end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Extracts a column from a row and return all occurances as an array
|
-- Extracts a column from a row and return all occurances as an array
|
||||||
local function col2tab(rs, cname)
|
local function col2tab(rs, cname)
|
||||||
local tab = {}
|
local tab = {}
|
||||||
local cpos
|
local cpos
|
||||||
for i=1, #rs.cols do
|
for i=1, #rs.cols do
|
||||||
if ( rs.cols[i].name == cname ) then
|
if ( rs.cols[i].name == cname ) then
|
||||||
cpos = i
|
cpos = i
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if ( not(cpos) ) then
|
if ( not(cpos) ) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for _, row in ipairs(rs.rows) do table.insert(tab, row[cpos]) end
|
for _, row in ipairs(rs.rows) do table.insert(tab, row[cpos]) end
|
||||||
return tab
|
return tab
|
||||||
end
|
end
|
||||||
|
|
||||||
local function createINstmt(tab)
|
local function createINstmt(tab)
|
||||||
local tab2 = {}
|
local tab2 = {}
|
||||||
for i=1, #tab do tab2[i] = ("'%s'"):format(tab[i]) end
|
for i=1, #tab do tab2[i] = ("'%s'"):format(tab[i]) end
|
||||||
return stdnse.strjoin(",", tab2)
|
return stdnse.strjoin(",", tab2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- This next section contains all the tests
|
-- This next section contains all the tests
|
||||||
|
|
||||||
-- Logging
|
-- Logging
|
||||||
test { id="3.1", desc="Skip symbolic links", sql="SHOW variables WHERE Variable_name = 'log_error' AND Value IS NOT NULL", check=function(rowstab)
|
test { id="3.1", desc="Skip symbolic links", sql="SHOW variables WHERE Variable_name = 'log_error' AND Value IS NOT NULL", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="3.2", desc="Logs not on system partition", sql="SHOW variables WHERE Variable_name = 'log_bin' AND Value <> 'OFF'", check=function(rowstab)
|
test { id="3.2", desc="Logs not on system partition", sql="SHOW variables WHERE Variable_name = 'log_bin' AND Value <> 'OFF'", check=function(rowstab)
|
||||||
local log = col2tab(rowstab[1], 'Value')
|
local log = col2tab(rowstab[1], 'Value')
|
||||||
return { status = isEmpty(rowstab[1]), result = log, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = log, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="3.2", desc="Logs not on database partition", sql="SHOW variables WHERE Variable_name = 'log_bin' AND Value <> 'OFF'", check=function(rowstab)
|
test { id="3.2", desc="Logs not on database partition", sql="SHOW variables WHERE Variable_name = 'log_bin' AND Value <> 'OFF'", check=function(rowstab)
|
||||||
local log = col2tab(rowstab[1], 'Value')
|
local log = col2tab(rowstab[1], 'Value')
|
||||||
return { status = isEmpty(rowstab[1]), result = log, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = log, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
test { id="4.1", desc="Supported version of MySQL", sql="SHOW VARIABLES like 'version'", check=function(rowstab)
|
test { id="4.1", desc="Supported version of MySQL", sql="SHOW VARIABLES like 'version'", check=function(rowstab)
|
||||||
local ver = col2tab(rowstab[1], 'Value')[1]
|
local ver = col2tab(rowstab[1], 'Value')[1]
|
||||||
return { status = true, review = true, result = ("Version: %s"):format(ver) }
|
return { status = true, review = true, result = ("Version: %s"):format(ver) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="4.4", desc="Remove test database", sql="SHOW DATABASES like 'test'", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
test { id="4.4", desc="Remove test database", sql="SHOW DATABASES like 'test'", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
||||||
@@ -68,155 +68,155 @@ test { id="4.4", desc="Remove test database", sql="SHOW DATABASES like 'test'",
|
|||||||
test { id="4.5", desc="Change admin account name", sql="SELECT user FROM mysql.user WHERE user='root';", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
test { id="4.5", desc="Change admin account name", sql="SELECT user FROM mysql.user WHERE user='root';", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
||||||
|
|
||||||
test { id="4.7", desc="Verify Secure Password Hashes", sql="SELECT DISTINCT user, password from mysql.user where length(password) < 41 AND length(password) > 0", check=function(rowstab)
|
test { id="4.7", desc="Verify Secure Password Hashes", sql="SELECT DISTINCT user, password from mysql.user where length(password) < 41 AND length(password) > 0", check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having weak password hashes"
|
users.name = ( #users > 0 ) and "The following users were found having weak password hashes"
|
||||||
return { status = isEmpty(rowstab[1]), result = users }
|
return { status = isEmpty(rowstab[1]), result = users }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="4.9", desc="Wildcards in user hostname", sql="select user from mysql.user where host = '%'", check=function(rowstab)
|
test { id="4.9", desc="Wildcards in user hostname", sql="select user from mysql.user where host = '%'", check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found with wildcards in hostname"
|
users.name = ( #users > 0 ) and "The following users were found with wildcards in hostname"
|
||||||
return { status = isEmpty(rowstab[1]), result = users }
|
return { status = isEmpty(rowstab[1]), result = users }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="4.10", desc="No blank passwords", sql="select distinct user, password from mysql.user where length(password) = 0 or password is null", check=function(rowstab)
|
test { id="4.10", desc="No blank passwords", sql="select distinct user, password from mysql.user where length(password) = 0 or password is null", check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having blank/empty passwords"
|
users.name = ( #users > 0 ) and "The following users were found having blank/empty passwords"
|
||||||
return { status = isEmpty(rowstab[1]), result = users }
|
return { status = isEmpty(rowstab[1]), result = users }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="4.11", desc="Anonymous account", sql="select distinct user from mysql.user where user =''", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
test { id="4.11", desc="Anonymous account", sql="select distinct user from mysql.user where user =''", check=function(rowstab) return { status = isEmpty(rowstab[1]) } end }
|
||||||
|
|
||||||
|
|
||||||
-- MySQL Permissions
|
-- MySQL Permissions
|
||||||
test { id="5.1", desc="Access to mysql database",
|
test { id="5.1", desc="Access to mysql database",
|
||||||
sql = { "SELECT user, host FROM mysql.db WHERE db = 'mysql' and ((Select_priv = 'Y') or (Insert_priv = 'Y') " ..
|
sql = { "SELECT user, host FROM mysql.db WHERE db = 'mysql' and ((Select_priv = 'Y') or (Insert_priv = 'Y') " ..
|
||||||
"or (Update_priv = 'Y') or (Delete_priv = 'Y') or (Create_priv = 'Y') or (Drop_priv = 'Y'))",
|
"or (Update_priv = 'Y') or (Delete_priv = 'Y') or (Create_priv = 'Y') or (Drop_priv = 'Y'))",
|
||||||
"SELECT user, host FROM mysql.user WHERE (Select_priv = 'Y') or (Insert_priv = 'Y') or " ..
|
"SELECT user, host FROM mysql.user WHERE (Select_priv = 'Y') or (Insert_priv = 'Y') or " ..
|
||||||
"(Update_priv = 'Y') or (Delete_priv = 'Y') or (Create_priv = 'Y') or (Drop_priv = 'Y')" },
|
"(Update_priv = 'Y') or (Delete_priv = 'Y') or (Create_priv = 'Y') or (Drop_priv = 'Y')" },
|
||||||
check = function(rowstab)
|
check = function(rowstab)
|
||||||
|
|
||||||
local result = tab.new(2)
|
local result = tab.new(2)
|
||||||
tab.addrow(result, "user", "host")
|
tab.addrow(result, "user", "host")
|
||||||
|
|
||||||
local rs = rowstab[1]
|
local rs = rowstab[1]
|
||||||
for _, row in ipairs(rs.rows) do
|
for _, row in ipairs(rs.rows) do
|
||||||
tab.addrow( result, row[1], row[2] )
|
tab.addrow( result, row[1], row[2] )
|
||||||
end
|
end
|
||||||
|
|
||||||
return { status = false, review = true, result = { tab.dump(result), name="Verify the following users that have access to the MySQL database" } }
|
return { status = false, review = true, result = { tab.dump(result), name="Verify the following users that have access to the MySQL database" } }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.2", desc="Do not grant FILE privileges to non Admin users",
|
test { id="5.2", desc="Do not grant FILE privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE File_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE File_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the FILE privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the FILE privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.3", desc="Do not grant PROCESS privileges to non Admin users",
|
test { id="5.3", desc="Do not grant PROCESS privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Process_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Process_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the PROCESS privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the PROCESS privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.4", desc="Do not grant SUPER privileges to non Admin users",
|
test { id="5.4", desc="Do not grant SUPER privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Super_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Super_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the SUPER privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the SUPER privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.5", desc="Do not grant SHUTDOWN privileges to non Admin users",
|
test { id="5.5", desc="Do not grant SHUTDOWN privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Shutdown_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Shutdown_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the SHUTDOWN privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the SHUTDOWN privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.6", desc="Do not grant CREATE USER privileges to non Admin users",
|
test { id="5.6", desc="Do not grant CREATE USER privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Create_user_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Create_user_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the CREATE USER privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the CREATE USER privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.7", desc="Do not grant RELOAD privileges to non Admin users",
|
test { id="5.7", desc="Do not grant RELOAD privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Reload_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Reload_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the RELOAD privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the RELOAD privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="5.8", desc="Do not grant GRANT privileges to non Admin users",
|
test { id="5.8", desc="Do not grant GRANT privileges to non Admin users",
|
||||||
sql=("SELECT user, host FROM mysql.user WHERE Grant_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
sql=("SELECT user, host FROM mysql.user WHERE Grant_priv = 'Y' AND user NOT IN (%s)"):format(createINstmt(ADMIN_ACCOUNTS)),
|
||||||
check=function(rowstab)
|
check=function(rowstab)
|
||||||
local users = col2tab(rowstab[1], 'user')
|
local users = col2tab(rowstab[1], 'user')
|
||||||
users.name = ( #users > 0 ) and "The following users were found having the GRANT privilege"
|
users.name = ( #users > 0 ) and "The following users were found having the GRANT privilege"
|
||||||
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
return { status = isEmpty(rowstab[1]), result = users, review = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-- MySQL Configuraiton options
|
-- MySQL Configuraiton options
|
||||||
test { id="6.2", desc="Disable Load data local", sql="SHOW variables WHERE Variable_name = 'local_infile' AND Value='OFF'", check=function(rowstab)
|
test { id="6.2", desc="Disable Load data local", sql="SHOW variables WHERE Variable_name = 'local_infile' AND Value='OFF'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.3", desc="Disable old password hashing", sql="SHOW variables WHERE Variable_name = 'old_passwords' AND Value='OFF'", check=function(rowstab)
|
test { id="6.3", desc="Disable old password hashing", sql="SHOW variables WHERE Variable_name = 'old_passwords' AND Value='OFF'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.4", desc="Safe show database", sql="SHOW variables WHERE Variable_name = 'safe_show_database' AND Value='ON'", check=function(rowstab)
|
test { id="6.4", desc="Safe show database", sql="SHOW variables WHERE Variable_name = 'safe_show_database' AND Value='ON'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.5", desc="Secure auth", sql="SHOW variables WHERE Variable_name = 'secure_auth' AND Value='ON'", check=function(rowstab)
|
test { id="6.5", desc="Secure auth", sql="SHOW variables WHERE Variable_name = 'secure_auth' AND Value='ON'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.6", desc="Grant tables", sql="SHOW variables WHERE Variable_name = 'skip_grant_tables' AND Value='OFF'", check=function(rowstab)
|
test { id="6.6", desc="Grant tables", sql="SHOW variables WHERE Variable_name = 'skip_grant_tables' AND Value='OFF'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.7", desc="Skip merge", sql="SHOW variables WHERE Variable_name = 'have_merge_engine' AND Value='DISABLED'", check=function(rowstab)
|
test { id="6.7", desc="Skip merge", sql="SHOW variables WHERE Variable_name = 'have_merge_engine' AND Value='DISABLED'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.8", desc="Skip networking", sql="SHOW variables WHERE Variable_name = 'skip_networking' AND Value='ON'", check=function(rowstab)
|
test { id="6.8", desc="Skip networking", sql="SHOW variables WHERE Variable_name = 'skip_networking' AND Value='ON'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.9", desc="Safe user create", sql="select @@global.sql_mode, @@session.sql_mode FROM dual WHERE @@session.sql_mode='NO_AUTO_CREATE_USER' AND @@global.sql_mode='NO_AUTO_CREATE_USER'", check=function(rowstab)
|
test { id="6.9", desc="Safe user create", sql="select @@global.sql_mode, @@session.sql_mode FROM dual WHERE @@session.sql_mode='NO_AUTO_CREATE_USER' AND @@global.sql_mode='NO_AUTO_CREATE_USER'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
test { id="6.10", desc="Skip symbolic links", sql="SHOW variables WHERE Variable_name = 'have_symlink' AND Value='DISABLED'", check=function(rowstab)
|
test { id="6.10", desc="Skip symbolic links", sql="SHOW variables WHERE Variable_name = 'have_symlink' AND Value='DISABLED'", check=function(rowstab)
|
||||||
return { status = not(isEmpty(rowstab[1])) }
|
return { status = not(isEmpty(rowstab[1])) }
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user