# SyScan'14 Singapore: All About The Rpc, Lrpc, Alpc, And Lpc In Your Pc By Alex Ionescu

https://www.youtube.com/watch?v=UNpL5csYC1E

[00:00] so Tata my talk is all about the LPC RPC.
[00:03] LPC lrpc in your PC which sounds very confusing.
[00:06] but I sent five title suggestions to Thomas 4 which made a lot of sense and he picked this one so that's this fault.
[00:13] so brief little bio by myself.
[00:17] I've been reverse engineering windows since about 1999 working on react OS which is an open source implementation of Windows.
[00:24] after a few years reversing windows I then went to the most logical place to work which is Apple to work on iOS on the core platform team.
[00:34] so I worked on the bootloader drivers and XE new kernel for all the AI devices us an intern there for a few years and then once I graduated and went on to work across strike which is a security company in the Bay Area.
[00:49] so pretty much been doing windows internals for about more than a decade now at the same time working on on Apple stuff as well but that's not that's not where we'll be.
[01:00] talking about right now so what I'm going to be talking about is something that started out pre Vista as something called LPC or local procedure call.
[01:08] LPC is a mechanism that was added to Windows NT from the very beginning which allowed two processes to talk to each others or the kernel to talk the user mode.
[01:21] so most of us does have things like named pipes mail slots sockets and Windows has all those mechanisms.
[01:27] the kernel team wanted to have something more efficient more specific that a kernel less portable but being able to take advantage of some kernel specific functionality.
[01:38] so they created this thing called LPC.
[01:40] now LPC was undocumented but through the years many security researchers have found bugs and LPC issues in LPC and today it's a fairly understood mechanism.
[01:50] now since LPC's undocumented developers don't use LPC.
[01:53] so developers instead that you would use either and I can mention name pipes for example chrome uses name pipes to talk between it surrender ends.
[02:02] broker or they would use RPC which is the remote procedure call interface that Microsoft uses in Windows Bay's on the DC standard from almost two decades ago now.
[02:14] an RPC because of some issues in LPC namely its lack of asynchronous support.
[02:22] actually use name pipes so previous stuff you're using RPC you are pretty much talking over name pipes.
[02:29] Microsoft then has something called comm become the common object model which is a way to share data and share objects and share functions within a process and outside of a process and decom or distributed comm is how you can have comm objects better out of process and you can do comm method calls to those objects and decom uses RPC internally.
[02:50] and so the reason i measuring this it's because we're see that what happened is the LPC became deprecated and so in vista they got rid of LPC and replaced it with what they call advanced the LPC or asynchronous LPC and what a LPC did.
[03:06] is a brought a synchronicity.
[03:08] it brought cancel ability and it brought atomicity guarantees to LPC and because of those new changes the RPC team in Microsoft switched to using by default the a LPC protocol in Windows instead of named pipes and what this means is that all the components that were using are PCB for which we're relying on named pipes a pretty old and well understood system are now using a LPC which is an undocumented and very little understood system so even though you've never coded with a LPC and most applications don't use a LPC as long as using RPC in your application or some application is using RPC which is the remote procedure call you're using a LPC and because decom the distributed comm object model uses RPC now any time you interact with a niqab jecht you're using a LPC and so decom is very very central to Windows for example every time you change the time you're creating a decom.
[04:08] object windows user mode drivers are decom objects.
[04:11] Windows 8 applications on the Windows Store are comm object.
[04:14] so pretty much everything is this decom and if they don't they use RPC.
[04:17] and so pretty much every process today even the simplest win application has at least one active a LPC connection to probably at least one process running the system rights.
[04:22] so everyone on a system is talking to other things and some of those things are running with extremely high privileges.
[04:34] so that becomes obviously very interesting playground.
[04:38] so if most if many windows EP is are using our PC and decom if using my drivers using decom if we know store applications or decom.
[04:43] I mean if you have a bug in a OPC you can own a OPC servers including the kernel which it does have a few a OPC servers of its own.
[04:49] you can own any RBC RPC server and you can own any decom.
[04:55] now stepping back a bit if you find a bug in the RPC runtime over a LPC which is called lrpc the local or the LPC.
[05:11] protocol behind RPC then you can own arbitrary RPC service and arbitrary decom objects.
[05:16] So instead of finding bugs in a specific server you can try to find bugs in the actual runtime in the RPC layer or even better in the acts with a LPC runtime in the kernel.
[05:25] And if you have an LPC bug pretty much means that from any sandbox from any context you can exploit a system and get pearls rights.
[05:34] Even the most you know if you take the chrome renderer for example which is an example of a pretty good sandbox even it surrender has an LPC handle to someone.
[05:42] So as soon as you have any OPC handle if you have any bug that obviously becomes very very interesting.
[05:49] Plus all the individual bugs that can exist in a OPC servers themselves because each a OPC server implements its own packet interface its own messages its own logic.
[05:58] And so because this is undocumented nobody really expects you to talk to it so there's a little bit of security through obscurity that says well hey I'm a Microsoft team I'm implementing a OPC server no one knows.
[06:12] how a OPC works so maybe I'm not going to do all the parameter checking or maybe I will.
[06:17] we'll see so I want to talk a little bit about how a OPC works very brief details on how LPC servers and clients communicate and some of the behaviors behind LPC.
[06:27] so if you're familiar with BSD sockets a OPC should be a little bit similar because to begin with you have a server that calls a Windows epi and TLB sikri port.
[06:41] gives a port name some attributes like how big can the messages across the sport be and a secure descriptor that says you know who can connect it a sport.
[06:50] the server thing gets a handle to what's called an Al PC server connection port.
[06:55] and so these ports their windows and T objects similar to mutex see similar to events semaphores so their name is going to be globally accessible in the object manager namespace people will be able to open handle city sports and they use a standard Windows object model now you.
[07:14] have this named port and a system like Bob sport.
[07:16] the server will then call ntal PC send weight receive port to send a message on the sport or to receive a message on a port.
[07:25] now of course the very first time you're starting up as a server you have nothing to send so you send nothing and you just block on receiving messages.
[07:33] and if you are doing blocking calls and you don't have to because a a PC does support asynchronous calls.
[07:39] if you're doing blocking calls you as the server will now block on this API waiting for the first message to be received.
[07:45] and if this is a brand-new server the first message you should ever receive should be the client trying to connect you.
[07:52] so how does a client connect.
[07:54] client calls NTL BC Connect port passes in the name of the port passes in any attributes of the port on its side.
[08:02] so I don't want to receive replies from a server that are bigger than X bytes for example and you can specify an initial connection message.
[08:08] a sinistra connection message allows a server for example to decide whether or not it should allow
[08:15] you to connect but as long as the security descriptor says that Bob you can connected a sport then Bob can try to connect at a port with this API at this point da OPC server will wake up.
[08:28] now if on the other hand whoever created that ports and this port is having only or system only then you won't even be able to try connecting to it unless your admin or your system so let's say you're able to connect to it well now the server will receive a connection request.
[08:42] so the server will wake up it'll get a packet that says there's a connection request and if the client passed in connection payload the server will see the payload now and some clients pass in a little pail ooh that says things like you know I'm version 1.0 here is my data here is some use a magic word and the server will validate are you passing you the initial connection packet that I expect.
[09:07] so this is something that servers and clients can implement on their own.
[09:09] the server also gets from the OS the pit the tid the CID the token and a few
[09:18] other pieces of information about who's trying to connect to it so the server can take action and say well I am allowing arbitrary servers the clients to connect but if their CID doesn't match or if their CID isn't something I like that I'll disconnect them so servers can take decisions on whether or not they want to accept a connection or not.
[09:36] once they make that decision they will always call ntal BC accept connect port.
[09:42] now even though the name says except there's a boolean variable that says do you actually want to accept it or not so if you reject it then a client wakes up and gets the status of ever does not get a handle.
[09:53] if you accept it you can then respond to the connection packets you can say you pass me saying version 3 I'm accepting your connection but I'm responding by letting you know that I'm actually implementing version 4 just FYI so you can respond with your own packet as well and as a server you can allocate your own structure to identify this client because if you're going to have 4 5 6 100 clients as you
[10:20] start receiving actual messages from the clients you want to know who you're talking to.
[10:22] so you will usually malloc some internal structure of your own and associate that structure with this sport.
[10:30] when you call the connect API so when you call that connect that sorry that accept API.
[10:33] so when you call that accept function you pass in a port context which is whatever pointer you would like to associate with this sport.
[10:39] from now on whenever the client talks to you that specific line are you accepted you're going to get the port context associate with that client so you know who's talking to you now.
[10:49] the server gets a new handle so you had the initial handle for your connection port this is the handle through which clients can attempt to connect.
[10:59] once a client connects to you once you accept the client you get a new handle.
[11:04] just similar to be as the sockets right in DSD sockets you call socket to have your service socket then you call except maybe against a single time you want to accept the client and you get a new socket handle.
[11:13] so same thing in a LBC meter well in a client side the client remember was blocked on the connect when
[11:20] the connect returns the climb gets a handle too.
[11:22] so you have three handles in this case the master server connection port handle through which connections are being made.
[11:29] you have the client side handle and a service side handle and as new clients try to connect you can have additional client side handles and additional service I handles as well.
[11:39] plus the master handle that you began with.
[11:42] so it should be fairly easy simple protocol semantics that most other protocols implement as well.
[11:47] now when you actually send an LPC message the payload can be anything you want.
[11:52] the only thing is that has to have this port header on top of it.
[11:57] and this is a document of structure into Microsoft header files.
[11:59] this port header basically has a little piece of data that tells the server how big is your message and what type of message are you sending.
[12:09] it also has a space for the pit and at it.
[12:12] now you don't fill that out.
[12:14] the kernel will fill that out for you.
[12:16] and so when you pass a message the receiver of the message will always get
[12:20] your paid and your tid plus the actual message length that you passed in.
[12:26] how big this message can be depends on LPC or a LPC.
[12:28] so back in the LPC days it could be as big as 256 bytes in the LPC world.
[12:34] today it can be as big as 64 kilobytes.
[12:36] but what if you need to send a bigger message then it won't fit at this point.
[12:42] you create what LPC lets you do which is an LPC port section.
[12:44] sections are the windows name for shared memory objects.
[12:48] and so section represents some piece of ram that the server wants to share with other clients.
[12:55] and the server will receive a view of this region of ram.
[12:58] so local virtual address space mapping that points that is these cookies bytes.
[13:02] and when the message gets sent to a client the client will receive a view that maps this Ram as well.
[13:12] and now both the server and the client they share the address space that corresponds to these pages Ram.
[13:16] and so the data doesn't be copied in and out the more in 640.
[13:21] with more than 64 kilobytes you're wasting a lot of time copying data between client and server.
[13:27] with shared memory you don't have to copy any data.
[13:29] the data is always there.
[13:31] now that does cause some interesting side effects that I'll talk about but it's a lot faster than the normal Marshall and Andy marshalling of the data.
[13:38] so how do you pass a view.
[13:40] well you passed out with weather or weather or are called LBC attributes that we'll share in a second.
[13:46] now before we get to attributes when you actually send a message with a LPC you can send it as a Datagram or as a request.
[13:55] and this is again very similar to network protocols.
[13:57] so a request has to have reply so that's the standard TCP model.
[14:02] a Datagram does not have a reply.
[14:05] in fact you cannot you will not get a reply in a server cannot send a reply.
[14:11] so if using synchronous LPC we send a request you're going to block under your eye you have to get reply back.
[14:18] if you're using asynchronous LPC and you send a
[14:21] request then you can either set up an auto completion port.
[14:25] and this is a standard MSDN documented mechanism that Windows developers use for asynchronous file i/o.
[14:29] it can be used for asynchronous LPC i/o as well.
[14:32] you can have a kernel callback function so if you actually implement an LPC server in the kernel you can have a callback function that gets a synchronously called every single time there's a message.
[14:43] or you can use what's called a memory completion list which is about a feature.
[14:47] so these these three techniques allow you to receive asynchronous messages.
[14:50] otherwise if you're going to be doing synchronous LPC your thread will block every single time you send reply.
[14:55] your thread will block every single time you wait on a request and it's your choice which of these mechanisms you want to use.
[15:02] now with datagrams you'll never block because there's nothing for you to block on.
[15:07] a Datagram is like UDP send a message hope it comes back hope it gets received but you have no idea and nothing will ever come back to you.
[15:16] so what are these attributes that I mentioned on the earlier slide.
[15:18] so I said when you have a data view when you have
[15:21] it when you have a share section you have these views and you have to put them in an attribute so attributes are ABC's way of handling what I would call metadata
[15:32] so your payload is a data it's some opaque information between you and a server or between a server and the client
[15:39] the metadata is information that it needs to be trusted in some sort of way or needs to be tracked in a special way that we don't want to treat opaquely
[15:48] and in LPC in the religion C system there were no attributes and so in the LPC system if you wanted to share data that had some sort of trust level associated with it that had some sort of requirement around its reference counting LPC did none of that for you
[16:05] so if you pass the pointer with LPC you have to hope the point would still be valid if you pass the handle a LPC with LPC you have to hope the handle will still valid with a LPC there's ways to actually track these these pointers or these handles or these other trusted
[16:22] resources and so for example if you have a shared view and you're passing the address of that view between the client and a server because you want them to share that that address will be packed in an attribute called the data view attribute and the Kerner will manage the value of that attribute in a kernel will manage sending back and forth that attribute so you're not going to be able to lie to the client or the server about that address and we'll see that also gives you some additional features or let's say you want to have a sequence number you want to know between this client and this server what is the this is the enth or the N + 1 message what's the actual sequence number of this message so if you have an asynchronous server and you're receiving messages out of order which will happen when you have an e synchronous server you can reorder them based on a sequence number or if you want to check if a message is global unique and you'd like to have something like a message ID well the kernel can fill in those fields for you the alb C runtime in the kernel can track sequence numbers for you you can track message IDs for you and if you'd like that then
[17:23] you have what's called a context attribute.
[17:24] the context attribute keeps track of all this per message specific metadata as well.
[17:31] the other kind of attribute you can have is an attribute that says what was the security context of the sender when you when it send this message.
[17:39] because you may want it to know okay so I got this message from an ad or I got this message from an unprivileged user.
[17:46] how can you trust that data well you asked for security attribute and the kernel will fill it in for you.
[17:52] and finally if you want to pass handles between a client and a server use a handle attribute and I'll show an example of how that works.
[17:58] so every time you send out a message you tell a LPC which of these four attributes you're also packaging with that message.
[18:07] now some of those attributes you control like the handle attribute you specify what handle to send the data view attribute you specify with view to send the context attribute and security attribute.
[18:16] the Karner will fill in for you you don't get to pick you on sequence number obviously it has to be trusted.
[18:21] so every time a message is sent a OPC
[18:24] builds this attribute structure and packages with the message and let in another layer save your data layer and you have your metadata layer every time a message is received the receiving side can say here's the ALP C input attributes that I'd like to receive so as a server I can say I want to receive handle attributes I want to receive context attributes I don't want to receive data view attributes so you get to specify what attributes you're willing to accept which attributes you don't want to accept and so a sender can only send you valid attributes but the receiver doesn't want to receive them then use the sender either won't be able to send a message at all or the message will just be dropped or the data and the attributes will not be exposed will not be sent to the server in other words if I have let's say a data view attribute I'm saying here's a shared memory section that I want you to share and I'm sending you a message with that attribute and on the receiving side you're saying I don't want to receive
[19:24] any shared memory sections from you then that section simply will not be mapped
[19:28] on the other hand if you accept an attribute then the kernel will fill in some data or will take action based on that attribute
[19:37] so if you're saying you want a context attribute the kernel will generate a sequence number the kernel will generate a message ID and you're going to get that data
[19:46] if you're saying that you want a security attribute the kernel will jet will capture the token will capture the SID and will send that to you
[19:52] so that's not so bad but if on the other hand you say that you are willing to accept data view attributes then you're going to get whatever view was sent by the client mapped in your address space
[20:03] so the client sent a 500 megabyte view you're going to map a 500 megabyte view of that address space as well
[20:11] the client sent you 20 handles you're going to get 20 handles
[20:15] duplicating address space and I that or your object table in that point it's your job to manage these resources that were given to you by your client or by your receiver
[20:21] so for example the handle
[20:27] attribute is used when I want to share a
[20:29] handle with another server or client in
[20:32] the LPC days in my payload I would put
[20:35] handle number 8 and the colonel would
[20:38] hope handle number 8 is valid to begin
[20:41] with and would just send that number 8
[20:43] to the receiving side the receiving side
[20:46] would then have to hope that 8 is still
[20:48] valid might have been half an hour later
[20:51] must have must hope that 8 is the type
[20:54] of object it expects to be so maybe I
[20:56] want a process handle but 8 is a threat
[20:58] handle well too bad
[21:00] maybe 8 was valid but then you closed 8
[21:03] and you reopened 8 so now a to some
[21:05] other object with LPC I didn't know any
[21:08] of this so a OPC comes in and says you
[21:10] want to send a handle use an attribute
[21:12] package that handle a special way that
[21:15] tells the colonel this number 8 means
[21:17] something and it means that this is a
[21:19] threat object and then a carnival
[21:21] validator when you send this message is
[21:23] a 2 valid is 8 a thread and if so it's
[21:27] going to make a copy of 8 into the
[21:29] kernel object table now there's going to
[21:31] be an actual kernel handle 2 8 let's
[21:34] call it 88 and it's going to send 88 to
[21:37] the receiver
[21:37] now the LPC runtime on the receiver will
[21:40] check is 88 valid yes is 88 what the
[21:44] server thinks it is so the server says I
[21:46] want process handles but you sent the
[21:48] valve thread handle I'm going to get rid
[21:50] of that is a server sided wanted a
[21:52] thread handle you passed in a thread
[21:54] handle good now we're going to make
[21:55] another copy of this handle let's call
[21:57] it 48 which is going to be valid for the
[22:00] receiving side and so this way we make
[22:02] sure that the original handle if you
[22:04] mess around with it nothing bad can
[22:06] happen if the original handle wasn't
[22:09] valid to begin with or was pointed to
[22:11] another
[22:11] object you're never going to receive it
[22:13] and this is a really nice mechanism that
[22:15] guarantees through receiving silac
[22:17] server I'm getting valid handles
[22:20] similarly the view attribute has similar
[22:23] guarantees for clients and servers so if
[22:27] I want to send you some data a map of
[22:29] over 64 kilobytes I use this view well
[22:32] one of the things that a OPC gives you
[22:34] with views as you can see that a view is
[22:36] auto release and this is why I send you
[22:39] a one megabyte message and my view gets
[22:41] unmapped you receive the one megabyte
[22:44] view and then it gets mapped in your
[22:46] address space you send it back to me
[22:48] he gets unmapped from your address base
[22:50] and I remap it in mind in this way if
[22:53] I'm talking to 50 different clients and
[22:55] I'm sending one megabyte messages I
[22:57] don't have to keep map in my address
[22:58] base 51 megabyte views so that's one
[23:01] nice thing it gives you the other really
[23:04] nice thing it gives you is the ability
[23:06] of a secured view and what secure view
[23:09] says is well if I have a client and a
[23:12] server and they're sharing data what can
[23:15] happen is I can have a client sending a
[23:20] message to a server and remember they
[23:22] have two separate views but these two
[23:26] views are sharing the exact same piece
[23:29] of ram and so I can send you a message
[23:32] that has let's say a length associated
[23:34] with this I'm going to say the length of
[23:35] the message is you know eight bytes and
[23:38] then I've got a pointer to some payload
[23:40] so this immediately writes eight in RAM
[23:42] it writes the payload in RAM which
[23:46] immediately writes eight in the server
[23:47] address space and writes the pointer in
[23:49] a server address space first thing the
[23:51] server does is a valley to live 8 is
[23:54] smaller than my maximum good to go now
[23:58] I'm going to do a mem copy of this
[24:00] length into some pointer from that
[24:01] pointer and so I'm about to do the mem
[24:03] copy still referencing your input number
[24:07] here well on the client side I can race
[24:10] with you and change this 8 after you
[24:13] validated it to let's say 800 and now
[24:17] you suddenly see 800 and when you do
[24:19] your memo
[24:20] your memory 800 bytes so this is a
[24:23] simple time of use versus time of
[24:25] check bug once you have a system calls
[24:27] for example but over shared memory
[24:29] becomes a lot easier to do this kind of
[24:32] attack so this becomes a huge problem in
[24:36] decom because the way decom works is
[24:40] what I'm actually packaging here is an
[24:42] actual call so all my scalar arguments
[24:45] all my pointer arguments the actual the
[24:47] very call I'm making Thetas comm object
[24:49] is going to be in a shared memory
[24:51] section and so all the parameters that
[24:53] I'm sending to the function are all
[24:55] going to be in the show memory section
[24:56] and if I can change the parameters of
[24:59] the function while the function is
[25:00] actually running that's obviously very
[25:02] bad and so with LPC there is nothing you
[25:06] can do about this and that's another
[25:07] reason why we have to use name pipes
[25:09] with a LPC the views can be marked
[25:12] secured and what secure it says is you
[25:16] write your data here in this view which
[25:19] is like before and when you are actually
[25:22] sending the message from client to
[25:24] server as it crosses the boundary this
[25:27] view gets a remapped read-only and now
[25:32] the receiving view gets mapped readwrite
[25:35] and now the serve the content the sender
[25:38] the client can no longer change the data
[25:41] in the view while the server or the
[25:43] receivers processing it on top of that a
[25:46] bunch of undocumented windows functions
[25:48] are used to make this whole region
[25:50] unmodifiable unnhhh on unmapped bool so
[25:54] lock the memory virtual protect won't
[25:56] work remapping it won't work so all
[25:59] these api is on a slide are used to make
[26:01] sure that there's no way that you're
[26:04] ever going to be able to touch that
[26:05] memory again while the receiving side is
[26:08] processing it so this is a key component
[26:10] of how decom is able to work and again
[26:13] the attribute mechanism let's the kernel
[26:15] manage all this in a safe and secured
[26:17] way so these are look like really good
[26:20] features to have and makes a OPC looks
[26:23] really good and it's true from any drink
[26:25] standpoint a OPC is a really advanced
[26:27] and useful communication mechanism but
[26:29] things can obviously go wrong so here's
[26:34] a little example of some code on how you
[26:36] would initialize a port
[26:39] so you're trying to connect to a server
[26:41] the first thing you would do is
[26:43] initialize your own client port so you
[26:45] can tell a OPC when you when I connect
[26:47] to the server these are my attributes
[26:49] for example I'm going to be receiving up
[26:52] to 60 kilobytes worth of reply because
[26:54] you know what you can have a malicious
[26:56] client you may also have a malicious
[26:58] server and so I'm going to say the
[27:00] server tries to send me more than 60
[27:02] kilobytes I'm not going to accept that
[27:04] message and you specify what kind of
[27:06] security you want dynamic tracking
[27:08] static tracking this is usual Windows
[27:10] protocol stuff so very easy now I have
[27:12] this port attribute structure the next
[27:17] thing I want to do is initialize some
[27:18] sort of connection message so let's say
[27:20] I have an LPC server that needs me to
[27:23] actually send a message when I connect
[27:25] well as I mentioned even the simplest a
[27:28] LPC message has to have this port header
[27:31] and that port header basically has the
[27:33] length of the messages being sent it has
[27:36] the message of the length of the message
[27:37] including the message header and length
[27:40] it a message excluding the message
[27:41] header so all I'm saying here is I have
[27:45] a message Connect structure it's length
[27:48] is size of message Connect and the data
[27:50] of the payload is whatever message
[27:51] Connect is - the size of the header so
[27:55] you do this every single time you send
[27:56] any sort of a lbc message simple enough
[27:59] alright next I want to actually connect
[28:02] at a port so there's this API I
[28:04] mentioned nkl pc connect port and I pass
[28:06] in a handle that I'll get this is where
[28:10] I'm going to get my server port the name
[28:12] of the server I'm trying to connect to
[28:14] the attributes of the port I'm trying to
[28:16] connect to a send a flag here that says
[28:18] that says I want this request to be
[28:20] synchronous you can have asynchronous
[28:23] connections which are kind of weird
[28:24] where you're basically I'm going to
[28:25] connect to you but let me know later you
[28:27] can do that if you want to and I'm
[28:29] passing in the connection message that I
[28:32] created on the earth slide which is
[28:33] empty this is a server for example that
[28:36] needs you to send a connection message
[28:37] but it doesn't actually read the payload
[28:40] it just wants you to send a message
[28:42] maybe it's going to reply to you in that
[28:44] message so you have to allocate the
[28:45] buffer and then I'm passing in that my
[28:47] connection message size is size that
[28:50] connect message
[28:50] so assuming that this servant name
[28:53] actually exists assuming I have access
[28:56] to the server name assuming that my
[28:58] connection message is valid and is of
[29:01] the right size the server will accept my
[29:04] connection or not and all these null
[29:06] parameters at the end are where I could
[29:08] receive a reply back so if I don't want
[29:10] to receive a reply back I'm just going
[29:12] to put some spin of some notes right and
[29:14] here I'm going to get a connection if it
[29:16] all worked out I get a handle back to
[29:18] the server now I'm going to start
[29:21] communicating with a server so I'm going
[29:23] to tell alt see what kind of attributes
[29:25] I'm going to send in my messages and so
[29:28] down here I'm saying I'm passing in some
[29:31] message attributes and I'm going to be
[29:33] passing in a data view attribute when I
[29:35] allocate a buffer for this data view
[29:38] attribute so this is kind of a located a
[29:40] second structure for my attributes so
[29:43] every time I send a message I'm going to
[29:44] send this metadata payload and the data
[29:47] payload a little bit later on is enough
[29:50] next step is let's say I will actually
[29:53] want to send a view so I won't bore you
[29:55] with all the code here but basically I
[29:57] call LPC to create a section of you I
[30:00] pass in a size and then I build my view
[30:03] attribute I set it up here's my my view
[30:06] size and I tell a LPC go ahead and map
[30:10] this view so first I create the section
[30:12] then I map the view into my address
[30:15] space and then when I send a message is
[30:18] going to be mapped into the receiving
[30:19] side address space as well so if it all
[30:22] worked out I'm here I'm also mapping the
[30:25] view as auto-release so I've got an
[30:28] orderly's view on my sending side so
[30:32] I've got the attribute I've allocated it
[30:35] mapped it and filled it out I've got my
[30:37] connection message and I've got my
[30:38] connection how do I send a message well
[30:42] when I send a message I'm going to have
[30:45] to specify out of the attributes that
[30:47] I've set up which ones are valid in this
[30:50] message this lets you set up an
[30:52] attribute buffer once and every time you
[30:54] send a message you can decide which
[30:56] attributes are valid so you can actually
[30:58] have some left over argument attributes
[31:00] that you don't want to use right now and
[31:02] so you simply don't order them
[31:04] being a valid in this way you don't have
[31:06] to reallocate an attribute structure
[31:08] every single time you can allocate all
[31:09] the attributes in a world and every time
[31:11] you send a message decide which one you
[31:13] want to send and so I'm sending this
[31:15] data view and I'm going to fill in the
[31:17] data view with 4 1 4 1 4 1 4 1 so I have
[31:20] a one page worth of shared memory I'm
[31:23] just filling out for one for one and
[31:24] then I'm actually going to send a
[31:26] message to the server so every time you
[31:29] send a message again you have this
[31:31] header so this is the same code as
[31:33] earlier and then I'm going to send a
[31:36] message to my server I'm going to tell
[31:39] my side to release the message once it's
[31:42] done here is the message and here the
[31:44] attributes of the message and the size
[31:46] the message and again I passed the null
[31:48] here because I don't want any reply
[31:50] don't care by the reply so now normally
[31:54] the server would receive my message and
[31:55] this view and if the server is accepting
[31:58] data views so the server on its end also
[32:02] passed in this flag then the server will
[32:04] automatically get my 4 kilobyte view map
[32:07] in its address space and then it's a
[32:09] servers job to release that view and so
[32:14] here's where things get interesting
[32:15] it's the server's job to release that
[32:18] view and so the server is not expecting
[32:20] of you if the server doesn't know how to
[32:22] release of you over server releases the
[32:25] viewing correctly the server remains
[32:27] with a view and then I can keep sending
[32:30] another view at another view and another
[32:32] view so with data views once you receive
[32:37] it once as the server you said I'm
[32:39] willing to receive views to actually get
[32:42] rid of the view you first up will have
[32:44] to mark the view as available for
[32:47] release so you're either going to set
[32:50] this flag that says unmapped the view or
[32:53] you're going to manually call the API to
[32:56] free the view but this flag where that
[32:59] API only marks the view for release
[33:02] because right now you are the receiving
[33:04] side you're the server you have a
[33:06] message that you're holding on to
[33:08] there's still a view associated with
[33:10] that message we're not going to free it
[33:12] yet so how does the LPC runtime know
[33:15] when to release the message
[33:17] you have to first of all said this flag
[33:19] that says please release any resources
[33:22] associated with this message and you
[33:24] have to send a reply to the client once
[33:27] you send the reply with that flag with a
[33:30] view attribute with this flag then the
[33:33] runtime is going to say you're passing a
[33:35] me of you your view sets the unmapped
[33:37] the existing view your flocks has to
[33:39] unmount the release messages okay I'm
[33:41] going to go and release his view so if
[33:43] you don't expect to receive a view and
[33:45] you ignore it it's going to be leaked if
[33:48] you don't actually reply to the message
[33:50] the view will be leaked as well so even
[33:53] though you freed of you unless you make
[33:55] a reply it's not going to matter and so
[34:00] an LPC server developer that Microsoft
[34:03] can make a lot of assumptions which are
[34:05] incorrect and some which which we can
[34:07] understand like for example hey I know
[34:09] that this message should never have a
[34:10] view so let me not bother and check if
[34:12] there's a view associate with it now
[34:14] this would be a pretty stupid assumption
[34:15] because someone can understand how a LPC
[34:17] works someone can try to send you this
[34:19] message with the view and then you're
[34:20] screwing yourself okay so if I do get a
[34:23] view I'm going to harden myself I'm
[34:26] going to do secure development and I'm
[34:27] going to drop the message or cancel it
[34:29] there's an API to ignore message and to
[34:32] cancel a message which makes sense but
[34:34] the LPC runtime does not free views when
[34:37] you cancel a message so if you just
[34:38] cancel it a message you're protecting
[34:40] yourself from any data that you don't
[34:41] care about but the view is still there
[34:44] okay you're little bit smarter you're
[34:46] saying I'm going to free the view or
[34:48] market a market for on mapping well
[34:51] remember you also have to reply to the
[34:53] message so if you didn't reply to the
[34:55] message
[34:55] it didn't matter you marked it for on
[34:57] mapping it will never be unmapped
[34:59] okay I'm going to get a view I'm going
[35:03] to free it or market for on mapping and
[35:06] I'm going to reply to the server but I'm
[35:09] all again replying to the server this is
[35:10] a request
[35:11] right because datagrams don't need
[35:13] replies remember datagrams are like UDP
[35:15] there is no reply well because you're
[35:18] not replying the view is going to be
[35:20] leaked so that's interesting because
[35:22] you're going to Datagram you're not
[35:24] supposed to reply to the diagrams but if
[35:25] you don't reply to the message then the
[35:27] view doesn't feed and then okay I'm
[35:30] going to get the view market for
[35:32] mapping setting and plus here you also
[35:33] didn't send the release flag so this was
[35:36] the hardest one to blame the developer
[35:37] because he freed the view he marked the
[35:40] firaon mapping he set the flag but he
[35:44] only replies to request he doesn't reply
[35:46] to datagrams
[35:47] because datagrams don't need replies
[35:49] well that's an incorrect assumption and
[35:53] and that's an interesting one see
[35:56] because in a strict protocol sense yes a
[35:58] Datagram does not need a reply in fact
[36:00] if you try to send a reply to a Datagram
[36:03] the receiving the the sender side will
[36:05] never get an answer datagrams don't have
[36:07] replies but the whole release logic
[36:10] behind attribute says for me through
[36:12] release and attribute you have to reply
[36:15] to the message this is my indication
[36:16] that it's okay to get rid of these
[36:19] resources so you have to reply to data
[36:22] grams if there's a view associated with
[36:23] them it's an internal semantic behavior
[36:26] but you have to do that if you don't do
[36:28] it you will be leaking the view and so
[36:30] many a OPC servers inside windows don't
[36:33] reply to datagrams ever because they're
[36:35] saying it's a Datagram doesn't need to
[36:37] reply well then if I package and
[36:39] malicious view that Datagram you're
[36:41] going to be leaking it even if you tried
[36:43] your best to free it you did all the
[36:45] right steps
[36:45] you forgot to reply and in fact LPC
[36:48] warns you about this there's a little
[36:50] flag in the header when you receive that
[36:51] message that says LPC continuation
[36:55] required means you must reply to this
[36:57] message but this is a new behavior to a
[37:01] LPC right LPC we didn't have views and a
[37:04] lot of the LPC servers and Microsoft in
[37:06] Windows are legacy LPC servers where
[37:09] someone ported the code to use a LPC and
[37:12] when they pour to that code they don't
[37:14] check for this flag in the LPC world you
[37:16] never reply to diagrams it never made
[37:18] sense in a LPC we have attributes
[37:21] this adds this additional behavior and
[37:23] so I don't know this isn't documented
[37:26] internally Microsoft if they don't learn
[37:28] about this but if they don't do that
[37:30] last step they end up leaking the view
[37:32] as well and so by and this is with use
[37:36] with handles you have the same issue
[37:38] remember you can pass handles between a
[37:40] client and a server and so if you're
[37:41] receiving handles but you're not closing
[37:44] them
[37:44] and or releasing them by replying to the
[37:48] message you're going to be leaking
[37:50] handles as well and leaking handles will
[37:52] exhaust your object table and so I've
[37:54] identified several windows 7 LPC servers
[37:58] that either leak data views so you can
[38:02] keep stuffing more and more views or
[38:04] that leak handle so you can keep
[38:05] stuffing more and more handles so this
[38:08] gives you a denial of service attack to
[38:10] those specific LPC servers that have
[38:12] this vulnerability by exhausting your
[38:14] address space it also gives you the
[38:16] ability heap spray any of the servers so
[38:19] there is a bug or something then that
[38:21] goes wrong inside of them you have the
[38:23] ability to basically fill their address
[38:24] space with whatever data you want to
[38:26] control I then start looking at Windows
[38:28] 8.1 and I put an X because I found two
[38:32] so far so in Windows 7 I found 6 in
[38:35] Windows 8 Phone I found 2 so far but I'm
[38:37] still looking at so there's still new
[38:39] servers that they're adding to Windows 8
[38:41] Windows 8.1 and those new servers still
[38:43] have those issues so I'm currently
[38:47] preparing a vulnerability port for nsrc
[38:49] so I'm not going to reveal the names of
[38:51] which servers have these vulnerabilities
[38:53] until you know that gets reported but
[38:56] this is a standard you know design flaw
[38:58] in anyone that tries to write an LPC
[39:00] server if they're not doing all those
[39:02] steps if you can send them data views
[39:04] you can exhaust address space so I'll do
[39:07] them a little bit later on and show you
[39:09] one example of an affected server now
[39:14] that's the kind of class of bug that
[39:16] affects individual LPC servers and so if
[39:20] you have a really well-written LPC
[39:22] server it's not going to be subject to
[39:24] those bucks and Windows has about 20 of
[39:26] them so yes I found bugs and 7 just 7
[39:28] out of 20 screen to bad but it's still
[39:30] 14 of them that actually work normally
[39:32] because they either don't use data views
[39:34] or because they keep track of data views
[39:36] correctly and so my next target which is
[39:39] more interesting was well what about
[39:41] local RPC itself what about the AL PC
[39:44] handling inside the RPC runtime because
[39:48] let's say that the RPC runtime never
[39:50] replies to datagrams
[39:51] then any single time you have any RPC
[39:55] server or any comma
[39:57] any
[39:58] in the world almost has one of these
[40:00] you're going to be able to exhaust and
[40:02] inject memory into in stress space now
[40:04] unfortunately the RPC runtime does a
[40:06] really really good job of handling a LPC
[40:09] views so they don't have that issue so
[40:13] the RBC runtime is RPC rt4 dll and it
[40:16] uses a LPC as the backend protocol so
[40:19] whenever you have any sort of RPC server
[40:21] or decom object it's going to end up in
[40:24] this RPC control object named space and
[40:27] with Wynn abdi a PC control namespace
[40:32] and all these different ports here they
[40:37] are all RPC servers running side windows
[40:40] and then all these Oh le ports it's
[40:44] object linking exchange is the old name
[40:46] for calm and so these are all different
[40:49] calm updates there's no immediate way
[40:51] from the name just to figure out what
[40:53] that is but these are any sort anytime
[40:55] you've loaded any comm DLL or created
[40:57] any surf comm object-- it's going to end
[40:59] up with the port so if your process is
[41:01] hosting a common object you're hosting
[41:03] one of those ports and if you're
[41:05] connecting to another process comm
[41:06] object you're connecting through in
[41:08] these ports and I'll show you in win
[41:10] Bank how you can tell this I've got a
[41:12] few more ports here and then I've got
[41:14] some unnamed RPC ports as well so a lot
[41:16] of different endpoints you can try
[41:18] connecting to and if so there is a bug
[41:20] in the RPC runtime any of these ports
[41:23] whether it's a DHCP server where there's
[41:26] the RPC endpoint mapper event log else
[41:29] as the auditing server the Bluetooth
[41:31] server they would all be vulnerable to a
[41:34] bug like this the service Control
[41:36] Manager else has again and even the
[41:39] kernel which has some of these ports on
[41:40] its own so that's obviously very
[41:42] interesting attack surfers now there's
[41:45] extension aside win back that are going
[41:46] to show you who's connected to a port
[41:48] and so on and so on forth and we have
[41:50] time I'll show you how to use some of
[41:52] that but the aapc layer is just one
[41:55] layer because with a LPC you connect to
[41:57] the RPC runtime but then the way you
[41:59] send RPC messages is to actually use the
[42:01] actual lrpc protocol so the interesting
[42:06] about RPC is that when you connect an
[42:09] RPC server you have to bind to
[42:11] / and so whenever you have an RPC client
[42:14] and server you have an interface ID
[42:15] which is a good a version and a
[42:18] marshaling syntax so this is all stuff
[42:20] that's handled by your ID l5 by
[42:22] interface definition language file it's
[42:24] all part of the documented behavior of
[42:26] RPC
[42:26] so whenever there's a connection being
[42:28] made there's a bind request but RPC does
[42:32] not act because RPC was based on n key
[42:34] it on the name pipe file system with
[42:37] name pipes you always open the pipe then
[42:39] you send a packet and so they kept this
[42:42] behavior so even though with LPC while
[42:44] you're connecting you can send a message
[42:46] because of the old behavior with RPC you
[42:49] first connect and then you send your
[42:51] message so this means that a connection
[42:54] time the RPC runtime knows nothing about
[42:56] you and it's all done at binding time
[42:59] and binding is an actual message so a
[43:02] full RPC connection is first on a LPC
[43:04] connection and then an LPC message
[43:07] that's a bind request essentially that
[43:10] means the RPC runtime has to create
[43:12] those ports allowing absolutely everyone
[43:15] to connect to them because it doesn't
[43:18] know ahead of time who's able to connect
[43:20] so looking at any a LPC port that's
[43:23] associate of the RPC server behind it
[43:25] you're going to see everyone is allowed
[43:28] to connect which is great because it
[43:30] means that there is any bug in the
[43:32] handling of a LPC messages in the
[43:34] runtime anyone will be able to exploit
[43:36] such a bug because the runtime will
[43:38] start parsing messages waiting for you
[43:40] to send a bind message if you send a
[43:43] malformed bind message or maybe you
[43:45] don't send a bind message or whatever it
[43:47] is you're trying doing you're now
[43:48] talking to the runtime in a server so at
[43:50] least you have you have something going
[43:51] on between you two and so that's
[43:54] obviously it's going to be useful so as
[43:58] soon as you actually register an RPC
[44:00] server the runtime creates the port and
[44:03] then the runtime creates a server loop
[44:06] that waits for a LPC messages now I also
[44:09] mentioned that in order to be vulnerable
[44:11] the server has to specify that it wants
[44:15] to receive data views that it wants to
[44:17] receive handles and so the RPC server
[44:19] runtime can receive connection requests
[44:23] can receive normal requests can receive
[44:25] buying requests etc and in the RPC world
[44:28] some of these message do have data views
[44:30] and so as soon as you have a server that
[44:32] accepts some messages that have these
[44:35] and some messages that don't have views
[44:37] you have to tell it ahead of time
[44:39] I accept views and then later on you
[44:42] decide which views you'd like to drop or
[44:45] which views you you would not want to
[44:46] drop and so the potential exists for RPC
[44:49] to receive unexpected attributes and not
[44:53] to receive them so a simple example is
[44:55] if I have two possible message types
[44:59] message one has a data view and message
[45:02] 2 does not have a data view in my
[45:05] protocol when I actually wait for
[45:07] messages I have to tell a LPC send me
[45:12] views because there is an off chance
[45:15] that I might receive message 1 and then
[45:18] I would do my handling that says ok if I
[45:21] do receive message 1 then you know do
[45:23] something with the view and if I receive
[45:28] message 2 then I'm going to do something
[45:34] else
[45:35] and if I'm smart and then after I do all
[45:39] this free the view if I got one free
[45:44] view if all right well if I'm not smart
[45:50] I'm going to free the view only in case
[45:54] one where I'm going to say message
[45:56] message type 2 never receives views and
[45:59] so I don't have to free them so that
[46:02] would be an example of a but not the RPC
[46:03] runtime did this if the RPC runtime said
[46:05] hey you know what connection messages
[46:07] never have views so I'm not going to
[46:09] bother freeing of you because no one
[46:11] knows how to speak RPC and so no one can
[46:14] send me this so it's actually a pretty
[46:17] complex function it's called process i/o
[46:20] the last bullet there and it handles all
[46:22] the possible RPC messages in a single
[46:25] function so it's extremely hard to
[46:26] reverse engineer now this function
[46:29] handles different types of messages and
[46:32] they're all defined by this enumeration
[46:34] called tag l RPC message types and so
[46:37] you can have requests
[46:39] which are basically RPC calls or you can
[46:42] have the bind request which is sender
[46:43] the connection you can have fault
[46:45] messages through use for errors you can
[46:47] have responses or cancellations which
[46:48] are use when you're doing asynchronous
[46:50] calls there's something called callback
[46:52] based RPC and pi pays RPC and so you can
[46:55] have that information there as well so
[46:56] there's all sorts of structures that
[47:00] identified what an RPC message looks
[47:02] like what an RPC request looks like what
[47:05] a bind message looks like and these are
[47:07] not documented but for a very very long
[47:09] while Microsoft is to ship the private
[47:12] symbols for the Windows 8 RPC runtime by
[47:14] accident on their symbol server they
[47:17] still do ship some private symbols back
[47:19] Siddhant
[47:20] and so it was easy to just use wind back
[47:22] and dump and see exactly what all these
[47:24] structures look like so I knew now how
[47:26] to send I'm try to try sending a
[47:29] malformed local RPC message over a LPC
[47:32] so I looked at runtime code and it
[47:35] actually has really good management of
[47:37] lrpc messages it was actually written
[47:39] obviously by team that had done fuzzing
[47:41] that had done hardening and debug build
[47:44] or to check build there's a bunch of
[47:46] assertions they have a whole message
[47:48] class for checking protocol errors and
[47:50] so they actually do a really really good
[47:52] job of how to handle a LPC messages
[47:54] correctly in fact the way I found out
[47:56] that to release a view you have to do
[47:58] all those things was to look at the RPC
[48:00] runtime code and see that they were
[48:02] doing all these things and then I wrote
[48:03] my own code which wasn't doing all of
[48:05] them and I saw that unless I was doing
[48:06] all the steps the RPC runtime was doing
[48:09] I had a leak view so actually they do a
[48:11] pretty good job of managing that so I
[48:13] wasn't able to get any really
[48:14] interesting behavior out of the RPC
[48:16] runtime with my simple fuzzer
[48:18] but I'm not a guy who normally writes
[48:20] fuzzers so I didn't I'm not that doesn't
[48:24] mean there's no bugs but I wrote a
[48:26] simple fuzzing app just to try seeing it
[48:28] as any crashes so then I started looking
[48:30] at data view attributes seeing ok
[48:33] instead of pausing it with random
[48:34] messages maybe I consented random
[48:37] attributes and the LPC runtime is
[48:40] actually very the RPC was actually very
[48:41] smart as soon as it gets a data view
[48:44] attribute it always sets an internal
[48:46] reply flag it says oh my god I've got a
[48:48] dataview I have to reply to this message
[48:50] so someone really knew what was going on
[48:53] in fact they don't even check if
[48:54] continuation required a set they assert
[48:56] on it they say this has to be set so
[48:58] they're very keenly aware that you have
[49:00] to reply to data grams and so they
[49:03] always build an attribute that has
[49:05] unmapped
[49:06] existing and they always reply the reply
[49:09] variables set in fact they're so good at
[49:11] freeing views that sometimes and they
[49:13] have this code at like two three
[49:15] different places so when they get an
[49:16] invalid message they free the view and
[49:18] then when they send the reply the free
[49:19] the view again and then right before
[49:21] sending reply they'd free the view again
[49:22] like they're really paranoid about this
[49:24] and they don't use handle attributes
[49:26] like okay so I can't find any bugs
[49:28] that's not fun but I noticed something
[49:32] interesting and this is all
[49:34] unfortunately blacked out because
[49:36] although I reported this six months ago
[49:38] it's the lazier day so I don't like
[49:41] dropping 0 days since Microsoft's a
[49:43] sponsor but who will give them a few
[49:48] more days or maybe whiskey con I get
[49:51] enough shots in me whiskey con maybe so
[49:54] anyway this is a fairly easy bug though
[49:56] if you look at it you'll be able to
[49:57] figure it out which is every time they
[49:59] were freeing messages every time they're
[50:02] handling an invalid packet they send an
[50:07] error report so every time there's an
[50:09] invalid packet such as a packet that has
[50:11] a data view and it shouldn't have a data
[50:12] view they send reply back saying you
[50:15] shouldn't be sending your data view now
[50:17] the problem is the function that sends
[50:19] replies back doesn't actually free the
[50:23] message buffer so you have to free the
[50:25] message buffer on your own so the
[50:27] runtime has to handle in the valid
[50:29] packet free the view send the reply back
[50:33] that is client and then free the actual
[50:35] buffer of the message so the data view
[50:37] is mapped but the data view is unmapped
[50:39] but they also have to free the actual
[50:41] message buffer right because I have up
[50:42] to 64 K of data that I can send plus a
[50:45] view and so the issue is that in some
[50:47] cases actually one specific case if you
[50:49] send the right kind of packet to the RPC
[50:51] runtime and it has a data view the data
[50:54] view gets unmapped
[50:55] that part is all good but the actual
[50:57] data packet leaks and so if you keep
[50:59] sending that data packet again and again
[51:01] and again and again to any RPC server in
[51:04] the world locally on your machine
[51:06] you will be able to eventually spray its
[51:09] entire heap and possibly probably
[51:12] eventually crash it because you've just
[51:15] filled up all the dress space and it
[51:17] will no longer be able to respond to any
[51:19] messages so a little app called RPC nuke
[51:22] and try it a few various servers and a
[51:25] hundred percent of time I was able to
[51:26] kill them in some cases even killing the
[51:29] entire machine so during the demo you'll
[51:31] see that I'm going to exhaust the memory
[51:33] of a server hopefully my screen will do
[51:36] the what it did the other times just
[51:37] turn black and die the machine should
[51:39] become unusable with that specific
[51:41] server because some servers are so
[51:42] critical that if you do as them the
[51:44] entire machine basically stops working
[51:46] so I can reliably heap spray any almost
[51:49] pretty much any process in the machine
[51:52] from an arbitrary user privilege so from
[51:55] guest I can inject memory anywhere I
[51:57] want to which is already a pretty good
[51:59] technique if you have an ability now I
[52:01] haven't yet found any server that
[52:03] crashed enough in a way other than
[52:05] running out of memory which is really
[52:09] handed by the server stopping to receive
[52:11] clients but if the server process were
[52:13] actually were to crash then I would
[52:15] actually get some sort of pointer now it
[52:17] might be a null pointed reference or it
[52:19] might be some internal behavior so I've
[52:21] only looked at about a dozen of them
[52:22] still trying to still try to run the
[52:24] fuzzer on the nuclear and other apps but
[52:26] hopefully there'll be at least one RPC
[52:28] server out there or one process out
[52:30] there that way runs out of memory those
[52:32] the wrong thing and then you can control
[52:34] that to make it jump to this heap spray
[52:37] that I'm able to put in so this is about
[52:40] six months ago reported and I'm running
[52:42] out of patience but they said a few more
[52:45] days and we'll see what happens with
[52:46] that because from their point of view
[52:48] it's just a local d OS it's not like
[52:50] you're crashing machines remotely but
[52:52] it's still nice technique for injecting
[52:54] memory so I'll skip the wind back
[52:57] section since risky con is going to be
[53:00] soon and then I'll just do a demo of two
[53:03] examples so one of them which is killing
[53:05] an actual al PC server and one of them
[53:07] which is trying to kill an RPC server
[53:09] and I'll have VM map up and running in
[53:14] the first case
[53:17] so this is a nice little process and
[53:21] then I'm going to set up my command
[53:24] prompt see
[53:33] so if everything works well this is
[53:35] going to be sending one message to this
[53:37] server that's hosted here so it says
[53:42] okay I created a view and I sent a
[53:44] message through a server and if i
[53:47] refresh VM map well it's only been one
[53:50] message so I'm not sure you'll notice a
[53:51] change but it did go a little bit bigger
[53:54] here we'll send it a few more okay let's
[54:03] refresh again that's 81 mix and if I
[54:07] just keep holding enter to let it go a
[54:09] few hundred times and so something
[54:11] interesting is going to happen which is
[54:14] that it's actually I'm only sending four
[54:16] kilobytes so pressing enter a hundred
[54:18] times would have been at most a Meg but
[54:21] now this has gone up to ninety megabytes
[54:22] and what's actually gotten bigger every
[54:24] time is this gray section and this gray
[54:27] section of VM map references unusable
[54:30] memory and what's happening is I'm
[54:32] getting all these chunks of 60 kilobytes
[54:35] of unusable memory that are being
[54:37] consumed plus if I go and click on
[54:39] shareable here you will see four
[54:41] kilobyte mappings as well which I'm
[54:43] going to show you and here's another
[54:44] interesting behavior the windows memory
[54:48] manager forces you to allocate things on
[54:50] 64 kilobyte black granularities but with
[54:53] the LPC views you can make views more
[54:55] than 64 kilobytes such as 4 kilobytes so
[54:58] it's actually happening is I'm consuming
[55:00] a 4 kilobyte view and the next time the
[55:03] process makes any memory allocation it's
[55:05] going to be on the next 64 kilobyte
[55:07] boundary so my next view is going to be
[55:09] on the next 4 kilobytes and my next view
[55:11] is going to be on the next 64 kilobit
[55:13] boundary and in fact any other
[55:14] allocation in the process will make will
[55:16] always be on the next 64 kilobyte binary
[55:19] so VM map calls this region unusable
[55:22] because nothing can ever use this memory
[55:26] in this process again no allocation API
[55:29] will allow you to get a memory address
[55:31] that's not aligned on 64 kilobytes so
[55:34] not only am i leaking these little 4
[55:36] kilobytes of controlled memory I'm also
[55:38] creating these large regions of unused
[55:39] memory and this is useful for exhausting
[55:42] the address space because if I was
[55:44] actually creating 64 K views
[55:46] the system-wide commit charge will also
[55:48] be increasing by six four kilobytes but
[55:50] because my views are tiny Windows thinks
[55:53] I'm consuming very little memory even
[55:55] though the process is being harmed a lot
[55:56] more so these Maltese are actually
[55:59] pretty bad because of this 60 kilobytes
[56:01] of unusable memory that keeps
[56:02] accumulating now the process hacker if I
[56:05] take a look at the process you should
[56:08] see a lot of small map commit views so
[56:13] any of these you look at and that's the
[56:15] four wonderful one I'm signing so I can
[56:17] just keep filling it up crash it or just
[56:20] control of its address space fill it up
[56:21] with for once for once for once or once
[56:23] and I'm not necessarily feeling it out
[56:26] by creating giant views but that
[56:28] unusable memory it's going to keep
[56:29] growing growing growing growing and
[56:30] eventually the process will stop working
[56:32] or in a better case actually crash so
[56:36] that's an example of a specific bug in
[56:37] some a OPC server hosted by that process
[56:41] now the more fun one is the RPC bug so
[56:47] with RPC nuke I can just give it the
[56:51] name of a server I'm interested in and
[56:53] what I'm going to try doing is killing
[56:55] the actual service Control Manager so
[56:58] the service control manager has runs
[57:01] inside this services that XE process and
[57:06] it has let's elevate so you can see the
[57:10] handles services the nexi so it's
[57:15] extremely privileged obviously it runs
[57:17] with system rights for the token system
[57:21] my command prompt is just running a
[57:24] standard user and if you look at its
[57:27] handles one of the handles that it has
[57:29] is the NTSB CS port this is the port
[57:32] that's used to talk to a source control
[57:35] manager I could actually use any of
[57:36] these ports it doesn't matter because
[57:38] this is a bug in the RPC runtime itself
[57:40] but I'll just I'll just use the first
[57:41] one and see what happens with the memory
[57:44] consumption which right now is at 39
[57:50] megabytes and I'll just run this for a
[57:53] little bit then I'll do the conclusion
[57:55] they don't let it keep running and geek
[57:57] Oh n TS VCS
[58:05] all right so I controlled seated and the
[58:08] serves that XC now has a gigabyte of
[58:11] commit memory and if I look at its
[58:14] memory somewhere in here or all these
[58:18] read/write heap sections all filled with
[58:20] for one for one for one for one for so I
[58:23] can do this to any process out there all
[58:26] the models have at least one a LPC port
[58:28] to something that's open i pretty much
[58:31] everyone is hosting something so I'll
[58:34] let it run in a minute but I want to
[58:35] finish up by saying LPC is really
[58:37] complex and the resource management
[58:39] system gives lbc developers a lot of
[58:42] functionality but they have to know how
[58:43] to use it so I would recommend Microsoft
[58:46] should probably have a brown bag like
[58:47] you see slides to teach people how to
[58:49] use a LPC obviously they a lot of teams
[58:52] don't know how to use it they're not
[58:54] freeing these resources now the lrpc bug
[58:57] is a simple mistake so the fact that the
[58:59] RPC runtime has a has a has a bug that
[59:01] are not freeing memory that's just
[59:03] someone not adding a free call and when
[59:05] you have a 4 kilobyte function with like
[59:08] fifty five thousand lines of code
[59:09] handling every single possible packet I
[59:11] would suggest you should refactor that
[59:13] but the LPC bugs definitely mean that
[59:16] people are that max up don't know how to
[59:18] write a LPC service correctly and so
[59:20] that makes me think there's probably
[59:22] more bugs than just spraying memory bugs
[59:25] like I said I'm not an expert at writing
[59:26] fuzzers and there's a lot more research
[59:29] to be done also decom is very
[59:32] interesting because it in a day all
[59:33] function calls are decomp calls and the
[59:36] decom runtime has additional overhead on
[59:38] top of the LPC runtime so next step is
[59:41] to look at D comments seeing if there's
[59:42] ways to bypass some of the comprar
[59:44] tection that's actually that's actually
[59:46] there so let's see if I can just leave
[59:50] this running see what happens
[59:54] two gigs three weeks
[01:00:00] hopefully my machine will stop working
[01:00:04] sometimes it just deadlock something
[01:00:06] that freezes sometimes nothing happens
[01:00:07] well obviously this is happening that's
[01:00:11] and now I get a warning my computer is
[01:00:16] low on memory what's expected and things
[01:00:21] are still work out things are
[01:00:23] disappearing it's a good sign try
[01:00:27] clicking on start I can't click on start
[01:00:29] I can't click on it my Mouser
[01:00:32] disappeared
[01:00:34] my CPU find us turnaround high no black
[01:00:41] screen but uh-oh
[01:00:42] black screen yeah it's dead alright
[01:00:46] thank you
[01:00:48] no hi at first I would like to thank you
[01:00:52] for this great research on our PC I've
[01:00:56] got in fact two questions first of all
[01:00:58] when you are describing a a LPC and
[01:01:02] there is this resource excavation and
[01:01:04] heap spraying techniques for attacking
[01:01:07] to describe it's exactly the same as L
[01:01:09] RPC to describe later yes the LPC gives
[01:01:14] you shared section views yes the lrpc
[01:01:17] gives you heap views better than a day
[01:01:19] it still spray anything yet yes and the
[01:01:23] second thing when you are describing
[01:01:24] about the heap spraying when you are
[01:01:25] sending four kilobyte the data but of
[01:01:27] course the granularity always 64
[01:01:28] kilobytes it's normal so in fact the
[01:01:31] hips pray effectively you still need to
[01:01:33] send 64 kilobytes because then if I
[01:01:35] actually want to take you spray s out
[01:01:36] send a full 64 kilobyte I sent four on
[01:01:39] purpose to the shuttle yes
[01:01:42] so I believe these two things thank you
[01:01:45] Cheers
