The Windows Sandbox Paradox
The Windows Sandbox Paradox
Paradox
Nullcon 2015
James Forshaw @tiraniddo
Obligatory Background Slide
● Researcher in Google’s Project Zero
● Specialize in Windows, especially local
privilege escalation
● Never met a logical vulnerability I didn’t
like
What I’m Going to Talk About
https://www.flickr.com/photos/23258385@N04/2237739552/
Let’s Write a Sandbox
https://openclipart.org/detail/101707/happy-pencil-by-jonata
Sandboxing Requirement #1
● Easy to get in, hard to get out
http://upload.wikimedia.org/wikipedia/commons/d/d9/GravityPotential.jpg
Sandboxing Requirement #2
● Protects the user’s data from disclosure
https://openclipart.org/detail/190821/cles-de-serrure---lock-keys-by-enolynn-190821
Sandboxing Requirement #3
● Work within the limits of the OS
http://upload.wikimedia.org/wikipedia/commons/8/8b/MUTCD_R2-1.svg
Sandboxing Requirement #4
● Sandboxed application is usable
○ Limited Performance Impact
http://pixabay.com/p-305189/
Typical User-Mode Approach
Resources
Broker Process Files, Registry,
IPC Services Network,
Processes etc.
Normal-Privilege
Low-Privilege
Sandboxed Process
Object Security Descriptor
Owner of
Secured Resource
Mandatory Integrity
Label
Discretionary
Access Control List
(DACL)
Access Tokens
User Security
Identifier
Groups
Mandatory
Label
Privileges
Resource Access Check
Desired Access: IL Check
e.g. Read and Write
Owner
Check
DACL Check
Greater
or Equal Policy for:
Read Access
Write Access
Execute Access
Allowed
True By Policy
Continue to
Deny Access
Owner Check
Owner Check
User SID Owner
False
Is Equal
All
True
Access
Granted
Continue to
Grant Access
DACL Check
Kernel DACL Check
BUILTIN\Users BUILTIN\Administrators RW
BUILTIN\Users BUILTIN\Administrators RW
BUILTIN\Users BUILTIN\Administrators RW
Everyone BUILTIN\Users RW
BUILTIN\Users BUILTIN\Administrators RW
Everyone BUILTIN\Users RW
Owner Restricted
Check SIDs Owner
Check
Restricted
DACL Check SIDs DACL
Check
Uninitialized Process
External
Resources
Process Initialization
Uninitialized Process
External
Resources
Initial Thread
Process Initialization
Uninitialized Process
External
Resources
Initial Thread
LdrInitializeThunk
Attack Surface
Kernel Device
Win32k
Services Drivers
Kernel
System
SYSTEM Services
Level Resources:
● Files
● Registry
Hives
Broker ● WEVT
User Level Other User Applications
Process
Sandboxed
Process
Kernel Attack Surface
~300 Syscalls
Kernel Attack Surface
\Device\Harddisk1\SomeName
Native NT Path
Opening a Device Name
\Device\Harddisk1\SomeName
Native NT Path
\Device\Harddisk1 \SomeName
Device Path Device
Namespace Path
Opening a Device Name
\Device\Harddisk1\SomeName
Native NT Path
\Device\Harddisk1 \SomeName
Device Path Device
Namespace Path
Create File
Handler
Harddisk Driver
Securing the Device
● So what’s the problem?
○ By default security of device path enforced by kernel
○ Security of namespace IS NOT enforced by kernel
● If the driver doesn’t do its own checking or
sets appropriate flags there’s NO security
Example: Windows Sockets
● Would like to block network access, so let’
s do a quick test:
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0)
return 1;
}
/* Do socket stuff*/
WSACleanup();
Example: Windows Sockets
● Would like to block network access, so let’
s do a quick test:
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(wVersionRequested, &wsaData) != 0)
return 1; Fails here!
/* Do socket stuff*/
WSACleanup();
Example: Windows Sockets
● On Linux/OSX sockets implemented as
system calls
● Implemented in the Ancillary Function
Driver
● You interact with it via \Device\Afd, open
the device namespace such as
\Device\Afd\Endpoint
● No security on the namespace :(
● Further interaction via DeviceIoControl
Native Sockets
BOOL ConnectSocket(HANDLE hSocket, u_short srcport,
const SOCKADDR_IN& inaddr)
{
ConnectData data = { 0 };
data.sin_family = AF_INET;
data.sin_port = htons(srcport);
data.inaddr = inaddr;
DWORD dwSize;
Set permission
Broker
of resource
Resources, Files,
Low Privilege Registry etc.
Create, Read
Sandbox Process and Write
Sharing Resource Access
● Adding appropriate entries to security
descriptor is easy to allow shared access
● Has advantage that everything can be
done in the sandboxed process
● No overhead
● Trouble is any “supported” operation can
be performed
Bad Registry
● The registry supports symbolic links
● This isn’t very well documented
● No permissions required to create these
links other than being able to create a
registry
● Surely not an issue?
○ It is if a higher privileged process also accesses
those keys
IE EPM Escape / Audio Server
System Privilege
Audio Service
User’s Registry
Low Privilege
IE Sandbox Process
https://code.google.com/p/google-security-research/issues/detail?id=99
IE EPM Escape / Audio Server
System Privilege
Audio Service
User’s Registry
Low Privilege
https://code.google.com/p/google-security-research/issues/detail?id=99
IE EPM Escape / Audio Server
System Privilege
Audio Service
User’s Registry
Low Privilege
https://code.google.com/p/google-security-research/issues/detail?id=99
Lack of Documentation
● No documentation on how to defend
yourself against this attack
Lack of Documentation
● No documentation on how to defend
yourself against this attack
Lack of Documentation
● No documentation on how to defend
yourself against this attack
Broker Resource Access
Normal Privilege
Create, Read
and Write
Broker Resources, Files,
Registry etc.
Low Privilege
Create, Read
and Write
Sandbox Process
Filesystem Fun
● Instead of changing security of resources
instead we’ll do everything through the
broker
● Let’s us hook calls to CreateFile and pass
them to the broker
Win32 Path Support
Path Description
some\path Relative path to current
directory
c:\some\path Absolute directory
\\.\c:\some\path Device path, canonicalized
\\?\c:\some\path Device path, non-
canonicalized
\\server\share\path UNC path to share on server
Legacy Filesystem Behaviour
● MS-DOS has a lot to answer for, these
files names don’t do what you expect:
○ “COM1” -> Opens the first serial port!
○ “LPT1” -> Opens the parallel port?!
○ And others
Legacy Filesystem Behaviour
● MS-DOS has a lot to answer for, these
files names don’t do what you expect:
○ “COM1” -> Opens the first serial port!
○ “LPT1” -> Opens the parallel port?!
○ And others
● Surely an absolute path will work?
○ c:\path\LPT1 -> Opens the parallel port!
○ \\.\c:\path\LPT1 -> Creates the file you expect
● Now got a file the user can’t delete!
More edge cases
● Trailing spaces are removed from paths:
○ "c:\some\path " -> "c:\some\path"
○ "\\.\some\path " -> "c:\some\path"
○ "\\?\some\path " -> "c:\some\path "
● Congratulations you’ve again made a file
a user can’t delete
Canonicalization
● Type of Win32 path affects
canonicalization behaviour
Create
Broker Resources, Files,
Registry etc.
Low Privilege
Create,
DuplicateHandle
Read/Write
Sandbox Process
Hybrid Resource Access
● Windows uses handles to reference open
resources
● We can use the DuplicateHandle method
from the broker to copy that handle back
● Only pay penalty on resource open/create
not read and write
● Any risks in doing this?
Reparse Points
● NTFS supports directory symlinks
○ Supports file symlinks as well but you need
additional privileges
● Linux/OSX have a specific system call
‘symlink’ to create file system symbolic
links
● In Windows you just a file handle to a
directory
Reparse Points
● Need to open a handle to a directory
○ Pass FILE_DIRECTORY_FILE to NtCreateFile
● What if the broker doesn’t allow you to
specify that?
● Use the NTFS alternate data stream
name instead
○ dir::$INDEX_ALLOCATION or
○ dir::$I30:$INDEX_ALLOCATION
● Just because
Mixed Semantics
● ActiveX install broker has a function to
load a signed DLL
BOOL IsSignedFile(string path) {
CreateFile(path, ...);
...
}
if (IsSignedFile(path)) {
LoadLibrary(path);
}
}
Mixed Semantics
Mixed Semantics
Mixed Semantics
lpFileName Parameter Path loaded
c:\my\path\test.dll c:\my\path\test.dll
Mixed Semantics
lpFileName Parameter Path loaded
c:\my\path\test.dll c:\my\path\test.dll
c:\my\path\test c:\my\path\test.dll
Mixed Semantics
lpFileName Parameter Path loaded
c:\my\path\test.dll c:\my\path\test.dll
c:\my\path\test c:\my\path\test.dll
c:\my\path\test. c:\my\path\test
Sharing Sections
Unnamed Resources
● Certain classes of Windows resources opt
out of security when they have no names
● Section objects are just one such type
● Leads to problems.
IPC Technologies
● Three main ways of doing IPC on
Windows
○ Named Pipes
○ Local RPC (ALPC)
○ Sockets
● Already seen sockets aren’t securabled
resources
● What problems would these come with?
Named Pipes
● Named pipe servers are created using
CreateNamedPipe method (really
NtCreateNamedPipeFile)
● Named pipe clients are created using the
normal NtCreateFile API
Supporting Creating Pipes
Chrome CreateNamedPipe IPC
HANDLE CreateNamedPipeAction(string name, ...) {
// Name is lowercase already
if (name.beginswith("\\\\.\\pipe\\chrome.") {
return CreateNamedPipe(name, ...);
} else {
return NULL;
}
}
Chrome CreateNamedPipe IPC
● Intention was to only allow named pipes
with a prefix
● Even though the function should only ever
open named pipes it’s using the \\.\
syntax.
● Canonicalize!
○ \\.\pipe\chrome.xxx\..\mypipe
Is Windows Getting Better?
Reducing Kernel Attack Surface
Kernel Attack Surface
Owner Capability
Check SIDs Owner
Check
Capability
DACL Check SIDs DACL
Check
Medium IL Resource IL
Greater
or Equal Policy for:
Read Access
Write Access
Execute Access
Allowed
True By Policy
Continue to
Deny Access
Owner Check
Drawbridge / PicoProcess
● Isolation/sandbox technologies developed
by Microsoft
● Uses process isolation to secure an
application
● Can be completely isolated from the
kernel, including system call filtering
● Currently not available in consumer
versions of Windows :(
Questions?