Consegui parte do código de uma aplicação que eu sei que esta rodando em https://socketfeaver-7jktu72cma-uc.a.run.app/, sera que consigo fazer algo com isso?
BOITA{f4_S2_55t1}

Primeiramente, ao entrar no site podemos se deparar com a seguinte aplicação:

center

E o código da aplicação sendo:

import sqlite3, random
from flask import Flask, render_template, render_template_string, redirect, request, session
from waitress import serve
from flask_socketio import SocketIO, emit
 
app = Flask(__name__)
app.secret_key = 'slakjkjkj'
socketio = SocketIO(app)
 
def AntiSqli(login, senha):
    blacklist = ["'", "-", '"']
    if login != '' and senha != '':
        for char in blacklist:
            if char in login or char in senha:
                return 1
            else:
                pass
 
        return 0
    else:
        return 1
 
def loginApp(login, senha):
    protect = AntiSqli(login, senha)
    if protect == 0:
        banco = sqlite3.connect('f4ctf.db')
        cursor = banco.cursor()
        cursor.execute(f"SELECT * FROM users WHERE nome = '{login}' AND senha = '{senha}'")
        if cursor.fetchall() != []:
            return 0
        else:
            return 1
 
    else:
        return 1
 
def registerApp(login, senha, nickname):
    banco = sqlite3.connect('f4ctf.db')
    cursor = banco.cursor()
    cursor.execute(f"SELECT * FROM users WHERE nome = '{login}' AND senha = '{senha}'")
 
    if cursor.fetchall() == []:
        cursor.execute(f"INSERT INTO users(nome, senha, nickname) VALUES ('{login}', '{senha}', '{nickname}')")
        banco.commit()
        
        return 0
    else:
        return 1
 
@app.route('/')
def welcome():
    return redirect('/login')
 
@app.route('/<alo>')
def alo(alo):
    try:
        if ('user' in session and session['user'] == username):
            return ''
        else:
            nmr = (random.randint(99999,9999999))
            return render_template('notfound.html', saida=nmr)
    except:
        nmr = (random.randint(99999,9999999))
        return render_template('notfound.html', saida=nmr)
 
@app.route('/register', methods=['GET', 'POST'])
def register():
    global username
    if request.method == 'POST':
        try:
            username = request.form['username']
            password = request.form['password']
            nickname = request.form['nickname']
 
            if registerApp(username, password, nickname) == 0:
                session['nickname'] = nickname
                return redirect('/login')
            else:
                pass
        except:
            return render_template('register.html')
    return render_template('register.html')
 
 
@app.route('/login', methods=['GET', 'POST'])
def login():
    global username
    if request.method == 'POST':
        try:
            username = request.form['username']
            password = request.form['password']
 
            banco = sqlite3.connect('./f4ctf.db')
            cursor = banco.cursor()
            cursor.execute(f"SELECT * FROM users WHERE nome = '{username}'")
            result = cursor.fetchall()
 
  
            if loginApp(username, password) == 0:
                session['user'] = username
                session['nickname'] = str(result[0][2])
                return redirect('/chat')
            else:
                pass
        except:
            return render_template('index.html')
    return render_template('index.html')
 
@app.route('/chat', methods=['GET', 'POST'])
def chat():        
    try:
        if ('user' in session and session['user'] == username):
            nick = render_template_string(session['nickname'])
            return render_template('socket.html', uname=nick)
 
        else:
            nmr = (random.randint(99999,9999999))
            return render_template('notfound.html', saida=nmr)
 
    except Exception as error:
        print(error)
        nmr = (random.randint(99999,9999999))
        return render_template('notfound.html', saida=nmr)
 
@socketio.on('username')
def handle_message(data):
    socketio.username = data
    
@socketio.on('message')
def handle_message(data):
    emit('message', {'username': socketio.username, 'message': data}, broadcast=True)
 
@app.route('/logout', methods=['GET'])
def logout():
    try:
        if ('user' in session and session['user'] == username):
            resp = redirect('/login')
            resp.delete_cookie("session")
            return resp
        else:
            pass
 
    except:
        nmr = (random.randint(99999,9999999))
        return render_template('notfound.html', saida=nmr)
 
 
if __name__ == '__main__':
    print('[+]Name:   SocketFeaver\n[+]Host:   0.0.0.0\n[+]Port:   80\n[+]Status: Up')
    serve(app, host='0.0.0.0', port=80)

Em uma primeira análise, podemos descartar a possibilidade de ataques do tipo (CWE-89) SQL Injection nos campo de login. E, após executar testes automatizados utilizando o SQLMap nos parâmetros de inscrição, percebemos que todos os parâmetros são falsos-positivos.

center center center

Dessa maneira, somos obrigados a procurar outro ponto de exploração nessa aplicação.

Criando uma conta nesse sistema, podemos perceber que o parâmetro nickname reflete diretamente na página após o login:

center

Juntando o fato de que temos uma aplicação construída em Python sobre o framework Flask, há uma grande desconfiança que possa existir algum tipo de (CWE-1336) Server-Side Template Injection (SSTI) nessa plataforma. Assim, para testar, iremos criar uma nova conta com o nickname {{ 7*7 }}.

É notório agora que temos um (CWE-1336) Server-Side Template Injection (SSTI). Podemos então inserir um payload malicioso para ler o conteúdo da flag. O payload que usaremos será:

{{request.application.__globals__.__builtins__.__import__("os").popen("cat flag.txt").read()}}

O payload funciona da seguinte forma:

  1. Ele pega o atributo global do flask application
  2. Desse atributo, ele pega o atributo global do Python __globals__
  3. Desse atributo, ele chamada os builtins do Python com __builtins__
  4. Esse atributo, por sua vez, importa a biblioteca os
  5. É chamada a função popen para conseguir um Arbitrary Command Execution
  6. O conteúdo do comando é lido pelo método read()

E assim, conseguimos pegar a flag em questão.

center