Okay.
So hi everyone, I'm Thomas Gagne from Sky Recon System.
And I will talk about LPC and LPC interfaces
and the professional creation on Windows.
So basically this presentation is on two different parts.
The first part will be about the LPC.
The second part on the LPC.
And as it has been said,
we will see the basic architecture,
some explanation about an exploit
that has been reported to Microsoft,
a demonstration of this exploit,
and talking about how we can protect Windows
against this type of attacks.
There is a paper that will be released
in the Recon website.
It will contain a lot more details about the exploitation
that should be available after the conferences.
Okay, so what is the LPC interface?
Basically the LPC interface is a local socket system.
That's a communication system across process
with local features.
It has been created for the Windows NT subsystem.
It has been undocumented.
And basically you can interact
with either privileges process.
The LPC interface is its proven in the Windows Vista.
It's supported all the LPC functions
and everything has been rebuilt
in order to make better performances
and change the whole design.
So the LPC is interesting
because many system process export LPC interface,
a public interface.
So that's a way to access privileges process.
Most Windows API that deal with thread
or anything related to process goes through LPC
even if we don't see it.
The transportation for some components
like RPC or other is done by the LPC.
And the Cesar Siridor introduced the feature of the LPC
that's all remote mapping section.
Basically you are able to map a section
on the server process and you have the remote base address.
That's made the local preparation a lot easier.
So that's mainly why the LPC interface is known
for privileges, coalition, reliability.
Now the LPC is well documented on the internet
so you don't have to reverse many things
to understand how it works.
The LPC, the A-LPC is interesting
because it share all the points of the LPC.
And of course we can ask ourselves
how it has been improved on the design
and on the security part.
In the security part it has been done
with the security development lifecycle.
And as the LPC interface, we will see in the next slide,
the LPC interface was not secure in the first version.
So basically we ask ourselves if the A-LPC
will be directly secure or it will have some security issues.
So the LPC interface works with a client,
classical architecture, a server, a client.
As it's local it used a named object called a port.
Basically you create a port when you create the server.
You can apply as a restriction on this port.
And this named object is used for the connection.
Incoming connection can be discard by the server
depending on information.
And everything is based on a message system.
When you want to ask a connection,
you send a connection message.
Same for this connection, for request or reply,
everything is handled on the channel
through the message base system.
There is many vulnerabilities on the LPC interfaces.
Basically there is two types of novelty.
First about the kernel design.
As I said the LPC interface was not secure
in the first version.
So there was some design issue.
You were able to sniff some message
that was for another server.
You were able to send a message specifying another process
and another thread.
And you have more typical vulnerabilities
based on the way the user-learn interface parsed
the data you send through the LPC.
So those are examples.
There is even more vulnerabilities.
There's just some examples.
What did 7.9 happen to the LPC?
Seven.
How was it applied to DNS?
Well as I said the LPC used the LPC for local transportation.
And there was an issue based that was exploitable
through the LPC without necessarily using directly the RPC.
I didn't make much research about it.
I just looked in the internet.
Okay so we made the LPC research
in order to understand really all the LPC works.
Because even if it's more documented in the internet
there are still a lot of dark spots.
And we really want to understand
what features was available through the LPC.
We know that for example when you ask for some information
for a specific user,
if you want to change the password of the user
you will go through a LPC interface.
So if there is some features that are available
but should not be, that should be restricted.
And of course that's a good introduction
to public escalation as the LPC helps
for public escalation that's a lot easier using the LPC.
We thought it could be a good way to see
if it needs some protection layer in the LPC.
So now I'm gonna present the public escalation.
So basically the public escalation that I found
was on the LCSS process.
LCSS stands for Local Security Authority
Subsystem Service.
That's a critical component of the Windows subsystem.
And it's on every request based on user privilege and groups.
It have access to the same database
that store all the password.
So that's a really critical LPC interface
that has been targeted many times for local escalation.
Almost all features of the LCSS process
goes through the LSA authentication port.
And that's a really huge LPC interface.
So it implement a dispatch table.
This is dispatch table.
Basically by looking at the names
you see what is supported.
For example there is EFS for the crypto part.
There is a system of packages
that you can register and call.
There is everything related to enumeration of user,
seed and things like that.
Of course you have also the login process.
So two of the functions in the LPC dispatch table
implements a new system that I call
the remote buffer system.
Basically you send a message through the LPC interface
that contains local address on the client process.
And it will mirror the data in the server process.
This system works with three functions.
The LCP capture buffers function
will just copy your entries from the LPC message.
The map token buffer will do the mirroring.
It will allocate new buffers
and copy the data from the client process
to the server process.
And the last function, the LCP uncapture buffers
basically liberate all allocated data.
So there was a mistake in the way
uninsulated data was done
when you used the LPC in it context function.
So here is a figure that shows you
every steps of the sec buffer desk,
the remote buffer system.
The first is the LPC message.
The second is when every entry are captured
in the sec buffer desk structure.
And the last step is when everything is still as,
so you can see that it changed the flag entry.
So it indicates that the address is local
and it should be liberated in the late last function.
And it changed the function for a local address.
So this IDA graph show you where the issue.
Basically, you can capture the buffer
and by specifying a specific byte in the LPC message,
you discard the mirroring phase.
So basically, you are able to submit some flag
that indicates that your address you have is local,
but you submit a custom address
and you are able to submit any address you want
to the LTL free IP function.
So exploiting the LTL free IP function
is not something common,
but there is many, many documentation
about exploitation of the IP on Windows Express P2.
Basically, we used a crafted chunk
in the remote map section in order to push
for a chunk in a look-aside list.
So a look-aside list is a fast allocation list
that is used for exploitation on Express P2.
So we are able to correct this list
and return a custom point from the allocation
and then overwrite the part of the memory.
In order to do that, we have to create a valid chunk
and the valid chunk must have a valid cookie,
a valid flag, and valid alignments.
So the worst part is getting a valid cookie.
So getting a valid cookie is basically breaking
the cookie algorithm that's based on the address,
a chunk cookie in the IP header,
and the IP cookie generated in the IP system structure.
The IP process structure.
In our case, the address is static
as it's in the remote mapping section.
So there is only 256 possibilities.
And when a invalid cookie is found,
it will not break the process.
It will not stop the process.
So we are able to brute force this value
and find the correct cookie.
Basically, we have some data just after the chunk header
and we will check after every attempt
if this data has been replaced by a pointer.
If it has been replaced, we know it's going to be
in the look-aside list and we can correct the list
by replacing this pointer.
On EL CSS and XPCP2, we are on a critical system component.
So the data execution provision system is activated.
This system does allow denied execution
of non-executable page.
So we cannot just jump in our remote section,
because it's only mapped in read and write.
So we have to find another way.
Basically, we replaced an empty entry
in the LPC dispatch table.
And we use that to jump through different parts
of assembly in the intdl module
so we can get the control of the stack,
deactivate the DUP,
and execute our shellcode.
Okay, so the control for redirection is made
through the context when you call the LPC dispatch table.
Basically, we control data in the first argument
in the EDI register.
We do not control fully the 18 first bytes of this buffer
as it is the LPC message structure.
Basically, we can look at the specific context
depending on the service pack, language pack.
And as I said, we get the stack control
in order to deactivate the DUP and jump in the shellcode.
To deactivate the DUP, we use the uniformity technique.
Basically, you jump in a part of intdl
with a specific context that will deactivate the DUP
and return on an address on your stack.
So now I'm gonna show you a demonstration.
So basically, the demonstration will,
is launched from a guest account
and we will correct the SSS process
to sniff every login attempt
and reveal password in clear.
So as you can see, we brute force the Q key
and find the right value.
Then we're able to update the look-aside list,
overwrite a part of the table and do our stuff.
So now, if I'm locking my station, for example,
it will create a file.
So we'll see the authentication workstation,
the user and the password in clear.
So that issues only a single function
and it works if every type of authentication.
And of course, it works too if,
if I try to log in with an administrator user.
So that's just an example of what you are able to do
using the, by owning the SSS process.
Of course, as you are in the system component,
you can inject yourself in the kernel,
go in other critical components, do whatever you want.
So how can we protect against this type of attack?
First, we can restrict the mappet section
feature of the LPC interface.
First, we saw that no one uses it almost,
and almost all LPC interface allow you
to mappet section in a remote process,
but basically almost no one, no interface use it, support it.
After some small research, we found out that
some private LPC kernel components use this feature
to speed up the communication through use alone
and kernel line.
So basically, we're saying that there, it can be,
you can have two different approach.
First, you can blacklist the remote mapping section feature
on some LPC interface that you think are critical.
That's not the better way because
LPC interface evolve across versions,
and you're not sure that in the version later,
there is no, there will not be support
of the remote mappet section feature.
We can also look at the server write level
and the client write level,
and if the server is either on the client,
we just denied this feature.
We can also deactivate the,
disable the deactivation of the DEP,
but as we saw on, in Windows Vista SP1,
there is a new function called set process DEPi.
The set process DEP PULSI.
Basically, it made return to Lipsy expedition
even easier than previously with a uniformity technique.
So that shows that the activated,
the help, the DEP protection is a feature.
And we can understand that as if the DEP find out
that there is an issue, it will crash the process.
And if this process is a system component,
it will reboot your,
reboot your hardware, your system.
So we cannot just disable the DEP,
but we can look at when the DEP is deactivated,
look at the stack to see if there is some return to Lipsy,
some kind of weird stack,
and then accept the deactivation or not.
So, this expedition was also using the LTE free function.
So basically we could filter this function
in order to, to gene, to,
in order to improve the protection of the IP.
When you looked at Windows Vista,
you see that the IP has been totally remade.
It's been secured for the moment no one break,
break this, this new security.
But we cannot use the Windows Vista improvement
in Windows XP 2000 or 2003,
because we do not have access
to internal components of the IP.
Basically we are able to filter pointers for liberation
or return allocated pointers,
but it can create, can slow down the,
a lot the workstation.
So now I'm gonna present the LPC.
The LPC is a new version of the LPC interface
that's been introduced in Windows Vista.
The old LPC code has been removed,
but there is still support for the LPCs called function.
If you looked at the, at the bottom figure,
you can see that there is many exported function
that share the same function to, to respond user need.
And there is some improvement in the,
in the overall performance of the LPC.
If you compare with the LPC,
it's support IO completion port,
which is a thread organization system for the server.
Basically it will change the number of thread available,
livable for the, for the server,
depending on the request.
And the overall performance and the user interface
has been improved to, to response faster
and use asynchronous response by default.
Here's a comparison of a version in LPC and ALPC in IDA.
The top function is on the LPC, the bottom is on ALPC.
The LPC interfaces, basically the components used a lot
of bigger, big functions without dependencies
across functions, if they need to check a specific flag,
they will just look directly in the function
and not call another function to validate the LPC message.
But in the LPC, there is a lot more function.
So the modularity has been greatly improved.
There is like 20 times more crossing a module
and a lot of more functions.
So this new interface integrates new functions
that start with the NT LPC.
There is 21 new functions.
One of the more interesting function is NT LPC
send wait receive port.
Basically it replaced full function in the LPC
because before you have a function to send a message,
to receive a message, to send and wait for receiving
a message, to receive a message and some other.
So it has been a lot simplified.
And there is totally new feature as you are able
to open the sender thread of process,
create a section of presentation
and things like that, we'll see later.
Okay.
So this is this function, this new function.
There is a lot of more new function
but this one is interesting.
All send and receive elements are optional.
So you are able to send a message
or just wait for reception or both.
One of the new arguments are the message buffer.
You can see in message buffer and out message buffer.
That's a new system integrates in the LPC interface.
This new message buffer system is dynamic structure.
Basically there is only two field static under structure
and everything related to the structure size
or access to structure in the dynamic data
are made using NT Deload function.
That's interesting because that's the way
to manage the remote section system and in the LPC.
So in order to map a section on the remote process
in the server, it's a little bit more complicated
than before.
First you have to call the NT LPC create part section.
You submit a section or you ask the function
to create the section for you.
It will link your section with the LPC per object
and return you a specific handle.
This handle must be set in the entry
of the dynamic message buffer
of the type LPC message flag view.
And this entry must be submitted
to the NT LPC create section view function.
Basically it will initialize the structure to be ready
and create another representation
called a view in the kernel.
Finally you have the message buffer ready to be sent.
But when you send a message buffer
it will not necessarily map the section on the server.
By default it will not because the server
has to specify in the out message buffer
the type of the section view.
If it's not specified it will just not work.
This architecture of message buffer is a little weird
because first of all nothing indicates
if the remote section mapping worked or not.
Basically it will show the same ways if it worked or not
and the message buffer will not be changed.
Of course you don't have the remote address
like it was in XP in the LPC interfaces.
I saw too that message buffer is available
during the connection.
But as a message buffer is linked most of the time
with an LPC object and the LPC object
does not exist for the connection,
I don't really understand how it works.
Well there is another way now that when you map a section
then disconnect from the LPC and redo every steps
to remap this section on the remote process.
The section will remap it twice
and you can do that whatever you want.
So basically you can fill the overall system
with your section.
Basically that's like a HIP spray attack without the HIP.
That could resolve the issue of the,
that you don't know the base address of the remote section.
But as I said most interfaces, LPC interface
does not support the section mapping.
So the vulnerability was in a new component
called a resource reserve.
This new component basically is around a type
that is linked with the LPC object called a blob type.
So the blob type resource reserved basically
link an empty kernel message object with the LPC object.
This message, this presentation of a message in the kernel
is not linked with any LPC port or any process.
That's a blank message.
But we're not sure exactly what it is for
because we don't see any wild example.
It is not used by any interface.
And I even think that Microsoft did not know
if they use it or not.
So here is the available assembly.
First it will look up for a message from the message ID.
If you submit a sign in message ID
it will look for a resource reserved,
a message linked to a resource reserved.
And later it will try to access the LPC server object.
But a resource reserved message does not have a link
with the LPC server object.
So basically it will try to access new.
In Windows you are able to allocate the new page.
Then we're able to redirect the data that will be used.
And finally it will submit a pointer from the LPC server
object to the XSF query post lock shell function.
That's a lock mechanism function.
So we're able to change the behavior of the process
and overwrite a single byte in the kernel.
In order to allocate the new page
you have to call the anti-allocate
virtual memory function.
By specifying an address in the first page
it will allocate the new page.
I think there is another way to do that
but basically everyone use this way.
So we must target something really special.
As the XSF query post lock shell
is an undocumented function
and it's a little bit complicated.
So basically we made some tests to see
how it will change data when it acquires an address
and when it realises it.
We saw that when the iBite is set
it will set the low byte to one.
It only works in Vista because on XP and other version
it does not behave the same way.
We target the blob definition structure.
That's a structure in the data on the kernel
and basically it defines what is this blob type entry
by an ID and some callback function.
You can see that the delete callback function is new.
You can set up a new callback.
It will not be called but using the next pointer
and unalign this pointer we are able to set the iBite
and then we will set the low byte in the new pointer.
That's a little bit.
There is more details in the paper
that explain every steps,
what is done when you acquire the pointer,
the acquired latch and when you realize it.
I show you demonstrations.
It will be a little more clear.
So for this exploit I made a breakpoint
to show you the stack.
If you look at the stack you see that we call a syscall.
That's why you have the key fast call entry
and then the stack is in the kernel
and it will call the user line.
That's how we get the execution of the user line code
in the ring zero process privilege write level.
So I said that unalign you set the low byte to one
and that's why it called the 100 function
in hexadecimal form.
So this exploit just changed the parent process token
in order to increase the privilege of the color.
You can see that first we were a guess call a mix
and then we are a system.
Okay so basically the kernel is now
the next exploitation landscape
because exploiting the kernel is a lot easier
than exploiting the user line,
especially on Windows Vista
where every system component code base
has been drastically improved.
The previous vulnerability was not exploitable
in Windows Vista not only because the app changed
but also because they changed the alpha system.
They improved the base, the code base.
In the kernel exploitation a new difference
is really important, is as important
and even more stable than a simple overflow
in the app or things like that.
But as you have to protect the kernel
the protection will be a lot harder than for user
because if you made a mistake
you're dealing with undocumented stuff
and if you made a mistake it will crush the overall system.
So for a third party vendor it's not acceptable.
Basically there is two approach.
First the software protection you see
to use your look at command actor attack vector
and you modify the operating system behavior
to deny for example the new page allocation.
As before we saw that the system does not use it
and we were wrong because it is used
like for video installation
or everything related to thread creation
on the kernel and in the user line
and maybe some packages can use it to hide themselves.
We can also add in the kernel pool.
The kernel pool is the hip of the kernel
and it is used a lot during the exploitation of the kernel.
There is a paper from Kostya Koshinsky
about that during CISCON Hong Kong that's really interesting.
It's possible but it needs a lot of reverse
because it uses a lot internal structure
and exported by the kernel.
The other approach is using the hardware
in order to restrict the operating system.
We can use the visualization as for rootkits
but basically we can talk about it
but it's a lot easier to talk about it than create it.
So it takes a lot of time
and you have to be really careful
because the more you monitor the system, the hardware,
the more your system will slow down.
That's certainly the best choice
to protect the operating system
but that's also the hardest.
PAX integrates a component called kernexec
that's not really known.
Basically kernexec creates a separation
between the user line and the kernel line.
The user line is accessible only when the Linux kernel
call a specific function called get user.
So it restricts basic kernel escalation
as user line is not available.
It's not the better restriction but that's a good way
but it's not possible on Windows
because the Windows kernel protects itself
but does not protect others.
It does not use a single function to access the other one.
There is also a concept like protecting the ADT,
the Cisco table, the GDT that are not applicable in Windows
because all entry various and search software
whoop those table.
So the conclusion, of course there's still vulnerability
in the Windows subsystem components.
Most are unusual.
Windows Vista improved a lot,
it's got base and robustness.
We saw Windows Vista application
directly in the kernel component,
the main kernel component.
But the main kernel component is certainly the more secure
in the kernel address space.
There is a lot of other driver that are easier
to attack and to exploit.
I believe that serious kernel protection
will need an improvement in the way
the Windows kernel is designed
because for the moment you are behind
you are between documented stuff and undocumented stuff.
You have to go far in the undocumented stuff
to create a good protection.
But basically when you do that,
you can create some issue on the operating system,
some unknown behavior and that made the development
even harder.
So thank you for attention.
Do you have any question?
Thank you.