38

Chrome のサンドボックスがどのように機能し、ユーザーを悪意のあるコードから保護するために何をするかを説明するリソースがいくつかあります。

Chromium ブログ
Chromium 開発者ドキュメント
サンドボックス FAQ

それは素晴らしいことです。私は、彼らが採用している OS 中心の設計が気に入っています (「OS は、おそらく私たちよりも自分自身を保護する方法を知っているので、私たちはそれを許可します」というアプローチのようなものです)。サンドボックス自体は、Chrome に依存しないように設計されていますが、多かれ少なかれスタンドアロンであるため、プログラムのアーキテクチャに互換性がある限り、理論的にはすべてのプロセスをサンドボックス化できます (サンドボックス化されたコードは、サンドボックス化されていない親)。

たまたま、設計がサンドボックス化に適したアプリケーションを持っていて、それで親/子プロセスを動作させることができました。Chromium コードを入手しましたが、次に何をすればよいかわかりません。

誰かが実際にこれで何かをサンドボックス化しましたか? 使用方法や API を文書化したリソースはありますか? かなり単純なはずだと思いますが、どこから始めればよいのか途方に暮れています。

編集:答えの下にある私の発見!

4

2 に答える 2

31

さて、Chrome でコードをサンドボックス化することについて私が見つけたものは次のとおりです。

まず、クロムのソース コードを取得する必要があります。これは大きく、取得にはしばらく時間がかかりますが、使用可能な結果が得られる信頼できるチェックアウトへのショートカットをまだ見つけていません。また、そのページの指示に厳密に従うことが非常に重要です。Google の乗組員は自分たちが何をしているのかを知っており、無駄な手順には熱心ではありません。そのページのすべてが必要です。はい。すべての。

ソースを取得したら、サンドボックスを使用するために実際にクロム全体をビルドする必要はありません (数時間かかることもあります!)。代わりに、スタンドアロンを構築できる別のサンドボックス ソリューション (サンドボックス フォルダーにあります) を提供するのに十分なほど優れています。このプロジェクトをビルドし、すべてがコンパイルされることを確認します。もしそうなら、素晴らしいです!そうでない場合は、ビルド ページの手順に従っていませんか? 頭を下げて、今度は実際にやってみよう。心配しないで、待ってます...

すべてが構築されたので、sandbox_poc プロジェクト (「poc」 = 概念実証) に注目します。このプロジェクトは基本的に、サンドボックス環境の特定のエントリ ポイントで任意の dll を起動するサンドボックスの最小限の GUI ラッパーです。サンドボックスを作成して使用するために必要なすべての手順を示しており、これまでで最高のリファレンスです。しばし参考に!

コードに目を通してみると、実際にサンドボックス化されているコードがそれ自体であることに気付くでしょう。これはすべてのサンドボックスの例で非常に一般的であり、このスレッド(古い可能性があります) によると、おそらく現時点でサンドボックス化する唯一の有効な方法です。このスレッドでは、理論的に別のプロセスをサンドボックス化する方法について説明していますが、私は試していません。ただし、安全のために、自己呼び出しアプリを使用することは「既知の適切な」方法です.

sandbox_proc には非常に多くの静的ライブラリが含まれていますが、それらはほとんどが構築したサンプル UI 用のようです。最小限のサンドボックスに必要と思われる唯一のものは次のとおりです。

sandbox.lib base.lib dbghelp.lib

ただし、プロジェクトを見ても完全には明らかではない別の依存関係があり、それは私が最も長く巻き込まれたものです. サンドボックス ソリューションを構築すると、出力ファイルの 1 つが " wowhelper.exe" になります。どこにも言及されていませんが、このファイルは、サンドボックス化している実行可能ファイルと同じディレクトリにコピーする必要があります。そうでない場合、コードをサンドボックス化しようとすると、一般的な「ファイルが見つかりません」というエラーで常に失敗します。何が起こっているのかわからない場合、これは非常にイライラする可能性があります。今、私は Windows 7 64 ビットで開発していますが、これは wowhelper の要件 (WOW は 16/32/64 ビット間の相互運用アプリの一般的な頭字語です) と関係があるかもしれませんが、それをテストする良い方法がありません。たった今。他に詳しい方いたら教えてください!

これで環境に関することはすべて終わりました。ここにちょっとしたサンプル コードがあります。ここでは子プロセスで wcout を使用していますが、サンドボックスで実行するとコンソール出力が表示されないことに注意してください。そのようなものはすべて、IPC を介して親プロセスに伝える必要があります。

#include <sandbox/src/sandbox.h>
#include <sandbox/src/sandbox_factory.h>
#include <iostream>

using namespace std;

int RunParent(int argc, wchar_t* argv[], sandbox::BrokerServices* broker_service) {
    if (0 != broker_service->Init()) {
        wcout << L"Failed to initialize the BrokerServices object" << endl;
        return 1;
    }

    PROCESS_INFORMATION pi;

    sandbox::TargetPolicy* policy = broker_service->CreatePolicy();

    // Here's where you set the security level of the sandbox. Doing a "goto definition" on any
    // of these symbols usually gives you a good description of their usage and alternatives.
    policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
    policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, sandbox::USER_LOCKDOWN);
    policy->SetAlternateDesktop(true);
    policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);

    //Add additional rules here (ie: file access exceptions) like so:
    policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, sandbox::TargetPolicy::FILES_ALLOW_ANY, "some/file/path");

    sandbox::ResultCode result = broker_service->SpawnTarget(argv[0], GetCommandLineW(), policy, &pi);

    policy->Release();
    policy = NULL;

    if (sandbox::SBOX_ALL_OK != result) {
        wcout << L"Sandbox failed to launch with the following result: " << result << endl;
        return 2;
    }

    // Just like CreateProcess, you need to close these yourself unless you need to reference them later
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    broker_service->WaitForAllTargets();

    return 0;
}

int RunChild(int argc, wchar_t* argv[]) {
    sandbox::TargetServices* target_service = sandbox::SandboxFactory::GetTargetServices();

    if (NULL == target_service) {
        wcout << L"Failed to retrieve target service" << endl;
        return 1;
    }

    if (sandbox::SBOX_ALL_OK != target_service->Init()) {
        wcout << L"failed to initialize target service" << endl;
        return 2;
    }

    // Do any "unsafe" initialization code here, sandbox isn't active yet

    target_service->LowerToken(); // This locks down the sandbox

    // Any code executed at this point is now sandboxed!

    TryDoingSomethingBad();

    return 0;
}

int wmain(int argc, wchar_t* argv[]) {
    sandbox::BrokerServices* broker_service = sandbox::SandboxFactory::GetBrokerServices();

    // A non-NULL broker_service means that we are not running the the sandbox, 
    // and are therefore the parent process
    if(NULL != broker_service) {
        return RunParent(argc, argv, broker_service);
    } else {
        return RunChild(argc, argv);
    }
}

うまくいけば、他の好奇心旺盛なコーダーがサンドボックス化するのに十分です! 幸運を!

于 2009-10-30T03:27:51.713 に答える
2

どのような答えが欲しいのか正確にはわかりません...最初にすべきことは、Chromeのソースコードリファレンスを確認することです。私たちが興味を持っているのはこれです:

sandbox:ハッキングされたレンダラーがシステムを変更するのを防ごうとするサンドボックスプロジェクト。

そのコードを調べて、Chromiumのレンダリング部分でAPI参照を探すと役立つ場合があります。

レンダラー:各タブのサブプロセスのコード。これはWebKitを埋め込み、I/Oのためにブラウザーと通信します。

そこを見回すと、Google自身がサンドボックスをどのように使用しているかがわかると思います。

//Lets start up the sandbox, I'm using the Chrome Blog example
TargetPolicy::SetTokenLevel()
TargetPolicy::SetJobLevel()
TargetPolicy::SetIntegrityLevel()
TargetPolicy::SetDesktop()

一般的に、これは新しいコードベースを満たすときに使用するアプローチです。どのように呼び出されるかを確認してください。

于 2009-10-24T11:10:28.570 に答える