Count To A Million Challange (JavaScript)
Writeup for the countoamillion challenge posted on r/webdev by u/MobilePanda1
The website: Count To A Million
The challenge: On the website a user needs to enter number in incremental order and reach to 1 Million to get placed on the leaderboard.
- You need to go sequentially, if current number is k, you should only enter k+1, any other value will reset it to 1
- Console is being cleared continuously, so this cannot be used
- Opening devtools will close the whole tab, a nice trick there ;)
- Scripts are obfuscated, so this is not possible to read source code, use the debugger or even make sense from the downloaded script.
- You’re allowed to do scripting / automation to achieve the goal
Part 1: Seeking the APIs
If we can look at the network calls being made we can maybe replay them to automatically increase the counter. Or if we found some way to directly manipulate the number like a payload key or something, that would make it easy.
Here, I used HTTP Toolkit (httptoolkit.com) to intercept the network calls being made.
I found a websocket which was being used for counter updates. No other calls seem to be useful. So, let's try to replay this.
Part 2: Writing script to replay
I wrote a NodeJS script, using the websocket — npm (npmjs.com) package. I copied cookies and header values from the intercepted request and added message payload in the format server expects.
Couple of tries are we’re on baby!!
Phase 3: Automation and stabilization
The initial script would send event using setIntervals and I ran into couple of problems. Let’s see them below
- How to make it like real communication?
The problem with setInterval approach is that if I send another event before server updates the counter, it may result in inconsistency on server side and it’ll end up resetting to 1.
To deal with this, extracted the function to send events to server. I only send event when I receive a message from server. So this is how it goes, first connect -> server replies with msg -> send event with counter++ -> server replies with msg -> repeat
Now it’ll not reset to 1 - But it still did 😞
Upon further debugging, I found that sometimes the socket connection will break from server side and process will close. If the last value I sent was k+1, since server connection broke, on the server side the counter is either still k or updated to k+1.
For me, this is dangerous 50–50 guess, if made wrong, I’ll loose all the progress and have to reset my counter from start.
To deal with this, I parsed the message I get from server, using JSON.parse and got the value from server when I start the script first. Then I send correct value. So, we’re sorted with counter being reset. - Dealing with script crashes
Since a lot of people were running script to win the challenge, it ended up overwhelming the server and connections were being frequently closed. Everytime this happens, I had to manually run the node script again.
So I installed pm2 (npmjs.com), and ran the script via this. Now whenever the server crashes, pm2 will restart this on its own.
So now we’re sorted for the night, so far, my counter is ~23K and rank is 18.
I’ll run this for a day and let’s see how far we go xD.
Script code: count-to-a-million-challenge-script (github.com)
Next challenge
- Even though my script is running continuously, how have other people manage to climb a way ahead (sadly my rank’s slipping)
- Are other people using different tools or languages for faster rank-ups, is JS slow here, or is it some server / network issue?
- How was the feature to devtool detection was implemented by challenge creator?
- Is there any better way to solve this?
Update: The challange is closed now, can’t see my rank but score is about 56k (script is still running xD). As explained by the winner, they determined that server was hosted on DigitalOcean, he managed to determine data center and deployed his script closest to that. Thus, resulting in very low latencies and high score rate.