1. اختيار طريقة تنفيذ في وضع الحماية
يبدأ وضع الحماية باستخدام برنامج تنفيذي (راجِع Sandbox Executor)، وهو المسؤول عن تشغيل Sandboxee. يحتوي ملف العنوان executor.h على واجهة برمجة التطبيقات اللازمة لهذا الغرض. تتسم واجهة برمجة التطبيقات بالمرونة الشديدة وتتيح لك اختيار ما يناسب حالة الاستخدام. توضّح الأقسام التالية الأساليب الثلاثة المختلفة التي يمكنك الاختيار من بينها.
الطريقة 1: مستقلة – تنفيذ ملف ثنائي مع تفعيل وضع الحماية
هذه هي أبسط طريقة لاستخدام وضع الحماية، وهي الطريقة المقترَحة عندما تريد وضع برنامج ثنائي كامل في وضع الحماية بدون توفّر الرمز المصدر. وهي أيضًا الطريقة الأكثر أمانًا لاستخدام وضع الحماية، لأنّه لا يوجد تهيئة خارج وضع الحماية يمكن أن يكون لها تأثيرات سلبية.
في مقتطف الرمز التالي، نحدّد مسار الملف الثنائي الذي سيتم وضعه في وضع الحماية
والوسيطات التي يجب تمريرها إلى استدعاء نظام execve. كما هو موضّح في ملف العنوان
executor.h، لا نحدّد قيمة لـ envp
، وبالتالي ننسخ البيئة من العملية الرئيسية. تذكَّر أنّ الوسيطة الأولى هي دائمًا اسم البرنامج المطلوب تنفيذه، وأنّ مقتطف الرمز لا يحدّد أي وسيطة أخرى.
من الأمثلة على طريقة التنفيذ هذه: static و tool.
#include "sandboxed_api/sandbox2/executor.h"
std::string path = "path/to/binary";
std::vector<std::string> args = {path}; // args[0] will become the sandboxed
// process' argv[0], typically the
// path to the binary.
auto executor = absl::make_unique<sandbox2::Executor>(path, args);
الطريقة 2: Forkserver في Sandbox2 - تحديد وقت وضع التنفيذ في وضع الحماية
توفّر هذه الطريقة مرونة عدم استخدام وضع الحماية أثناء عملية التهيئة، ثم اختيار وقت تفعيل وضع الحماية من خلال استدعاء ::sandbox2::Client::SandboxMeHere()
. ويجب أن تكون قادرًا على تحديد وقت بدء وضع الحماية في الرمز البرمجي، كما يجب أن يكون الرمز البرمجي أحادي السلسلة (يمكنك الاطّلاع على السبب في الأسئلة الشائعة).
في مقتطف الرمز التالي، نستخدم الرمز نفسه الموضّح في الطريقة 1 أعلاه. ومع ذلك، للسماح للبرنامج بالتنفيذ بطريقة غير محددة النطاق أثناء عملية التهيئة، نطلب set_enable_sandbox_before_exec(false)
.
#include "sandboxed_api/sandbox2/executor.h"
std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto executor = absl::make_unique<sandbox2::Executor>(path, args);
executor->set_enable_sandbox_before_exec(false);
بما أنّ المنفّذ لديه الآن بيئة اختبار معطّلة إلى أن يتم إعلامه من خلال Sandboxee، علينا إنشاء مثيل ::sandbox2::Client
، وإعداد عملية التواصل بين المنفّذ وSandboxee، ثم إعلام المنفّذ بأنّ عملية الإعداد قد انتهت وأنّنا نريد بدء استخدام بيئة الاختبار الآن من خلال استدعاء sandbox2_client.SandboxMeHere()
.
// main() of sandboxee
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, false);
// Set-up the sandbox2::Client object, using a file descriptor (1023).
sandbox2::Comms comms(sandbox2::Comms::kSandbox2ClientCommsFD);
sandbox2::Client sandbox2_client(&comms);
// Enable sandboxing from here.
sandbox2_client.SandboxMeHere();
…
أحد الأمثلة على طريقة التنفيذ هذه هو crc4، حيث يمثّل crc4bin.cc
Sandboxee ويُعلم المنفّذ (crc4sandbox.cc
) بموعد الدخول إلى وضع الحماية.
الطريقة 3: Forkserver مخصّص - إعداد ملف ثنائي، والانتظار لتلقّي طلبات fork، وتوفير بيئة الاختبار المعزولة بنفسك
يتيح لك هذا الوضع بدء تشغيل ملف ثنائي وإعداده لتشغيله في بيئة معزولة، كما يتيح لك إتاحته للمنفّذ في لحظة معيّنة من دورة حياة الملف الثنائي.
سيرسل برنامج التنفيذ طلب إنشاء نسخة إلى الرمز الثنائي، والذي سيتم fork()
(عبر ::sandbox2::ForkingClient::WaitAndFork()
). وستكون العملية التي تم إنشاؤها حديثًا جاهزة لوضعها في بيئة الاختبار المعزولة باستخدام ::sandbox2::Client::SandboxMeHere()
.
#include "sandboxed_api/sandbox2/executor.h"
// Start the custom ForkServer
std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto fork_executor = absl::make_unique<sandbox2::Executor>(path, args);
fork_executor->StartForkServer();
// Initialize Executor with Comms channel to the ForkServer
auto executor = absl::make_unique<sandbox2::Executor>(
fork_executor->ipc()->GetComms());
يُرجى العِلم أنّ هذا الوضع معقّد جدًا ولا ينطبق إلا في حالات محدودة، مثل عندما تكون لديك متطلبات صارمة بشأن الذاكرة. ستستفيد من COW ولكن سيكون هناك عيب يتمثل في عدم توفّر ASLR حقيقي. من الأمثلة الأخرى على الاستخدام الشائع أن يكون لدى Sandboxee عملية إعداد طويلة ومكثفة لوحدة المعالجة المركزية يمكن تشغيلها قبل معالجة البيانات غير الموثوق بها.
للاطّلاع على مثال على طريقة التنفيذ هذه، راجِع custom_fork.