Closed Bug 1346963 Opened 3 years ago Closed 3 years ago

WL: stackup.0 investigation

Categories

(mozilla.org :: Security Assurance, task)

task
Not set

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 983344

People

(Reporter: dveditz, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(3 files)

Attached file main.js
Wikileaks sent us three javascript files in a directory called "stackup.0". They are devoid of web page context so it's hard to know exactly how they were used. In particular there is heavy use of an "epf" object that seems to be defined elsewhere. Hopefully that stuff is part of an exploit framework (Exploit P.... Framework?) and the files we have at least show the vulnerability.
Attached file vuln.CopyFromArray.js
Attached file worker.js
The meat is in vuln.CopyFromArray and it's well documented. There may be multiple bugs in there. Things I wouldn't want them to be able to do:

"Creates a MemoryView object that gives us full read and write access to the address space of the process"

   // Overwrite the 16 or 32 most significant bits of the second element
   // in the replacement array to change its type to a string.

Note that the Wikileaks dump might be old. Devoid of the messaging context we don't know what versions this exploit targeted or how long ago this was developed. Back in Firefox 18 sfink fixed a copyFromArray() issue in bug 797128.
The apparent meat, going to a decent degree off comments (but also with knowledge of the fixes we've done to typed array/array buffer smelliness as guide), is:

    // Trigger the vulnerability. On 32-bit systems, we overwrite the 32
    // most significant bits of the second element in the replacement array
    // to change its type from a double to an string. On 64-bit systems we
    // overwrite only the 16 most significant bits, because the fake string
    // pointers takes up the low 47 bits.

    if (epf.target.x64 === false)
            uint32Array.set(secondOverwriteArray, (16-4)/4); 
    else
            uint16Array.set(secondOverwriteArray, (16-2)/2);

where |secondOverwriteArray| is an array with a getter function on element 0, which itself does

    uint16Array.set(firstOverwriteArray, (8-2)/2);

where |firstOverwriteArray| is *another* array with a getter function on element 0, which does

    _self.postMessage([epf.vuln.CopyFromArray.PARENT_ARRAY_BUFFER], [ arrayBuffer ]);

within it.

That looks extraordinarily like an invocation of the problem that existed before bug 983344 was fixed.  |postMessage| will detach the relevant ArrayBuffer, there's a complicated dance to have the relevant getters return magical constants of special import to the JS engine, the JS engine considers the ArrayBuffer GC'd once references drop eventually, stuff is allocated in its place, overwrites using those magic constants happen.  IMO.

If the above is reality, this was fixed in Firefox 28-30ish, according to bug 983344's version data.  So, um, woo?  pwn2own told us about a zero-day and let us fix it, but that vulnerability was being actively exploited (if the bits at the end of vuln.CopyFromArray.js are accurate) in Firefox [18, 28), i.e. the full length of time that we implemented ArrayBuffer detaching (previously known as neutering) and hadn't yet fixed bug 983344.

Since I was asked to "take a look" at this and "figure out who should be CC'd", and I think I've covered the first half, let's scrounge around for someone with some familiarity with the above to agree or disagree with me.  And the Fickle Finger of Fate points at sFink!
Flags: needinfo?(sphink)
Yes. I've read through all of the 3 files, and it looks like a clear exploit of the ArrayBuffer detaching bug. The code is remarkably clear and well-commented; I wish our own code was up to its standard more often!

Although this exploit doesn't use it, bug 982974 was a very similar sort of flaw, but fixed in the same timeframe.
Flags: needinfo?(sphink)
(In reply to Steve Fink [:sfink] [:s:] from comment #5)
> Although this exploit doesn't use it, bug 982974 was a very similar sort of
> flaw, but fixed in the same timeframe.

bug 982974 and bug 983344 were both 2014 Pwn2Own exploits.
Group: infrasec
Status: NEW → RESOLVED
Closed: 3 years ago
Component: Security Assurance → JavaScript Engine
Product: mozilla.org → Core
Resolution: --- → DUPLICATE
Version: other → 18 Branch
Duplicate of bug: CVE-2014-1514
Group: infrasec
Component: JavaScript Engine → Security Assurance
Product: Core → mozilla.org
Version: 18 Branch → other
Blocks: 1349845
Group: mozilla-employee-confidential, core-security, infrasec
You need to log in before you can comment on or make changes to this bug.