A View Into ALPC RPC Pacsec 2017
A View Into ALPC RPC Pacsec 2017
ALPC-RPC
Introduction
ALPC
RPC
UAC
Advanced features
A view into ALPC-RPC
& vulnerability
research
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
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
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
Clément Rouault
& Thomas Imbert
PacSec
PORT_MESSAGE
A view into
ALPC-RPC
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
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
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 :)
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
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
RPC
appinfo!AiIsEXESafeToAutoApprove
UAC
Advanced features
Bypass UAC for trusted binary:
& vulnerability g_lpAutoApproveEXEList
research
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
Clément Rouault
& Thomas Imbert
PacSec
Agenda
A view into
ALPC-RPC
Introduction
ALPC
RPC
Conclusion
Clément Rouault
& Thomas Imbert
PacSec
ALPC Message Attributes structure
A view into
ALPC-RPC
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
Conclusion
Token Expose tokens ID
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
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 *
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
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
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
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
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
client.alpc_client.send(p)
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
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);
}
// [...]
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
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
CVE-2017-11783
Conclusion
https://github.com/hakril/PythonForWindows
https://portal.msrc.microsoft.com/en-US/
security-guidance/advisory/CVE-2017-11783