Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recap of recent progress #17

Closed
natevw opened this issue Nov 25, 2013 · 2 comments
Closed

Recap of recent progress #17

natevw opened this issue Nov 25, 2013 · 2 comments

Comments

@natevw
Copy link
Owner

natevw commented Nov 25, 2013

Okay, so here's how I understand #15 works mostly for @kumavis but also adding some followup items I want to check.

According to ES5, even a literal Function Definition follows the algorithm for Creating Function Objects. This algorithm sets the prototype of the new object to "the standard built-in Function prototype object".

This is why I gave up before, but your trick is that as section 15.3 of the spec describes, this "standard built-in" object can still be configured like any other.

The heart of the matter is this line of code:

_gObj.Function.prototype.constructor = evel.Function;

[Note that I’ve simplified it! You were assigning _gObj.Function.constructor.prototype.constructor which is equivalent to _gObj.Function.prototype.constructor.prototype.constructor (since Function.hasOwnProperty('constructor') === false). But Function.prototype.constructor === Function already, which is where the simplified version above comes from.]

So anyway, the way the environment starts out is with (to use V8’s naming) Function.prototype = function Empty() {}. ES5 simply specifies that Function.prototype is a function that accepts any arguments and returns undefined. To quote 15.3.4.1 verbatim: "The initial value of Function.prototype.constructor is the built-in Function constructor." This is what gave us the #12 exploit.

So, the only magic we really have to do is change the constructor value from the initial Function to evel.Function. Assigning _gObj.Function is just taking care of the more obvious access.

We need to assign evel.Function.constructor = evel.Function while setting up the iframe because we have fixed up the iframe context’s Function.prototype.constructor whereas evel.Function still has its original "standard built-in Function" proto from when generated on the main window. (This confused me for a bit: the constructor assignment to self in step 17 of 13.2 happens on the Function.prototype object not the Function.__proto__/Object.getPrototypeOf(Function) one.)

So I think this just might work (great job @kumavis) but I also think there may be some loose ends lying around:

@natevw
Copy link
Owner Author

natevw commented Nov 25, 2013

Yup, confirmed Function.__proto__.constructor("return this")() still gives "[Object Window]"

@natevw
Copy link
Owner Author

natevw commented Nov 25, 2013

Looking through the browser discrepancies in the last item, I'm not seeing anything really interesting. There's a thread discussing some of the issues as well: https://mail.mozilla.org/pipermail/es5-discuss/2009-May/002543.html

So there certainly could be something we're still missing, but I think I'm going to close this and simply reiterate the challenge again :-)

@natevw natevw closed this as completed Nov 25, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant