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)