Nmap Development mailing list archives
Re: [nmap-svn] r35102 - nmap-exp/gyani/scripts
From: Daniel Miller <bonsaiviking () gmail com>
Date: Wed, 12 Aug 2015 22:16:39 -0500
Gyani, This one looks good to go. If you can, it would be good to include a reference or even an update script for finding the top modules and themes. Dan On Tue, Aug 11, 2015 at 2:18 PM, <commit-mailer () nmap org> wrote:
Author: gyani
Date: Tue Aug 11 12:18:48 2015
New Revision: 35102
Log:
Reviewed the drupal theme integration I had made. Made a couple of changes
added xmloutput, renamed args and variables.
Modified:
nmap-exp/gyani/scripts/http-drupal-enum.nse
Modified: nmap-exp/gyani/scripts/http-drupal-enum.nse
==============================================================================
--- nmap-exp/gyani/scripts/http-drupal-enum.nse (original)
+++ nmap-exp/gyani/scripts/http-drupal-enum.nse Tue Aug 11 12:18:48 2015
@@ -11,23 +11,25 @@
Enumerates the installed Drupal modules/themes by using a list of known
modules and themes.
The script works by iterating over module/theme names and requesting
-MODULES_PATH/MODULE_NAME/LICENSE.txt same for theme except logo.png is
searched for. MODULES_PATH is either provided by the
-user, grepped for in the html body or defaulting to sites/all/modules/.
If the
-response status code is 200, it means that the module/theme is
installed. By
+MODULES_PATH/MODULE_NAME/LICENSE.txt for modules and
THEME_PATH/THEME_NAME/LOGO.png.
+MODULES_PATH is either provided by the user, grepped for in the html body
+or defaulting to sites/all/modules/.
+
+If the response status code is 200, it means that the module/theme is
installed. By
default, the script checks for the top 100 modules (by downloads), given
the
huge number of existing modules (~10k).
]]
---
-- @args http-drupal-enum.root The base path. Defaults to <code>/</code>.
--- @args http-drupal-enum.search-limit Number of modules to check.
+-- @args http-drupal-enum.number Number of modules to check.
-- Use this option with a number or "all" as an argument to test for all
modules.
-- Defaults to <code>100</code>.
--- @args http-drupal-enum.direct_path_modules Direct Path for Modules
--- @args http-drupal-enum.direct_path_themes Direct Path for Themes
+-- @args http-drupal-enum.modules_path Direct Path for Modules
+-- @args http-drupal-enum.themes_path Direct Path for Themes
-- @args http-drupal-enum.type default all.choose between "themes" and
"modules"
-- @usage
--- nmap -p 80 --script http-drupal-enum --script-args
direct_path_modules="sites/all/modules/",direct_path_themes="themes/",search-limit=10
<target>
+-- nmap -p 80 --script http-drupal-enum --script-args
modules_path="sites/all/modules/",themes_path="themes/",number=10 <target>
--
--
--@output
@@ -45,7 +47,6 @@
-- | themes
-- |_ theme470
-- Final times for host: srtt: 329644 rttvar: 185712 to: 1072492
--- TODO version checking
-- TODO xml-output
-- TODO better paths as some use /contrib and /customs. need to search
deeper.
@@ -70,7 +71,7 @@
portrule = shortport.http
--Reads database
-local function read_data_file (file)
+local function read_data (file)
return coroutine.wrap(function ()
for line in file:lines() do
if not line:match "^%s*#" and not line:match "^%s*$" then
@@ -81,7 +82,7 @@
end
--Checks if the module/theme file exists
-local function existence_check_assign (act_file)
+local function assign_file (act_file)
if not act_file then
return false
end
@@ -100,7 +101,7 @@
else
default_path = DEFAULT_MODULES_PATH
end
- local body = http.get(host, port, root).body
+ local body = http.get(host, port, root).body or ""
local pattern = "sites/[%w.-/]*/" .. type_of .. "/"
local found_path = body:match(pattern)
return found_path or default_path
@@ -108,33 +109,33 @@
function action (host, port)
- local result = {}
+ local result = stdnse.output_table()
local file = {}
local all = {}
local requests = {}
- local drupal_autoroot
local method = "HEAD"
--Read script arguments
- local operation_type_arg = stdnse.get_script_args(SCRIPT_NAME ..
".type") or "all"
+ local resource_type = stdnse.get_script_args(SCRIPT_NAME .. ".type") or
"all"
local root = stdnse.get_script_args(SCRIPT_NAME .. ".root") or "/"
- local resource_search_arg = stdnse.get_script_args(SCRIPT_NAME ..
".search-limit") or DEFAULT_SEARCH_LIMIT
- local direct_path_themes = stdnse.get_script_args(SCRIPT_NAME ..
".direct_path_themes")
- local direct_path_modules = stdnse.get_script_args(SCRIPT_NAME ..
".direct_path_modules")
+ local search_limit = stdnse.get_script_args(SCRIPT_NAME .. ".number")
or DEFAULT_SEARCH_LIMIT
+ local themes_path = stdnse.get_script_args(SCRIPT_NAME ..
".themes_path")
+ local modules_path = stdnse.get_script_args(SCRIPT_NAME ..
".modules_path")
- local drupal_themes_file = nmap.fetchfile
"nselib/data/drupal-themes.lst"
- local drupal_modules_file = nmap.fetchfile
"nselib/data/drupal-modules.lst"
+ local themes_file = nmap.fetchfile "nselib/data/drupal-themes.lst"
+ local modules_file = nmap.fetchfile "nselib/data/drupal-modules.lst"
- if operation_type_arg == "themes" or operation_type_arg == "all" then
- local theme_db = existence_check_assign(drupal_themes_file)
+ if resource_type == "themes" or resource_type == "all" then
+ local theme_db = assign_file(themes_file)
if not theme_db then
return false, "Couldn't find drupal-themes.lst in /nselib/data/"
else
file['themes'] = theme_db
end
end
- if operation_type_arg == "modules" or operation_type_arg == "all" then
- local modules_db = existence_check_assign(drupal_modules_file)
+
+ if resource_type == "modules" or resource_type == "all" then
+ local modules_db = assign_file(modules_file)
if not modules_db then
return false, "Couldn't find drupal-modules.lst in /nselib/data/"
else
@@ -142,49 +143,40 @@
end
end
- local resource_search
- if resource_search_arg == "all" then
- resource_search = nil
- else
- resource_search = tonumber(resource_search_arg)
+ if search_limit == "all" then
+ search_limit = nil
end
- -- search the website root for evidences of a Drupal path
- local theme_path = direct_path_themes
- local module_path = direct_path_modules
-
- if not direct_path_themes then
- theme_path = get_path(host, port, root, "themes")
+ if not themes_path then
+ themes_path = (root .. get_path(host, port, root,
"themes")):gsub("//", "/")
end
- if not direct_path_modules then
- module_path = get_path(host, port, root, "modules")
+ if not modules_path then
+ modules_path = (root .. get_path(host, port, root,
"modules")):gsub("//", "/")
end
-- We default to HEAD requests unless the server returns
-- non 404 (200 or other) status code
- local response = http.head(host, port, root .. module_path ..
"randomaBcD/LICENSE.txt")
+ local response = http.head(host, port, modules_path ..
stdnse.generate_random_string(8) .. "/LICENSE.txt")
if response.status ~= 404 then
method = "GET"
end
for key, value in pairs(file) do
- local temp_table = {}
- temp_table['name'] = key
local count = 0
- for obj_name in read_data_file(value) do
+ for resource_name in read_data(value) do
count = count + 1
- if resource_search and count > resource_search then
+ if search_limit and count > search_limit then
break
end
-- add request to pipeline
if key == "modules" then
- all = http.pipeline_add(root .. module_path .. obj_name ..
"/LICENSE.txt", nil, all, method)
+ all = http.pipeline_add(resource_name .. "/LICENSE.txt", nil,
all, method)
else
- all = http.pipeline_add(root .. theme_path .. obj_name ..
"/logo.png", nil, all, method)
+ all = http.pipeline_add(resource_name .. "/LICENSE.txt", nil,
all, method)
end
-- add to requests buffer
- table.insert(requests, obj_name)
+ table.insert(requests, resource_name)
end
-- send requests
@@ -194,29 +186,29 @@
return nil
end
- for i, response in pairs(pipeline_responses) do
+ for i, response in ipairs(pipeline_responses) do
-- Module exists if 200 on HEAD
-- or contains identification string for GET or key is themes and
is image
- if method == "HEAD" and response.status == 200 or method == "GET"
and response.status == 200 and (string.match(response.body,
IDENTIFICATION_STRING) or key == "themes") then
- table.insert(temp_table, requests[i])
+ if response.status == 200 then
+ print("sumo")
+ end
+ if response.status == 200 and (method == "HEAD" or (method == "GET"
and response.body:match(IDENTIFICATION_STRING))) then
+ result[key] = result[key] or {}
+ table.insert(result[key], requests[i])
end
end
- table.insert(result, temp_table)
requests = {}
all = {}
end
- local len = 0
- for i, v in ipairs(result) do
- len = len >= #v and len or #v
- end
- if len > 0 then
- result.name = string.format("Search limited to top %s
themes/modules", resource_search)
- return stdnse.format_output(true, result)
+
+ if result['themes'] or result['modules'] then
+ return result
else
if nmap.verbosity() > 1 then
- return string.format("Nothing found amongst the top %s resources,"
.. "use --script-args search-limit=<number|all> for deeper analysis)",
resource_search)
+ return string.format("Nothing found amongst the top %s resources,"
.. "use --script-args number=<number|all> for deeper analysis)",
search_limit)
else
return nil
end
end
+
end
\ No newline at end of file
_______________________________________________
Sent through the svn mailing list
http://nmap.org/mailman/listinfo/svn
_______________________________________________ Sent through the dev mailing list https://nmap.org/mailman/listinfo/dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Re: [nmap-svn] r35102 - nmap-exp/gyani/scripts Daniel Miller (Aug 12)
