Sandboxing a process

608 views
Skip to first unread message

voodo

unread,
May 29, 2011, 8:52:23 PM5/29/11
to Chromium-dev
Hello,
I've been trying to sandbox a process with the chrome's sandbox and
have been failing. The image of the target process is different than
the broker process.
I tried looking for information in this group and came across this
thread:

http://groups.google.com/group/chromium-dev/browse_thread/thread/f6ee308557249e81/e9c1114575b15033

Sadly it's unclear what the resolution of this issue was.

I'm only interested in intercepting API calls and routing them to the
broker process. Can someone please point out to where I might get that
info? Perhaps a detailed document explaining the working of the
sandbox?

I only need a sandboxing of say notepad.exe.

voodo

unread,
May 29, 2011, 9:09:41 PM5/29/11
to Chromium-dev
More specifically this is what I did:

sandbox::BrokerServices* broker =
sandbox::SandboxFactory::GetBrokerServices();

sandbox::ResultCode result1 = broker->Init();

sandbox::TargetPolicy* policy = broker->CreatePolicy();
policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
policy->SetTokenLevel(sandbox::USER_UNPROTECTED,
sandbox::USER_UNPROTECTED);
policy->SetAlternateDesktop(false);

policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY, L"c:\\Windows\
\System32\\notepad.exe");

PROCESS_INFORMATION target;
std::wstring process_image = L"c:\\Windows\\System32\\notepad.exe";
std::wstring arguments = L"c:\\Windows\\System32\\notepad.exe";

result1 = broker->SpawnTarget(process_image.c_str(),arguments.c_str(),
policy,&target);
policy->Release();
policy = 0;

::ResumeThread(target.hThread);
broker->WaitForAllTargets();

With this code, the debugger breaks at debugger_win.cc Line 107. I'm
obviously doing something wrong but can't figure it out :-(

On May 30, 5:52 am, voodo <achintyasha...@gmail.com> wrote:
> Hello,
> I've been trying to sandbox a process with the chrome's sandbox and
> have been failing. The image of the target process is different than
> the broker process.
> I tried looking for information in this group and came across this
> thread:
>
> http://groups.google.com/group/chromium-dev/browse_thread/thread/f6ee...

Carlos Pizano

unread,
May 30, 2011, 4:17:38 PM5/30/11
to Chromium-dev, voodo
>> With this code, the debugger breaks at debugger_win.cc Line 107. I'm

Can you copy the full stack trace? we need to see the source of the
assert.

>> policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES

For adding these kind of generic file rules, it is best to use the
helpers that we use in chrome, you should familiarize with this file:
src/chrome/common/sandbox_policy.cc



voodo

unread,
May 30, 2011, 4:39:39 PM5/30/11
to Chromium-dev
Here's the stack trace of the call.

> sandbox_poc.exe!base::debug::BreakDebugger() Line 107 C++
sandbox_poc.exe!logging::LogMessage::~LogMessage() Line 614 C++
sandbox_poc.exe!base::AtExitManager::RegisterCallback(void (void *)*
func=0x0044fe50, void * param=0x00000000) Line 46 C++
sandbox_poc.exe!
Singleton<base::win::OSInfo,DefaultSingletonTraits<base::win::OSInfo>,base::win::OSInfo>::get()
Line 230 + 0xc bytes C++
sandbox_poc.exe!base::win::OSInfo::GetInstance() Line 17 C++
sandbox_poc.exe!base::win::GetVersion() Line 69 + 0x5 bytes C++
sandbox_poc.exe!sandbox::SetTokenIntegrityLevel(void *
token=0x000000f4, sandbox::IntegrityLevel
integrity_level=INTEGRITY_LEVEL_LAST) Line 288 + 0x5 bytes C++
sandbox_poc.exe!
sandbox::RestrictedToken::GetRestrictedTokenHandle(void * *
token_handle=0x0018fb04) Line 132 + 0x13 bytes C++
sandbox_poc.exe!sandbox::CreateRestrictedToken(void * *
token_handle=0x0018fb04, sandbox::TokenLevel
security_level=USER_UNPROTECTED, sandbox::IntegrityLevel
integrity_level=INTEGRITY_LEVEL_LAST, sandbox::TokenType
token_type=PRIMARY) Line 125 + 0xc bytes C++
sandbox_poc.exe!sandbox::PolicyBase::MakeTokens(void * *
initial=0x0018fabc, void * * lockdown=0x0018fb04) Line 132 + 0x19
bytes C++
sandbox_poc.exe!sandbox::BrokerServicesBase::SpawnTarget(const
wchar_t * exe_path=0x020e9e00, const wchar_t *
command_line=0x020e9e80, sandbox::TargetPolicy * policy=0x01db1ac8,
_PROCESS_INFORMATION * target_info=0x0018fe80) Line 246 + 0x10 bytes C
++
sandbox_poc.exe!wWinMain(HINSTANCE__ * instance=0x00400000,
HINSTANCE__ * __formal=0x00000000, wchar_t * command_line=0x00273a4e,
int show_command=0x00000001) Line 76 + 0x27 bytes C++
sandbox_poc.exe!__tmainCRTStartup() Line 263 + 0x2c bytes C
sandbox_poc.exe!wWinMainCRTStartup() Line 182 C
kernel32.dll!77353677()
[Frames below may be incorrect and/or missing, no symbols loaded for
kernel32.dll]
ntdll.dll!77e89d72()
ntdll.dll!77e89d45()

The call fails when the code tries to get OS info. I'm using win7 64
bits if that helps...

In the meantime I'll study the file that you have suggested. Thanks
for the tip!

voodo

unread,
May 31, 2011, 11:09:00 AM5/31/11
to Chromium-dev
I have been digging into the code and have some questions regarding
the sandbox. Can someone please help me out?
1. I hope it is possible to sandbox an exe where the target image is
different than broker?
2. What is the use of SANDBOX_EXPORTS? Is it to be defined when the
target and broker are different?
3. If the target and broker can indeed be different how are variables
like g_original transferred to the new image?

I'm still looking into the code. I'm sorry if I sound like a novice.

If the above are very basic questions can someone please point me to a
detailed document for the sandbox. The design document is just an
architectural overview of the sandbox.

Ricardo Vargas

unread,
May 31, 2011, 2:22:30 PM5/31/11
to achinty...@gmail.com, Chromium-dev
The assertion:

NOTREACHED() << "Tried to RegisterCallback without an AtExitManager";

Now we need an AtExitManager declared by every executable that uses singletons. We usually do that early on the main code (just create an object on the stack).

It should be possible to use a different image for the target, and in that case SANDBOX_EXPORTS should be defined at the project level. Everything should work (I'm not saying that it does, 'cause we don't test it). Keep in mind that the target still needs to call TargetServices::LowerToken as soon as possible. It may be simpler to start with a 32 bit broker/target (notepad is 64 bit so you need a 64 bit broker).

--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
   http://groups.google.com/a/chromium.org/group/chromium-dev

voodo

unread,
May 31, 2011, 8:47:23 PM5/31/11
to Chromium-dev
Thanks for your comment. It really helped but I'm still unable to
spawn a target with a different image
than the broker. I have now changed the target image to be notepad+
+.exe which I know is 32 bit. And I'm using a 32 bit broker. I also
defined SANDBOX_EXPORTS at the project level. Here's the stack trace:
--------------------------- Begin --------------------------
> sandbox_poc.exe!base::debug::BreakDebugger() Line 107 C++
sandbox_poc.exe!logging::LogMessage::~LogMessage() Line 614 C++
sandbox_poc.exe!sandbox::ServiceResolverThunk::ResolveTarget(const
void * module=0x028c0000, const char * function_name=0x024bfb30, void
* * address=0x0018f7a0) Line 36 C++
sandbox_poc.exe!
sandbox::ServiceResolverThunk::ResolveInterceptor(const void *
interceptor_module=0x028c0000, const char *
interceptor_name=0x024bfb30, const void * * address=0x0018f7a0) Line
20 C++
sandbox_poc.exe!
sandbox::InterceptionManager::PatchClientFunctions(sandbox::DllInterceptionData
* thunks=0x001c0000, unsigned int thunk_bytes=848,
sandbox::DllInterceptionData * dll_data=0x0018f834) Line 465 + 0x28
bytes C++
sandbox_poc.exe!sandbox::InterceptionManager::PatchNtdll(bool
hot_patch_needed=false) Line 382 + 0x14 bytes C++
sandbox_poc.exe!
sandbox::InterceptionManager::InitializeInterceptions() Line 111 +
0xd bytes C++
sandbox_poc.exe!
sandbox::PolicyBase::SetupAllInterceptions(sandbox::TargetProcess *
target=0x024bf708) Line 444 + 0x8 bytes C++
sandbox_poc.exe!
sandbox::PolicyBase::AddTarget(sandbox::TargetProcess *
target=0x024bf708) Line 227 + 0xc bytes C++
sandbox_poc.exe!sandbox::BrokerServicesBase::SpawnTarget(const
wchar_t * exe_path=0x02089e08, const wchar_t *
command_line=0x02089ea8, sandbox::TargetPolicy * policy=0x024b1ac8,
_PROCESS_INFORMATION * target_info=0x0018fe3c) Line 282 + 0xc bytes C+
+
sandbox_poc.exe!wWinMain(HINSTANCE__ * instance=0x00400000,
HINSTANCE__ * __formal=0x00000000, wchar_t * command_line=0x00293a4e,
int show_command=1) Line 78 + 0x30 bytes C++
sandbox_poc.exe!__tmainCRTStartup() Line 263 + 0x2c bytes C
sandbox_poc.exe!wWinMainCRTStartup() Line 182 C

--------------------------- End Stack trace--------------------------

These are my findings while trying to debug.
1. In the function InterceptionManager::PatchClientFunctions the code
is looking for _TargetNtCreate@48 in the target module. This
obviously does not exist in the target module. Hence the assert fails.
2. The function ServiceResolverThunk::ResolveInterceptor tries to find
the interceptor function in the target module. That makes sense if
both the images are the same. I guess I would have to alter this
function with a SANDBOX_EXPORTS section which looks for the
interceptor function in a module which would have to be defined by
me.
3. The local interceptor on the target module would have to be a dll
which I would have to map to the target process after I call
createprocess? How can I do that? Can I remotely inject a dll in the
target process which carries the interceptor functions before I try to
patch the functions like NtCreateFile etc? Perhaps you can suggest a
better approach.
4. I don't need to call Targetservices::LowerToken() if I don't care
about lockdown? I just want to patch the functions and have them
routed to the broker for the time being. I can alter this behavior
later. But the first priority is to get the patching and IPC working.

Please point out the errors that I have made above.

Thanks again for your comments :-)
> > Chromium Developers mailing list: chromium-...@chromium.org

Ricardo Vargas

unread,
May 31, 2011, 9:50:46 PM5/31/11
to achinty...@gmail.com, Chromium-dev
Yeah, I was not thinking clear enough. Sorry about that.

The sandbox code cannot be used as-is to sandbox a random executable. The sandbox library has to be used in both the broker AND the target process, and it has to reside in the main executable, not in a DLL.

Even the interception code by itself relies on the presence of the library compiled into the target executable. Once that requirement is met, we can deal with having two different images for the broker/target.

Are you using notepad just as an initial test or do you need to restrict a random (not under your control) executable?

Chromium Developers mailing list: chromi...@chromium.org

voodo

unread,
May 31, 2011, 10:08:54 PM5/31/11
to Chromium-dev
I need to restrict random executables. Basically I just want to
redirect I/O to a directory of my choice. Eventually this can be
extended to completely sandboxing executables with pipes, mutant etc
being redirected as well. So I need to get the interception working...
I looked at other hooking libraries (Easyhook, MS Detours etc) but I
want to do it on my own with the IPC working... I'm willing to put in
the hard yards. I am just unable to decipher the interception related
code properly.
Any pointers to how I should go about that?
Also can I map the sandboxing DLL into a random process after I've
called createprocess and the child process is suspended?

Carlos Pizano

unread,
Jun 1, 2011, 11:09:44 PM6/1/11
to Chromium-dev, voodo


On May 31, 7:08 pm, voodo <achinty...@gmail.com> wrote:
> I need to restrict random executables. Basically I just want to
> redirect I/O to a directory of my choice. Eventually this can be
> extended to completely sandboxing executables with pipes, mutant etc
> being redirected as well. So I need to get the interception working...
> I looked at other hooking libraries (Easyhook, MS Detours etc) but I
> want to do it on my own with the IPC working... I'm willing to put in
> the hard yards. I am just unable to decipher the interception related
> code properly.

Basically you want to redo http://www.sandboxie.com/

> Any pointers to how I should go about that?

The thing is that we did not created the chrome sandbox for what you
are after. Certainly code in there is solving some of your problems
and you are welcome to re-use it or be inspired by it.

Take for example the concept of lock-down: it is necessary that once
the sandboxed process has loaded the critical components and obtained
the critical resources and *before* it touches any untrusted input it
should call LowerToken(), that locks down the sandbox. If you sandbox
a notepad, when is the right time to call this?

I forgot to mention it before but are you aware of
http://www.chromium.org/developers/design-documents/sandbox ?
> ...
>
> read more »

voodo

unread,
Jun 2, 2011, 12:02:21 AM6/2/11
to Chromium-dev
> Basically you want to redohttp://www.sandboxie.com/

Not yet. Sandboxie intercepts a lot of calls. I want to begin with
intercepting only NtDll calls for the time being. I'm sure I'd run
into a lot of problems but I'm kinda looking forward to them :-)

> The thing is that we did not created the chrome sandbox for what you
> are after. Certainly code in there is solving some of your problems
> and you are welcome to re-use it or be inspired by it.
>
> Take for example the concept of lock-down: it is necessary that once
> the sandboxed process has loaded the critical components and obtained
> the critical resources and *before* it touches any untrusted input it
> should call LowerToken(), that locks down the sandbox. If you sandbox
> a notepad, when is the right time to call this?
>


Yes. I understand that now. I've been looking into the sandbox code
and it looks like I'd have to do make major alterations to it. I can
reuse parts like PEimage class and some interceptor code. I think that
should be a good beginning. I had been reading up on the chrome
sandbox and came across some news items regarding it's origins being
in GreenBorder sandbox. So I thought I'd give it a shot. As I said, my
aim is only to get the api interception and IPC working first. Looking
at the code I realized that all the TargetXXX functions call the
original function first. Only if that fails (access denied) is the
call forwarded to the broker. My approach would be to forward all the
calls to the broker. If it's a 'write' call then the original file can
be copied to the "sandboxed" directory and then the call can be
reissued with the modified path at the broker's end (like Sandboxie).
This would negate the need for Lowertoken (only for I/O). I can build
the rest from there on. The biggest problem I had was the asserts
failing. I hope I can take it forward from here. I'd peep in again
sometime and let you guys know if you're interested...

> I forgot to mention it before but are you aware ofhttp://www.chromium.org/developers/design-documents/sandbox ?

I did. But it's very high level and does not explain how the code
works. I've figured out most of the code now. Well, thanks a ton for
your help.

On Jun 2, 8:09 am, Carlos Pizano <c...@chromium.org> wrote:
> On May 31, 7:08 pm, voodo <achintyasha...@gmail.com> wrote:
>
> > I need to restrict random executables. Basically I just want to
> > redirect I/O to a directory of my choice. Eventually this can be
> > extended to completely sandboxing executables with pipes, mutant etc
> > being redirected as well. So I need to get the interception working...
> > I looked at other hooking libraries (Easyhook, MS Detours etc) but I
> > want to do it on my own with the IPC working... I'm willing to put in
> > the hard yards. I am just unable to decipher the interception related
> > code properly.
>
> Basically you want to redohttp://www.sandboxie.com/
>
> > Any pointers to how I should go about that?
>
> The thing is that we did not created the chrome sandbox for what you
> are after. Certainly code in there is solving some of your problems
> and you are welcome to re-use it or be inspired by it.
>
> Take for example the concept of lock-down: it is necessary that once
> the sandboxed process has loaded the critical components and obtained
> the critical resources and *before* it touches any untrusted input it
> should call LowerToken(), that locks down the sandbox. If you sandbox
> a notepad, when is the right time to call this?
>
> I forgot to mention it before but are you aware ofhttp://www.chromium.org/developers/design-documents/sandbox ?
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages