1. یک روش اجرای Sandbox را انتخاب کنید

Sandboxing با یک مجری شروع می شود (به Sandbox Executor مراجعه کنید)، که مسئول اجرای Sandboxee است. فایل هدر executor.h حاوی API مورد نیاز برای این منظور است. API بسیار منعطف است و به شما امکان می دهد بهترین گزینه را برای مورد استفاده خود انتخاب کنید. بخش های زیر 3 روش مختلف را که می توانید از بین آنها انتخاب کنید، شرح می دهد.

روش 1: مستقل - یک باینری را با سندباکس از قبل فعال کنید

این ساده‌ترین راه برای استفاده از sandboxing است و زمانی که می‌خواهید یک باینری کامل را که هیچ کد منبعی برای آن ندارید، جعبه سندباکس کنید، توصیه می‌شود. همچنین ایمن‌ترین راه برای استفاده از sandboxing است، زیرا هیچ مقدار اولیه بدون سندباکس وجود ندارد که بتواند اثرات نامطلوبی داشته باشد.

در قطعه کد زیر، مسیر باینری را برای سندباکس شدن و آرگومان هایی که باید به یک execve syscall ارسال کنیم، تعریف می کنیم. همانطور که در فایل هدر executor.h مشاهده می کنید، مقداری برای envp تعیین نمی کنیم و بنابراین محیط را از فرآیند والد کپی می کنیم. به یاد داشته باشید، اولین آرگومان همیشه نام برنامه ای است که باید اجرا شود، و قطعه ما هیچ آرگومان دیگری را تعریف نمی کند.

نمونه هایی از این روش اجرا کننده عبارتند از: استاتیک و ابزار .

#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: Sandbox2 Forkserver - به مجری بگویید چه زمانی باید Sandbox شود

این روش انعطاف‌پذیری را ارائه می‌دهد که در طول مقداردهی اولیه، جعبه‌بندی نشده باشد، و سپس با فراخوانی ::sandbox2::Client::SandboxMeHere() انتخاب کنید که چه زمانی وارد sandbox شود. این نیاز دارد که بتوانید زمانی را که می خواهید sandboxing را شروع کنید در کد تعریف کنید، و باید تک رشته ای باشد (چرا در پرسش های متداول بخوانید).

در قطعه کد زیر، از همان کدی استفاده می کنیم که در روش 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() sandbox را شروع کنید.

// 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 ) اطلاع می‌دهد که چه زمانی باید وارد sandbox شود.

روش 3: Forkserver سفارشی - یک باینری آماده کنید، منتظر درخواست فورک و جعبه سند باشید.

این حالت به شما امکان می دهد یک باینری را راه اندازی کنید، آن را برای sandboxing آماده کنید و در یک لحظه خاص از چرخه حیات باینری خود، آن را در اختیار مجری قرار دهید.

مجری یک درخواست فورک را به باینری شما ارسال می کند، که 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 دارای یک مقداردهی اولیه طولانی و فشرده CPU است که می تواند قبل از پردازش داده های نامعتبر اجرا شود.

برای مثالی از این روش اجرایی، custom_fork را ببینید.

،

1. یک روش اجرای Sandbox را انتخاب کنید

Sandboxing با یک مجری شروع می شود (به Sandbox Executor مراجعه کنید)، که مسئول اجرای Sandboxee است. فایل هدر executor.h حاوی API مورد نیاز برای این منظور است. API بسیار منعطف است و به شما امکان می دهد بهترین گزینه را برای مورد استفاده خود انتخاب کنید. بخش های زیر 3 روش مختلف را که می توانید از بین آنها انتخاب کنید، شرح می دهد.

روش 1: مستقل - یک باینری را با سندباکس از قبل فعال کنید

این ساده‌ترین راه برای استفاده از sandboxing است و زمانی که می‌خواهید یک باینری کامل را که هیچ کد منبعی برای آن ندارید، جعبه سندباکس کنید، توصیه می‌شود. همچنین ایمن‌ترین راه برای استفاده از sandboxing است، زیرا هیچ مقدار اولیه بدون سندباکس وجود ندارد که بتواند اثرات نامطلوبی داشته باشد.

در قطعه کد زیر، مسیر باینری را برای سندباکس شدن و آرگومان هایی که باید به یک execve syscall ارسال کنیم، تعریف می کنیم. همانطور که در فایل هدر executor.h مشاهده می کنید، مقداری برای envp تعیین نمی کنیم و بنابراین محیط را از فرآیند والد کپی می کنیم. به یاد داشته باشید، اولین آرگومان همیشه نام برنامه ای است که باید اجرا شود، و قطعه ما هیچ آرگومان دیگری را تعریف نمی کند.

نمونه هایی از این روش اجرا کننده عبارتند از: استاتیک و ابزار .

#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: Sandbox2 Forkserver - به مجری بگویید چه زمانی باید Sandbox شود

این روش انعطاف‌پذیری را ارائه می‌دهد که در طول مقداردهی اولیه، جعبه‌بندی نشده باشد، و سپس با فراخوانی ::sandbox2::Client::SandboxMeHere() انتخاب کنید که چه زمانی وارد sandbox شود. این نیاز دارد که بتوانید زمانی را که می خواهید sandboxing را شروع کنید در کد تعریف کنید، و باید تک رشته ای باشد (چرا در پرسش های متداول بخوانید).

در قطعه کد زیر، از همان کدی استفاده می کنیم که در روش 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() sandbox را شروع کنید.

// 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 ) اطلاع می‌دهد که چه زمانی باید وارد sandbox شود.

روش 3: Forkserver سفارشی - یک باینری آماده کنید، منتظر درخواست فورک و جعبه سند باشید.

این حالت به شما امکان می دهد یک باینری را راه اندازی کنید، آن را برای sandboxing آماده کنید و در یک لحظه خاص از چرخه حیات باینری خود، آن را در اختیار مجری قرار دهید.

مجری یک درخواست فورک را به باینری شما ارسال می کند، که 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 دارای یک مقداردهی اولیه طولانی و فشرده CPU است که می تواند قبل از پردازش داده های نامعتبر اجرا شود.

برای مثالی از این روش اجرایی، custom_fork را ببینید.