Monorail Project: project-zero Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 2 users
Status: Fixed
Owner:
Email to this user bounced
Closed: Aug 2015
Cc:



Sign in to add a comment
Flash: bypass of Vector.<uint> length vs. cookie validation
Reported by cevans@google.com, Jul 15 2015 Back to list
Flash v18.0.0.209 (https://helpx.adobe.com/security/products/flash-player/apsb15-18.html) contains new mitigations to defend against corruptions of Vector.<uint> (and other) lengths.

One of these mitigations, at Vector access time, compares the Vector's in-memory length with a representation of the same length XOR'ed with a secret cookie.

The bypass comes about because the secret cookie value is stored inside a structure, and a pointer to that structure is stored alongside the Vector length. Accordingly, the concept of the attack is to corrupt all of these things in the same header at the same time:

- The length.
- The length XOR'ed with the secret cookie.
- The pointer to the secret cookie.

At first glance, the attack may not sound too potent because it requires forging a pointer value, which generally requires an ASLR defeat. Given that Vector.<uint> corruptions are the common way to defeat ASLR, this introduces a chicken-and-egg problem for the attacker.

However, there are two situations where the attacker can forge a pointer value easily:

1) In 32-bit processes, the attacker can just allocate e.g. a 1GB ByteArray to spray the heap such that a specific address is known; and a repeating pattern can be placed inside the ByteArray so that known content is placed at the known address.

2) The attacker can abuse "User Shared Data", even on 64-bit processes. This is significant because spraying is generally not a good option in 64-bit processes. Taking Win 8.1 x64, all processes have a 1-page read-only mapping at 0x7ffe000, and the content is predicatable enough for our needs.


A specific attack against item 2) above on Win 8.1 x64 is presented. I don't have any good heap overflows handy at the moment, so you can "fake" the attack successfully in the debugger. This applies to Chrome Windows, 64-bit:

1) Run the SprayPoll.swf attached SWF. Wait 10 seconds for the first output.

2) Attach WinDbg and locate the mapping tagged "Heap", and sized 0x0`20000000 (512MB). That's a Vector.<uint> buffer.
.symfix
.reload
!address
-> locate it. Example addr: 0x8e`80008000

3) Bring up the memory view and locate the Vector.<uint> buffer object:
(At 0x8e`80008040):

        0x07ffff83	0x07ffff83	0x8b6fd5d7	0x00000000
	0x86f53000	0x00003d3c	0xf2f2f2f2	0x00000000

0x07ffff83 is the length, followed by the capacity, followed by length XOR cookie, followed by 32-bit 0x0, followed by a 64-bit pointer, followed by 0xf2f2f2f2 (value put inside the Vector).

3) Simulate a linear heap overflow in the debugger.
The challenge as attackers is to pick a sequence of bytes that corrupts this header, without having to know any secrets, and results in a Vector.<uint> object that can access out-of-bounds without trapping at runtime.

We pick this sequence:

        0x07ffff84	0x07ffff84	0x07ffff84	0x00000000
	0x7ffe0000	0x00000000	0xf2f2f2f2	0x00000000

Write that sequence into the memory window and resume the Flash process in the debugger (g).

4) Observe success for the attacker. An out-of-bounds read is demonstrated in the SWF output text.
There is no crash. How does it work?
By pointing the structure that contains the secret cookie into the User Shared Data mapping, we effectively pick a secret cookie value of 0x0. This occurs because the secret cookie offset within the structure is large (0xc68 or so), and User Shared Data is padded with nul bytes at the upper end.
Note that User Shared Data is at a fixed location, which enables the attacker to proceed here without knowing any secrets.
Once the secret cookie is set to 0x0, the length XOR cookie value can simply be set to the same value as the desired fake length. And job done.


Note that this attack, although generic, will only work for a subset of heap overflows: those where the attacker can write arbitrary bytes out-of-bounds, and at least 24 of them, and including the nul byte. This is reasonably common but not 100% of heap overflows. The defense may also hold against other vulnerability classes, such as use-after-free or type confusion, where the attacker may have less control over the corruption of memory content.


How to fix?
The cookie should probably not be fetched via a pointer that the attacker can corrupt. Alternative sources of cookies may include:
- The address of some function inside a DLL, which may provide enough entropy, particularly on 64-bit builds.
- The address of the Vector.<uint> buffer itself. I think this section option may be ok, but please do apply critical thought to the idea in case I haven't had enough caffeine.


This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

 
SprayPoll.as
1.1 KB Download
SprayPoll.swf
1.1 KB Download
Comment 1 by cevans@google.com, Jul 15 2015
Actually, for the "How to fix?" suggestion, maybe a better one is:

- Generate a random cookie value once and store it in a static variable. Thanks James.
Comment 2 by cevans@google.com, Jul 15 2015
Labels: Id-3925
Project Member Comment 3 by natashenka@google.com, Aug 11 2015
Labels: CVE-2015-5125
Status: Fixed
Comment 4 by cevans@google.com, Aug 19 2015
Labels: -Restrict-View-Commit Fixed-2015-Aug-11
Sign in to add a comment