Dear viewer, these subtitles were generated by a machine via the service Trint and therefore are (very) buggy. If you are capable, please help us to create good quality subtitles: https://c3subtitles.de/talk/660 Thanks!
OK, good morning.
Good morning, welcome again to
our second talk of the of the day.
Our next speaker is a
security researcher at Checkpoint
and he will be talking to us today
about exploiting seven and
serializer mechanisms.
So please give a big round
of applause to your Nili.
OK.
Hi, uh, welcome to my talk,
teaching the new dog old tricks,
it's about preserving memory internals
for security researchers.
And I must give
a disclaimer first. This is not to talk
about puppy code.
It's about being an interpreter.
So I hope you enjoy it
about me. My name is Yanai has
already said I work at Checkpoint,
my team and I work with many staff and
networks. Embedded devices,
exploits, client sites, exploits
and also memory corruptions of all sorts.
And today's agenda first
will have a brief introduction about PPY
and then we'll talk about PPY and
Serializer Mechanism.
After that, we'll talk about the
implementation of the Zevo system, the
value system of ENPI seven
now gaining this knowledge of uncivilized
and Zevo system. We'll see some bugs and
vulnerabilities.
After that, we'll discuss the internals
of the allocator in pre seven.
It's a new aligator and using
our knowledge of the al-Qaeda and we
can see how we can exploit the bugs and
write remote code execution exploits,
then we'll have conclusion's questions,
etc..
So let's begin.
PPY is the most used,
uh, language in Web applications
today for writing Web applications and
basically its server side language and
servers rule the world.
All our information, all the data we have
in applications is in the server side.
So it's very interesting as
a malicious attackers
want to get some information to attack
the servers usually.
And when I said
it's the most used language today
to today, the most popular version of
this language is version five.
But unless you came up,
a new version was released
seven. And this is what we're going to
talk about today.
So it's the most simple, one
of the most important languages today.
And what about the security of
P2P applications?
Well, like every popular
yeah. Every popular language
has vulnerabilities written into
it or written by it.
So we know many vulnerabilities
of fiscal injection in recent years and
exercises.
These are high level vulnerabilities and
it depends on the code you're writing to
your Web application.
But there also memory corrections.
How can you have memory corruptions in
high level then, would you ask?
Well, some of the functionality of PCB
is implemented in the interpreter
itself, which is written in the C, and
when you pass user input to this kind of
functionality and you have bugs there,
you can get some exceptions.
The most notable example for this
is the insulated function which has
been exploited many times over
the recent years.
And this is exactly the function we're
going to talk about today. But in the new
domain of P seven.
So what about the history of unsterilized
of too many civies, actually,
and most of these vulnerabilities
were exploited in object injection.
So property oriented programing, if you
heard of it. And this is a
logical explanation. It depends on
the application that
is used, how this application to Peterffy
application was written, but there also
have been no corruptions and corruptions
does not depend on the application.
Moer corruption exploitation depends only
on the B version.
As I said, version five of version seven.
And for memory corruptions in
five, there was a generic exploit
developed by Ionic
Essar. Uh, it was described in Blacket
2010.
And this, uh,
exploit could basically work on every
five memory corruption and
manner corruption you had.
So as I said, it's a very old problem.
But here is an example from, uh,
this year on July, uh,
this small website that I don't know if
you're familiar with it, uh, open
the backbone thing.
And this bug bounty, um,
attracted the attention of
a company called Eventide.
They looked at the API and found
this, uh, API call a post
request. And you can see a cookie here.
And this cookie has a very interesting
format. This is the format of an
serialize.
And of course, when you send, uh, the
request, you get a response and you see
that the scroll actually process, uh,
this cookie. So we have a vulnerable
and serialize right there.
And what they did, the first and
serialize and version five, this, uh,
in this instance and found the new
vulnerability exploited it got the
bounty.
So what about pre seven?
I'm talking about all the time.
Well, it's a new release of the language.
It was, uh, released just a year ago
and they kind of reimplemented
everything for performance.
So they re implemented a value system.
They have implemented the memory
allocation mechanisms.
And for this reason, the
exploitation technique of
the memory corruption does not work
anymore. Uh, exploitation of
our corruptions depend heavily on the
memory layout. And when you change all of
that, nothing works.
But still, we have the uncivilized
functionality in P7 because you
have some sort of backward compatibility
and there have been some civs,
object injections, Sageworks being purely
logical, but the corruptions while
still there, you can still find more
corruption vulnerabilities in
unsterilized.
You don't have any remote exploits until
this talk. More or less.
Yeah, thanks for me.
So let's talk about in Cirillo's
and Unsterilized first.
We have to I have to make
something clear.
You should say disorderlies and
unsterilized is a grammatically
incorrect. And if it bugs you, well,
that's how it's going to be for the rest
of these stocks. So I'm sorry, but
we can go on and this is
the documentation of the serializing
unsterilized functionality in
basically what SERIALIZE does.
It takes values and converts them to a
string that you can store
and retrieve later.
And unsterilized is the reverse
operation. So you get the string in a
specific format of unsterilized.
You convert it back into a value.
And this is very
simple, you would say, but there have
been too many vulnerabilities there and
we'll see exactly why.
So let's have an example of
serialization. OK, soon we want to
serialize this nice
array that has another inside of it
and so on.
And we'll go step by step and serialize
it to to Syria to unsterilized format.
So first, we're serializing an array with
four elements.
So as you can see down below we have the
string and it's a column for
a four every column, four
for four values.
And in every
array is actually a hash table or a
dictionary.
So it's a key value store.
But when you have an array, it's
the keys are implicit.
The keys are just running index,
running index and it's implicit.
So we're serializing the first entry.
It's integer zero as key.
So you have Ikon zero.
And now for the volume
next we're serializing
integer one for key and integer one three
three seven as the volume
and then we're serializing
a string. So we have integer two
as the key and string.
So we have s four string Kullen five,
four, five characters.
Then we have Epel.
This is the value of the string.
Natsuo serializing another array so we
have the implicit key integer free and
the value a column free
for three values in this
nested area.
Next we have an explicit key string
so we have s four string column, one for
one character a for the value of the
string and this is the key and the value
is integer one next to serializing
a class and object actually.
So we have gone back to the implicit
keys. So it's integer zero as an implicit
key. Then we have object
that the class name has freekeh eight
character. So it's called an eight
column. The class name Usted declasse.
Then we have Callon zero zero is the
number of properties in this object.
Zero properties, nothing in there, curly
brackets with empty
properties. Then we're serializing
integer. One is key and integer seven
fifty one as value.
And this was the process of
serialization.
Quite straightforward.
And we have this nice format that we know
about. Next I want to show you exemptive
and serialization and this would be the
exact reverse. So it's going to be a bit
boring. But I want to show
something here. PPY supports
a feature called References and
References means that during an
serialization in the format,
we can specify instead of specifying a
value such as integer or string, we can
specify a reference.
And this tells the mechanism,
go back, see what was the
end value we just passed,
which is a and I want a copy of this
value or a reference to this value.
And in order to support this feature
during an serialization, every value
that is passed by the insulin's mechanism
is kept a reference to.
So we have this array cultivar Hegira
in this in this area.
We have pointers to every parsed value
and let's see how it's done so first and
serializing an array with four elements
so you can see in the fresh area and it's
one based error. You have pointer to this
array we just instantiated.
Next we have a key integer
zero and value now and
we considered the second pointer points
to the null we just passed.
Next we have integer one key
integer one four three seven as a value
and the third pointer points to one three
three seven.
Then we have the string Epel
as the value and the first pointer for
pointer points to this value.
Next, we have this
array. Now, this is an internal array,
but the varnish area is
a flat area. So even though we have some
nice thing here, we have array within an
array in the value IT values are
nested, the very hash
array is flat and the
pointer points to the array NextEra and
serializing the key A and
the value one and.
We have another pointer to the value,
then we're in satiate, instantiating the
steady objects, so we have another
object there and a seven pointer points
to this instantiated object.
And now something interesting is going to
happen. We're an serializing
a reference to the third value.
So what would happen here?
The answer is functionality.
We'll go and check the Rajeshwari,
go to the third value.
The third value here is the pointer
to the integer one four, three, seven.
And now we need to create
a reference to this value.
So this is what we do.
We can serialize this value and we create
a reference to a previously parsed
value. So this hope supports
this feature of references of backward
references and this mechanism.
This feature caused many bugs in the past
because as you can see, we keep a pointer
to stuff we maybe need maybe we
don't need it again.
And there has been some confusions over
the years.
If you got lost in this complicated
format, there are some points I want you
to remember. So first, it's a complicated
format, OK?
Yes, obviously in complicated formats
leads to bugs and
bugs. And we're going to see it soon.
We have many, many ways to control
allocations, right. Where instantiating
objects were instantiating were and
serializing strings of various lands.
We are an serializing hash tables of
various lands. So we have lots of control
as users and we keep
these references things.
So we keep references backwards
to things we unsterilized in the past and
we can reuse them.
So in his case, we have some use.
After free, we managed to free some
object in some magical way.
We still have control and we can go
forward as exploiters.
So now we talk about the Zevo system
in PPY.
Now, Zervos are basically values like
this, how to interpret their calls,
values or host variables.
This is a variable.
I'm sorry that we have to stop, but
there won't be much of it anymore any
time soon. So anytime soon.
And as high level language,
we have a couple of features for our
variables.
One, we have automatic memory management
or a garbage collection and we
have this references reference.
When Y is a reference
to X, it means that the value
of variable Y changes when the value of
X changes and vice versa.
So they both basically are variables
holding the same value.
And this is how the Zervos
were implemented. In FY five.
We had this struct called Zevo.
It was on the hip, it was referenced,
counted, and every Zevo was basically
a pointer to this struct.
And every time we created a new level, we
had to create to allocate destruct
on the hip and initialize it to
the memory management was quite
obvious. We have reference count and we
have memory cycle detection.
So it was a very simple algorithm
which most people know about.
And to make references to make
two variables point to the same value was
just to pointer is pointing to the same
struct and everything was very simple,
very nice, but it was
slow. So when implementing
P seven and having some motivation,
motivations to change it and
the implementors wanted list the
references. Now if Zevo laser
pointer, every time you need to reference
a value, you have to dereference the
pointer, which can be expensive.
Also, every time you create a new value,
even if it's for a short time, even if
you know exactly where it is, we still
have to make allocation on the hip,
which can be expensive.
So they designed a system for embedding.
They said, OK, I don't want to see those
to be just on the hip.
I want to be able to embed them
everywhere I went on the stack in order
struct and so on.
And this is how the new level system is
implemented. We have this Zevo struct,
but now it's a bit different.
It's simpler.
Zervos are just destruct and this
contains only value in type.
So there is no reference counting and
we can put this struct wherever we want.
And the value thing here
can be one of two things.
It can be a primitive type, for example,
primitive type like integers or floats
and so on.
But PPY supports also strings.
So if you want to support complex types
like strings or objects, Disvalue would
be a pointer to a complex struct
and this fact will be on the hip.
OK, so this struct will not be
on the stack, it will be somewhere on the
hip and it will also be referenced,
counted.
So here's an example.
This is an integer, and in memory,
we'll just have the value one three,
three seven and the type long,
that's it. We don't know where it is.
And it's quite simple
now to support reference counting.
Now it's the responsibility of
whoever initialize that initialized
Decebal. Right. If Decebal is in a
struct, whoever initialize destruct
needs to clear it up.
But there is one complication
here. If the value is a primitive
value, everything is good.
But if it's a pointer to another struct,
this structure should be referenced,
counted and when it's referenced and this
is how the garbage collection works,
it checks disvalue pointed
by this evil and it has also reference
count and garbage collection.
Now let's see an example.
OK, so this is the string struct.
As I said, it's a complex type.
So this struct is on the hip
and is pointed by Zevo.
As you can see, the first field
in this struct is the reference count
and the left field is a flexible array
member array, remember.
So when
when allocating a string,
we allocate more data, enough
memory to store to string content itself
and we exit via this
field.
So this is what it looks like when we're
initializing
and variable string.
Then we have this struct it's of
type string. We're allocating the
string on the hip.
We initialize it with the values.
You can see we put the value Epel here
and we just point the Zevo
to this string and the reference count is
one.
And this construct is under
hyp.
So how can we manage
the references?
How do the references feature
was implemented
this time? We cannot just make one
zero point to another because they may be
in different scopes. One can be instruct,
the other can be on the stack and
they must be managed.
Right. So there is a solution
here in PRPD
implemented another
type called references, and it's easier
to show than experience or show how it
works.
Assume you have this variable X,
which has one, four, three, seven, and
now we have the verbal way, which is a
reference to variable X.
OK, so we have it in memory and I want to
make a reference to it.
So we initialize
a new struct on the hip
called the reference, and this struct has
two fields. The first field is a
reference count and a second field
is another Zevo, and we initialize this
Zevo value to be the same as X,
so you can see it contains a copy of the
value. Then we change the type of X
to be a reference and now it points to
the same reference and now we can
initialize Y and we will be the same.
So it also be a reference to something on
the tape. So we moved the contents
of X to the hip and now we can have
the two civils X and Y.
We just pointers through the hip like
previously.
The key thing to remember about Zervos is
that they're designed for embedding so
they can be in many places which can
cause some bugs.
The motivations or goals were achieved.
There are less references and less hip
usage, but making a
reference is a bit complicated.
Reference is not the feature
that used too much except in exploits.
So it is.
Yeah. So this there
is a trade off here between
the Zervos are our most
simple, but preference are more
complicated and it's worth trade off in
my opinion at least.
So now that we know about and serialize
and we know about Zevo, let's see
some bugs and vulnerabilities.
So first, the user financial value.
Now, since Zervos
used to be pointers, initializing
pointers was very easy, right?
Everybody knows how to initialize upon a
pointer you just pointed to now and
you're done.
Initialize instructs is a different
story, right? We need to initialize them
with some macros or maybe some constants.
It may take some time.
And programmers tend to skip
this phase if, if, if it's possible
you don't initialize destructs, which is
a problem. And this is a
can lead to some vulnerability's.
And this is the exact example here
we have this function, the special object
storage and serialize, and this
function is the custom implementation
of serialization of the struct
SBL Object Storage.
This class is implemented in C-code.
Some of the classes in the SBL, the
standard library are implemented in C
and this is the case here.
And as you can see, the first line, two
variables are declared entry and
these are Zevo.
So there are Zevo struct
and at no point in this code
they're initialized.
And after a few lines of code, we reach
this statement calling
the function Pevar and serialize.
This is the C implementation of the
unsterilized function.
And the first value is a pointer to this
that was never initialized.
And this is supposed to be an out
variable, but it's not
OK. So but this is where we were going to
store the string and serializing
the next variable is P p points
to the stringer and serializing.
So this function, what it does, it's
unsterilized is the string pointed by
P and stores the value in F.
However, internally we reach
this line of code Zevo
Pointer Destroy, which means please
destroy the Zevo which is pointed by
our Val. Right.
And what is Auroville? In our case?
It's inf.
It's exactly the thing we did not
initialize at no point.
And the reason the code does this is
to make sure there is no value in this
before writing new values.
But since this value was never
initialized, what's in this value
is garbage from the stack.
And if you shape your stack correctly,
you can cause some bad things to happen.
So this was Sivi two dozen 16 seven
four eight zero.
OK, so the next example is type
confusion. And we are
going to rely on the fact that making
references is very complicated
process as you see any changes, the type
of the Zevo, OK, and
we can suspect somebody forgot
about this possibility and this is
exactly what's happened.
So we have the same function again.
And this is you have more
lines of code from the same function, but
it's the unsterilized of the SBL
object storage.
And as you can see in the second line
here, we are calling the internal
unsterilized and we're again converting
the string pointed by P and
stored to the result
in the Zevo entry.
OK, two lines later
we're talking. The type of what we just
unsterilized making sure is of type
object, so you can see that if
the type of entry is not the object,
the function builds, better things
happen. But if it's nothing
should happen, but if it's a type object,
we can go on and in the last line where
an serializing
the next value is advanced here and now
it points onwards
in the string and we're converting the
string pointed by and store it into ENF.
But what happens if enough is
actually a reference to entry?
Well, the type of entry is going to
change and let's see how what happens.
So first on serializing entry
and it's an object and we're checking
and this is actually an object and
everything is good but next year and
serializing ENF and ENF is
a reference to entry.
So according to the process, first
we're allocating a Zen reference on the
hip and we're initializing to be
the copy of entry.
Then we're changing the type of entry to
be of type, reference and point to
this reference. And of course, Lesli,
we're initializing ENF, but
in this process we actually change the
type of entry after we
checked it.
So this is a bug and actually better
things happen.
It's not exploitable, but it's still a
bug and was fixed. So this is about seven
three two five eight in
pieces system.
OK, so here is this is the last bug
for today and it's a use after three.
And a problem stems from the fact that
now Zyvox are embedded instructs
and we keep pointers to receivals, but
trucks have their own rules of how they
change. And some structures
tend to change to place in memory
without telling any anything else.
And if we keep using these pointers,
we're actually pointing to Nauru, which
is not not not valid anymore.
So such a dynamic
struct can be a hash table, for example.
And this code is processing
the data function.
This function is a function that
processes every hash table
during the serialization, and tables can
be also properties
of an object.
And here in the first line, we're
declaring it variables and the next
line we're adding a new entry to a hash
table.
So what we do here is Zend hash
at new we're adding a new entry.
The first parameter is the hash table
and the second part is the key.
And the result of this function is a
pointer to this evil.
That is the value.
So we get data points to
this Zevo we need to fill
and then we're calling the last line.
This line calls the internal
implementation of Serialize and
again, it converts the string
pointed by P and starts is
stores its value in data where
data is pointing to not look at the
list parameter here.
It's the VA hash, this array we talked
about in the previous part and
VA hash keeps pointers to every
piece of every value we passed,
including data.
So data points internally to the hash
table and it is stored in the in
the VA hash.
But what happens if you manage to insert
another value to the hash table?
Then the hash will might resize right.
Hash tables, gross sometimes in memory
and when they grow internally they
reallocate their memory to store
additional values.
So this is how it looks like in the first
year and serializing an object.
And this object has some properties, for
example, it has to poverties zero and
one. And then magically we managed
to insert another value to the properties
hash table and it reallocates.
So now the hash points
to the new value that was
serialized.
But the two previous values are not valid
anymore.
And this is not very common scenario.
It's quite hard to exploit this or to
trigger it is vulnerability, actually,
because if you remember the format before
and serializing an object, there
is a number of properties in this object
and B, makes sure the hash table
has enough capacity to hold
all these properties.
Yep.
There are two ways to do trigger this
vulnerability. The first one is the wake
up function, and this is a function
that objects can define.
And this function, this method is called
after the object has been serialized.
And if for some reason dysfunction
defines a new
property on the fly, then the interpreter
is not aware of this beforehand.
So inserting a new property on the fly
can cause this.
This can trigger this vulnerability.
And also we have my all time favorite
object in our class, the date interval
class. And this class has a very
interesting behavior.
It does not initialize its properties
hash table beforehand or
it's actually
only when accessing the properties of
this object, then it defines
and adds its properties to the hash
table. So if we manage to
come to some functionality, such as
to string or wake up, that touches
this object.
Or some objects, properties such as the
interval we can trigger this
vulnerability, and
this was Sivi 2016 seven four
seven nine.
So these bugs
are complicated. There are still
unsterilized vulnerabilities even
between the time I submitted this stock
and to date or has been at least one more
that was reported and published,
the vulnerabilities are a bit different
than what we used to see because the
civil system is a bit different, but
still very corruptions.
And these vulnerabilities let us
use frid values as
we've seen the two vulnerabilities.
Let us reuse the feed values.
And this is a property that we're
going to need in order to exploit these
vulnerabilities.
So after we know about
how the system works internally and
is the civil system works and we
found some bugs, are we going to talk
a bit about the alligator?
Because when exploiting this
kind of corruption vulnerabilities, we
need to know how the
alligator works, how memory looks like.
So we had the previous alligator
of Peachtree five, and it's not too
important, but it was he based alligator
and every slot slot is the
allocation unit in.
OK, so it's called slot and it has
this size and flex to each allocation
and also a filius for caching.
And it was it was very fine and was
nice for exploiting.
But now we have a different alligator.
The alligator here is it's a completely
right. There is nothing similar
and it features beans or memory pulls as
you know them and Frehley's.
This is basically how the alligator
works. These are the basic building
blocks.
And I'll go and throw some details at you
and you probably see them or not.
The alligator works in chunks of two
megabytes from the operating system and
these chunks are divided into pages.
The first page is Page a script.
He describes the chunk
and it has a couple of strokes.
The two important ones is the one
describing the pages, which page
pages are user free to use
and pointers to the beans or to the
Frehley's that were initialized.
And every bin is a list
of specific size we have the 32
bytes mean we have the six invites being
and it can spin over multiple pages.
Now, let's say it in a way you can
actually remember.
So here is a chunk from the operating
system. It's of two megabytes and it's
divided. It is divided into pages.
First page is the descriptor.
You can see the free slots.
It is just array of pointers
to three lists and page info
for each page.
And this is what the bin looks like.
So bin it can spend over multiple pages.
This is the 16 bytes bin and we
initialize it as a frailest.
So every six invites points to the next
bytes and we
register it in the trunk descriptors.
So we have the page information, 16
bytes spends over two pages and
pointed to the frailest.
Now the allocation algorithm is quite
simple. First, we want to
assume we want to allocate the
A of size 30.
Then you check to which it belongs to.
I think it belongs to bin number five.
Then we check if there is freely
available or is a bin initialized if
there is no initialize been we initialize
a newborn and then we just pop from the
list. So assume you want to allocate
thirty bytes.
There is no thirty bytes been available
right now, so we're
initializing a newborn and then we just
pop from the list.
Assuming we want to make any replication
of the same size. It's even simpler.
You just pop from the feeblest.
Freeing memory is the inverse
operation, so we get some point.
We want to freed back to the pool.
So we checked which chunk it belongs and
which page within the triangle belongs
to. We read the descriptor to
know to, which is to push it back and
we push it back to the fullest.
So as assume we want to free
the first part of this
bin, then we just see it belongs
to the third page. We see the third page
is of bin 32.
We go to the frailest and we just push
back.
Well, I want to remember about the
alligator. Is that the alligator is very,
very predictable, which is important for
us as exploiters and
it's impossible to free just random
punters.
This was used in the previous
exploitation technique, but it's not
possible anymore because we have some
meat operations and lookups and it's hard
to forge memory to look
the correct way for this to work
and we can abuse this point is
to get arbitrary, right.
So we can change them.
If we can change the frailest and then
allocate a few slots,
we might we can allocate to the place we
want to. And I'm going to explain it much
more later.
So now that we have vulnerabilities and
we know about the allocator and how
it works, it's time to write an expert.
And every exploit has a few stages,
the most common on our leaks.
So we want to leak some memory
information to bypass days
later than we would like to read
some memory so we can read
the data or gadget's
function pointers.
So on it would like to write,
maybe write our code, maybe write
some other stuff and we would like
to execute. This is what we're here for.
And first thing we're going to talk
about, like I think is the most
complicated part, and
we're going to abuse the allocator.
It's our best friend here.
It's roughly based on the previous
exploitation technique, but it's a
generalization of it.
And we're going to use our ability to
serialize freed objects.
And we believe we can serialize objects,
not only use them, because this is how we
initially started. Right.
We have unsterilized if we're an
serializing something, we probably it was
serialized before. So we have some
kind of a mechanism here that we
serialize something and answer and
serialized it back and so on.
The Elkader, if you remember, is
officially so it overrides everything
that is passed to it. So if if free
pointers, the al-Qaeda is going Afri
slot's, that al-Qaida is going to
override them.
And after we freedon, we use
them. We can read via these pointers
and read some data.
That was also Freeth.
So this is how it's going to work.
The placatory, the released and the first
pointer is in this slots in the free
slots is the next slot.
It's just the pointer, right?
So here is the free slot
struct and you can see the first field is
the pointer.
And when we read Friede Objects, we can
sometimes read via this pointer.
I mean, we freed the slot
and we're still using it so we can read
VRD Responder and read to the next slot,
next free slot.
So here is my all time favorite
class in the interval class.
And as you can see, this how destruct is
implemented in memory. And the first
field is a pointer.
How lucky we are.
Right.
And it points to distract and
distract is a very simple struct.
It has many fields, but all of them are
integers. There are not only integers,
integers. SLR is assigned Longlong,
so they're also unsterilized and written
back to the user.
So when on serializing diskless,
we're actually getting these numbers the
year, the month that they and so on.
So how are we going to forge link in
practice? First are going to allocate
this date interval and we will allocate
an object like for example a string
and then we're going to free both
objects. First the string, then the
date interval.
And the al-Qaeda is going to override the
date interval with a pointer to the
string, to the friede string, because
this is how it works.
And the card is also going to overwrite
this string with some pointers.
So when we serialize this date interval,
we were going to read this objects and
here's some hex dump for you because you
really wanted it.
And here is a you can see the Frehley's
before we start our exploit and now we
allocate that interval.
And as you can see, it points to some
strike that I initialized with
Venezuelans because it doesn't matter so
much. And we're also allocating
or an serializing a string one after
the other. And now we're offering
the two of them.
And as you can see, the date interval
pointer, the first pointer now points
to the Friede string and one on
serializing this date interval actually
gets the values in the string will get
these pointers as integers, which is very
nice.
How can read memory?
Well, we have this very nice struct
already. So if we can control this struct
fully, if we can control Zevo
fully, we can just change this pointer
to whatever we want.
So pointing the first field in the
date interval will let us read any
kind of memory we want if we don't
control the level fully, which can be the
case in 64, which it was the case.
There is a more complicated way and
I'm not going to discuss it here.
But basically we can use a different
object at a period object which
has a first first feel.
There's a point at which points to
another stock and destruct.
We control another pointer, that is to
enter a copy on an serialization so we
can read memory with
your copy. And you can see all the
details in the paper published
earlier this year.
I'll give you links in the end of this
stock.
How can we possibly write memory
o writing memory is a
much more complicated here and is
what we're gonna do. We're going to free
some strings back to the allocator and
in the strings are going to write
pointers to wherever we want, whichever
one we want to write.
Then we going to abuse the frailest and
we're going to change the pointer in the
field and going to increase them or
decrease them depending on our
vulnerability,
unordinary.
And at some point, if we increase them
enough, they will actually point
to this memory we want to write.
So after a few locations, we'll actually
have the memory. Elkader, give us the
address we want to write
and this is
what we want to happen. So how can we
free these strings?
As we said, every value we're passing
on, Serialize gets a reference in the
Treasury.
So we have reference to almost everything
and nothing is free during an
serialization.
Except there is one exception and
it's in the hash table.
We can use the same key twice.
Keys are not kept references
and if we're using the same key twice and
the keys can be strings, the second time
we're using Diski, it is free.
The hash table looks at the.
And says, now, I've already got this guy
I don't need anymore and freeze it back
to the alligator, no references to it
are made and it's back in the alligator
for us.
And the next thing we need to know is how
to abuse pointers in the Frehley's.
This is the most interesting part here.
And
the reason it is possible and it's very
common is because we have type
confusion here, right?
We have the free slots, which are first
field is a point there, but we
also have the something that was
free, the value that was free and we
still have a reference to it.
And on the hip, every
every struct on the hip has a reference
count and the reference reference count
is always the first field.
So if you take descender object, for
example, this first field
is a reference.
So if we have a type confusion between,
uh, an object,
so not that accurate, but if an object
was freed and we can still use it,
increasing the references or decreasing
the references to this object actually
increases or decreases a pointer.
So it is how we can control this pointer
and some more Hexham.
So this is part of the exploit
they wrote to bug seven one three
one one.
And here you can see that
we already freed the strings back to the
alligator. So you can see the four ones
in the up.
And now we're going to trigger the
vulnerability. The vulnerability here
lies in the array object
plus and parsing
it increases the pointer into
four by two. And now we have Yusoff.
They're free of this address.
The first that is pointed by the
frailest. It's still in the alligator,
but we have a reference to it.
And it was the 11th, uh,
value that we passed.
So eddying references to this address.
So R11 parsing, R11, so
on. We're increasing this pointer
by two every time and at
some point reach the values, just feed
back to the hip or back to the alligator.
So now if we allocate
twice from the spin, the first thing
we allocate at the object
that was corrupted and the second time
we will actually can write to four one
four one for one and we will fold.
But this is exactly what we wanted,
right?
So codification, after all, this code
execution is quite simple,
if very controlling, as evil, as I said,
the easiest way is to override a call.
You do you control some object.
You can decide what complex
it has, but if you don't control Zevo
fully, you can just we have a
right primitive so we can write that
function pointer and that's about it.
So takeaways from this
exploit the allocative is your friend.
Please use it, use it wisely.
And these primitives are usable.
They can be used in many different
vulnerabilities within the serialized
mechanism.
And combining all these primitives, you
get the remote code execution.
Conclusion from the talk, even though
you're writing your code in high level
language such as BHP, you're still
vulnerable to memory,
corruptions or other low level problems.
The new design of being is for
efficiency. You still have
vulnerabilities. I don't think it's
more secure or less secure in a way.
And the Elkader is exploit friendly.
Please, when you're writing an exploit,
use it.
Uh, and never, never,
never use in this function is a remote
code execution.
Basically, every time it was
in some somewhere in the reachable code,
it was exploited.
Some more information you can find in
Checkpoint blog and also a description of
this talk, I have a link to the paper
I just published
and they're going to be another
publication soon about the
vulnerabilities. I talk about more
information about them, and also a third
vulnerability, which I did not discuss
here.
Feedback system is a
second link and there is every
bug recorded and every vulnerability
is some of the bugs doesn't have civies,
unfortunately.
And the third link is Nikita Popover.
I think I pronounce his name correctly
blog. He's a main contributor to
B and he has many explanations about
internal mechanisms within between
if you want to contact me. So you have my
corporate e-mail, my Twitter and
most other platforms such
as Gitmo and so on, couch surfing, I
don't know.
Uh, so that's
it. Any questions?
Thank you and I if you have questions,
please line up next to the microphones
and ask your question.
If you are leaving, please do so quietly.
Any questions from here or
from the Internet?
People are overwhelmed.
So I'll start with a question, actually,
because I have one, I understand the
internals too much into the applications
of exploiting things they talk
about eventless in the wild.
Are we expected to see this in the wild?
Actually, P7 seven is not very
widely used.
I now think it's two percent.
It's just a year old.
But as soon as the big
platforms, the big storms will
move to this new language, I
predict we will see some of them other
vulnerabilities. But I assume we'll see
more exploits coming
next.
Questions from the audience or from the
Internet?
The Internet has a question.
Yes.
Yes. Are there any popular project
that are affected by these
vulnerabilities?
Not that I know of, not yet, because P7
is not widely used by now.
There are no big names using P2P
seven
sorry, Internet.
If you have more questions, then
go ahead.
I one from the audience, last chance.
OK, so again, please give a big round of
applause to United States.