How We Hacked a Billion-Dollar Company for Unlimited Snacks

How We Hacked a Billion-Dollar Company for Unlimited Snacks

We were really close to being caught.

Reverse Engineering
Exploit
Security
Free Food

Who can resist free food? I certainly can’t.

As a human being, I deeply love feeding my body, especially when delicious items enter that body without money leaving my bank account. So when a fast-food giant (let's call them ChickenDonald because it is legally safer and comedically superior) launched a new in-app section labeled "Games", my instincts activated instantly.

Suddenly, this wasn’t just a game.
This was spiritual.
This was destiny.
This was “beat the game -> free food.”

Naturally, one thing would lead to another.
Naturally, that “another” would be reverse-engineering their corporate minigame until it begged for mercy.


The Game That Looked Too Simple

After grabbing my order, I opened the game.

It was a smooth, cartoony obstacle-dodging minigame that looked hastily built. Everything about it screamed client-side: no server checks, no real-time validation, nothing that seemed particularly secure.

The game

And I thought:
"What if... instead of playing it normally... we play it creatively?"


Attempt #1: Beating It With AI Because Why Not

My first idea was noble but incredibly stupid:
I spent 36 full hours programming a pixel-perfect clone of the game in PyGame so I could eventually train an AI to master it automatically.

In theory: genius.
In practice: every tiny mismatch (gravity, hitbox size, jump arc, anything) caused the AI to behave like a confused toaster.

I was sleep-deprived, my clone barely worked, and I had learned nothing except that chicken-based flappy games hate me.

So I called my friend Sean.
I showed him the repo.
He listened patiently.

Then he said the sentence that reset my brain:

“Why don’t we just cheat the real game?”

And honestly?
That was the smartest thing anyone had said to me in days.

Goodbye, PyGame clone.
Your service was appreciated but unnecessary.


Discovering the Hidden Web Version

The next morning, Sean sent me a screenshot while I was walking to the gym.

He had intercepted a network request from the ChickenDonald mobile app.
Inside the request was a URL... pointing to a fully playable web version of the game.

The login landing page

This was huge.

If the game ran in a browser, that meant:

  • inspectable source code
  • editable JavaScript
  • viewable network calls
  • full control over every pixel of chicken-related physics

I ran home, opened the URL on my computer, and there it was:
the entire official game, running inside Chrome like a nervous intern waiting to be exploited.


The Login Problem

At the bottom of the game was a “Login” button.

I clicked it.
Nothing happened.

It wasn't broken; it simply expected to be inside the mobile app, where the app would inject a function to perform the login process.
Chrome, tragically, is not a mobile app.

The endpoint failing

But we found something far more interesting while digging through the mess of obfuscated code:

The game checked localStorage (a tiny storage space in your browser) for a bearer token.
If the token existed, BOOM: you were instantly considered logged in.

The code checking for
log-in

The endpoint failing

So all we needed was that token.


Getting Inside the Game

Using request interception on my phone, I captured the exact authentication token the app used when contacting the server.

Then I pasted that token directly into Chrome’s localStorage.

Refreshed the page.

Now we were logged in.
Inside the official game.
Running our own tools.

The logged in game

We could finally see how the score system worked... which meant we could finally break it.


The Score Payload Problem

Our first thought was simple:
“Can we just fake a high score and send it to the server?”

No.
Absolutely not.

The final score submission wasn’t a clean number like { score: 99999 }.
It was an enormous encrypted blob containing:

  • timestamps
  • action histories
  • taps and input actions
  • collected points events
  • damage events
  • a hash of the whole payload

The logged in game

🔍
The payload from an actual score submission.

This meant you couldn’t simply edit the message.
Every field depended on other fields.
If one changed, the entire hash system collapsed.

But here’s the catch:

All those complicated values were being generated on the client.
And if the client is editable... the proof system will happily "prove" whatever reality you create.

We didn’t need to forge a score.
We needed to modify the game so that genuinely playing it produced a ridiculous score.


Diving Into the Obfuscated Code

The real game logic wasn’t in the obvious JavaScript files.
It was buried deep inside a giant, heavily obfuscated script.

So we de-obfuscated it.

Suddenly, it went from unreadable spaghetti to... well, spaghetti you could at least identify the ingredients of.

We searched for:

  • damage calculation
  • health variables
  • collision detection
  • anything that controlled player survival

Eventually, we found the damage handler.

It worked like this:

if (playerHasShield) {
  // ignore damage
} else {
  playerHealth -= someAmount;
}

Perfect.
We simply forced it to always take the “ignore damage” route.

Instant immortality.


Oops: Immortal People Cannot Die

The first time I tested it, I became undefeatable.

I could play forever.
Nothing hurt me.
I was the chicken messiah.

But also:
I couldn’t die, which meant I couldn’t submit a score.

Closing the tab removed my modifications.
Which was... unfortunate.

So I added a new variable:

stopCheating = false

Whenever I wanted to die (to trigger the final score submission), I just opened the console and set:

stopCheating = true

Boom.
Damage turned back on, and the problem was solved.


We Accidentally Snitched on Ourselves

After our very first successful immortal run, I checked the network logs out of paranoia.

Then my stomach dropped.

The game had sent an error log to Sentry, the developer’s error-tracking service, containing one of my modified code lines.

Including the original variable name I had used:

stopCheating

Yes, the app literally told the developers: "Someone added a variable named stopCheating."

Not ideal.

We immediately renamed it to enableDebug, which sounded like a boring leftover from development rather than a confession.

We didn't know if they were going to find us out by this minor mistake, so we also deleted the account to make sure no trace was left.

Crisis somewhat averted.


Building Tools, Because Why Stop Now?

At this point, by the time everything was working, the project had grown into a team trying to earn our free chicken.

We went crazy with the optimizations.

👇
We added a custom UI overlay for toggling cheats

The leaderboard website.

👇

We built a separate website tracking leaderboard movements

The leaderboard
website.

👇

We created a Discord bot to notify us of suspicious accounts cheating up their score

The tracking discord
webhook.

Because at this point, this wasn't just a cheat. It had become a craft, a lifestyle, a chicken-fueled art project that consumed our every waking moment.


The Final Plan

We didn’t want to look suspicious.

So our strategy was:

  • never jump too high in the leaderboard too fast
  • keep our accounts in realistic positions
  • run our big “immortal sessions” near the very end
  • make each run last 1-2 hours so the data looked human

Our strategy was very careful also because we were pretty sure someone else was doing the same thing. Other accounts were behaving similarly to ours, jumping in points and reaching scores that were hardly humanly possible.

We prepared everything: timers, scripts, snacks. This was our Super Bowl, our moment of truth, our digital heist finale.


The Last Hour

The final hour of the contest arrived.

Our long games were already running.

At 5 minutes before closing, we waited with nervous anticipation. At 4 minutes, the tension was building. At 3 minutes, stress began creeping in. At 2 minutes, panic was warming up in the bullpen. At 1 minute, we finally killed our characters.

Everything seemed to go smoothly. All the chrome tabs sent out the submission HTTP request, containing the huge data about the run.

It wasn't immediate. The payload of the request was multiple MBs long, because it contained all of the events of the 3 hours game.

We held our breath.

Then: Error.

They had shut score submissions five minutes early.

Our three-hour immortal runs? Gone. Vanished into the digital ether like they never existed.

The error message.

🎉

Luckily, our sleeper accounts had been slowly climbing for days and still landed safely in prize range.


One Month of Silence

The rules said winners would be contacted within 30 days.

Thirty days passed with radio silence.

We assumed they had caught us. We assumed Sentry had betrayed us. We assumed we were doomed to a life of paying full price for chicken nuggets.

Then, we got a notification. An email from ChickenDonald.

The email.

We had won.

Free chicken for an entire year.

We did it.


The Weekly Ritual

Now, every Sunday, without fail, we gather at the nearest ChickenDonald. We redeem our free chicken, eat like champions, and laugh about the beautiful chaos that brought us here.

The tradition.

At first, we had to explain to the staff why we were legally entitled to free food. Now they know us by sight. They see us walk in, die a little inside, and begin preparing our order almost instinctively.

One manager even asked for a picture with us.

Honestly? It was worth every single line of code we wrote.


Big thanks to my friends who took part in the project!

Toma Mirko Sean
Back

Subscribe to my blogposts

Get updates on my latest projects and articles directly to your inbox.
No spam, unsubscribe anytime.