PwnThyBytes
where we ranked #17. Like always, a great CTF with cool challenges. However, because I had some exams that overlapped with the competition I couldn't participate for the entire period of it. During the CTF I tried an interesting challenge which I will try to explain in this blog post. d8
which is running on a server with the purpose of being exploited in order to gain Remote Code Execution
.tctf.diff
) and the d8 executable.tctf.diff
file, we can see that some changes have been made to typed-array-set.tq
such that the check inside the TypedArray.prototype.set
method was removed.
Now what does this mean? In order to explain how this patch affects the security of d8, let's have a look at a simple example: var a = [1,2,3];
Variable a
is a JSArray
. The way v8 handles this internally is by creating a so called Hidden Class
(also known as Map
/ Shape
). This class is shared with all objects that have the same structure / shape.Elements Backing Store
. The Backing Store only stores the values. Attached
. When it loses the refference it is Detached
. JSArray
) and an ArrayBuffer (JSArrayBuffer
)? Typed Array
is and how the security is affected by allowing the user to use .set()
on a detached ArrayBuffer (Use After Free
).%DebugPrint
will not work ) except for %ArrayBufferDetach()
.
new ArrayBuffer(SIZE)
), there are 4 allocations taking place: calloc(SIZE)
for the Data buffer.malloc(48)
for the BackingStoremalloc(32)
for the shared_ptrmalloc(40)
for the ArrayBufferExtension%ArrayBufferDetach()
), the first 3 chunks are freed. heap exploitation
on libc2.27.
fd
and bk
pointers are populated with appropriate addresses.bk
pointer will be overwritten with a libc address..set()
method is still available for detached buffers, we can use it to copy the content of the buffer into an undetached buffer and then print it.libc
is, we automatically know where system()
is located in memory. But how can we invoke it?custom_deleter_
, if we manage to set it, we can invoke a "custom" deleter
.!= 48
. overlaps
with the buffer used by the 3rd Array to store the BackingStore..set()
on detached array, we can basically overwrite
the BackingStore and craft a custom one containing the flag set and the deleter
pointing to system()
.flag{dbc68439ba5f2cdbccf459cd3edb54c80b9c89e9}