
مفكِّك ترميز pickling في بايثون ومحلِّل ثابت.

Fickling هو مفكك كود، ومحلل ثابت، وأداة إعادة كتابة البايت كود لتسلسلات كائنات Python pickle. يمكنك استخدام Fickling لكشف، وتحليل، وهندسة عكسية، أو حتى إنشاء ملفات pickle أو ملفات قائمة على pickle خبيثة، بما في ذلك ملفات PyTorch.
يمكن استخدام Fickling كـ مكتبة بايثون و واجهة سطر أوامر معًا.
تم اختبار Fickling على Python 3.9 حتى Python 3.13 وله تبعيات قليلة جدًا. يمكن تثبيت كل من المكتبة وأداة سطر الأوامر عبر pip أو uv:
# Using pip
python -m pip install fickling
# Using uv
uv pip install fickling
PyTorch هي تبعية اختيارية لـ Fickling. لذلك، من أجل استخدام وحدتي pytorch
و الخاصتين بـ Fickling، يجب عليك تشغيل:
polyglot# Using pip
python -m pip install fickling[torch]
# Using uv
uv pip install fickling[torch]
يمكن أن يساعد Fickling في تأمين قواعد أكواد الذكاء الاصطناعي/التعلم الآلي من خلال المسح التلقائي لملفات pickle الموجودة في النماذج. يربط Fickling وحدة pickle ويتحقق من عمليات الاستيراد التي تتم عند تحميل نموذج. وهو يتحقق فقط من الاستيرادات مقابل قائمة مسموح بها من الاستيرادات من مكتبات التعلم الآلي التي تُعتبر آمنة، ويحظر الملفات التي تحتوي على استيرادات أخرى.
أضف الأسطر التالية في أقرب وقت ممكن، قبل استيراد torch أو numpy أو أي مكتبة أخرى تستخدم pickle:
import fickling
# This sets global hooks on pickle
fickling.hook.activate_safe_ml_environment()
لإزالة الحماية:
fickling.hook.deactivate_safe_ml_environment()
من الممكن أن تحتوي النماذج التي تستخدمها على استيرادات غير مسموح بها من قبل Fickling. إذا كنت لا تزال ترغب في تحميل النموذج، يمكنك ببساطة السماح باستيرادات إضافية لحالة الاستخدام الخاصة بك عبر وسيط also_allow:
fickling.hook.activate_safe_ml_environment(
also_allow=[
"some.import",
"another.allowed.import",
]
)
مهم: يجب عليك دائمًا التأكد من أن الاستيرادات المُضافة يدويًا آمنة فعليًا ولا يمكن أن تمكن المهاجمين من تنفيذ كود تعسفي. إذا لم تكن متأكدًا من كيفية القيام بذلك، يمكنك فتح مشكلة في مستودع Fickling على Github تشير إلى الاستيرادات/النماذج المعنية، وسيقوم فريقنا بمراجعتها وإدراجها في القائمة المسموح بها إذا أمكن.
يمكن دمج Fickling بسلاسة في قاعدة الأكواد الخاصة بك لكشف وإيقاف تحميل الملفات الخبيثة في وقت التشغيل.
فيما يلي نعرض الطرق المختلفة التي يمكنك من خلالها استخدام fickling لفرض فحوصات السلامة على ملفات pickle.
في الخلفية، يربط fickling مكتبة pickle لإضافة فحوصات سلامة بحيث يؤدي تحميل ملف pickle إلى إطلاق استثناء UnsafeFileError إذا تم اكتشاف محتوى خبيث في الملف.
# This enforces safety checks every time pickle is used to deserialize
fickling.always_check_safety()
# Attempt to load an unsafe file now raises an exception
with open("file.pkl", "rb") as f:
try:
pickle.load(f)
except fickling.UnsafeFileError:
print("Unsafe file!")
with fickling.check_safety():
# All pickle files loaded within the context manager are checked for safety
try:
with open("file.pkl", "rb") as f:
pickle.load("file.pkl")
except fickling.UnsafeFileError:
print("Unsafe file!")
# Files loaded outside of context manager are NOT checked
pickle.load("file.pkl")
عند الخروج، يستعيد مدير السياق أي شيء تم تثبيته عند الدخول إليه، لذلك يظل الخطاف الموجود بالفعل ساريًا بدلاً من ترك pickle بدون خطاف.
# Use fickling.load() in place of pickle.load() to check safety and load a single pickle file
try:
fickling.load("file.pkl")
except fickling.UnsafeFileError as e:
print("Unsafe file!")
# Perform a safety check on a pickle file without loading it
if not fickling.is_likely_safe("file.pkl"):
print("Unsafe file!")
يمكنك الوصول إلى تفاصيل تحليل السلامة في fickling من داخل الاستثناء المُطلق:
>>> try:
... fickling.load("unsafe.pkl")
... except fickling.UnsafeFileError as e:
... print(e.info)
{
"severity": "OVERTLY_MALICIOUS",
"analysis": "Call to `eval(b'[5, 6, 7, 8]')` is almost certainly evidence of a malicious pickle file. Variable `_var0` is assigned value `eval(b'[5, 6, 7, 8]')` but unused afterward; this is suspicious and indicative of a malicious pickle file",
"detailed_results": {
"AnalysisResult": {
"OvertlyBadEval": "eval(b'[5, 6, 7, 8]')",
"UnusedVariables": [
"_var0",
"eval(b'[5, 6, 7, 8]')"
]
}
}
}
إذا كنت تستخدم لغة أخرى غير Python، فلا يزال بإمكانك استخدام CLI الخاصة بـ fickling للتحقق من سلامة ملفات pickle:
fickling --check-safety -p pickled.data
تتيح CLI الخاصة بـ Fickling تتبع تنفيذ الآلة الافتراضية الخاصة بـ Pickle بأمان دون تمرين أي كود خبيث:
fickling --trace file.pkl
يتيح Fickling حقن كود تعسفي في ملف pickle سيتم تشغيله في كل مرة يتم فيها تحميل الملف:
fickling --inject "print('Malicious')" file.pkl > malicious.pkl
يمكن استخدام Fickling لتفكيك ملف pickle لمزيد من التحليل:
>>> import ast, pickle
>>> from fickling.fickle import Pickled
>>> fickled_object = Pickled.load(pickle.dumps([1, 2, 3, 4]))
>>> print(ast.dump(fickled_object.ast, indent=4))
Module(
body=[
Assign(
targets=[
Name(id='result', ctx=Store())],
value=List(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3),
Constant(value=4)],
ctx=Load()))],
type_ignores=[])
يحتوي PyTorch على تنسيقات ملفات متعددة يمكن من خلالها إنشاء ملفات متعددة الصيغ، وهي ملفات يمكن تفسيرها بشكل صحيح كأكثر من تنسيق ملف واحد. يدعم Fickling تحديد وإنشاء وفحص الملفات متعددة الصيغ باستخدام تنسيقات ملفات PyTorch التالية:
>> import torch
>> import torchvision.models as models
>> from fickling.pytorch import PyTorchModelWrapper
>> model = models.mobilenet_v2()
>> torch.save(model, "mobilenet.pth")
>> fickled_model = PyTorchModelWrapper("mobilenet.pth")
>> print(fickled_model.formats)
Your file is most likely of this format: PyTorch v1.3
['PyTorch v1.3']
اطّلع على أمثلتنا لمعرفة المزيد حول استخدام fickling!
كائنات Python المخللة هي في الواقع بايت كود يتم تفسيره بواسطة آلة افتراضية مبنية على مكدس داخل Python تسمى "Pickle Machine". يمكن لـ Fickling أخذ تدفقات بيانات pickle المخللة وتفكيكها إلى كود Python قابل للقراءة البشرية، والذي عند تنفيذه، سيعيد إنتاج الكائن المتسلسل الأصلي. هذا ممكن بفضل تنفيذ Fickling المخصص لـ PM. يعتبر Fickling آمنًا للتشغيل على ملفات قد تكون خبيثة لأن PM الخاص به ينفذ الكود بشكل رمزي بدلاً من تنفيذه بشكل صريح.
لا يحدد المؤلفون أي معنى لحرف "F" في Fickling؛ قد يرمز إلى "fickle"، ... أو شيء آخر. استنباط معناه هو رحلة شخصية في التقدير وتُترك كتمرين للقارئ.
تعلم المزيد عن fickling في مقالنا و محاضرة DEF CON AI Village 2021.
إذا كنت ترغب في تقديم تقرير خطأ أو طلب ميزة، فيرجى استخدام صفحة المشكلات الخاصة بنا. لا تتردد في الاتصال بنا أو التواصل عبر Empire Hacking للحصول على مساعدة في استخدام أو توسيع fickling.
تم تطوير هذه الأداة بواسطة Trail of Bits. وهي مرخصة بموجب رخصة GNU Lesser General Public License v3.0. تواصل معنا إذا كنت تبحث عن استثناء للشروط.
© 2021, Trail of Bits.