James Forshaw @tiraniddo 1
James Forshaw @tiraniddo
Obligatory Background Slide
2
● Researcher in Google’s Project Zero ● Specialize in Windows
○ Especially local privilege escalation ● Never met a logical vulnerability I didn’t like
James Forshaw @tiraniddo
What I’m Going to Talk About ● Privilege escalation in Windows
○ Good places to look for bugs, mixture of user mode and kernel mode tips
● Fun tricks you can use to exploit vulnerabilities ○ Some even many at Microsoft weren’t aware of
● Mainly logical vulnerabilities, not worrying about memory corruption
3
James Forshaw @tiraniddo
Windows Local Attack Surface
4
James Forshaw @tiraniddo
Windows Local Attack Surface
5
James Forshaw @tiraniddo
Windows Local Attack Surface
6
James Forshaw @tiraniddo 7
Hunting for Elevation of Privilege Bugs
James Forshaw @tiraniddo
Local System Vulnerabilities are Dead!
8
James Forshaw @tiraniddo
Windows Kernel Attack Surface
9
James Forshaw @tiraniddo
System Services and Drivers
10
Windows 7 SP1
Windows 8.1 Windows 10
Services 150 169 196
Drivers 238 253 291
7 8 10
James Forshaw @tiraniddo
Service Privilege Levels
11
Windows 7 SP1 Windows 8.1 Windows 10
Local System 53.69% 56.89% 61.14%
Local Service 32.21% 31.14% 28.50%
Network Service 14.09% 11.98% 10.36%
7 8 10
James Forshaw @tiraniddo
Service Start Mode
12
Windows 7 Windows 8.1 Windows 10
Auto 30.07% 26.19% 24.10%
Disabled 5.23% 3.57% 2.05%
Manual 53.59% 43.45% 42.56%
Triggered 11.11% 26.79% 31.28%
7 8 10
James Forshaw @tiraniddo
Command Line Arguments for Services?
13
Arbitrary Arguments for Service
James Forshaw @tiraniddo
Who uses the Arguments?
14
Used here.
James Forshaw @tiraniddo
Example: Mozilla Maintenance Service
/** * Main entry point when running as a service. */ void WINAPI SvcMain(DWORD argc, LPWSTR *argv) { // ... ExecuteServiceCommand(argc, argv); }
15
James Forshaw @tiraniddo
A Number of Security Issues
16
James Forshaw @tiraniddo
Simple C# Test Program
class Program { static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: ServiceName args"); Environment.Exit(1); } ServiceController service = new ServiceController(args[0]); if (service.Status == ServiceControllerStatus.Stopped) { service.Start(args); } } }
17
James Forshaw @tiraniddo
Finding RPC Services
18
James Forshaw @tiraniddo
Finding Exposed COM Services
19
Menu: Registry > Local Services
James Forshaw @tiraniddo
Device Drivers
James Forshaw @tiraniddo
Accessible Device Objects
21
7 8 10
Windows 7 Windows
8.1 Windows
10
Read/Write 64 54 52
Read-Only 6 6 5
James Forshaw @tiraniddo
Opening a Device Name
\Device\Harddisk1\SomeName Native NT Path
James Forshaw @tiraniddo
Opening a Device Name
\Device\Harddisk1\SomeName
\Device\Harddisk1 \SomeName Device Path
Native NT Path
Device Namespace Path
James Forshaw @tiraniddo
Opening a Device Name
\Device\Harddisk1\SomeName
\Device\Harddisk1 \SomeName Device Path
Native NT Path
Device Namespace Path
Harddisk Driver
Create File Handler
James Forshaw @tiraniddo
Securing the Device Namespace
● 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
James Forshaw @tiraniddo
Vulnerable Code Patterns
NTSTATUS DriverEntry(DRIVER_OBJECT *DriverObject, ...) { // Potentially vulnerable IoCreateDevice(DriverObject, 0, Name, FILE_DEVICE_UNKNOWN, 0, TRUE, &DeviceObject); // Device namespace security enforced IoCreateDevice(DriverObject, 0, Name, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &DeviceObject); // Despite the name, still vulnerable IoCreateDeviceSecure(DriverObject, 0, Name, FILE_DEVICE_UNKNOWN, 0, TRUE, SecuritySddl, NULL, &DeviceObject); }
26
James Forshaw @tiraniddo
Example: Windows Sockets
● On Linux/OSX sockets implemented as system calls ● Implemented in the Ancillary Function Driver ● You interact with it via \Device\Afd ● But you must open the device namespace passing it \Device\Afd
\Endpoint ● No security on the namespace :( ● Further interaction via DeviceIoControl
James Forshaw @tiraniddo
Native Sockets
BOOL ConnectSocket(HANDLE hSocket, u_short srcport, const SOCKADDR_IN& inaddr) { // hSocket is opened file \Device\Afd\Endpoint ConnectData data = { 0 }; data.sin_family = AF_INET; data.sin_port = htons(srcport); data.inaddr = inaddr; DWORD dwSize; return DeviceIoControl(hSocket, 0x00012007, &data, sizeof(data), nullptr, 0, &dwSize, nullptr); }
James Forshaw @tiraniddo
Talk to Any Registered IP Endpoint
● For example SMB or DCE/RPC
29
https://code.google.com/p/google-security-research/issues/detail?id=222
James Forshaw @tiraniddo
What to Look For?
● Best place to look is in the handlers for: ○ IRP_MJ_DEVICE_CONTROL ○ IRP_MJ_FILE_SYSTEM_CONTROL ○ Classic IOCTL bugs
● Control Code encodes what permissions the device handle needs to call and includes parameter passing information.
30
Device Type bits 30 - 16
Required Access 15-14
Function Code 12-2
Transfer Type 1-0
METHOD_BUFFERED 0
METHOD_IN_DIRECT 1
METHOD_OUT_DIRECT 2
METHOD_NEITHER 3
FILE_ANY_ACCESS 0
FILE_READ_ACCESS 1
FILE_WRITE_ACCESS 2
James Forshaw @tiraniddo
IOCTL Example
31
Online decoder: https://www.osronline.com/article.cfm?article=229
James Forshaw @tiraniddo
DosDevice Drive Lookup
32
\??\C:\SomePath
Per-User Device Map
Per-Process Device Map
GLOBAL?? Device Map
Virtual ?? Device Map
\Device\XYZ\SomePath
James Forshaw @tiraniddo
Per-Process DeviceMap
const int ProcessDeviceMap = 23; struct PROCESS_DEVICEMAP_INFORMATION { HANDLE DirectoryHandle; }; bool SetProcessDeviceMap(HANDLE hDir) { PROCESS_DEVICEMAP_INFORMATION DeviceMap = {hDir}; NTSTATUS status = NtSetInformationProcess( GetCurrentProcess(), ProcessDeviceMap, &DeviceMap, sizeof(DeviceMap)); return status == 0; }
33
James Forshaw @tiraniddo
Using Per-Process Device Map
NTSTATUS DoDeviceIoControl(DRIVER_OBJECT *Driver, PIRP Irp) { // Potentially vulnerable PIO_STACK_LOCATION stack_loc = ...; if (stack_loc‐>DeviceIoControl.IoControlCode == IOCTL_SOMETHING) { UNICODE_STRING name = L"\\??\\C:"; UNICODE_STRING target = L"\\Device\\Target": IoCreateSymbolicLink(&name, &target); } } HANDLE hDir; UNICODE_STRING name = L"\\GLOBAL??"; NtOpenDirectoryObject(&hDir, DIRECTORY_TRAVERSE, &ObjAttr); SetProcessDeviceMap(hDir);
34
https://code.google.com/p/google-security-research/issues/detail?id=538
James Forshaw @tiraniddo
The Hand Which Giveth…
● MS15-111 Removed Per-Process Device Map from Sandboxes if (ProcessInformationClass == ProcessDeviceMap) { if (RtlIsSandboxedToken(NULL)) { return STATUS_ACCESS_DENIED; } return ObSetDeviceMap(ProcessHandle, DirectoryHandle); }
35
James Forshaw @tiraniddo
Per-User DeviceMap
36
James Forshaw @tiraniddo
Impersonation and DeviceMaps
● When a privileged service impersonates a user they also impersonate their device map.
● Dropping a C: symbolic link in per-user device map directory allows control over where that service things the C: is while impersonating.
● Prior to MS15-038 you could use this load DLLs in the target process ○ This was fixed by adding a new object attribute
OBJ_IGNORE_IMPERSONATED_DEVICEMAP which disables the impersonation device map.
● But still useful, for example process creation while impersonating still vulnerable
● Also reading of “protected” configuration. ● Original DLL version available at
https://code.google.com/p/google-security-research/issues/detail?id=240
37
James Forshaw @tiraniddo
Use Process Monitor
● Process Monitor logs the impersonation context on file creation events.
● Use this to see if any system service is impersonating the user while opening anything useful (DLLs probably don’t count).
38
Look for this value
James Forshaw @tiraniddo
Interesting Object Attribute Flags
39
Flag Name Value Description
OBJ_CASE_INSENSITIVE 0x0040 Interesting if system is configured as case sensitive (default is no)
OBJ_OPENLINK 0x0100 Opens a “link” object. Used to open a registry key symbolic link
OBJ_KERNEL_HANDLE 0x0200 If not set in kernel mode, exposed handle to current process
OBJ_FORCE_ACCESS_CHECK 0x0400 If not set in kernel mode will open the resource with no security checks
OBJ_IGNORE_IMPERSONATED_DEVICEMAP 0x0800 Ignore the impersonated device map
James Forshaw @tiraniddo
Default ACLs and Owners
● A file or object’s permissions depend one of three things: ○ The inherited permissions from its container (e.g. a Directory) and/or, ○ The default permissions from the current active token ○ An explicit Security Descriptor passed to kernel system call
40
Default GROUP
Default DACL
Default OWNER
Integrity Level also Inherited from Token
James Forshaw @tiraniddo
What if DeviceMap Doesn’t Exist?
NTSTATUS SeGetTokenDeviceMap(TOKEN *token, DEVICE_MAP **device_map) { if (!token‐>LogonSession‐>pDeviceMap) { swprintf_s( &SourceString, L"\\Sessions\\0\\DosDevices\\%08x‐%08x", token‐>AuthenticationId.HighPart, token‐>AuthenticationId.LowPart); InitializeObjectAttributes(&ObjectAttributes, SourceString, OBJ_KERNEL_HANDLE, ...); ZwCreateDirectoryObject(&DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); ObSetDirectoryDeviceMap(&token‐>LogonSession, DirectoryHandle); } *device_map = token‐>LogonSession‐>pDeviceMap; }
41
James Forshaw @tiraniddo
Default Security
● Because devicemap directory created in-process on demand it gains the permissions of the caller: ○ Owner set ○ Default DACL
● Means we can access the device map ● We can use this in limited ways to circumvent loss of per-process
Device Map ● Also works for many other resources such as Registry Keys and
Files
1. Get a token (such as from S4U) with an uninitialized devicemap 2. Impersonate token and access device map to create it 3. Open resource/call kernel function while impersonating the user
42
James Forshaw @tiraniddo
Win32 Automatic Redirection
43
● Win32 APIs redirect certain file names when called native APIs e.g. ○ COM1 -> \??\COM1 ○ NUL -> \??\NUL ○ And others
● System services rarely guard against it. ● If you can get the call under impersonation you can redirect the file
access even if you don’t have control over the complete path ● For example
○ If the service will open c:\somepath\yourfile you can redirect to another file
○ Potentially exploitable for configuration information
James Forshaw @tiraniddo
Path Canonicalization
● Path canonicalization is fundamentally different between Windows and Linux/OSX
● In Linux or OSX the path is passed to the kernel as is ○ Kernel responsible for path canonicalization ○ Both . and .. directories are real directory entries
● In Windows it must be passed as an absolute path to kernel ○ Relative path components removed in user mode ○ Current directory processed ○ Both . and .. are simulated
44
James Forshaw @tiraniddo
Path Canonicalization
45
A B C
Path Linux/OSX Windows
A/B/C Valid Valid
A/B/C/../../B Valid Valid
A/B/D/../C Invalid Valid
A/B/D”/../C Invalid Valid
const char* path = "c:\\my\\app.exe\" \\..\\..\\windows\\notepad.exe"; if (CheckSig(path)) { snprintf(cmdline, "\"%s\" arg", path); CreateProcess(NULL, cmdline, ...); }
James Forshaw @tiraniddo
NTFS Invalid Characters
46
James Forshaw @tiraniddo
Object Manager Invalid Characters
47
James Forshaw @tiraniddo
Windows Kernel Uses Counted Strings
48
Specifies length in bytes
James Forshaw @tiraniddo
Windows Kernel Uses Counted Strings
49
NUL terminated!
James Forshaw @tiraniddo
Alternate Data Streams on Directories
50
James Forshaw @tiraniddo
UAC Auto Elevation Directory Check
51
c:\windows\ c:\windows\tracing\ app.exe app.exe
ALLOWED BANNED
James Forshaw @tiraniddo
Folder Permissions
52
c:\windows\ c:\windows\tracing\ app.exe app.exe
ALLOWED BANNED
James Forshaw @tiraniddo
AiCheckSecureApplicationDirectory Bypass
53
● Need to be able to write a file with a secure path ● How can we write to C:\Windows without writing to C:\Windows?
c:\windows\ malicious.exe
ALLOWED
c:\windows\ ????
ALLOWED?
James Forshaw @tiraniddo
NTFS Alternate Data Streams FTW!
54
c:\windows\ tracing:malicious.exe
ALLOWED ● Only need FILE_WRITE_DATA/FILE_ADD_FILE access right on
directory to created named stream. ● Bug only fixed in Windows 10, not in Windows 8.1 and below.
James Forshaw @tiraniddo
Windows Symbolic Links
55
Windows NT 3.1 - July 27 1993 Object Manager Symbolic Links Registry Key Symbolic Links
Windows 2000 - Feb 17 2000 NTFS Mount Points and Directory Junctions
Windows Vista - Nov 30 2006 NTFS Symbolic Links
James Forshaw @tiraniddo
Mitigated in Sandboxes
56
NTFS Mount Points
Registry Key Symbolic Links
Object Manager Symbolic Links
BANNED
LIMITED
LIMITED
James Forshaw @tiraniddo
Weird Default Permissions
● Both C:\Windows\Temp and C:\ProgramData have permissions which allow a normal user to create new files
● If you can find a program misusing these you can create new files or symbolic links to attack them
● You can’t delete files necessarily, but of course worth finding a way of doing so.
57
James Forshaw @tiraniddo 58
James Forshaw @tiraniddo
The Tools of the Trade (well my choice)
59
● SysInternals ○ Process Explorer ○ Process Monitor ○ WinObj
● WinDBG ● Rohitab API Monitor (http://www.rohitab.com/apimonitor) ● RPCView (http://www.rpcview.org/) ● OleView.NET (https://github.com/tyranid/oleviewdotnet) ● Sandbox Analysis Tools (
https://github.com/google/sandbox-attacksurface-analysis-tools ● IDA Pro
James Forshaw @tiraniddo
Questions?
60
Top Related