Hacking agar.io

If you remember from previous posts on here, I managed to successfully hack the popular agar.io game to remove the advertisements. I thought I would follow-up with some pertinent information about the company Miniclip who makes the game. Please read on, you’ll be glad you did.

Over the months since then, those posts on my site have been quite popular. They’re quite possibly the 3rd-highest content for organic search engine hits here on WordPress for my blog. At some point, I would guess that my posts became known by the game makers themselves at Miniclip who have actually invested time and effort to try to block me from their game.

The first level of pushback from them came when they tried to prevent me from entering my name 👁‍🗨⚙ in the interface by messing with the character kerning between both characters, making it look stupid, basically (something like this 👁‍🗨          ⚙). So of course, I just changed my name to ⚙👁‍🗨 instead and played on.

This worked for some time (a year?) After this and for some unremembered reason, I wanted to temporarily change my name. When I went to change it back, I found that Miniclip now blocked me from entering either character—they actively prevent the use of these two characters in the game simply for the purpose of spiting me!

So I changed my name and played on. But perhaps three days ago, my iPad was bricked. I actually had to stay on the phone with Apple support since it wouldn’t get past the initial registration screen. So I had to restore the iPad and then apply a previous backup. After all that things seemed to be back to normal.

And then I played the agar.io game and it bricked itself during game play. You guessed it: Miniclip has added this evil code to their game for taking out users they don’t like.

From the wiki page on Miniclip:

On 1 September 2005, the United States Computer Emergency Readiness Team issued an advisory concerning Miniclip:

The Retro64 / Miniclip CR64 Loader ActiveX control contains a buffer overflow vulnerability. This may allow a remote, unauthenticated attacker to execute an arbitrary code on a vulnerable system…. Although the ActiveX control is no longer in use by either retro64.com or miniclip.com, any system that has used certain pages of these web sites in the past (prior to September, 2005) may be vulnerable.[7]

In 2006, several security firms reported that some Miniclip users had installed a “miniclipgameloader.dll” which contained the hostile code identified as “Trojan DownLoader 3069”.[8] In the same year, another download related to Miniclip installed “High Risk” malware called “Trojan-Downloader.CR64Loader”.[9]

So Miniclip already has a history of installing malware in their games for the purpose of hacking their users.

I would strongly suggest boycotting Miniclip and uninstalling any of their apps as a result of these findings. I will be reporting them to Apple iTunes as a result of this.

hacking agar.io, part 5

I guess now anyone who’s been following will also want to a chance to play Agar.io without ads. Here are the step-by-step instructions.

Note: Throughout, I’ll use 1.2.3.4 as the IP address of the DNS server you’ll be creating. Assume that every time you see this, you’ll be substituting your own server’s private IP address. Any other IP address you see should be typed in exactly as I’ve shown.

I’ll be including instructions for two different DNS servers. Choose the one that makes more sense for you based upon your experience.

Node.js DNS server version

Since I like JavaScript, here’s a Node.js implementation which may be augmented to include a nice HTML administrative interface if you’d like. I haven’t gotten quite that far yet but you can see what it takes to host a DNS server and a webserver all in one application.

  1. I assume that you already have Node.js installed, as well as npm and the express-generator. If not, you’ll need to install each first.
  2. Open a terminal
  3. Change to your home directory and optionally, change into a subfolder like ~/Sites like I did. Create one if necessary with: mkdir ~/Sites
  4. Run the express command to generate a new project:  express one-trick-pony
  5. If that ran correctly, change into the newly-created folder:  cd one-trick-pony
  6. Run the npm command to install the dependencies:  npm install
  7. Determine the IP address of your server and save this information for later: ifconfig | grep en1
  8. Run the npm command to install dnsd into your project (those are two hyphens without a space between them):  npm install dense –-save
  9. Edit the www file:  vi ./bin/www
    1. After this line var http = require(‘http’); add the indicated text seen in the block quote below
    2. After this line server.on(‘listening’, onListening);, optionally add the line:  console.log(‘Webserver running at *:3000’);
  10. Determine the path of the node command you usually use and save this information for later:  which node
    1. Run the su command to elevate into superuser (root) mode:  su
    2. Change to the working folder from before: cd /Users/yourname/Sites/one-trick-pony
    3. Run the node command giving a full path to the executable, which you found in the earlier step: ../../local/node/bin/node ./bin/www
    4. At this point, you should see that the server is running, indicating that it’s listening to two different ports:  53 (DNS) and 3000 (HTTP).
  11. From a workstation you can verify that the DNS server is running with the indicated command, noting that the server should still be logging requests:  dig @1.2.3.4 www.agar.io
  12. Now from the iPad, for example, go to Settings -> Wi-Fi -> select the i logo next to your connected local wi-fi zone -> DHCP -> DNS -> (write down everything here and save it), overwrite it with 1.2.3.4 (your server’s private IP address)
  13. Press the Home button twice and if Agar.io is running, swipe up to remove it from memory
  14. Start up the Agar.io app and verify that it logs in (even with Facebook), it works AND it no longer displays advertisements.
  15. When you’re finished, in Settings -> Wi-Fi, either “Forget This Network” your existing local wi-fi profile (re-entering your password) or manually re-enter the earlier DNS information that you wrote down from an earlier step.  Your iPad is now ready to behave like before.
  16. When you’re completely finished, go back to the server’s terminal session and press Ctrl-C to end Node and then enter the exit command to leave the su session.

Code to add into the ./bin/www file:

var dnsd = require(‘dnsd’);

function dns_handler(req, res) {
console.log(‘%s:%s/%s %j’,
req.connection.remoteAddress,
req.connection.remotePort,
req.connection.type,
req);

var question =
res.question[0],
hostname = question.name,
length = hostname.length,
ttl = Math.floor(Math.random() * 3600);

if (question.type == ‘A’) {
// Agar.io website
if (hostname == ‘agar.io’ || hostname == ‘www.agar.io’ || hostname == ‘m.agar.io’) {
res.answer.push({name:hostname, type:’A’, data:”104.20.26.122″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”104.20.25.122″, ‘ttl’:ttl});
}
// Facebook.com authentication
if (hostname == ‘facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.69.228″, ‘ttl’:ttl});
}
if (hostname == ‘www.facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.77.36″, ‘ttl’:ttl});
}
if (hostname == ‘graph.facebook.com’) {
res.answer.push({name:hostname, type:’A’, data:”31.13.77.6″, ‘ttl’:ttl});
}
// AmazonAWS
if (hostname == ‘prod-miniclip-v3-881814867.us-west-2.elb.amazonaws.com’) {
res.answer.push({name:hostname, type:’A’, data:”52.42.253.135″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.43.226.3″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.39.93.232″, ‘ttl’:ttl});
}
// Miniclippt.com
if (hostname == ‘mobile-live-v5-0.agario.miniclippt.com’) {
res.answer.push({name:hostname, type:’A’, data:”52.8.170.192″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.9.37.138″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”54.183.177.123″, ‘ttl’:ttl});
res.answer.push({name:hostname, type:’A’, data:”52.52.55.140″, ‘ttl’:ttl});
}
}
res.end();
}

var dnsServer = dnsd.createServer(dns_handler);
dnsServer.zone(‘agar.io’,
‘ns1.agar.io’, ‘root@agar.io’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘facebook.com’,
‘ns1.facebook.com’, ‘root@facebook.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘amazonaws.com’,
‘ns1.amazonaws.com’, ‘root@amazonaws.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.zone(‘miniclippt.com’,
‘ns1.miniclippt.com’, ‘root@miniclippt.com’, ‘now’, ‘2h’, ’30m’, ‘2w’, ’10m’);
dnsServer.listen(53, ‘1.2.3.4’);
console.log(‘DNS server running at 1.2.3.4:53’);

Bind DNS server version

This version will assume that you have a Linux (Ubuntu, in this case) server or workstation that can run the bind9 service.

Here, I assume that you’re comfortable with commands in a terminal, know what sudo does and can use the vi editor to edit and save a file. You know what touch does. If any of these don’t sound familiar, then this probably isn’t the option for you.

On a Linux (Ubuntu) server, do the following:

  1. Make sure that your system is up-to-date:
    1. sudo apt-get update
    2. sudo apt-get upgrade
    3. sudo apt-get dist-upgrade
  2. Install the DNS service, noting that it will take a fair amount of configuration work
    1. sudo apt-get install bind9 bind9utils bind9-doc
  3. cd /etc/bind
  4. Create four empty files, one per “forward” zone. In the next steps you’ll be editing each, making sure to substitute your own server’s private IP address in each case.
    1. sudo touch for.agar.io
    2. sudo touch for.facebook.com
    3. sudo touch for.miniclippt.com
    4. sudo touch for.amazonaws.com
  5. sudo vi for.agar.io
    1. $TTL 86400

      @   IN  SOA     pri.agar.io. root.agar.io. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.agar.io.

      @       IN  A           104.20.25.122

      @       IN  A           104.20.26.122

      pri     IN  A           1.2.3.4

      www     IN  A           104.20.25.122

      www     IN  A           104.20.26.122

      m       IN  A           104.20.25.122

      m       IN  A           104.20.26.122

  6. sudo vi for.facebook.com
    1. $TTL 86400

      @   IN  SOA     pri.facebook.com. root.facebook.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.facebook.com.

      @       IN  A           31.13.69.228

      pri     IN  A           1.2.3.4

      www     IN  A           31.13.77.36

      graph   IN  A           31.13.77.6

  7. sudo vi for.miniclippt.com
    1. $TTL 86400

      @   IN  SOA     pri.miniclippt.com. root.miniclippt.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.miniclippt.com.

      pri     IN  A           1.2.3.4

      mobile-live-v5-0.agario     IN  A   52.52.55.140

      mobile-live-v5-0.agario     IN  A   54.183.177.123

      mobile-live-v5-0.agario     IN  A   52.8.170.192

      mobile-live-v5-0.agario     IN  A   52.9.37.138

  8. sudo vi for.amazonaws.com
    1. $TTL 86400

      @   IN  SOA     pri.amazonaws.com. root.amazonaws.com. (

      2011071001  ;Serial

      3600        ;Refresh

      1800        ;Retry

      604800      ;Expire

      86400       ;Minimum TTL

      )

      @       IN  NS          pri.amazonaws.com.

      pri     IN  A           1.2.3.4

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.42.253.135

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.39.93.232

      prod-miniclip-v3-881814867.us-west-2.elb  IN  A 52.43.226.3

  9. sudo vi named.conf.local
    1. # Append this to the file:

      zone “agar.io” {

      type master;

      file “/etc/bind/for.agar.io”;

      };

      zone “facebook.com” {

      type master;

      file “/etc/bind/for.facebook.com”;

      };

      zone “amazonaws.com” {

      type master;

      file “/etc/bind/for.amazonaws.com”;

      };

      zone “miniclippt.com” {

      type master;

      file “/etc/bind/for.miniclippt.com”;

      };

  10. sudo vi named.conf
    1. # Append this to file:

      logging {

      channel query.log {

      file “/var/log/query.log”;

      severity debug 3;

      };

      category queries { query.log; };

      };

  11. Make sure that the service can read/control its configuration files:
    1. sudo chmod -R 755 /etc/bind
    2. sudo chown -R bind:bind /etc/bind
  12. sudo vi /etc/apparmor.d/usr.sbin.named
    1. # Insert this line inside the “/usr/sbin/named {” section

      /var/log/query.log w,

  13. Create an empty log file, change ownership and make sure that the service can write to it
    1. sudo touch /var/log/query.log
    2. sudo chown bind /var/log/query.log
    3. cat /etc/apparmor.d/usr.sbin.named | sudo apparmor_parser -r
  14. Verify that the configuration files will parse correctly:
    1. sudo named-checkconf /etc/bind/named.conf
    2. sudo named-checkconf /etc/bind/named.conf.local
    3. sudo named-checkzone agar.io /etc/bind/for.agar.io (repeat for other zone files)
  15. Stop/start the DNS service:
    1. sudo systemctl restart bind9
  16. Follow the instructions from step 11 in the Node.js section to verify that the DNS server is running, substituting the IP address of the Ubuntu server.
  17. As before, configure the iPad to use your server’s IP address and test the Agar.io app
  18. You can watch what the app is querying from your server, giving you insight into how many ad servers are actually involved: tail -f /var/log/query.log
  19. When you are completely finished, you may stop the DNS server:  sudo systemctl stop bind9

That’s it. I’ve described how to setup two different DNS servers which should effectively cheat the ads you’d normally see during Agar.io game play.

And now, I think I’ll settle into some uninterrupted Agar.io and all without having to unnecessarily stop the game to shutdown some long-running/buggy ad attempt (losing my earned XP points).

hacking agar.io, part 4!

Eureka! I’ve managed to totally cheat the ads and still play Agar.io on my iPad! Yesh.

For those of you following along, here are the entries that I had to create in my surrogate DNS server:

  • agar.io (with A records @, www and m)
  • facebook.com (with A records @, www and graph)
  • amazonaws.com (with A record prod-miniclip-v3-881814867.us-west-2.elb)
  • miniclippt.com (with A record mobile-live-v5-0.agario)

This allows the game to startup, authenticate via Facebook’s mechanism and to start the game. Gone are the ads in their entirety.

hacking agar.io, part 3

This would be the third post in a series. You might want to read the first in the series if you haven’t already done so. Here, I continue with the work related to rendering the game server’s ads so that they don’t display at all.

DNS server

It struck me that if I could build a relatively-ignorant DNS server of my own and point my iPad to it then I could control which servers my computer talks to. Remove everything but the minimum and this should work for killing the Agar.io advertisements.

So I would need to use nslookup to find the IP addresses of the servers the game talks to. And since I’m authenticating via Facebook’s mechanism I’d need to educate the DNS server to this as well.

I happen to have an Ubuntu server which is under-utilized at the moment since I’m using it to develop WordPress plugins. So I installed bind9 (the DNS service) to this server and then configured it with some entries and zones:

  • agar.io @, www and m
  • facebook.com @ and www

For each of the entries above, I just used the nslookup command to determine what the normal IP address(es) would be and used those values.

The next step would be to make sure that this bind service does not do recursive lookups, in other words, it won’t ask for help if it doesn’t know the zone in question. So in theory, it will only give answers to the entries I’ve made; anything else will fail a lookup.

Next, on the iPad -> Settings -> Wi-fi -> my zone area, I manually set the only DNS server to be the IP address of my private server. I then confirmed that in a browser I could not resolve Google.com but could see the webpage for Agar.io.

Did it work? Not yet. Upon startup it either is missing a critical server it needs to talk to and the app now can’t do the DNS lookup to find that server. It’s okay. I’ll keep hacking away at this to find out what server that is. I should be able to get this approach to work, I just need to go to school on the application some more to find out.