60
James Forshaw @tiraniddo https://www.flickr.com/photos/giuseppemilo/40760404654

James Forshaw @tiraniddo

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: James Forshaw @tiraniddo

James Forshaw @tiraniddo

https://www.flickr.com/photos/giuseppemilo/40760404654

Page 2: James Forshaw @tiraniddo

Who am I?

● Researcher in Google’s Project Zero● Specialize in Windows

○ Especially local privilege escalation○ Logical vulnerability specialist

● Author of a book on attacking network protocols

● @tiraniddo on Twitter.

2

Page 3: James Forshaw @tiraniddo

Why Talk About Windows Runtime?

Understand the Technology

Aid to Reverse Engineering

Improve Security Research

3

Page 4: James Forshaw @tiraniddo

Background Research

https://conference.hitb.org/hitbsecconf2012ams/materials/D1T2%20-%20Sebastien%20Renaud%20and%20Kevin%20Szkudlapski%20-%20WinRT.pdf

https://www.troopers.de/downloads/troopers17/TR17_Demystifying_%20COM.pdf

4

Page 5: James Forshaw @tiraniddo

This Talk is based on Windows 10 1803/1809

5

Page 6: James Forshaw @tiraniddo

OleViewDotNet

6https://github.com/tyranid/oleviewdotnet

Page 7: James Forshaw @tiraniddo

Win32 (KERNEL32/USER32/GDI32)

Windows Runtime

What’s the Windows Runtime (WinRT)?

COM Runtime

RPC Runtime

7

UWP Application

Page 8: James Forshaw @tiraniddo

Component ProviderComponent Consumer

COM Joins Everything Together

JavaScript

C

C++

.NET

JavaScript

C

C++

.NET

COM

8

Page 9: James Forshaw @tiraniddo

IInspectable the New Root of EvilMIDL_INTERFACE("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90")IInspectable : public IUnknown {public:

HRESULT GetIids(ULONG *iidCount,IID **iids);

HRESULT GetRuntimeClassName(HSTRING *className);

HRESULT GetTrustLevel(TrustLevel *trustLevel);

};9

Get a list of interface IDs supported by class.

Get class name.

Get class trust level.

Page 10: James Forshaw @tiraniddo

Activation Factories● Component classes can’t be directly ‘newed’ so WinRT defines a factory

interface, IActivationFactory. Does not use IClassFactory.

DEFINE_GUID(IID_ActivationFactory,"00000035-0000-0000-C000-000000000046");

struct IActivationFactory : public IUnknown {HRESULT ActivateInstance(IInspectable **instance

);};

10

Page 11: James Forshaw @tiraniddo

Activation Factories and InstancesHRESULT RoGetActivationFactory(HSTRING activatableClassId,REFIID iid,LPVOID* factory);

HRESULT RoActivateInstance(HSTRING activatableClassId,IInspectable** instance,

);

11

Abbreviated as ACID

Example ACID: “Windows.Foundation.Uri”

Page 12: James Forshaw @tiraniddo

%ProgramData%\Package\ActivationStore.dat

HKEY_CURRENT_USER\Software\ClassesHKEY_LOCAL_MACHINE\Software\Classes

Runtime Class Registry Keys

System

Windows Runtime

Classes

Per-App Runtime Classes

Per-App Runtime

Extension Classes

12

Page 13: James Forshaw @tiraniddo

Runtime Extension Classes

13

Contract ID Description

Windows.Launch Default Application Launch

Windows.Protocol URI Protocol Handler

Windows.BackgroundTasks Background Task

Windows.File Launch and pass a file object

Windows.Search Search request

Page 14: James Forshaw @tiraniddo

Class Trust Levels

14

HRESULT GetTrustLevel(TrustLevel *trustLevel);

Full Trust

Partial Trust

Base Trust

Can only be created in a fully trusted context

Can be created in a sandbox context through a broker

Can be created in any context

Page 15: James Forshaw @tiraniddo

AppContainer Sandbox

System ServiceBase Trust Class

RPCSS

DCOM Activator

15

Base Trust Class

Page 16: James Forshaw @tiraniddo

AppContainer Sandbox

System Service

Normal User Level

Partial Trust Class

Runtime Broker

Partial Trust Class

RPCSS

DCOM Activator

16

Page 17: James Forshaw @tiraniddo

DEMO 1

17

Page 18: James Forshaw @tiraniddo

Application Manifest XML

18

<Package><Identity Name="Microsoft.MicrosoftEdge"

Publisher="CN=Microsoft Corporation, ..."Version="44.17763.1.0"ProcessorArchitecture="neutral"/>

<Applications><Application Id="MicrosoftEdge"

Executable="MicrosoftEdge.exe"EntryPoint="MicrosoftEdge.App">

...</Application>

</Applications></Package>

Package Identity

Application Launch

Page 19: James Forshaw @tiraniddo

System Service

Normal User Level

Application Activation

SIHOST

Application Activator

EXPLORER

RPCSS

19

Call ActivateApplication over DCOM

Page 20: James Forshaw @tiraniddo

System Service

Normal User Level

Application Activation

SIHOST

Application Activator

EXPLORER

RPCSS

Process State Manager

HOST ID: XYZ

20

Create a new Application Host

Page 21: James Forshaw @tiraniddo

AppContainer Sandbox

System Service

Normal User Level

Application Activation

SIHOST

Application Activator

EXPLORER

RPCSS

DCOM Activator

HOST ID: XYZ

21

Create Application via Activator

Page 22: James Forshaw @tiraniddo

AppContainer Sandbox

System Service

Normal User Level

Application Activation

SIHOST

Application Activator

EXPLORER

RPCSS

HOST ID: XYZ

22

Pass Arguments to Application

Page 23: James Forshaw @tiraniddo

WinRT Activation Properties

CustomHeader

Property 1

Property 2

Property 3

Property 4

struct ComWinRTActivationPropertiesData {HSTRING activatableClassId;HSTRING packageFullName;ULONGLONG userContext;PBLOB rtbProcessMitigationPolicyBlob;

};

struct ExtensionActivationContextPropertiesData {ULONGLONG hostId;ULONGLONG userContext;GUID componentProcessId;ULONGLONG racActivationTokenId;PBLOB lpacAttributes;ULONGLONG consoleHandlesId;ULONGLONG aamActivationId;

};

ActivationPropertiesIn

23

Page 24: James Forshaw @tiraniddo

Extension Activation

24

// Exported as Ordinal #65HRESULT RoGetExtensionRegistration(HSTRING contractId,HSTRING packageId,HSTRING activatableClassId,IExtensionRegistration **extensionRegistration);

IExtensionRegistration* reg =;RoGetExtensionRegistration("Windows.Launch",

"Pkg_1.0.0.0_xxxxxxxxx", "App", &reg);reg->set_HostId(12345678);IInspectable* obj;reg->Activate(&obj);

Page 25: James Forshaw @tiraniddo

AppContainer Access Token Attributes

25

Application Host ID System

Application ID

Package Flags

Low Privilege App Container

Caller needs SeTcbPrivilege to add or modify security attributes.

Page 26: James Forshaw @tiraniddo

Building the System Application ID

26

Component Example

Package Name Microsoft.MicrosoftEdge

Publisher ID 8wekyb3d8bbwe

Package Family Name Microsoft.MicrosoftEdge_8wekyb3d8bbwe

Package Full Name Microsoft.MicrosoftEdge_44.17763.1.0_neutral__8wekyb3d8bbwe

Package Moniker Same as Package Full Name

Package-Relative App ID App

Application User Model ID Microsoft.MicrosoftEdge_8wekyb3d8bbwe!App

Page 27: James Forshaw @tiraniddo

AppContainer SID and Capabilities

27

<Capabilities><Capability Name="internetClient"/><Capability Name="privateNetworkClientServer"/><rescap:Capability Name="childWebContent"/><rescap:Capability Name="confirmAppClose"/><rescap:Capability Name="lpacCom"/>...<DeviceCapability Name="location"/><DeviceCapability Name="microphone"/><DeviceCapability Name="webcam"/>

</Capabilities>

Package Family Name and

Package SID

Page 28: James Forshaw @tiraniddo

DEMO 2

28

Page 29: James Forshaw @tiraniddo

Reverse Engineering Native Components

29

Page 30: James Forshaw @tiraniddo

Windows Metadata

30

C:\Windows\System32\WinMetadata

Page 31: James Forshaw @tiraniddo

Combining Interfaces

class RuntimeClass {// Default constructor.public RuntimeClass();// Constructor with parameter.public RuntimeClass(int p);// Static method.public static int A();// Instance method.public int B();

}

Factory Object

Instance Object

31

Page 32: James Forshaw @tiraniddo

Combining Interfaces

class RuntimeClass {// Default constructor.public RuntimeClass();// Constructor with parameter.public RuntimeClass(int p);// Static method.public static int A();// Instance method.public int B();

}

Factory Object

Instance Object

interface IActivationFactory {HRESULT ActivateInstance(IInspectable **instance

);}

interface IRuntimeClass {HRESULT B(int* retval);

}32

Page 33: James Forshaw @tiraniddo

Combining Interfaces

class RuntimeClass {// Default constructor.public RuntimeClass();// Constructor with parameter.public RuntimeClass(int p);// Static method.public static int A();// Instance method.public int B();

}

Factory Object

Instance Object

interface IActivationFactory {HRESULT ActivateInstance(IInspectable **instance

);}interface IRuntimeClassFactory {HRESULT ActivateInstanceWithParam(

int p,IRuntimeClass** instance);

}

interface IRuntimeClassStatics {HRESULT A(int* retval);

}

interface IRuntimeClass {HRESULT B(int* retval);

}33

Page 34: James Forshaw @tiraniddo

Finding the Implementation Binary

34

PS> $cls = Get-ComRuntimeClass -Name "Class.Name"Get object for the class

PS> $cls.DllPathIf In-Process get DLL path

PS> $cls.ServerEntry.ExePathIf OOP NormalExe get Server Exe Path

PS> $cls.ServerEntry.ServiceNameIf OOP service get Service name

Page 35: James Forshaw @tiraniddo

Activation Entry Points

35

HRESULT DllGetActivationFactory(HSTRING activatableClassId,IActivationFactory **factory

);

HRESULT RoRegisterActivationFactories(HSTRING *activatableClassIds,PFNGETACTIVATIONFACTORY *activationFactoryCallbacks,UINT32 count,RO_REGISTRATION_COOKIE *cookie

);

Exported from a DLL

Called in an EXE

Page 36: James Forshaw @tiraniddo

C++ Application Frameworks

36

C++/CX (Custom C++ dialect)void App::OnLaunched(LaunchActivatedEventArgs^ e) {

Handler^ handler = ref new Handler();handler->HandleLaunch("Launched");

}C++/WRL (C++ 11)HRESULT App::OnLauncher(ILaunchActivatedEventArgs* e) {

ComPtr<IHandler> handler;HRESULT hr = Make<Handler>(&handler)if (FAILED(hr))

return hr;HStringReference str(L"OnLaunched");return handler->HandleLaunch(str.Get());

}

C++/WINRT (C++ 17)void App::OnLaunched(LaunchActivatedEventArgs const& e) {

Handler handler = Handler();handler.HandleLaunch(hstring(L"Launched"));

}

Page 37: James Forshaw @tiraniddo

IDL File

37

namespace WRLClass {[uuid(E74F1CF0-59C7-4CA6-BDE5-0F9DED9B4EF7),

version(1.0), exclusiveto(WinRTClass)]interface IWinRTClass : IInspectable {

HRESULT Add([in] int a, [in] int b,[out, retval] int* value);

}

[version(1.0), activatable(1.0)]runtimeclass WinRTClass {

[default] interface IWinRTClass;}

}

Page 38: James Forshaw @tiraniddo

C++/WRL Implementation

38

class WinRTClass : public RuntimeClass<IWinRTClass> {InspectableClass(L"WRLClass.WinRTClass", BaseTrust)

public:HRESULT STDMETHODCALLTYPE Add(

/* [in] */int a,/* [in] */int b,/* [retval, out] */int * value

) override {*value = a + b;return S_OK;

}};

ActivatableClass(WinRTClass);

Define base implementation of IInspectable

Interface Implementation

Define ActivationFactory

Page 39: James Forshaw @tiraniddo

Finding Implemented Interfaces

39

HRESULT QueryInterface(REFIID riid, void** ppv) {bool handled = false;HRESULT hr = CustomQueryInterface(riid, ppv, &handled);if (FAILED(hr) || handled)

return hr;

return Super::AsIID(this, riid, ppv);}

Overridable Custom QI

Call AsIID helper method

Page 40: James Forshaw @tiraniddo

AsIID Helper

40

HRESULT AsIID(RuntimeClass<IT...>* implements,REFIID riid, void **ppv) {

HRESULT hr = E_NOINTERFACE;if (riid == __uuidof(IUnknown)|| riid == __uuidof(IInspectable)) {

*ppv = implements->CastToUnknown();hr = S_OK;

} else {hr = implements->CanCastTo(riid, ppv);

}if (SUCCEEDED(hr))

static_cast<IUnknown*>(*ppv)->AddRef();return hr;

}

Variadic Template Handle Base

Case

Specific CanCastTo

Page 41: James Forshaw @tiraniddo

CanCastTo Helper

41

HRESULT RuntimeClass<I1, I2, I3> CanCastTo(REFIID riid,void* ppv) {

if (riid == __uuidof(I1)) {ppv = static_cast<I1*>(this);

} else if (riid == __uuidof(I2)) {ppv = static_cast<I2*>(this);

} else if (riid == __uuidof(I3)) {ppv = static_cast<I2*>(this);

} else {return E_NOINTERFACE;

}return S_OK;

}

Variadic Template Expanded

Test Each Interface

Page 42: James Forshaw @tiraniddo

String Handles (HSTRING)typedef struct HSTRING__{

int unused;} HSTRING__;

// Declare the HSTRING handle for C/C++typedef HSTRING__* HSTRING;

WindowsCreateString(PCNZWCH sourceString,UINT32 length,HSTRING *string

);

WindowsCreateStringReference(PCWSTR sourceString,UINT32 length,HSTRING_HEADER *hstringHeader,HSTRING *string

);Reference counted on the heap. Scoped on the stack.

Opaque string handle structure.

42

Page 43: James Forshaw @tiraniddo

The Real HSTRING

struct HSTRING_HEADER_INTERNAL {WINDOWS_RUNTIME_HSTRING_FLAGS flags;unsigned int length;unsigned int padding1;unsigned int padding2;const wchar_t *stringRef;

};struct STRING_OPAQUE {HSTRING_HEADER_INTERNAL header;volatile int refcount;wchar_t string[1];

};

Used for stack scoped “reference” strings.

Inline string data and reference count for use on the heapPCWSTR WindowsGetStringRawBuffer(

HSTRING string,UINT32 *length

);

Call to get raw buffer and length.

43

Page 44: James Forshaw @tiraniddo

PS> $intf = Get-ComClassInterface $cls

Get all known interfaces for a class.

PS> $obj = New-ComObject -Class $clsCreate a new instance of a COM object.

PS> $prx = $intf | Get-ComProxyGet proxy information for a list of interfaces.

PS> $prx | Format-ComProxyFormat the COM proxies as text.

44

Page 45: James Forshaw @tiraniddo

Debugging Applications

45

PS> Get-ComRuntimeExtension -Launch | `Select PackageId, AppId

Get all registered Windows.Launch Extensions

PS> windbg.exe -plmPackage PKGID -plmApp APPIDStart a package and debug it.

PS> plmdebug.exe /enableDebug PKGID DBGPATH.EXEEnable debugging for a package

Page 46: James Forshaw @tiraniddo

DEMO 3

46

Page 47: James Forshaw @tiraniddo

Windows Runtime Security

47

Page 48: James Forshaw @tiraniddo

AppContainer Sandbox

System Service

Normal User Level

Sandbox Escape OOP Attack Surface

Runtime Broker

Partial Trust Class

48

Service Process

OOP Runtime Class

User Process

Interactive User Class

Page 49: James Forshaw @tiraniddo

Get Interactive User classes

PS> Get-ComRuntimeClass -TrustLevel PartialTrustGet list of partial trust classes

Get svchost hosted classes

49

PS> Get-ComRuntimeServer -IdentityType SessionUser ` | Select -ExpandProperty Classes

PS> Get-ComRuntimeServer -ServerType SvchostService `| Select -ExpandProperty Classes

Get EXE hosted classes

PS> Get-ComRuntimeServer -ServerType ExeService `| Select -ExpandProperty Classes

Page 50: James Forshaw @tiraniddo

Partial Trust Class Default Permissions

50

Allows all AC at the same user to access the class.

PS> Show-ComSecurityDescriptor -RuntimeDefault

Page 51: James Forshaw @tiraniddo

Class Specific Permissions

51

PS> Show-ComSecurityDescriptor $cls

Adds the lpacAppExperience capability

Page 52: James Forshaw @tiraniddo

Finding Accessible Classes

52

PS> Get-ComRuntimeClass | Select-ComAccess -pid X

Page 53: James Forshaw @tiraniddo

Package Name Checks

53

BOOL BrokerAuthenticateCOMCaller() {HANDLE token;CoImpersonateClient();OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, &token);WCHAR family_name[255];ULONG family_name_length = 255;NTSTATUS status = RtlQueryPackageClaims(token,

family_name, &family_name_length);if (NT_SUCCESS(status))return wcsicmp(package_name, L"MicrosoftEdge") == 0;

return FALSE;}

Reads from WIN://SYSAPPID

Page 54: James Forshaw @tiraniddo

Incorrect Capability or Missing Security Checks

54

HANDLE CheckedCreateFile(string path) {// Get client token.HANDLE token;CoImpersonateClient();OpenThreadToken(GetCurrentThread(), &token);

HANDLE ret = INVALID_HANDLE_VALUE;if (CapabilityCheck(token, L"internetClient")) {ret = CreateFile(path, ...);

}

return ret;}

Checking for internetClient capability

But opening a file.

Page 55: James Forshaw @tiraniddo

HSTRING is a Counted String

55

UINT32 length;PCWSTR str = WindowsGetStringRawBuffer(hString,

&length);// Might not be equal.assert(wcslen(str) == length);

HRESULT WindowsStringHasEmbeddedNull(HSTRING string,BOOL *hasEmbedNull

);

Page 56: James Forshaw @tiraniddo

TOCTOU in Marshaled Interfaces

56

HRESULT StartViewer(IFileObject file) {if (file.GetPath().EndsWith(".exe"))return E_ACCESS_DENIED;

ShellExecute(file.GetPath());} class MyFileObject : IFileObject {

bool _returned = false;string GetPath() {

if (_returned)return "calc.exe";

_returned = true;return "safe.txt";

}}

First call returns safe filename.

Second call returns unsafe filename.

Takes Generic interface

Page 57: James Forshaw @tiraniddo

Inject a DLL Into Running Process

57

Only Store signed DLLs can be loaded

Page 58: James Forshaw @tiraniddo

DEMO 4

58

Page 59: James Forshaw @tiraniddo

Conclusions

● All based on familiar COM programming paradigms● The Windows Runtime has many interesting attack surfaces

○ Attack surface which might be accessible remotely○ Plenty of Sandbox to User and User to System privilege escalation routes

● Tooling is not quite there, making an effort with OleViewDotNet

59

Page 60: James Forshaw @tiraniddo

60