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: