from flask import Flask, request, jsonify import socket import sys # Command line arguments: python backend.py [password] if len(sys.argv) < 3: print("Usage: python backend.py [valkey_password]") sys.exit(1) VALKEY_HOST = sys.argv[1] VALKEY_PORT = int(sys.argv[2]) VALKEY_PASSWORD = sys.argv[3] if len(sys.argv) > 3 else "" app = Flask(__name__) sock = None def init_socket(): global sock sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((VALKEY_HOST, VALKEY_PORT)) if VALKEY_PASSWORD: auth_cmd = f"*2\r\n$4\r\nAUTH\r\n${len(VALKEY_PASSWORD)}\r\n{VALKEY_PASSWORD}\r\n" sock.sendall(auth_cmd.encode()) sock.recv(1024) @app.route('/api/user/role', methods=['POST']) def set_user_role(): global sock try: data = request.json username = data.get('username') role = data.get('role') print(f"[SET] {username} = {role}") key = f"user:{username}:role" set_cmd = f"*3\r\n$3\r\nSET\r\n${len(key)}\r\n{key}\r\n${len(role)}\r\n{role}\r\n" sock.sendall(set_cmd.encode()) sock.recv(1024) return jsonify({"status": "success", "username": username, "role": role}) except Exception as e: return jsonify({"status": "error", "error": str(e)}), 500 @app.route('/api/process', methods=['POST']) def process_script(): global sock try: data = request.json script = data.get('script', '') print(f"[EVAL] Lua script executed (injection in buffer)") eval_cmd = f"*3\r\n$4\r\nEVAL\r\n${len(script)}\r\n{script}\r\n$1\r\n0\r\n" sock.sendall(eval_cmd.encode()) # Read ONLY the first line, leave injection in buffer error_line = b"" while not error_line.endswith(b"\r\n"): chunk = sock.recv(1) if not chunk: break error_line += chunk return jsonify({"status": "error", "error": error_line.decode().strip()}), 500 except Exception as e: return jsonify({"status": "error", "error": str(e)}), 500 @app.route('/api/user/role', methods=['GET']) def get_user_role(): global sock username = request.args.get('username', 'victim') try: key = f"user:{username}:role" get_cmd = f"*2\r\n$3\r\nGET\r\n${len(key)}\r\n{key}\r\n" sock.sendall(get_cmd.encode()) first_line = b"" while not first_line.endswith(b"\r\n"): chunk = sock.recv(1) if not chunk: break first_line += chunk if not first_line: print(f"[GET] Error: Empty response") return jsonify({"status": "error", "error": "Empty response"}), 500 first_line_str = first_line.decode().strip() if first_line_str.startswith("$"): length_str = first_line_str[1:] if length_str == "-1": print(f"[GET] {username} = None") return jsonify({"status": "success", "username": username, "role": None}) length = int(length_str) data_bytes = b"" while len(data_bytes) < length: chunk = sock.recv(length - len(data_bytes)) if not chunk: break data_bytes += chunk sock.recv(2) # trailing \r\n data = data_bytes.decode() print(f"[GET] {username} = {data}") return jsonify({"status": "success", "username": username, "role": data}) elif first_line_str.startswith("+"): # Simple string response data = first_line_str[1:] print(f"[GET] {username} = {data}") return jsonify({"status": "success", "username": username, "role": data}) elif first_line_str.startswith("-"): print(f"[GET] Error: {first_line_str}") return jsonify({"status": "error", "error": first_line_str}), 500 print(f"[GET] Unexpected: '{first_line_str}'") return jsonify({"status": "error", "error": f"Unexpected response: {first_line_str}"}), 500 except Exception as e: return jsonify({"status": "error", "error": str(e)}), 500 if __name__ == '__main__': print(f"Backend server starting... ({VALKEY_HOST}:{VALKEY_PORT})") init_socket() app.run(host='0.0.0.0', port=5001, debug=False)