Tag Archives: trivia crack

Going to Prom with Trivia Crack

Update: As someone on Reddit noticed, you could avoid the need to modify Google Chrome’s start up and still accomplish the below by simply redirecting the request to an HTTP web server that serves the static JSON response, instead of redirecting to a Data URL.  This would mean you have to have a server set up, and the project would have more moving parts, but no modification to browser start up would be needed.

After releasing Trivia Cracker, a Chrome extension that automatically selects the correct answer for you while playing the mega-hit game Trivia Crack, a lot of people had opinions to share. Some were positive, some negative, but one comment in particular caught my eye:

Comment on my blog requesting what would become Trivia Crack Prom

 

An opportunity to help out a young computer scientist, and with his love life nonetheless! It’s not often that the solution to a tough computer science problem could result in not just a great first date, but maybe even wedding bells and kids. Naturally, this piqued my interest — at all levels. The hacker, mentor, and hopeless romantic in me were all hooked. So I responded to the comment and waited to hear back.

My response on the Trivia Crack blog to the request for Trivia Crack Prom

 

To protect my creative high school friend’s privacy, I’ll refer to him as Bob for the remainder of this post. And let’s call the girl Bob wanted to ask to prom Alice. Given the time until prom and Bob’s previous knowledge of web development, we decided that, to make the deadline, I would develop this Trivia Crack wingman-program for him.  But, I did request a few things in return:

  1. If Alice said yes, Bob would email me a photo of the two of them on prom night.
  2. At some point in the future, when Bob feels ready, he should go back and look at the code for this project and make sure he understands how it works. To prove he understands it all, he should modify it to ask a different question with different possible answers.
  3. If Alice and Bob get married, they should name their first born child after me.

Just kidding about that third part.

After we agreed on the terms, it was time to get cracking. To summarize, the goal was to modify Trivia Crack so that Alice could play the game like she normally does, not knowing it was any different, but the question she’d be asked would not be one of trivia, but a prom proposal. From my previous work cracking Trivia Crack, I had a pretty good idea of how the Trivia Crack Facebook client works in its communication with the Trivia Crack server API. Namely, I knew that when a new game is started and after the user answers correctly, the Trivia Crack client requests from the server the next question to ask the user.  The server responds with not just the question, but all the possible answers to the question, as well as the correct answer. Here’s an example of the response body the server sends:

triviacracker6

 

Yes, Trivia Crack is breaking the cardinal rule of “never trust the client” here by sending the correct answer to the client, and I talk more about the consequences of that in my blog post on Trivia Cracker, but for now lets focus on prom night!

Knowing a fair amount about Google Chrome extensions, I knew that Chrome extensions have access to Chrome’s webRequest API. This API provides the ability to redirect outgoing requests from the browser to alternate URLs. I also knew that you can turn a JSON payload into a Data URL using the data:text/json;,{…} format. Together, these functionalities meant that I could, through a Chrome extension, man-in-the-middle the Trivia Crack get next question API response to be any JSON payload I desired. And it just so happened that this was a perfect way to get Trivia Crack to ask Alice to prom. Throwing this together actually only took a few lines of code — almost the entire “response override” functionality of the Chrome extension is below. You can also check out the entire project’s code on GitHub if you’re interested.

Trivia Crack Prom project's code

 

As you can see from the snippet above, all I’m doing is adding a listener for any HTTP requests in Chrome to Trivia Crack’s get next question API. When that listener fires, I am giving Chrome a static JSON payload with the custom prom-related question / answers, as a Data URL, and asking Chrome to redirect the request to this URL instead. Here’s a diagram of the data flow:

Trivia Crack Prom data flow

 

Simple, aye? If you wanted to make things more robust, instead of doing a “static” man-in-the-middle (hard coding the custom response), you could do a dynamic man-in-the-middle — when the listener fires, make your own request to Trivia Crack’s get next question API, modify the question and answer parts of the response you receive, and then redirect to that as a Data URL. Due to Chrome’s webRequest API being synchronous you’ll have to make the AJAX request to Trivia Crack synchronously (SJAX?), and while synchronous AJAX is discouraged, it is possible to do and should be ok in this case considering this all happens on a background thread rather than the main browser thread. But anyway, this was just a quick weekend project, so I hard coded the response. Dijkstra forgive me.

Well, it should have been that easy. But because Trivia Crack uses cross-origin resource sharing (CORS) to make AJAX calls across domains, loading this up in Chrome and trying to overwrite the response resulted in an error:

The request was redirected to ‘data:text/json;,{…}’, which is disallowed for cross-origin requests that require preflight.

To get around this hurdle, since this project only needed to work once rather than be truly ship-able product, I modified Chrome’s start up to run with the –disable-web-security option specified. This flag relaxes some of the requirements of same-origin policy and CORS, allowing the response override to work. You wouldn’t want to keep this flag enabled for your daily use of Chrome, but for a quick prom-proposal, it’ll do…unless your potential date is very computer-security conscious, that is.

What’s scary about this is I wouldn’t have needed the –disable-web-security flag to do this if Trivia Crack wasn’t using CORS. This means any website that doesn’t use CORS can be man-in-the-middled by a Chrome extension, with no changes to Chrome’s start up needed. You may think you’re talking to your bank’s website, when really there’s a Chrome extension modifying your requests and the banking website’s responses, recording all of your sensitive data as it does so. Just another reason to be very careful about which Chrome extensions you trust, and what permissions you trust them with.

But back to the project at hand. At this point, the Chrome extension was all ready to ask Alice to prom. So I sent Bob the bits and the installation instructions. You can see the finished product in the video below:

 

Oh yeah, and you may be wondering if Alice said yes. I’ll let Bob fill you in on that part of the story himself:

She said yes when asked using the Trivia Cracker Prom Chrome extension!

 

And of course, Bob held up his end of the bargain — here’s a picture of the happy couple at prom, thanks to Trivia Crack! (Faces hidden for privacy). Update: Making image much harder to reverse image search. Behave, people…

The happy couple at prom, thanks to Trivia Crack

Still waiting on that first born child though. I’ll check back in a few years…

Interested in hearing about other side projects like this one? Subscribe to my blog and follow me on Twitter. I’ll let you know when I think of something fun.

Cracking Trivia Crack

Update 2: After writing this post, I also discovered another vulnerability in Trivia Crack that allowed for giving users unlimited lives/spins. At that time, I added this as another feature to Trivia Cracker. Yesterday (1/29/2016), Trivia Cracker started preventing this feature (automatic question answering continues to work — as described in this post). But what’s funny is, in addition to preventing it, the Trivia Crack server also calls me out specifically!

Trivia Crack error

 

Update 1: Using similar techniques to the below, I’ve also released a cheating Chrome extension for Candy Crush. Get it here.

 

As the holiday season began a few weeks ago, I started to notice that a new app, Trivia Crack, was becoming popular with my friends.  For those of you who don’t know, Trivia Crack is a new game for Android, iPhone, and Facebook. The premise of the game is simple, and very similar to another popular app from last year, QuizUp. Essentially, you answer trivia questions of various categories, competing against your friends for bragging rights. Despite the simplicity (or maybe due to it), Trivia Crack has become very popular as of late – racking up 5.3 million likes on Facebook and becoming the top free app in the Google Play (Android) store.

You’d think the developers of such a polished and successful game might have taken the time to implement it in a way that is secure from cheating, but it turns out writing a program to cheat at Trivia Crack is actually fairly simple. Over the course of a weekend, I was able to write and release a Chrome extension, Trivia Cracker, that turned me from a medicore-at-best Trivia Crack player to a seemingly genius demigod. You can see Trivia Cracker in action below:

So what’s wrong with Trivia Crack’s implementation that allowed me to so easily build a tool that lets anyone cheat? In short – when the Trivia Crack client requests from the Trivia Crack server the next question to ask the user, the server responds not just with the question and the possible answers, but also sends which answer is the correct answer. The details of the vulnerability, how I found it, and how I built a Chrome extension to take advantage of it are below.

 

1 – Finding the vulnerability

After losing to my friends in Trivia Crack one too many times, I decided I wanted to see if I could win in my own, special way. While I’m not so good at random trivia, I am pretty good at reverse-engineering. I suspected I might be able to take advantage of sending my own requests to Trivia Crack’s servers, or using some data in the responses from Trivia Crack’s servers, to gain an edge in the game. So I started by researching what kinds of data the Trivia Crack client and server pass back and forth.

To inspect this data, I played Trivia Crack in my browser on Facebook, while recording and inspecting the requests and responses sent between Trivia Crack’s client and server using a tool I’d created previously called Gargl. Yes, I know I could have used Fiddler or Chrome’s Developer Tools to do the same. I decided to use Gargl instead because in addition to letting you view client/server requests/responses, Gargl also lets you modify and parameterize these requests, and then auto-generates modules in a programming language of your choice so you can make these same requests without writing a line of code. More on that later.

Anyway, after telling Gargl to start recording and going to Trivia Crack on Facebook in my browser, the first step was to figure out which of the many requests being sent on this Facebook page were related to Trivia Crack, versus Facebook itself. Inspecting the HTML on the page showed that the Trivia Crack content is embedded into Facebook via an iframe. The element right above this iframe was a form meant to post to a peculiar URL- https://preguntados.com/game.

Using Chrome Dev Tools to inspect Trivia Crack's HTML

My limited knowledge of Spanish reminded me that “pregunta” means “question,” which seems related to trivia, so I suspected this was the domain where Trivia Crack is hosted. Going to the https://preguntados.com/game URL confirmed that suspicion:

Playing Trivia Crack on Preguntados.com

The next step was just to start playing Trivia Crack, and as I played look at the requests Gargl finds that the page is making to any url containing “preguntados.com”:

Using Gargl to record actions in Trivia Crack

As I answered Trivia Crack questions, I noticed a new request seemed to be issued for each question. Actually, the request seemed to be issued before I even “spun the spinner” in Trivia Crack to determine what category the next question would be:

Using Gargl to record actions in Trivia Crack

This made me think maybe the questions were predetermined, and the “random spinner” in fact was predetermined to land on a certain category (and ask a certain question) based on the response from the server to the “api.preguntados.com/api/users/<userID>/games/<gameID>” request that sent before you click the “Spin” button. To me, this meant I could probably alert the user to the question they are about to be asked ahead of time, so they would have as much time as they wanted to think about it or look it up. This would be an advantage because in Trivia Crack, you only get 30 seconds to answer a question once the question is shown, to prevent the user from looking up answers. In addition, in some game modes its not just the number of questions you get correct, but also the amount of time you take to answer, that determines if you win. If I could show the user the question ahead of time, they could obviously answer it much more quickly once Trivia Crack itself shows the question.

So I figured I had a lead and dug into the details of this request. It turns out this request actually provided a much larger “cheater’s advantage” than I thought…

 

2 – The vulnerability in detail

Using Gargl to look at the “api.preguntados.com/api/users/<userID>/games/<gameID>” request/response in detail, I was able to confirm that it does indeed provide the question to be asked, as well as the possible answers, in the response. However, I was surprised to find that the correct answer to the question is also embedded in the response!

Using Gargl to record actions in Trivia Crack - the response vulnerability

As you can see above, the response to this request contains the question, the possible answers, and which index in the array of possible answers is the correct answer. So if this data is indeed about the next question, after I click “Spin,” I should be asked “Which of the following African countries doesn’t have a coast?” and the correct answer should be answers[3] from above, which is “All of them do”. Clicking “Spin” proved this hypothesis correct:

Playing Trivia Crack, before selecting an answer

Playing Trivia Crack, selecting the correct answer

I also used my browser to find that repeated GET requests to “api.preguntados.com/api/users/<userID>/games/<gameID>” always give the same response, until you answer the question it provides. This means I could request this URL from my own tool and still receive the same question as the Trivia Crack client on Facebook would receive.

A response containing the correct answer, when the goal is that the user must determine the answer themselves, is in direct conflict with the “Defensive Programming” practice of programming – particularly the “never trust the client” web programming principle. Since the server has no control over how the client acts, it can’t assume the client will not act in a malicious way, and so must protect itself. The correct way of implementing answer checking behavior is to do it on the server side. Don’t send the correct answer to the client at any point, and instead make the client send the user’s answer to the server, where the server will then check it for correctness and credit the user if correct (and of course, only allow one answer to be sent per user per question).

However, Trivia Crack did not do this, and instead trusts the client. Now it was just a matter of creating a malicious client to take advantage of the fact that the correct answer is sent in the response. Ideally, one that would be easy for non-technical users to install and use. Hmm…how about a Chrome extension that just adds a button to the Trivia Crack game, when played on Facebook, that when clicked answers the current question correctly automatically??

 

3 – Taking advantage of the vulnerability

As I mentioned above, Gargl allows you to take the requests you had it record, modify and parameterize them as needed, and then auto-generate modules in a programming language of your choice to make these same requests. I’m not going to go into the details of that process since you can look at one of my Gargl blog posts to find that info, but essentially I generated a Gargl template file for Trivia Crack‘s various API requests, using the Gargl Chrome extension, and then used a Gargl generator to turn that template file into a Trivia Crack JavaScript library. Using Gargl for this allowed me to create a JavaScript library that talks to Trivia Crack’s servers, without writing a line of code to do so, and also have a template file around for the future in case I want to do the same thing later for another programming language.

Once I had this Trivia Crack JavaScript library, it was a simple matter of building a Chrome extension in JavaScript that runs on the domain loaded in the Trivia Crack Facebook game page iframe (preguntados.com), adds a button to the HTML for the game, and when that button is clicked requests the “api.preguntados.com/api/users/<userID>/games/<gameID>” URL, parses the response for the correct answer, and then clicks the answer button on the page representing the correct answer.

Trivia Cracker running on Trivia Crack to answer questions for me

And just like that, Trivia Cracker was born! Curious about the exact details of how Trivia Cracker works? Check out the source code on GitHub.

Interested in hearing about other side projects like this one? Subscribe to my blog and follow me on Twitter. I’ll let you know when I think of something fun.