[Music]
hello everyone welcome to our talk my
name is jerome from 360 alpha lab today
my colleague lee crusoe and i are going
to talk about a research on bug hunting
in chrome
first let me give a brief introduction
to our team 360 offer left many focuses
on mobile security including trust zoom
kernel applications like browser and so
on
we have reported more than 300 bucks to
top vendors including three exploited
chains of android devices and won the
highest reward of google vrp program
our team also successfully found many
targets in pantone and tm4 cup contests
so bug hunting is the main content of
our work
as a security researcher it is always a
good idea to learn from the old box and
try to find more
considering the complexity of the code
base
there is a high probability that bugs
shared with similar code patterns may
exist in many places throughout the code
base
found similar abilities based on a new
one this is called variant analysis
it can be performed by either menu
called audit automated analysis tools or
just writing your own further seated
with the poke
but to find the new box effectively
we need to understand the root cause of
the original bug sum up above pattern
from it and make sure this pattern is
good enough for describing other similar
bugs
however this is sometimes not an easy
task because not all bugs can be
abstracted briefly and the way how you
mutate the pattern may affect the
results greatly
for example suppose we found an out of
bounds bug caused by a just memory copy
we can perform some data flow analysis
on these parameters to other memory copy
calls
or we can consider other function calls
like memory memory set
and search the whole code base
depending on the choices our results are
definitely different
in this talk we take chrome as an
example to present how to discover new
bugs based on historical vulnerabilities
chrome uses a
multi-process architecture which
isolates different process from each
other with sandbox
we are focusing on the code runs in
browser process which means is on
sandbox
and we are going to use code qr to help
us locate potentially potential bugs
quickly
called ql is a grid analysis tool which
compiles code to a snapshot database
and can run queries against it for
program analysis
at last we will share the exploit
exploitation strategy of one of the box
we found to escape the chrome sandbox
let's start with the common bug pattern
in the chrome
render from host lifetime issues
so
what is a render from host
it is an object
lives in the browser process which
represents a frame in the render process
it provides a communication contact with
the frame in the render process usually
we can
delete a render from host object by just
closing the underlying iframe
many services in chrome need to access
render from host there are two common
ways to do it
one is to
storing a global id and using from id
functions to retrieve it back when you
need when you need to use it and the
other way is holding a row pointer to
random host as a class member variable
this means that the developer should
take responsibility to observe the
lifetime of random from host and clean
up the row pointer when the renderer
host is going away
so if a service can autolive the render
from host and still tries to access the
render post object after its destruction
is it causes a user for bug and can be
exported to escape the chrome sandbox
a representative example of this pattern
is the issue submitted by serial theory
which were the newsletter free in
installed application provider implement
implements
this class implements a module interface
named installed app provider which
provides installed app information
related to the arranging of the
requesting page
we can see that it holds a row pointer
to the random from host objects
this instance is created by a static
function named create and its lifetime
responded to
the lifetime of the module receiver
through make safe own receiver function
so the implementation will not be
deleted as long as the reserve stays
connected
quite a lot chrome module concepts here
but this code can be described in a
simpler way
there is no relationship between the
lifetime of random frame host and
install the app provider implementation
if we delete the rfh and invoke any
method which could access it
the use of a free work
in this case function filter installed
apps would do the trick
there are many other no similar issues
many other known similar issues so we
are wondering whether there are still
such kind of box exists in chrome
codebase
this bug pattern can be described in one
sentence
any class storing random host as a room
pointer in a member variable could be
vulnerable so as a simple graph command
throughout the code base can get the
corresponding results
however this description is too broad to
reduce false positives to an acceptable
range so we need to add more specific
constraints
according to the bug fixing a class can
get notified of various page events from
web contents by inheriting web content
observer class
including when a render phone host is
going to be deleted this gives a chance
to clean up the pointer to render from
host and prevent user free from happily
the fixing also indicates a way to
improve the description we can filter
out the class which is a subclass to web
contents observer and
implements the random frame deleted
method
similarly a subclass of frames or space
can also be include excluded because the
class in creating frame
service space will be destroyed when the
random from host is deleted
so taking together we can write a code
qr query for instance that meets the
following conditions
first
it store render from host as a room
pointer in a member variable
and the second
is not a subclass of frame service space
thirdly it's not a subclass of web
content observer or the render frame
deleted method is not implemented
it's not hard to write a code qr query
to search this
here is the key part of the query
first it finds a field which is a room
pointer to render from host
then it says the class is not a subclass
of frame service space
and not a subclass of web contents
observer or the random render frame
deleted method is not implemented
executing this query against a custom
built criminal snapshots gives us
29 results
we find one true positive after digging
deeper through the results
this is very similar to the case i
introduced before
and we submitted the vulnerability in
this issue but unfortunately got
duplicated which was reported one month
earlier
as we can see running from host lifetime
issue is a very common pattern that
keeps happening in the chrome codebase
and because this
its cause is not complicated this type
of availability will not exist for too
long
now i'm going to hand it over to licorso
and he will introduce a more complex
spark pattern in chrome
well as after all i will show the next
pattern that i will written issues
the firmware's lifetime issue is a very
common pattern but because its course is
not complicated this type of
availability will not exist for too long
and searching only based on infinity
availability patterns without any
mutation may not effect it
the way how to mutate the pattern is
important
next i will describe how we started from
a basic availability pattern to do
mutate and finally found 14
vulnerabilities and got five cvs
i think two vulnerabilities discovered
by other people as example
and first let's look at cve 2020 skills
for six one
in the course there is a possible path
that transport complete will call
console building block which has the
side effect of deleting this
and the next branch
if blobs this is by the fpc
could also be reached
however since this is deleted the member
variable by this message callback is
also freed and that's the uif triggered
as the next case
the network process will send readable
data to channel through websocket
channels and frame but in single frame
file channel could be called
if some checks falls in that case the
websocket instance will be deleted by
doing erase from a std set which opens
eight
same as the progress bar after retaining
from the send frame call the subsequent
code continues to be executed and the uf
will be triggered when accessing the
member variable variable
from these cases it can be seen that the
root cause of this block pattern is
during the code execution of a class
instance calling another function which
could cause the descriptor of this
instance when returning to the context
of the destruct distance to continue
execution the user free will occur if
any
member variable or member function has
axis
we can write a query of this pattern
with good care and the key part of the
query is as follows
the managing map tab class and the range
function are important from qr libraries
published by mmo
the management map type class is used to
different management tabs such as a set
or a map
and the reach function determines the
readability or functions including the
callback functions
of the screen we found several problems
of this pattern take cve 2021 to 1115 as
an example
password protect request is used to
check whether a familiar login from a
password reuse event is safe or not the
member function or at least checkdown
will call
fail
fail request proto when server if
condition matched
and you messed up field request proto as
some opinion requests will be sent
through send requests but if the
serialized information is flash server
to screen will fall
so the request will be finished
immediately
this will erase the request instance
from std site named pending requests
and then the user free will be triggered
when the finish
in
on whitelist check it out it's cody
so all queries seem to be effective but
how to mutate the pattern to make them
more efficient
based on the analyze or results will not
say we notice that releasing objects is
more a some unexpected conditional
branches in is point to be variable
and besides deleting the voice test
during execution we try to focus on
lifetime management of the object
referenced by a smart pointer
so we propose such variant
considering a smart pointer as the
unicorn pointer x
is real pointer to the managed object is
written in context for subsequent uses
and the x itself
will be moved as a parameter to a
function in the function f unc if the
check condition is not matched it
returns early before the ownership of x
is transferred to the new owner
this will cause the smart pointer x to
no longer be held by any owner resulting
in an unexpected implant seat release
the ut3 will be triggered when the
reserved row pointer is used later
a new query is required to search for
this kind of pattern so
key parts are as follows
here we use dominance to determine the
relationship between the return node and
the mode node in the control flow graph
to ensure that the pointer has not been
moved to a new owner at the time all
written
we also found several problems with this
pattern
here we take a bag as an example
the ownership or older web content will
be passed to this page handle
then this page handle will be mode to
maybe start deterioration as a parameter
at this time if the check falls it will
return immediately so speech handle will
be destroyed at this time all the web
contents becomes a download pointer and
the user free will be triggered when
accessing it
there are many search results for this
pattern but the return conditions or
most results is how to be met
we want to maintain the pattern more
specifically
when editing the query results of every
return we found that student pixel code
this is a ps4 code exist in the drag and
drop ui component
continue drag is a member function or
temp stripe type drive contacts
implement is called drag which is used
to execute the user's drug behavior
according to the everything pattern
everybody can destroy type drag contacts
implements during drag a uf will be
triggered when accessing the member
variable drive controller
we will look for opportunity to destroy
type drag contacts implement
in function drag
we found that
drag will inventory called ramuloob
which will run a nested messy group as
follows
so what is the nesting master group
developer
we are a new master loop to process
system and application task then to is
delegate associated with the current
threat
this blocks subsequent
code execution until the x
condition is
met the quick lure is responsible
to close the loop when the accident
condition is triggered and restore the
outer context
therefore if we could destroy some
instances in the new message loop after
we exit the new loop and back to the
blocking context a uf will be triggered
when the destroyed instance gets
accessed
take the code of dragon drop as example
type strap type drive contacts implement
could be destroyed during the message
loop after the loop access
in continue drag the code after drag
will continue to be equipped
the uf will be triggered when accessing
its member variable drive controller so
we got cve 2020
1604
finally we found a ufo box about the
news x11 clipboard
where the code did not check correctly
when using the netstate nicely loop as
well as to uf users related to the
message box under service or users in
the ozone clipboard
which are as same as the x11 clipboard
and google changed the clipboard apis to
be a sony more
send markers ins and or using the
nasalizing groups
take one of the x11 clipboard box as an
example when crown password manager can
listen to the passive event it will call
ready text and red text will return a
regular uh let's say my loop if chrome
password manager current are destroyed
the uif will be triggered when accessing
its member variable was on passcode
code
after the next
messy loop excite
well that story or everything issue
no i will handle the presentation over
too long thanks
thank you lee crystal
according to this box an unusual bug
pattern like round loop can often open
up a new attack surface with more
vulnerabilities
next i'd like to share how we discovered
another unusual pattern weak ptr
optimization and show how to exploit one
of the reloads to escape the chrome
sandbox
weak pointers are useful when an object
needs to be accessed only if it exists
and the managed object may be deleted at
any time by someone else
chrome implements its own version of
weak pointers named weak ptr
and it is widely used in the code base
the weak ptr class holds a weak
reference to an object that has no
effect on its lifetime
a null test of this class is necessary
before any use to ensure the underlying
object is still alive
here is a simple example
validate the pointer first before
calling a method
so what if we do not follow the rule and
invoke the method directly without any
not test after the object was deleted
the implementation of weak ptr may
answer this question
weak ptr class overloads the class
member axis operator to act like a
normal pointer for convenience
if the underlying object is not valid it
will return non-pointer instead of the
rule point therefore invoking the method
on an invalid with pdr object would only
result in non-pointed reference which is
regarded as non-exploitable
however this is not the truth when we
ran a test on kernel built with easy
we found a code area in which wikipedia
are being used commented out the noun
test code recompiled criminal and
trigger the corresponding code
instead of a non-pointed reference crash
we got a use of the free and valid
address
to make things simpler these example
codes can show what happens
the class full gas in our pointer to bar
and the get method would return the room
pointer if is valid
is true
but in the main function
that is valid or set false so the get
method should return null and the
virtual function call on our pointer
should crash the process
this is what happens if we compile the
code without any compile optimization
however if we add an additional
o3 command the crash disappeared
the reason why weak ptr did not work as
expected is that the llvm compiler
optimized out the branch which get
method would return non-pointer as a
result
more specifically the compiler
recognized that there was a non-pointed
reference which belongs to
undefined behaviors and choose to remove
related code
unfortunately this optimization strategy
could convert a non-point dereference
trash to an exploitable use after free
bug
considering that weak ptr is widely used
situation accessing the underlying
object without no test is likely to
exist in many places
in a function body a weak ptr could be a
class member variable
a function parameter or a stack elegant
variable
and the underlying object could be
accessed through pointer dereference
operator or member access operator
it is not a good idea to take all of
these points into one query so we can
search the pattern that occurs in most
situations
supposing the weak ptr is a class member
variable and it is accessed through the
member access operator
so about the code qr part
we first find this find the function
called invoked on the wikipedia object
we match the type name and find all axes
and the next step we want to ensure that
there is no null test before accessing
with pdr
so the code says that
there are not exist any if statement
which is related with pdr
the query gives about
363 results in our testing but many of
them are duplications of the same class
we got three cbd numbers after a quick
analysis and successfully exploited one
of them to escape chrome sandbox in 10th
cup last year
and again i'm going to hand it over to
liquor so for the exploitation part
okay
sex rule i will show the last section
about how to explore one of the weak
pointer back to escape the chrome
sandbox in the tm4 conf 1020
first it's about some payroll knowledges
unlike mojo rtc which security
researchers have been paying attention
to in recent years the vulnerability we
discovered existing latest ipc
in legislative each render process has a
single axis channel implementation go
between themselves and the browser
process
and this is used to send legacy fc
messages between the processes
there are two fundamental tabs or let's
say i've seen messages
control messages defined via ipc message
control micro
and rotate messages different via fc
message rooted micros
we now focus on the control messages
as figure should
control messages generally go between
the run design and the broad side
implementation
cost
all these classes implement exit center
and thus have a sender method for
sending a control message to their
remote counterparts
and they implement i've seen listeners
to receive incoming control messages
where our message received
the bug we used its availability in
browser side implementation so we can
trigger it by sending some run side
legacy fc requests
and another plural knowledge is about pp
api
within uh we need a sender to send the
fc message
but it is very
intricate to create and initialize our
connection to render rce therefore we
leaked rpp instance id and use the ppp
song structure to send ipc call using
the existing
connection
the structure of ub sound is shown in
finger there are global variables in
render process holding the address of
the functions
we can specify a connection to send the
ic message by passing in a
pvp instance id to these functions and
the business id
is only a global map we also
can link its value
putting it together we could flexibly
called the legacy ipc for subsequent
exploit
and about back fire is very competent in
chrome sandbox equal abilities a member
variable capable pointer or a smart
pointer and the row pointer is not
cleaned up after the smart pointer is
destroyed
the draw printer becomes a downloading
pointer and the variability will be
triggered when the pointer gets excised
the root cause of this part is similar
but kind of different the victim pointer
leading to user-free in this block is
worked as a
voice pointer
let's first take a look at the passive
pass or this pointer
the target smart pointer stores in map
resources
and its row pointer could be think about
wrapped as a
weak pointer as the
member variable or paper fail reference
host class another class
for our io host can open this wave
pointer and capability a member variable
named facetime host
after tweaking the course reference of
the map
resources we found that the key of the
map could be passing
from the right side
therefore if your party duplicate pp
resources to previously store the
ticket smart pointer will be destroyed
however it's real printer which is
wrapped as a waypointer is still stored
in fair system host
the user 3 will be triggered when it
gets used
but the type of system post is wake
pointer which means the raw pointer
will be checked whether it is valid
before use
however due to the compiler's
optimization or undefined behavior
mentioned before the check did not
detect effect
and about the exploit
after tracing the cross reference of
system host we found that the function
create file system operation is the
final vertical which we want to use
we at first want to spray blob to
replace the fluid
object with a buffer containing
completely controlled bytes but due to
the visual table call is more in-depth
we now need to construct the structure
to meet the constraints
on this path
and hijack the control flow
on windows if a library is loaded in
multiple processes
it will be at the same basis based
address
so the library loaded in the render
process will be loaded at unknown
address in the browser process
therefore we not only need to leak the
hype address to achieve our
exploit
at the beginning we try to use chat
buffers as my grant
he used the shared buffers between the
render and the browser process to do
have screening
to predict the hyper address but it need
to spread around 4 tb or copies of the
page
and after he proposed this exploit the
chrome team has set the limit on how
shared memory can be mapped in one
process to
32 gb
so maybe we need another way
so we found our compass that we are
seeing the contents of our format member
variable or fair system host to the
render
and we found our class ssl error handler
which has the same size as first system
host and has a higher address at the
outset we can send
we finally destroy the resource hosts
host
by using rust condition
after meeting the constraints and before
seeding the reply
and replace the free space with ssl
error handler
so we send
for hairbase or
hyperdrives to the render process and
change the code by rendering rce to
receive the me the run side
at this point we have the hair four pads
on the hyperdress
so we can predict the hyperdrives by
screening around 8 gb data through the
way macaroons use
it's little than 32 gb
and we
will use the user3 to do the vertical to
power to the stack to the spreading data
and finally achieve
arbitrary code execution
through iop
okay that's all about the exploitation
to escape the chrome sandboxing in team
full cup 2020 now let's watch our simple
demo video
so
ah
okay that's all
and about the conclusion
in this presentation we first briefly
introduced the background or chrome
multi-process architecture and its
interprocess communication system will
describe the significance of where it
analyzed and how it works with good ql
after that we review some classical
bugs and introduce how to generate more
abstract and complex vulnerability
patterns and the locating potential bugs
quickly
also when analyzing the vulnerability
pattern mutation
we introduced three patterns from the
shadow to the deeper
about run frame holes are written and
weak pointer optimization
at last we take a box that we used to
escape the crop sandbox in temple cup
2020 as an example to introduce how we
do the exploit
okay that's all thank you all for
listening and is there any question