This is essentially an AV exploit against Super Mario World that results in running the end game code. Watch the video. “…there’s a glitch that’s been known for a while, where Yoshi can end up in
the “I have an item in my mouth” state, but not actually have an item in his mouth. When he spits out this nothingness, the game crashes. …That address did not contain code, and so the system
crashed. But wait a second. What if, by some sheer coincidence, that address did contain code? The specific address dropped him in somewhere amongst various data for the game’s internal random
number generator, and the random number generator can be manipulated in a TAS. Could the game be coerced into running arbitrary code?…”
The first independent film to gross more than $200 million, Pulp Fiction was a shot of adrenaline to Hollywood’s heart, reviving John Travolta’s career, making stars of Samuel L. Jackson and
Uma Thurman, and turning Bob and Harvey Weinstein into giants. How did Quentin Tarantino, a high-school dropout and former video-store clerk, change the face of modern cinema? Mark Seal takes
the director, his producers, and his cast back in time, to 1993.
Not The Onion subreddit is for real stories that sound like The Onion articles. This is a compilation of those stories into a page that looks like The Onion.
In JavaScript numbers are 64bit floating point numbers which have 53 bits of mantissa. That means you can accurately represent [-2^53, 2^53] as integers in JavaScript. Aka [-9007199254740992,
9007199254740992].
Level 8 of the Stripe CTF is a password server that returns success: true if and only if the password provided matches the password stored directly via
a RESTful API and optionally indirectly via a callback URI. The solution is side channel attack like a timing attack but with ports instead of time.
(I found this in my drafts folder and had intended to post a while ago.)
Code
def nextServerCallback(self, data): parsed_data = json.loads(data) # Chunk was wrong! if not parsed_data['success']: # Defend against timing attacks remaining_time = self.expectedRemainingTime() self.log_info('Going to wait %s seconds before responding' % remaining_time) reactor.callLater(remaining_time, self.sendResult, False) return
self.checkNext()
Issue
The password server breaks the target password into four pieces and stores each on a different server. When a password request is sent to the main server it makes requests to the sub-servers
for each part of the password request. It does this in series and if any part fails, then it stops midway through. Password requests may also be made with corresponding URI callbacks and after the
server decides on the password makes an HTTP request on the provided URI callbacks saying if the password was success: true or false.
A timing attack looks at how long it took for a password to be rejected and longer times could mean a longer prefix of the password was correct allowing for a directed brute force attack. Timing
attacks are prevented in this case by code on the password server that attempts to wait the same amount of time, even if the first sub-server responds with false. However, the server uses
sequential outgoing port numbers shared between the requests to the sub-servers and the callback URIs. Accordingly, we can examine the port numbers on our callback URIs to direct a brute force
attack.
If the password provided is totally incorrect then the password server will contact one sub-server and then your callback URI. So if you see the remote server's port number go up by two when
requesting your callback URI, you know the password is totally incorrect. If by three then you know the first fourth of the password is correct and the rest is incorrect. If by four then two
fourths of the password is correct. If by five then four sub-servers were contacted so you need to rely on the actual content of the callback URI request of 'success: true' or 'false' since you
can't tell from the port change if the password was totally correct or not.
The trick in the real world is false positives. The port numbers are sequential over the system, so if the password server is the only thing making outgoing requests then its port numbers will also
be sequential, however other things on the system can interrupt this. This means that the password server could contact three sub-servers and normally you'd see the port number increase by four,
but really it could increase by four or more because of other things running on the system. To counteract this I ran in cycles: brute forcing the first fourth of the password and removing any entry
that gets a two port increase and keeping all others. Eventually I could remove all but the correct first fourth of the password. And so on for the next parts of the password.
I wrote my app to brute force this in Python. This was my first time writing Python code so it is not pretty.
Last time I had to do this there was a service named dynamicdns.org which seems to still exist but no longer appears to be free. Instead I used dnsdynamic.org which is free and has a web API
as well as links to and instructions for setting up native tools to dynamically update my IP address.