Sunday, November 17, 2024

SANS: Holiday Hack 2024: Act 1: Hardware Hacking 2

 This is another Terminal near Jewel Loggins.

Hardware Hacking 2

Silver Medal

This one isn't as page source involved as Hardware Hacking 1.

The Terminal shows a boot screen.  It's possible to get both silver and gold without interacting with option 2 U-Boot Console.

After booting into option 1, Startup System (Default), There's a message of the day (motd) that shows the instructions for an executable called SLH (Santa's Little Helper).  Jewel Loggins gives hints that says the goal is to add an access of 1 for the card with the id of 42.  He states that you'll need a password to do so and hints that passwords may be in plain sight.  Pressing the up arrow when first logging into commands shows commands that the player didn't type.  There's a file in the home directory of users that saves the bash history called .bash_history.  It's hidden, so to see it, ls -la must be done.  Either pressing up arrow enough, or cat .bash_history, will show a command that simply needs to be manipulated to get the Silver Medal.

Command in Bash History:

slh --passcode CandyCaneCrunch77 --set-access 1 --id 143

Manipulate it to the following to get the Silver Medal:

slh --passcode CandyCaneCrunch77 --set-access 1 --id 42

Gold Medal

Jewel Loggins hints that to get the Gold Medal, the db needs to be manipulated directory instead of using slh.  If ls -la is typed to see the bash history, players will notice another file called access_cards.  Running file -i on that file shows that it is a sqlite3 database.  Looking in /bin or /usr/bin, or simply knowing sqlite3 exists in many distributions of Linux, players will find that they can view and manipulate the db with this application.

sqlite3 access_cards
.tables
Looking at the tables shows the following tables in the access_cards db.
    access_cards config
pragma table_info(access_cards)
# access_cards table columns:
    id uuid access sid
pragma table_info(config)
#config table columns
   id config_key config_value
select * from config;
# the second entry in the config table has an hmac_secret and has a value of 9ed1515819dec61fd361d5fdabb57f41ecce1a5fe1fe263b98c0d6943b9b232e
#The SHA256 hash seems to be the word pizza, but the hash is the key itself, not pizza
# the third entry in the config table has an hmac_message_format with a value of {access}{uuid}
select id,uuid,access,sig from access_cards where id=42;
#id|uuid|access|sig
42|c06018b6-5e80-4395-ab71-ae5124560189|0|ecb9de15a057305e5887502d46d434c9394f5ed7ef1a51d2930ad786b02f6ffd

Jewel Loggins also hints that an hmac needs to be created and gives a hint that cyberchef can be used to create an hmac signature.
The hmac_secret is called a key in Cyberchef.  The key encoding should be UTF8.  The hashing function should be SHA256.  The key/secret itself gives a clue to the hashing type because its length is 64 characters (letters/numbers).  Looking this up gives more than one type of hash possibility, however, hmac in Cyberchef is limited to relatively few options, so finding the correct one isn't that bad.

The db gives the format of the input.  The access that is needed is 1.  Then the uuid of the card with an id of 42 should be appended to that.  The input should look like this:

1c06018b6-5e80-4395-ab71-ae5124560189

Make sure there are no spaces in the key or input in Cyberchef because a space can drastically change the hash.

The correct hash is: 

135a32d5026c5628b1753e6c67015c0f04e26051ef7391c2552de2816b1b7096



Next, the database needs to be manipulated.  In the Hardware Hacking 2 Terminal:

#If the player logged out of the Terminal
Select Option 1 Startup System Default Boot again
sqlite3 access_cards
update access_cards set access=1, sig="135a32d5026c5628b1753e6c67015c0f04e26051ef7391c2552de2816b1b7096" where id=42;

An Access Granted message should appear and the player should be awarded the Gold Medal.  Sometimes it takes a moment to appear because there's a script running that checks the signature change, and it takes time for it to run again.


SANS: Holiday Hack 2024: Act 1: Unshredding Shredded Document & Hardware Hacking 1

The next part is important for the next terminal, Hardware Hacking 1.

Unshredding Shredded Document

Talk to Morcel again after completing the Frosty Keypad.  Click on the green icon in the dock again.  There will be a bag of shredded paper.  In the badge, under hints, Morcel also gives a clue how to piece the shredded pieces back together.  It's a python script.

Most Linux distributions already have python or python3 or both installed.  Sometimes numpy is not included.  In my case, I had to install both pip3 and numpy.  Open a Terminal.

sudo apt install python3-pip
pip3 install numpy
unzip shreds.zip

Note, the new folder after shreds is unzipped is called "slices".

python3 heuristic_edge_detection.py slices

Once that is done, an assembled image pops out.



That looks kind of weird.

Looks like each of the images: The left side image and the right-side image needs to be flipped horizontally individually and connected back together.

I couldn't read every single character, but having dealt with serial communications before, I had an idea.

BAUD: 115200
PARITY: even
DATA: 7 BITS
STOP BITS: 1 BIT
FLOW CONTROL: RTS

Even if that is not known, in the Hardware Hacking 1 challenge, powering on the device and looking at the settings can assist with figuring this out.

Alternatively, print it out, cut it and tape it back together, or use your favorite photo editing software like GIMP to fix it.  I left STOPPITS in the image below because it looks like what was reassembled by the python script. 😁.  It is supposed to be STOP BITS.



Hardware Hacking Part 1:

This Terminal is near Jewel Loggins.

Silver Medal:

This can be done by trial and error, however, looking in the source code for the site is another valid solution, as well as understanding why each cable is a different color, and how to properly wire it, and the correct voltage to use.

Search and Learn Method:


The voltage matters.  In this case 3V are needed, so the tiny switch needs to be switched from 5 V to 3 V.  If this isn't correct, a pretty puff of blue smoke comes out of the device. Thankfully if the voltage is switched, it's fine.  This is hard to see, but in the manual that is shown to begin with, it has a picture with 3V.  This is how this is known.  The voltage is at 5V by default, so the tiny orange button needs to be clicked on the bridge at the bottom.  It's difficult to see but matches what is in the manual.

Identifying the wires by Googling may not be easy. Each of the cables have positive and negative charges.  If they're wired wrong, they can fry the board.  The game seems to start from a new state when the Terminal is opened again, so this can be brute-forced without much penalty that I'm aware of.  Santa's magic, I guess.  Don't know if there's a penalty on the scoreboard - have no idea how that functions in the background.

The device is on the left side - the bridge is on the bottom right side.  The PDA is at the top right side.

An important fact to remember is that the post for transmitting (TX) on the device is cabled to the receiving (RX) post of the bridge.  This also means that the post for receiving (RX) on the device is cabled to the transmitting (TX) post of the bridge.  That means the cables are crossed.  For the voltage (VCC) and ground (GND), the voltage post on the device goes to the voltage post of the bridge.  The ground post on the device goes to the ground post on the bridge.

For each of these, the left side of the cable goes to the device post.  The right side of the cable goes to the bridge post.  

The red cable is for the voltage (VCC).
The orange cable is for transmitting (TX).
The green cable is for receiving (RX)
The black cable is for the ground (GND).

It didn't seem to matter if the black and red cables were switched - ie black for voltage and red for ground.  Note: not crossed, I mean using one cable instead of the other.  A chart for usb I found by doing a Google-search notes the above though.  This could be different for different cables and pinouts.  It's best to consult documentation regarding the specific cables and devices being used.

Connect the wires.

The USB needs to be plugged into the bridge by clicking on the USB.

Make sure the V on the bride is set to 3V (The tiny orange square will be on the right-side of the tiny white rectangle with either 5V or 3V in it.)

Next click the power button (P) on the device.  Settings can be selected by clicking the up/down arrow buttons on screen.  To change the settings, click the left or right arrow buttons on screen.  Modify them according to the settings in the reassembled shreds.

BAUD: 115200
PARITY: even
DATA: 7 BITS
STOP BITS: 1 BIT
FLOW CONTROL: RTS

Click the Serial button (S) to start a serial connection.  Silver Medal awarded.

Source Code Method:


The colors for the cables and where they correspond to are defined in the connectPins() Method:

    const targetPins = [
      { pin: this.children.getByName('gnd'), dest: this.children.getByName('uGnd'), color: 0x000000 },
      { pin: this.children.getByName('tx'), dest: this.children.getByName('uRx'), color: 0x1bff00 },
      { pin: this.children.getByName('rx'), dest: this.children.getByName('uTx'), color: 0xff8700 },
      { pin: this.children.getByName('v3'), dest: this.children.getByName('uVcc'), color: 0xff0000 }
    ];

VCC = 0xff0000 = red
GND = 0x00000 = black
RX = 0x1bff00 = lime green
TX = 0xff8700 = dark orange

In that same method - connectPins(), there is a loop checking to see if the wires are wired.

    targetPins.forEach((targetPin) => {
      let connectionFound = false;

      jumperWires.forEach((wire) => {
        if (
          wire.female &&
          Phaser.Geom.Intersects.RectangleToRectangle(wire.female.getBounds(), targetPin.dest.getBounds()) &&
          wire.male &&
          Phaser.Geom.Intersects.RectangleToRectangle(wire.male.getBounds(), targetPin.pin.getBounds())
        ) {
          console.log(`Connected ${targetPin.pin.name} (${targetPin.dest.name}) with ${wire.female.name} and ${wire.male.name}`);
          allPinnedUp++;
          connectionFound = true;
          // You can add more logic here for when the connection is made
        }
      });

      if (!connectionFound) {
        console.warn(`No connection found for ${targetPin.pin.name} (${targetPin.dest.name})`);
      }
    });

When the pins are correct it states "All pinned up in the console."

    if (allPinnedUp === targetPins.length) {
      console.log("All pinned up!");
      this.allConnectedUp = true;
    } else {
      this.allConnectedUp = false;
    }
  }

Now we know how to tell if the wires are correctly wired.  We know the colors.  The left side part of the wire goes to the device, and the right side of the wire goes to the bridge.  Once the console says "All pinned up!" we know the wires are ready to go.

In a method called checkConditions(), there are voltage checks.

We can tell 5 volts is incorrect, because if it's 5 volts, all the pins are connected, and the usb has been moved, there is smoke coming out of the device, which is not preferable.  That smell of ozone is very memorable if you've ever fried a board in real life.

      if (this.uV === 5 && this.allConnectedUp && !this.usbIsAtOriginalPosition) {
        const smoked = this.children.getByName('smoked');
        smoked.start();
        this.playAudioForDuration(this.smokey, 3000);
        this.time.delayedCall(3000, () => smoked.stop(), [], this);
      }

If it's 3 volts, there is a check to see if all the serial connection settings are correct.  Then it brings up the serial connection and states to talk to Jewel Loggins.  This is the condition necessary to reach for the silver medal.

    if (this.uV === 3 && this.allConnectedUp && !this.usbIsAtOriginalPosition || this.dev) {
      // console.log("PARTY TIME");
      let checkIt = await checkit([this.currentPortIndex, this.currentBaudIndex, this.currentParityIndex, this.currentDataIndex, this.currentStopBitsIndex, this.currentFlowControlIndex], this.uV)
      if (checkIt) {
        this.popup("success! loading bootloader...\nGo speak with Jewel Loggins for the next step!");
        this.yippee.play();
      } else {
        this.merp.play();
        this.popup("Serial connection couldn't be established...\nPlease check your settings and try again.");
      }

Looking through the code, the settings for the console connection (USB), baud rate, parity, data, stop bites, and flow control index don't seem to be in the code.  It shows the potential settings, but not which ones are correct.  Could be I missed them?

Under the function showHelpScreen(), the settings for the PDA are set (the device on the top right-hand side that does the serial connection.

    const baudRates = [300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200];
    const dataBits = [5, 6, 7, 8];
    const parityOptions = ["None", "odd", "even"];
    const stopBits = [1, 2];
    const flowControlOptions = ["None", "RTS/CTS", "Xon/Xoff", "RTS"];
    const ports = ["COM1", "COM2", "COM3", "USB0"];

Seems like the information is sent to https://hhc24-hardwarehacking.holidayhackchallenge.com/api/v2/complete according to the checkIt() function.  So it looks like it's checked server-side.  This can still be brute forced by trying options though or finding the shredded papers and unscrambling them.

Note something interesting in that checkConditions() function.  (If(Voltage=3, all the wires are connected, and usb is moved from its original condition) OR (this.dev)).  When something is by itself like that without a condition, it means OR this.dev must be true.  What's dev?  Where is it?

At the beginning of the code it states:

this.dev = false;

What happens if that's changed to true?

this.dev = true

And uncomment the PARTY TIME line in the checkConditions() function.

Press the P button (for power).  Pressing the P button, it powers on without the usb being plugged in, and without a Voltage.

It seems to get past the first check, as evidenced the PARTY TIME being shown in the console, however, the settings have to be set to pass the next check to pop the serial connection.

Change if(checkit) to if(!checkit)

Press S (for serial).  Success!  It doesn't give gold though because this is an unintended solution. :(  Not sure if it works for silver.  I didn't test.

Gold Medal

The key to this one is the dev=true and checkIt() function found earlier.

this.dev earlier in the code needs to be set to true to bypass the first if statement in the checkConditions() function.

The following is the checkIt() function.

async function checkit(serial, uV) {
  // Retrieve the request ID from the URL query parameters
  const requestID = getResourceID(); // Replace 'paramName' with the actual parameter name you want to retrieve

  if (!requestID) {
    requestID = "00000000-0000-0000-0000-000000000000";
  }

  // Build the URL with the request ID as a query parameter
  // Word on the wire is that some resourceful elves managed to brute-force their way in through the v1 API.
  // We have since updated the API to v2 and v1 "should" be removed by now.
  // const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v1/complete`);
  const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v2/complete`);

  try {
    // Make the request to the server
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ requestID: requestID, serial: serial, voltage: uV })
    });

    // Check if the request was successful
    if (!response.ok) {
      throw new Error('Network response was not ok: ' + response.statusText);
    }

    const data = await response.json();
    console.log("Data", data)
    // Return true if the response is true
    return data === true;
  } catch (error) {
    console.error('There has been a problem with your fetch operation:', error);
    return false;
  }
}

Notice there's a commented line about changing from v1 to v2 in the checkIt() function because some resourceful elves brute forced their way through v1 and that v1 SHOULD not be active now?

uncomment v1 by removing the // near  // const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v1/complete`);

Add a comment for v2.  By placing // next to  const url = new URL(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/v2/complete`);

The try block under the checkIt() function is just looking for the requestID, serial, and voltage.

The game should get the requestID when you load the Terminal in Holiday Hack 2024.  The serial is an array containing [3,9,2,2,0,3]. and the voltage should be 3.  These settings can be seen in the Network tab in Chrome if the silver medal is done near the same time as the gold medal.  I think it's possible the requestID changes over time - like it times out.  I don't know for sure.  The serial and voltage will be the same at least.

The checkIt() function is called by the checkConditions() function.  checkIt() is passed the following values according to the checkconditions() function:

checkit([this.currentPortIndex, this.currentBaudIndex, this.currentParityIndex, this.currentDataIndex, this.currentStopBitsIndex, this.currentFlowControlIndex], this.uV)

None of these values matter because we are going to manually adjust them in the checkIt() function.

All of those, except for the voltage are settings for the serial connection.  They should look familiar: Port for Serial Port, Baud, Parity, Data, Stop Bits, and Flow Control.  When it's passed in, those settings are renamed to "serial" and placed in an array.  If the serial value passed in is confusing it soon won't be.  

Under the function showHelpScreen(), the settings for the PDA are set (the device on the top right-hand side that does the serial connection.

    const baudRates = [300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200];
    const dataBits = [5, 6, 7, 8];
    const parityOptions = ["None", "odd", "even"];
    const stopBits = [1, 2];
    const flowControlOptions = ["None", "RTS/CTS", "Xon/Xoff", "RTS"];
    const ports = ["COM1", "COM2", "COM3", "USB0"];

The first number (3) is the serial port index.  Remember computers count from 0.  The options are COM1, COM2, COM3, and USB0.  COM1=0, COM2=1, COM3=2, and USB0=3.  The next number is the BAUD.  Position 9 matches with the 115200 setting it needs to be.  The next option is the PARITY.  Position 2 is even.  The next setting passed is the DATA.  Position 2 is 7.  The next option passed is the STOP BITS.  Position 0 is 1.  The last option passed is the flow Control.  Position 3 is RTS.

The voltage is set to 3 like it says in the source code.  Knowing this info, a POST request can be sent to https://hhc24-hardwarehacking.holidayhackchallenge.com/api/v1/complete with the json formatted data after the v1 line is changed so that it is not commented, and the v2 line is commented out as described above.

The data looks like this in json:

{"requestID":"YOUR ID","serial":[3,9,2,2,0,3],"voltage":3}

This can be changed in the checkIt() function in the try block:

  try {
    // Make the request to the server
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ requestID: requestID, serial: serial, voltage: uV })
    });

After the changes described are made, and the S button is pressed, a serial connection screen should appear and the gold for HWH1 should be awarded.

There's another place to visit on that site shown in the source code:

Check out function dad. Lolz

https://hhc24-hardwarehacking.holidayhackchallenge.com/joke


SANS: Holiday Hack 2024: Act 1: cURLing & Frosty Keypad

cURLing

This is the Terminal near Bow Ninecandle in the Front Yard (Act 1).  I love their play on the word curling which is a sport in the Olympics, but they're referring to using the curl tool. :)

man curl - tells the potential options for curl.  This is useful to find any unknown parameters for curl.  RTFM and all. :)

Silver Medal:

Just do what the terminal asks to be done.

curl curlingfun:8080
curl -k https://curlingfun:9090
curl -k https://curlingfun:9090 -d "skip=alabaster"
curl -k https://curlingfun:9090 -b "end=3"
curl -k https://curlingfun:9090 -v
curl -k https://curlingfun:9090 -H "Stone: Granite"
curl -k https://curlingfun:9090/../../etc/hacks --path-as-is

Gold Medal:

Spent way too long trying to get the original commands into three commands using the :- AKA --next parameter in curl.  Then decided to check the Terminal for another file.

Then it made sense.

ls -la
cat HARD-MODE.txt

The items described in this file were already done for the silver medal, just different information.

curl -k https://curlingfun:9090 -d "skip=bow" -b "end=10" -H "Hack: 12ft"
curl -k --path-as-is https://curlingfun:9090/../../etc/button

The following was the only one that wasn't covered in the silver medal curling.  man curl to the rescue again.

curl -k -L https://curlingfun:9090/GoodSportsmanship


Jewel Loggins is next to Hardware Hacking 1 and Hardware Hacking 2 Terminals.  He recommends talking to Morcel Nugget because there was a note with the settings on it.

Frosty Keypad


Morcel Nuggest states that an important document was shredded and that a clue was placed on the keypad to the Shredder McShreddin 9000.  He also states that there is a book lying around somewhere that might be useful.  These are clues for the next Terminal Frosty Keypad.

Silver Medal:

The book isn't difficult to find.  In the 2024 Holiday Hack Challenge, Act 1 (The Front Yard) In Chrome, Right-Click and Inspect, then open the Elements tab.  Ctrl-F, Search the code for your player name.  Right above it says: data-location="<some x coordinate>,<some y coordinate>".  With the Developer Tools still open, move the character up and down, left and right, and watch that number change.  Next search for the book in that same tab.  Then simply move your character to those coordinates.  It sounds more complicated than it is.

Next, click on the Frosty Keypad.  There's a sticky note.  Take note of the numbers from left to right, top to bottom, exactly as they are.

2:6:1, 4:19:3, 6:1:1, 3:10:4, 14:8:3

Open the Frosty Book in the Items menu in the player badge (it's the green i icon in the dock).  The numbers above are what is called an Ottendorf cipher, or what is more commonly known as a book cipher.  Morcel Nouget hinted about it in the hints by saying "Who are you calling a dorf?"  He also mentions whatever is in there might be a National Treasure, in reference to the movie National Treasure because the book cipher was used to solve a puzzle in that movie.  It's fairly simple.

For 2:6:1: Go to page 2, word 6 in the Frosty Book, and choose the first character.  In this example, the word is SNUG.  The first letter is S.  

For 4:19:3: page 4, word 19, the third letter.  The word is WHAT.  The second letter is A.  (The question here was whether NEW-FALLEN was one word or two.  Since there's a dash/hyphen it counts as one, apparently)

For 6:1:1: NOW.  The third letter is N.

You can probably see where this is going, but let's do the last two:

For 3:10:4: CLATTER - which means the fourth one is T

For 14:8:3: TEAM - which means the fifth one is A

Those decoded letters spell SANTA.  The keypad accepts numbers though.  How do we correlate those letters to numbers?

If you look at a phone, the numbers correspond to letters.  Example: 2 is ABC. 3 is DEF, 4 is GHI, 5 is JKL, 6 is MNO, 7 is PQRS, 8 is TUV, and 9 is WXYZ.

The numbers corresponding to those letters are 72682.

Type in those numbers into the Frosty Keypad.  Then talk to Morcel Nugget.  Morcel informs us that there is another code.

Gold Medal:

For this one the hint is given from Morcel that maybe a UV light can be used to see which buttons on the keypad were pressed last (due to them still having residual heat and fingerprints may be visible).

Again, right-click Inspect in Chrome and click the Elements tab.  Search for your player-name.  Check for the player coordinates.  Then search for the light and move the character in that direction. (You could probably manipulate the code client side and just add the flashlight, but I didn't check.  What's the fun in that?)

Get the flashlight.  Go to the Frosty Keypad and the light should be available.  Left click on the light and keep holding the left mouse button.  Move it over the numbers.  Some numbers should have fingerprints.  They are 2,2,6,7,8.  Hey that looks familiar?  Still the same numbers as before.  However, we need a different permutation.

Ok.  Math... not a fun topic for me.  Not even sure if I'm correct, but I'm including my thought process, anyway.  From the other code for the silver medal, it is known that the combination to the keypad is 5 digits.  We know that each digit can be any of the numbers we discovered.

The first digit in the combination is either 2,2,6,7, or 8 which makes 5 possibilities for that 1st digit.  We're assuming we can't reuse numbers any of these numbers (except for the 2 because it's used twice).  The next digit in the permutation can only be four of those possibilities.  Then the next digit can only be 3 of those possibilities, and so on and so forth.  

Kind of remember some math from a while ago.  The number of permutations is found like this:

5*4*3*2*1 or 5! - that's 5 factorial.  When those numbers are multiplied together, that gives 120 possible permutations of those numbers for a 5-digit combination keypad.  However, since two of the digits are the same, that means that one could have 22678 as the possibility, and 22678 as the possibility again because the 2's could be chosen twice (due to 2 being used twice in the keypad) and happen to be chosen right next to each other.  This means unique permutations would have to be found.

Someone else did the work for me.  Why reinvent the wheel?  I used the following Powershell Commandlet.


Use a VM cut off from the host and the network.  Then open Powershell ISE.  Add the code for the new function in the code editor usually in the white area at the top, Double check to make sure there isn't evil in the commandlet, then click the green play button icon at the top above the code editor, to import the function.  Then: 

Get-StringPermutation -String "22678" | Select -Expand Permutation | Sort -Unique | Out-file -Encoding ascii permutations.txt

Just because I was curious, I did:
 
Get-StringPermutation -String "22678" | Select -Expand Permutation | Sort -Unique | Measure-Object 

I wanted to see how many permutations there were after de-duping with Sort -Unique.  There were 60.  

I guess intuitively that makes sense.  5 possibilities for the first digit, 4 possibilities for the second digit, 3 possibilities for the third digit, and then really there is only one possibility for the last couple digits or 5*4*3*1*1 or 60.  

Could be the script or I was wrong I suppose.  I'm not a mathematician.  Don't take math I do on here seriously.

Next, I wrote a Powershell script to try each combination.  

By studying the way the application functions in Chrome Developer Tools, a post request must be sent to https://hhc24-frostykeypad.holidayhackchallenge.com/submit?id=null.  It must contain json formatted data in the format of {"answer":"whatever the guess is"}

The code here will look bad.  There's a pic of the final code below.

1st Attempt:

foreach($line in [System.IO.File]::ReadLines("C:\Users\User\Downloads\permutations.txt")){
    $Body = @{"answer"="$line"} | ConvertTo-Json
        $response = Invoke-RestMethod -Uri "https://hhc24-frostykeypad.holidayhackchallenge.com/submit?id=null" -Method Post -Body $Body -Headers @{"Content-Type"="application/json"} -ErrorAction SilentlyContinue
        $line
}

Error Message - Limited to 1 Request Per Second.  Rate Limiting - oh joy.

Attempt 2:

foreach($line in [System.IO.File]::ReadLines("C:\Users\User\Downloads\permutations.txt")){
    $Body = @{"answer"="$line"} | ConvertTo-Json
        $response = Invoke-RestMethod -Uri "https://hhc24-frostykeypad.holidayhackchallenge.com/submit?id=null" -Method Post -Body $Body -Headers @{"Content-Type"="application/json"} -ErrorAction SilentlyContinue
        $line
    Start-Sleep -Seconds 1.5
}

Error Message - The data you've provided seems to have gone on a whimsical adventure, losing all sense of order and coherence

Still getting an error, but one response doesn't have an error.  What if I try a try catch block?  Powershell is weird in that there are some errors that will show up even if you do -ErrorAction SilentlyContinue.  In order to handle those errors, a try catch block should be used.  In this case, I really don't care about the error or how to handle it, so I'm telling it to do nothing.

Attempt 3:

foreach($line in [System.IO.File]::ReadLines("C:\Users\User\permutations.txt")){
    $Body = @{"answer"="$line"} | ConvertTo-Json
    try{
        $response = Invoke-RestMethod -Uri "https://hhc24-frostykeypad.holidayhackchallenge.com/submit?id=null" -Method Post -Body $Body -Headers @{"Content-Type"="application/json"} -ErrorAction SilentlyContinue
        $line
    }
    catch{
    }
    Start-Sleep -Seconds 1.5
}

Finally got it - just took a bit off time to run because of the rate limiting.  There are two possible combinations with those numbers.  The SANTA one we discovered with the book cipher, and one more.

Click on the pic to enlarge it.


Wonder if this one is a word? 22786?

Using the letters on the phone...

There are many possibilities.  I think my favorite is carvo.  Caramel infused vodka.  Sounds like it might be ok to try since I'm over the age where I'm permitted to try this beverage in my country.

Open the Frosty Keypad Terminal and type in 22786 enter, then the gold medal is awarded for this Terminal.














Wednesday, November 13, 2024

SANS: Holiday Hack 2024: Prologue

It's that time of year again!  SANS Holiday Hack Challenge.  Looks like the Counter Hack crew are changing up things a bit.  They have a scheduled release for each section of the challenge and are allowing write-ups to be posted a week after each section starts.  

I don't expect to complete the challenge, but that's not important.  Part of the fun is learning, and I learn something from every challenge I attempt.  I did do the last few years' challenges, but didn't post them.  This time around, I intend to post it whether I complete it or not.

The prologue was a fun little puzzle.  Not efficient solutions but they passed the objectives.

First Terminal

This one is easy.  Click on the Raspberry Pi Terminal near Jingle Ringford, and click into the top of the Terminal as described and type answer.

Elf Connect

The next Terminal is the Elf Connect Terminal near Angel Candysalt.  The game can be played normally, as described in the rules, to get the Silver Trophy.  

To get the Gold Trophy, the score needs to be manipulated. The Source Code can be viewed and manipulated by using Chrome Browser Developer Tools as shown in the video below.

Start the Terminal near Angel Candysalt, Click the "Click Anywhere to begin" button to get the rules off the screen, right-click, Inspect.  Then change to the Elements tab if it doesn't already place you there.  After that, look for the link to the game.  The link was in body in the iframe.  Right-click the link and select "Load in New Tab".

Go to the new Tab with the Elf Connect game loaded, Right-click and click Inspect again.  This can also be done in the full challenge window, but it's not as easy to see which code belongs to just the Elf Connect terminal itself.  If you're new to this, having the code just linked to the game in plain view makes it easier.

Play the game and see how it functions.  In the Application Tab, there's an area for Local Storage.  The score and round number are stored in this area.  Manipulating just this value doesn't seem to change the score because it's reset when the level is played and the score changes.

Go to the Console tab and type:

score+=score+1000000

Then play a round.  The next time you score, the score is updated but 1000000 is added to it.  This is how to get the Gold Trophy for this game.


Elf Minder

The next Terminal is Elf Minder, near Poinsetta McMittens.

Again, this one can be played legitimately.  Yes, even the Crate Caper level.  It's just important to understand how each of the entities function.  Entities are the items you can put into play like the tunnels and springs.

There are 12 levels visible at the start of the game.  Complete those to get a Silver Trophy.

A final level, A Real Pickle, is unlocked after the first levels are complete.

The game usually limits the springs to 2 and the portals/tunnels to 2, however, the source code can be manipulated to change that.

Again, Developer Tools in Chrome was used for this puzzle as described in the Elf Connect Terminal write-up/video above.

if (existingSprings.length === 2){
    //remove just the oldest spring
    const oldestSpring = game.entities.findIndex(entity => entity[2] === EntityTypes.SPRING);
    game.entities.splice(OldestSpring, 1);
}

Just change the 2 in the if statement to a number of your choosing like 500 for example.

The portals/tunnels are a different animal.  They can be manipulated, however, there was an error popped when more than two were used like the elf couldn't figure out where to go.

The puzzle can be solved without manipulating the number of portals.

The portal locations and the spring locations can be manipulated as well.  The game is laid out in a coordinate plane.  1,1 is the top left, all the way to 1,13 at the right.  Then the next row down is 2,1 to 2,13.  Each item placed is stored in Local Storage under the Application tab in Developer Tools in Chrome.  There is one entry in local storage for each level.  Example:  There would be a line for Sandy Start which would have entities and segments next to it.  Then a different line for A Real Pickle and so on a so forth.  The portals and tunnels go into an array called "entities".  The path segments go into an array called "segments".  

There are some rules that are checked server side as well as client side so commenting out those sections in the client-side code doesn't affect it server side, so the level doesn't count as being complete and an error pops up relating to that condition.  

Some things that should be checked are not.  Example: A tunnel can be placed on a boulder block and a segment can go to and from that tunnel.  Normally this wouldn't be allowed.

The points in either the segments or the entities can be manipulated making it possible to break rules.  Example: You can have a tunnel coming off the start square instead of the square nearby.  The video shows more detail of this.



Wednesday, September 6, 2023

It's Just A Text File...

Had to figure out a creative way to send an executable to someone.  This isn't a new method by any means-more of a reminder of how important security awareness training is.

Person didn't want to use OneDrive, Dropbox, or a myriad of other methods to share files.  Their e-mail blocked a bunch of different file formats including a password protected zip.

So I sent them a text file containing the base64 encoded version of a password protected zip that contained the executable I needed to send.

Then I sent instructions about how to decode it with multiple different methods in case one failed and the password without saying pass or password-just that they would need it and what it is.

Now imagine I'm a social engineer tricking people into doing this and downloading/running a dropper for me or I'm someone keen on bypassing DLP.  

People say, "There's no way someone would try that." My question is why not?

They said the same thing when I told a vendor at my former job that a social engineer could send a malicious QR code.

Here we are now years later and it's in the news that adversaries are doing that.  https://gbhackers.com/malicious-qr-codes-steal-employee-credentials/amp/

It was being done before it was in the news just not as wide-spread.

I was inspired that that could be done because one of the SANS Holiday Hack Challenges had us bypass a badge system that uses QR codes and it was vulnerable to SQL Injection.

I got to thinking-why wouldn't someone send a QR code via e-mail and social engineer people into scanning it.  It's easy.  So, when we were testing a vendor solution at old job, I tested that. I sent a malicious QR code.  I highly doubt I was the first person to think of this.

Every defense we put in place, they meet with a "new" tactic.  Even if the attack is actually old and very simple.  

Please-train people.  Try to think ahead-and not just what is popular now, but what could be a problem soon.

Monday, February 27, 2023

Created Very Basic Password Cracker

It's been a while.  Completed Holiday Hack 2022 while SANS CDI.  I saw the challenge go up early, so I started working on it as soon as I saw it.  I was taking SEC565 the week that I finished the Holiday Hack and did NetWars again that week.  It was nice to play NetWars again, given it had been a while.  Things have changed regarding NetWars.  They pause the game so you can't work on flags outside of the hours for the tournament.  In a way, it's good-it keeps students from being too focused on NetWars so they aren't paying attention in class.

Working on a different ctf.  In this one, they gave us a hash type  that's not supported by tools I use (like hashcat)-at least not for the versions I use that I'm aware of.  I was a little scared of this question.  I wouldn't call myself strong when it comes to programming or scripting.

I thought about very basically how logging in and crackers work.  You have a hash (and potentially a salt stored in a database.  When someone wants to login, they submit their password, then that password is hashed with the algorithm used to hash their password (and/or salt) to begin with, and that hash is compared to the hash stored in the database.

I thought, "How do I create a hash?"  Looked up that algorithm, and someone was nice enough to already have a program out there that creates hashes with that algorithm.  I took their program as a starting point.  Then I thought, "What do I want to do specifically?"  Take passwords from a list (dictionary), hash them with the salt, one by one, and compare each hash to the one I'm trying to crack.  Then tell me the password. "Are there any other variables I need?  Well, I needed one for comparing the hashes.  I also needed one for the password itself.  Are there any functions I need to add?  I added a loop that takes each password line by line from a file.  Then I added a function that compares the created hash and the original that tells me if the hashes match and what password it was.  It breaks out of the loop at that time as well.

I did a test run with one password/hash.  It worked.  Tried it with the hash for the ctf.  Worked again.  The password was in a well-known dictionary.  Thank goodness for that.

I went out of my comfort zone with this one; I wasn't sure if this would be a challenge I could tackle, but I did.  You don't really know what you are capable of unless you try.

Tuesday, October 25, 2022

Decrypting Unknown Image Challenge

I was given an unknown image.  I always take things like this, put it on a Linux machine and do strings to see if there's any header information that can be of use.  In this case, I see LUKS, aes, xts-plain64, sha1.  I'm not familiar with this format, so I Google.  This is a format used to protect disks and encrypt containers.  Breaking LUKS Encryption | By Oleg Afonin - eForensics (eforensicsmag.com).  While this is interesting, I didn't use this to solve the problem.

I'd gotten a Talino (Forensic Laptop | Extremely Portable Forensic Workstation (sumuri.com) a couple years ago - I tend to save up and overbuild my machines.  It's a nice forensics laptop. I'm interested in forensics, so I asked them how much it would cost to get certain tools added into the price of the laptop.  One of those tools was a nice application called Passware.  It's very easy to use.  I just opened it, dragged the image file into the GUI, and it automatically detected what type of image it was.



After that, I just clicked on the "Next" button and it started the attack.  It took a bit for it to iterate through the lists, but keep in mind, this machine is a couple years old.  They seem to update the password lists quite a bit, so that's nice.  (I blocked out the password just in case others want to try this challenge so that there aren't spoilers.)


You can add your own dictionaries in the menu at the top under Tools>Dictionary Manager, but if I recall it has to be in a certain format to be accepted.  I find that theirs is good, though.

I'm not in any way affiliated or sponsored by them.  I just think this is a neat tool and I'm glad I asked about it when I purchased my Talino.  I'm not affiliated or sponsored by Sumuri either.  A colleague recommended their laptops.  I'm happy with it as well.  It makes a good gaming rig.