A forum for reverse engineering, OS internals and malware analysis 

Discussion on reverse-engineering and debugging.
 #17160  by 0x16/7ton
 Thu Dec 13, 2012 9:03 pm
Hello again :)
After some research in sandboxie driver i found in them vulnerability "write zero (2 bytes) where",which get to us ability
disable driver signing (admin->ring0) by overwriting bool value g_CiEnabled.

To begin let's talk a little about the general concept in Sandboxie:
Sandboxie architecture implies a special structure for each process running in a controlled environment.
When we launch program in sandboxie,first starting wrap process Start.exe, which sends from usermode SbieDll.Dll,during initialization,
IOCTL to driver,and then the driver allocates memory for the first structure sandboxie processes.
For all other child processes structures allocated in notify callbacks in driver(CreateProcess,LoadImage).
Presence of a structure for the process checking by PID,if the structure exist - the process is running in a secure environment.
In the dispatch functions (\\Device\\SandboxieDriverApi) sandboxie handles only one IOCTL(0x222007),but in the buffer are
using by ZwDeviceIoControlFile they set specified ID of function(first dword x86 or qword x64 in buffer).

So the vulnerable code is in a function with ID=0x12340027
Buffer structs for that function look like that(for x64 version):
Code: Select all
	QWORD Header; //(0x12340027)
	PVOID Usermodebuffer;
	DWORD length_1;
Usermodebuffer-must point in user mode allocated buffer with size length_1.
That buffer validated by ProbeForWrite,pseudo code of this look like that:
Code: Select all
 if (length_temp==0)
     return error;
 if (length_original_buffer>=length_temp)
 memcpy (usermodebuffer,...,length_temp*2)
 *(WORD *)((char*)usermodebuffer[length_temp*2])=0; // << Here our 2 bytes write zero where :)
In condition length_1==0x2,we get length_temp==0 because length_original_buffer never can be zero(it's explained below) ,and in
result ProbeForWrite not validate input buffer.

Okay now let's talk about triggering vulnerable code.
Vulnerable function depends on an undocumented setting in sandboxie:
If sandboxie have these settings on x86 system in Object type hook (file type ParseNameProcedure),or on x64 system in minifilter callback,
when called ZwQueryAttributesFile(file_name) they compare the file_name with the name specified in the config DelayLoadDll.If name of dll equal
name in config-sanboxie allocates memory for the new structure DelayLoadDll (in that struct he copies the path to the file[file_name],and size of that path length_original_buffer),
and returns STATUS_OBJECT_NAME_NOT_FOUND (0xC0000034).
I do not understand, but no check is performed on all files, but only on the specific.
It was found experimentally that on x64 systems for cmd.exe in the directory systemroot/SysWow64 test triggered by ZwQueryAttributesFile (wow64 *. Dll) in early initialization pe file
in ntdll.dll.
Ok after,in initialization usermode dll SbieDll.dll send IOCTL to the vulnerable function with the buffer and him length.
In the vulnerable function, providing that the structure (DelayLoadDll) exist and allocated, they return path to the dll (need read like triggering exploit :)), otherwise an error code.
Path is converted from the native format and is passed as a parameter to LoadLibrary.

My goal was to take control of the call to the vulnerable function, which can be easy to achieve using the
documented setting InjectDll = [path_to_dll] (http://www.sandboxie.com/index.php?InjectDll)
and using Sbiedll api (http://www.sandboxie.com/index.php?SBIE_DLL_API) for manually updating settings.

Ok,now step by step of working exploit:
-Update Sandboxie settings like that:
  • DelayLoadDll=wow64log.dll (This dll is not necessary to initialize pe file)
-Dropped inject Dll to [path_to_dll]
-Launch start.exe (from sandboxie directory) with command line to exe path (systemroot/SysWow64/cmd.exe)
-In DllMain in injectDll we hook ZwDeviceIoControlFile and return control to SbieDll
-In hooked function we change parameters for(set size (length_1) to 0x2,and set Usermodebuffer to kernel mode address g_CiEnabled)

And in last once again, some things from which depends the exploit and some notes:
-Presence none document settings DelayLoadDll
-PE file must be specific? Have not fully understood this point (but enough to use cmd.exe)
-DelayLoadDll structure should be allocated before we sending IOCTL
-Calling the vulnerable function is possible only in the context of a secure environment Sandboxie
-Start-up code must run in not Sandboxie environment,because updating them settings denied from controlled environment
-Config sandboxie can be protected by password,but on default he not set

In my analysis can be a logic error or something another,but in general i think i am explained all needed stuff to trigger vulnerability :)
And anyway i am do this only for fun and learning.So enjoy it :)
PoC video of working exploit:

Very thanks NtClo$e(aka R00tkit ) for help me. ;)
Thanks for reading.
with Regards.
 #17255  by kmd
 Tue Dec 18, 2012 8:45 am

have you tried using this vulnerability:

1. allocate memory at 0x0 in user mode
2. fill this memory with shellcode
3. overwrite HAL_DISPATCH pointer with 0
4. trigger your code by calling NtQueryIntervalProfile

lets say your shellcode will print something from kernel mode to debug output.

because your poc actually fully useless due to incredible conditinios required to met -> you need sandboxed dropper to turn off sign check, not sandboxed itw dropper with malware driver to load. All at the same time, same machine with waiting. It is 100% impossible IRL.
 #17257  by 0x16/7ton
 Tue Dec 18, 2012 9:13 am
We have 2 bytes to zero value,so it is hard (or impossible?)overwrite address in HAL_DISPATCH pointer to our shellcode.
"...i am do this only for fun and learning".
If u need not "useless" content in exploitation 3d party drivers i am not help u.