XML Automated Gambling

by Andy Phillips  (andyphillips99@gmail.com)

Note:  This is not a hack or an exploit as such, just a way of bypassing the entire "front-end" of an industry to see how it behaves in pure data format.  This is for educational purposes only.  Please do not recreate anything in this article.

For those of you out there who are interested in how things work... online casinos are a huge area of interest.  Their systems must be able to provide genuine odds of winning whilst continually ensuring reliable company profits - and remember, obtaining truly random results is in itself a very tricky and interesting field.

This article is a brief story about an observation I made, followed by a series of discoveries, tests, and experiments.  I thought the results would be an interesting read.  Just make sure that you get permission if you do choose to recreate anything described in this article...

Observation

So I was poodling around on some casino flash games on a well known online casino.  You can play these games in demo mode, where the odds are produced in exactly the same way as the live games, but with virtual cash.  You get a virtual balance of £2,000 assigned to you when you start a session - and this will go down until it hits zero, then reset.

I loaded a slot machine game in demo mode, pulled the virtual lever, and watched some nice graphics followed by a winning message.  I had won less virtual money than I had put in.  Woohoo!

Using Google Chrome's "Inspect Element" feature, I clicked on the "Network" panel, which shows all HTTP requests between the browser and the server.  Unlike Firebug (although I love it), Chrome's feature also includes requests made by Flash - which is what we are looking for.

Here's part of the request URL:

/games?random=1330981573957&event=Spin&gameSkin=TikiIsland&numberOfCoins=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1&coinSize=0.1&partnerId=5&autoPlay=false&playMode=GUEST

I then expanded the network request, which was a simple GET request with a query string (although some other online casinos I've checked since use POST).

I pasted the URL request in my browser and was pretty surprised by the result:

<Events>
<ShowGameReferenceEvent gameReference="0"/>
<DisplayReelsEvent>
<Reel id="0">...</Reel>
<Reel id="1">...</Reel>
<Reel id="2">...</Reel>
<Reel id="3">...</Reel>
<Reel id="4">...</Reel>
</DisplayReelsEvent>
<DisplayWinEvent balance="1998.60" coinSize="0.10" grossWin="0.60" netWin="-1.40" wager="2.00">...</DisplayWinEvent>
</Events>

I haven't included the full XML response, but basically it contains all of the game information in cleartext: which symbols should show in each position for each reel, what the balance is, what the gross win is, the wager, and which lines won which amounts of money.

I then realized the deceptive issues with these slot machine games:

1.)  All of the slot machines in this casino use the same API; they just have different graphics, marketing, and jackpots.

2.)  If you reach a bonus round, the bonus rounds are highly deceptive.

Let me just elaborate on that second point...

It was this particular feature (bonus rounds) that really caught my interest, as this is where you can apparently win the jackpot, displayed at the top of the game and constantly increasing into the tens of thousands.

If you reach the end of this round (by apparently choosing the correct items consecutively), you are then confronted with just five boxes to choose from with the jackpot displayed above.  o the odds are presented to you as a one in five chance of winning it, which seems almost feasible because it would take a lot of time and money to actually reach this point.

Needless to say, after choosing a box I didn't win the jackpot, and when I looked at the XML workings of this process I was very surprised.

When you activate a bonus round (which is totally decided on the server side, remember!), the XML response includes a "bonus round" detailed journey of exactly how it's going to play out next.

<Pick type="WIN" value="15" />
<Pick type="WIN" value="45" />
<Pick type="WIN" value="30" />
<Pick type="WIN" value="100" />
<Pick type="RETURN" />

So, when confronted with a choice, I could pick any object and know I was going to win 15 pence, then 45, then 30, and so on - then fail and be returned to the game.

In other words, the "free" multiple choice element was an illusion.  The probability calculation (as far as I can tell) takes place on the server and the game is pre-played for you to eliminate further server calls.  The only issue I have here is that the odds are displayed as one in five or one in three on the UI, but actually could be anything!

Onward To See What We Can Do Next

So, obviously the casinos make massive money by offering appealing graphics, animations, and false representations to make you think you are close to winning big.  But are you?

I decided since I now had a GET request and an infinite balance, perhaps I could automatically play these games in vast numbers and check out the data afterwards.

I thought I would write PHP scripts to record data into MySQL databases to test out scenarios... like what would happen if you buy a thousand £1 scratch cards (overall loss of £350ish, biggest prize was £100) and which gambling techniques work best (too much to write in this article!).

Because the casino in question here wanted to remain anonymous, I've omitted parts of my script that would identify them and replaced it with notes.  An experienced PHP developer would have no problem further developing these scripts to test gambling tactics against games online.  Bear in mind, my example was using GET and not POST.

Script

Here's a quick overview of how this works.

We use Curl requests, specifically so that we can send a cookie (you can also use Curl to POST).  We need to send a cookie, otherwise the demo balance will reset on every move due to a new session.

Then we set up a loop to run for each play, say 1000 plays (whatever you like), build the request, then analyze the XML response, and log or write the data.

<?php
$i = $plays; // number of plays

while($i > 0) {
  $ch = curl_init();

  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($ch, CURLOPT_COOKIE, "***COOKIE DATA GOES HERE***");
  curl_setopt($ch, CURLOPT_URL, "***BUILD URL REQUEST HERE***");

  $xmlData = curl_exec($ch);

  curl_close($ch);

  $xml = simplexml_load_string ($xmlData);

  // Pull results from the XML
  $win = $xml->ShowGambleResultEvent[grossWin];
  $balance = $xml->ShowGambleResultEvent[balance];

  if($win > 0) {
    mysql_query("INSERT INTO results (result, balance, wager) VALUES ('WIN', ".$balance.", ".$wager.")");
  } 
  else {
    mysql_query("INSERT INTO results (result, balance, wager) VALUES ('LOSE', ".$balance.", ".$wager.")");
  }

$i-;

}
?>

Simple, huh?

Make a Curl request, get the response, dismantle the XML, read it, action it.

I'm sure most of the casinos out there return pretty clear XML, and it's easy to take this apart using SimpleXML.

You could even simulate human behavior with random delays and include a user agent definition to further emulate human play.  One could easily adapt this script to play roulette, blackjack, slot machines, or any number of games, and record statistical data or try out computational betting techniques.

If anybody does "beat the casino" using such methods, donations are always welcome.

Return to $2600 Index