使用Google Chrome沙盒 [英] Using the Google Chrome Sandbox

查看:258
本文介绍了使用Google Chrome沙盒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有几种资源可以解释Chrome中的沙箱是如何工作的以及它如何保护用户免受恶意代码的侵害。

Chromium Blog

Chromium开发者文档

(有些OS可能知道如何保护自己比我们更好地保护自己,所以我们让它)。他们还提到在几个地方,沙箱本身被设计为不依赖于在Chrome上,但是或多或少是独立的,所以理论上任何进程都可以被沙箱化,只要程序的体系结构是兼容的(沙箱代码必须以它自己的过程运行,作为非沙盒父项的子项。)



我恰好有一个应用程序,它的设计使沙盒成熟,并且能够让父母/子女进程与之一起工作。我有Chromium代码,不知道下一步该怎么做。

有没有人在那里用这个沙箱来做任何事情?是否有任何资源记录它的使用情况或API?我可以想象它应该是非常简单的,但我不知道从哪里开始。



编辑:我在下面的答案中找到答案!

解决方案

好的,这是我在Chrome上发现的有关沙箱代码的内容。 ,您需要获取铬源代码。这是,需要一段时间才能获得,但我还没有找到任何可靠的快捷方式来检出仍然可用的结果。阿洛斯,非常重要的是你要非常仔细地按照该页面的指示。 Google机组人员知道他们在做什么,并且不喜欢无用的步骤。该页面上的一切都是必需的。是。所有东西。



现在,一旦你获得了源代码,你就不需要整个构建chrome(这可能需要几个小时!)才能使用沙箱。相反,他们已经足够好,可以为您提供单独的沙盒解决方案(可在沙盒文件夹中找到)解决方案。建立这个项目并确保一切都编译完成。如果确实如此,太棒了!如果没有,你没有按照生成页面上的步骤操作,是吗?惭愧,这次真的去做吧。别担心,我会等待......

既然所有内容都已经构建了您的主要兴趣点,那么sandbox_poc项目(poc= Concept of Proof) 。这个项目基本上是沙盒周围的最小GUI包装器,它将在沙盒环境中的给定入口点启动任意dll。它显示了创建和使用沙箱所需的所有步骤,并且是您获得的最佳参考。当你查看代码时,你可能会注意到它实际上是沙盒的代码本身。这在所有沙盒示例中都很常见,根据此主题 (可能已经过时)可能是目前沙盒的唯一工作方式。该线程描述了理论上如何沙箱单独的过程,但我没有尝试过。然而,为了安全起见,有一个自助应用程序是已知的好方法。

sandbox_proc包含许多静态库,但它们似乎主要针对他们构建的示例UI。我发现的似乎只需要一个最小的沙盒是:

  sandbox.lib base.lib dbghelp。 lib 

还有另一个依赖,虽然看起来并不完全明显,但这是我被抓到的时间最长。当您构建沙盒解决方案时,其中一个输出文件应该是 wowhelper.exe 。虽然它在任何地方都没有提及,但必须将该文件复制到与您正在使用的可执行文件相同的目录中!如果不是这样,那么您对沙盒代码的尝试总是会失败,并显示通用的文件未找到错误。如果你不知道发生了什么,这可能是非常令人沮丧的!现在,我正在开发Windows 7 64位版本,这可能与wowhelper要求有关(WOW是16/32/64位之间的互操作应用程序的常用缩写),但我没有很好的方法来测试马上。请让我知道是否有其他人发现更多!



所以这就是所有环境的东西,这里有一些smaple代码让你走!请注意,虽然我在这里的子进程中使用wcout,但在沙箱中运行时看不到任何控制台输出。任何类似的东西都需要通过IPC传递给父进程。

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

使用namespace std;
$ b $ int RunParent(int argc,wchar_t * argv [],sandbox :: BrokerServices * broker_service){
if(0!= broker_service-> Init()){
wcout<< L无法初始化BrokerServices对象<< ENDL;
返回1;
}

PROCESS_INFORMATION pi;

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

//这里是您设置沙箱安全级别的地方。对这些符号的
//做一个goto定义通常会给你一个很好的描述它们的用法和选择。
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);

//在这里添加额外的规则(例如:文件访问例外),如下所示:
policy-> AddRule(sandbox :: TargetPolicy :: SUBSYS_FILES,sandbox :: TargetPolicy :: FILES_ALLOW_ANY, 一些/文件/路径);

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

policy-> Release();
policy = NULL;

if(沙箱:: SBOX_ALL_OK!=结果){
wcout<< L沙箱未能启动,结果如下:<<结果< ENDL;
返回2;
}

//就像CreateProcess一样,除非需要稍后引用它们,否则您需要自己关闭它们
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);

broker_service-> WaitForAllTargets();

返回0;

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

if(NULL == target_service){
wcout<< L无法检索目标服务<< ENDL;
返回1;
}

if(sandbox :: SBOX_ALL_OK!= target_service-> Init()){
wcout<< L未能初始化目标服务<< ENDL;
返回2;
}

//在这里执行任何不安全的初始化代码,沙箱尚未激活

target_service-> LowerToken(); //这会锁定沙盒

//此时执行的任何代码现在都已经过沙盒处理!

TryDoingSomethingBad();

返回0;

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

//非NULL的broker_service意味着我们没有运行沙箱,
//因此是父进程
if(NULL!= broker_service){
返回RunParent(argc,argv,broker_service);
} else {
return RunChild(argc,argv);
}
}

希望这足以让任何其他好奇的编码者沙盒化!祝你好运!


There are several resources out there that explain how the sandbox in Chrome works and what it does to protect users from malicious code.

Chromium Blog
Chromium Developer Documentation
Sandbox FAQ

That's great, and I like the OS-centric design that they have in place (somewhat of a "The OS probably knows how to secure itself better than we do, so we let it" approach.) They also mention in several places that the sandbox itself was designed to not be dependent on Chrome but instead more-or-less standalone so that theoretically any process could be sandboxed as long as the architecture of the program is compatible (sandboxed code must run as it's own process as a child of a non-sandboxed parent.)

I just happen to have an application who's design makes it ripe for sandboxing, and was able to get a parent/child process working with it. I've got the Chromium code and... have no idea what to do next.

Has anyone out there actually sandboxed anything with this yet? Are there any resources that document it's usage or APIs? I would imagine it should be pretty simple, but I'm at a loss for where to start.

EDIT: My finding below in the answers!

解决方案

Okay, so here's what I found about sandboxing code with Chrome.

First off, you'll need to go get the chromium source code. This is big, and will take a while to get, but I've yet to find any reliable shortcuts to checkout that still yeild usable results. Alos, it's very important that you follow the instructions on that page VERY CLOSELY. The Google crew knows what they're doing, and aren't keen on useless steps. Everything on that page is necessary. Yes. Everything.

Now, once you get the source, you don't actually have to build chrome in it's entirety (which can take hours!) to use the sandbox. Instead they've been nice enough to give you a separate sandbox solution (found in the sandbox folder) that can build standalone. Build this project and make sure everything compiles. If it does, great! If it doesn't, you didn't follow the steps on the build page, did you? Hang your head in shame and go actually do it this time. Don't worry, I'll wait...

Now that everything has built your main point of interest is the sandbox_poc project ("poc" = Proof of Concept). This project is basically a minimal GUI wrapper around a sandbox that will launch an arbitrary dll at a given entry point in a sandboxed environment. It shows all the required steps for creating and using a sandbox, and is about the best reference you've got. Refer to it often!

As you look through the code you'll probably notice that the code it actually sandboxes is itself. This is very common with all the sandbox examples, and according to this thread (which may be outdated) is possibly the only working way to sandbox at the moment. The thread describes how one would theoretically sandbox a separate process, but I haven't tried it. Just to be safe, though, having a self-calling app is the "known good" method.

sandbox_proc includes a great many static libs, but they appear to mostly be for the sample UI they've built. The only ones I've found that seem to be required for a minimal sandbox are:

sandbox.lib base.lib dbghelp.lib

There's another dependancy that's not entirely obvious from looking at the project though, and it's what I got caught up on the longest. When you built the sandbox solution, one of the output files should be a "wowhelper.exe". Though it's never mentioned anywhere, this file must be copied to the same directory as the executable you are sandboxing! If it's not, your attempts to sandbox your code will always fail with a generic "file not found" error. This can be very frustrating if you don't know what's going on! Now, I'm developing on Windows 7 64bit, which may have something to do with the wowhelper requirement (WOW is a common acronym for interop apps between 16/32/64bit), but I don't have a good way of testing that right now. Please let me know if anyone else finds out more!

So that's all the environment stuff, here's a bit of smaple code to get you going! Please note that although I use wcout in the child process here, you can't see any console output when running in the sandbox. Anything like that needs to be communicated to the parent process via 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);
    }
}

Hopefully that's enough to get any other curious coders sandboxing! Good luck!

这篇关于使用Google Chrome沙盒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆