# Confiant CrackMe Report
For this CrackMe, I was tasked with interacting with and manipulating the given page in such a way that would reveal the "hidden treasure". I used my browser's native tools such as the inspect tool, the JavaScript console, and viewing the page source in order to reverse-engineer the conditions required to reveal the treasure and crack the puzzle. A documentation of the solution as well as my problem-solving process and methodology follows.
## Solution
:::info
This crack depends on manipulating your browser's `userAgent` string and is thus best performed in Firefox, where the `userAgent` can be manipulated freely and persistently (in Chrome and Chromium-based browsers it can only be changed temporarily while the developer tools are active)
:::
### Modifying the browser's UserAgent
The browser's `userAgent` string must first be set such that the string `'BLACKSEA'` is at index 9 (10th character). This can be done in Firefox by navigating to `about:config` and adding a string for the `general.useragent.override` setting, such as `'aaaaaaaaaBLACKSEA'`. An example is shown below:

### Moving the "X" to the correct locations to acquire runes
The `X` on the page is interactible and can be dragged and dropped. Furthermore, once it is moved, a byte-encoded string representing the `X`'s location will appear and update continually. Once a valid `userAgent` has been set, the `X` must be moved sequentially to three precise locations to acquire "runes" corresponding to each location. The following locations are given as numbers in the format `[y,x]` and then their byte-encoded representations, which is what is displayed by the webpage (with some minor alternations).
#### alpha
This rune is located at `[82,73]`, or `['ODI=','NzM=']`

#### beta
This rune is located at `[80,76]`, or `['ODA=','NzY=']`.

#### gamma
This rune is located at `[69,89]`, or `['Njk=','ODk=']`. The treasure is revealed immediately after passing over this location, so the displayed coordinates in the screenshot are slightly off.

## Methodology
I didn't really use any special tools for this challenge, just the normal developer tools (inspect tool, etc.) available through my browser, as well as some Googling for fields or functions I wasn't immediately/intimately familiar with. Overall, my problem-solving process had roughly 5 phases, which are documented below.
### Phase 1: Getting my bearings
I approached this challenge by first looking at the DOM structure to understand the layout of the page. Upon opening the inspect tool, I was immediately taken to the page sources view and presented with a suspended JavaScript debugger and script for the page source. I extrapolated that this debugger was suspending the underlying loop that checked for the proper conditions for revealing the treasure. After looking at the script for a while without much luck understanding it, I closed the dev tools and tried interacting with the page. At this point, I found out that **the `X` could be moved by dragging/dropping, and also that the `gps` div filled with a string that changed as the `X` was moved**. A little more experimentation confirmed that the string likely represented a coordinate system. With this in mind, I returned to examining the script to try and understand how these strings were encoded.
### Phase 2: Finding a clue
Scanning the script with fresh eyes, I noticed that there were a lot of strings being combined that seemed to have a similar format to the string in the `gps` div. Examining how these were being used, I noticed that the variable `b`, which was aliasing the native function `atob`, was being called on many of these strings. **When I tried using the console to call `atob` on one of the `gps` strings, it returned a string representing a coordinate!** I spent a few minutes tinkering with the DOM in the inspect tool to try to render the "translation" of the `gps` strings, but after a few unsuccessful attempts I returned to examining the script, recognizing that this endeavor was not critical to unlocking the puzzle.
### Phase 3: Translation
I spent the next quarter hour or so using the console to "translate" and recording the meanings of various parts of the script. This also helped me gain a more in-depth understanding of what various parts of the script were doing. Some key pieces of information I recorded during this time were:
* **The contents of the `spikes` array:** `['navigator', 'userAgent', 'indexOf', 'LAMBERT', 'RIPLEY', 'ALDERSON', 'BLACKSEA', 'dir', 'clear', 'clue', 'canary', 'alpha', 'beta', 'gamma']`, obtained by mapping a composition of the `b` and `tY` functions to each value of the array.
* The value of `ee` - just the native `eval()` function
* Line 67 - `eval('debugger')`, which I presume to be the line that triggered the debugger
Most critically, I ran **the code on line 75 - `eval('alert("Congratulations Oh 1337 One! You have found my treasure!")')`**, which manually triggered the alert representing the puzzle's solution. I now had identified the line I wanted the script's execution to reach.
### Phase 4: `clue` validation and `userAgent` manipulation
Lines 69-74 contain the conditions that need to be met for the final line to be triggered. A cursory glance at the `IChing` function both confirmed that the `X`'s coordinates were being encoded via `btoa` and displayed in the `gps` div, and that **the first condition (`runes.length > 2`) could be fulfilled by moving the `X` to a series of 3 locations**, each of which would `push` another word (`alpha`, `beta`, then `gamma` from the `spikes` array) onto `runes`. Leaving the decoding of the location aside for the time being, I decided to focus on the second condition, which was that the sum of the character codes for each letter in the `clue` variable would sum up to 469. The three possible values of `clue` were `'LAMBERT'` (the default), `'RIPLEY'`, and `'ANDERSON'`. The following simple one-liner added up the sum of the character code values for a given clue:
```javascript
[...'LAMBERT'].map((x) => x.charCodeAt(0)).reduce((a, v) => a + v)
```
Which gave the following sums:
* `'LAMBERT'` --> 519
* **`'RIPLEY'` --> 469**
* `'ALDERSON'` --> 600
The condition for setting `clue` to `'RIPLEY'`, translated from line 47, was that `window['navigator']['userAgent'].indexOf('BLACKSEA') == 9`, or that **the string `'BLACKSEA'` appeared at index 9 of the browser's `userAgent` string**. A quick Google search later and I had found a way to manipulate the `userAgent` on the browser I was using (Vivaldi, a Chromium-based browser). However, the changes did not persist after I closed the developer tools, and I was unable to interact with the `X` while the developer tools were open, so I decided to switch to Firefox, which had a much simpler way to modify the `userAgent` persistently, as outlined [above](##Modifying-the-browser%E2%80%99s-UserAgent). After making this change, I could confirm that the value of `clue` had changed from `'LAMBERT'` to `'RIPLEY'` as desired.
### Phase 5: Decoding locations
The final phase consisted of decoding the appropriate locations to move the `X` to in order to add to the `runes` array. The `IChing` function, which performs location validation, **checks the location against the character code of each letter in `clue`**. Thus, I extracted an array of character codes for each letter in `'RIPLEY'` as well as byte-encoding them using `btoa`, which would give me the same representation used by the `gps`:
```javascript
[...'RIPLEY'].map((x) => x.charCodeAt(0)) --> [ 82, 73, 80, 76, 69, 89 ]
.map(btoa) --> [ "ODI=", "NzM=", "ODA=", "NzY=", "Njk=", "ODk=" ]
```
Giving me the (`y,x`) coordinates:
* `82,73`, or `'ODI=','NzM='`
* `80,76`, or `'ODA=','NzY='`
* `69,89`, or `'Njk=','ODk='`
After this, I just needed to move the `X` sequentially to each location (a feat of no small mouse precision) and the alert on line 75 was triggered, solving the puzzle!