from __future__ import annotations import argparse import json import shutil import subprocess import tempfile import urllib.request from pathlib import Path ROOT = Path("/home/hacnho/Projects/research") PY = ROOT / "targets/huntr/work/mleap-lab/.venv/bin/python" FILES = [ "control_model.json", "control_node.json", "trigger_model.json", "trigger_node.json", ] def parse_args() -> argparse.Namespace: ap = argparse.ArgumentParser() ap.add_argument("--repo", default="hacnho/mleap-mathbinary-pow-trigger-poc") return ap.parse_args() def main() -> int: args = parse_args() base = f"https://huggingface.co/{args.repo}/resolve/main" td = Path(tempfile.mkdtemp(prefix="hf_mleap_mathbinary_")) try: for name in FILES: urllib.request.urlretrieve(f"{base}/{name}", td / name) code = f""" import json from pathlib import Path import numpy as np from mleap.sklearn.preprocessing.data import MathBinary root = Path({str(td)!r}) ctrl = MathBinary().deserialize_from_bundle(str(root), 'control.node') evil = MathBinary().deserialize_from_bundle(str(root), 'trigger.node') rows = [] for x, y in [(2.0, 0.0), (2.0, 1.0), (3.0, 1.0), (2.0, 2.0), (0.0, 1.0), (1.0, 1.0), (-1.0, 1.0)]: arr = np.array([[x, y]], dtype='float64') rows.append({{ 'x': x, 'y': y, 'control': ctrl.transform(arr).values.tolist(), 'malicious': evil.transform(arr).values.tolist(), }}) print(json.dumps({{'rows': rows}}, indent=2)) """ proc = subprocess.run( [str(PY), "-c", code], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, ) payload = json.loads(proc.stdout[proc.stdout.find("{"):]) rows = payload["rows"] modelscan = shutil.which("modelscan") scans = [] if modelscan: for name in FILES: scan = subprocess.run( [modelscan, "-p", str(td / name)], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, ) scans.append( { "file": name, "clean": "No issues found" in scan.stdout, "stdout_tail": scan.stdout[-2000:], } ) out = { "repo": args.repo, "base": base, "rows": rows, "backdoor_observed": any( row["x"] == 2.0 and row["y"] == 0.0 and row["control"] == [[0.0]] and row["malicious"] == [[1.0]] for row in rows ), "benign_rows_equal": all( (row["x"] == 2.0 and row["y"] == 0.0) or row["control"] == row["malicious"] for row in rows ), "modelscan": scans, } print(json.dumps(out, indent=2)) return 0 finally: shutil.rmtree(td, ignore_errors=True) if __name__ == "__main__": raise SystemExit(main())