Today, we’re going to tackle a Hack the Box Challenge on the offensive side called Flag Command. The scenario that we’re given is
Embark on the "Dimensional Escape Quest" where you wake up in a mysterious forest maze that's not quite of this world. Navigate singing squirrels, mischievous nymphs, and grumpy wizards in a whimsical labyrinth that may lead to otherworldly surprises. Will you conquer the enchanted maze or find yourself lost in a different dimension of magical challenges? The journey unfolds in this mystical escape!
If you click to start the challenge, you’ll be given an IP:Port to connect to. In my case, it is 154.57.164.75:32410, yours will almost certainly be different. Going to that page, I see this:

I follow along and type start and it gives me options like this:
>> start YOU WAKE UP IN A FOREST. You have 4 options! HEAD NORTH HEAD SOUTH HEAD EAST HEAD WEST
I tried to play along still, but even when I typed an available option, it is apparently case sensitive. So they are doing some sort of input validation. Given that this is a text engagement, I was wondering if we’d get some command injection or something. The first step to that would be to get past the validation.
>> head north You do realise its not a park where you can just play around and move around pick from options how are hard it is for you???? >> HEAD NORTH Venturing forth with the grace of a three-legged cat, you head North. Turns out, your sense of direction is as bad as your cooking - somehow, it actually works out this time. You stumble into a clearing, finding a small, cozy-looking tavern with "The Sloshed Squirrel" swinging on the signpost. Congratulations, you've avoided immediate death by boredom and possibly by beasties. For now...
I checked and it does send the commands to the server. My next command was sent to http://154.57.164.75:32410/api/monitor as this request and then response
// Request
{command: "TURN BACK"}
// Response
{ "message": "You decide to turn back, but you realize you've lost your way. Night falls, and the forest becomes a dark, eerie place. You hear mysterious sounds closing in. Game over!" }
I tried a few simple commands and couldn’t get anything going
>> id 'id' command not found. For a list of commands, type 'help' >> help start Start the game clear Clear the game screen audio Toggle audio on/off restart Restart the game info Show info about the game >> info You abruptly find yourself lucid in the middle of a bizarre, alien forest. How the hell did you end up here? Eerie, indistinguishable sounds ripple through the gnarled trees, setting the hairs on your neck on edge. Glancing around, you spot a gangly, grinning figure lurking in the shadows, muttering 'Xclow3n' like some sort of deranged mantra, clearly waiting for you to pass out or something. Creepy much? Heads up! This forest isn't your grandmother's backyard. It's packed with enough freaks and frights to make a horror movie blush. Time to find your way out. The stakes? Oh, nothing big. Just your friends, plunged into an abyss of darkness and despair. Punch in 'start' to kick things off in this twisted adventure! >> start YOU WAKE UP IN A FOREST. You have 4 options! HEAD NORTH HEAD SOUTH HEAD EAST HEAD WEST >> id You do realise its not a park where you can just play around and move around pick from options how are hard it is for you???? >> ;id You do realise its not a park where you can just play around and move around pick from options how are hard it is for you???? >> id; # You do realise its not a park where you can just play around and move around pick from options how are hard it is for you????
Okay, let’s take a look at the source code of the web app. I went into Developer Tools -> Sources and saw that there are 3 main javascript files at work here.
<script src="/static/terminal/js/commands.js" type="module"></script> <script src="/static/terminal/js/main.js" type="module"></script> <script src="/static/terminal/js/game.js" type="module"></script>
Commands.js seems interesting. What’s in there?
export const START = 'YOU WAKE UP IN A FOREST.';
export const INITIAL_OPTIONS = [
'<span class="command">You have 4 options!</span>',
'HEAD NORTH',
'HEAD SOUTH',
'HEAD EAST',
'HEAD WEST'
];
export const GAME_LOST = 'You <span class="command error">died</span> and couldn\'t escape the forest. Press <span class="command error">restart</span> to try again.';
export const GAME_WON = 'You <span class="command success">escaped</span> the forest and <span class="command success">won</span> the game! Congratulations! Press <span class="command success">restart</span> to play again.';
export const INFO = [
"You abruptly find yourself lucid in the middle of a bizarre, alien forest.",
"How the hell did you end up here?",
"Eerie, indistinguishable sounds ripple through the gnarled trees, setting the hairs on your neck on edge.",
"Glancing around, you spot a gangly, grinning figure lurking in the shadows, muttering 'Xclow3n' like some sort of deranged mantra, clearly waiting for you to pass out or something. Creepy much?",
"Heads up! This forest isn't your grandmother's backyard.",
"It's packed with enough freaks and frights to make a horror movie blush. Time to find your way out.",
"The stakes? Oh, nothing big. Just your friends, plunged into an abyss of darkness and despair.",
"Punch in 'start' to kick things off in this twisted adventure!"
];
export const CONTROLS = [
"Use the <span class='command'>arrow</span> keys to traverse commands in the command history.",
"Use the <span class='command'>enter</span> key to submit a command.",
];
export const HELP = [
'<span class="command help">start</span> Start the game',
'<span class="command help">clear</span> Clear the game screen',
'<span class="command help">audio</span> Toggle audio on/off',
'<span class="command help">restart</span> Restart the game',
'<span class="command help">info</span> Show info about the game',
];
Okay, nothing exciting in there. The game.js is extremely boring and nothing is in there. That leaves us with main.js. There is a lot in main.js, but here is a relevant part where it checks the command and sends it to the API and also where it gets your options.
// HTTP REQUESTS
// ---------------------------------------
async function CheckMessage() {
fetchingResponse = true;
currentCommand = commandHistory[commandHistory.length - 1];
if (availableOptions[currentStep].includes(currentCommand) || availableOptions['secret'].includes(currentCommand)) {
await fetch('/api/monitor', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ 'command': currentCommand })
})
.then((res) => res.json())
.then(async (data) => {
console.log(data)
await displayLineInTerminal({ text: data.message });
if(data.message.includes('Game over')) {
playerLost();
fetchingResponse = false;
return;
}
if(data.message.includes('HTB{')) {
playerWon();
fetchingResponse = false;
return;
}
if (currentCommand == 'HEAD NORTH') {
currentStep = '2';
}
else if (currentCommand == 'FOLLOW A MYSTERIOUS PATH') {
currentStep = '3'
}
else if (currentCommand == 'SET UP CAMP') {
currentStep = '4'
}
let lineBreak = document.createElement("br");
beforeDiv.parentNode.insertBefore(lineBreak, beforeDiv);
displayLineInTerminal({ text: '<span class="command">You have 4 options!</span>' })
displayLinesInTerminal({ lines: availableOptions[currentStep] })
fetchingResponse = false;
});
}
else {
displayLineInTerminal({ text: "You do realise its not a park where you can just play around and move around pick from options how are hard it is for you????" });
fetchingResponse = false;
}
}
// LATER IN THE FILE
const fetchOptions = () => {
fetch('/api/options')
.then((data) => data.json())
.then((res) => {
availableOptions = res.allPossibleCommands;
})
.catch(() => {
availableOptions = undefined;
})
}
That /api/monitor gets POSTed to. Attempting a GET returns a MethodNotAllowed error. We will have to keep an eye on how it is interacted with. Let’s call the other API that we found: /api/options. That gives us this:
{
"allPossibleCommands": {
"1": [
"HEAD NORTH",
"HEAD WEST",
"HEAD EAST",
"HEAD SOUTH"
],
"2": [
"GO DEEPER INTO THE FOREST",
"FOLLOW A MYSTERIOUS PATH",
"CLIMB A TREE",
"TURN BACK"
],
"3": [
"EXPLORE A CAVE",
"CROSS A RICKETY BRIDGE",
"FOLLOW A GLOWING BUTTERFLY",
"SET UP CAMP"
],
"4": [
"ENTER A MAGICAL PORTAL",
"SWIM ACROSS A MYSTERIOUS LAKE",
"FOLLOW A SINGING SQUIRREL",
"BUILD A RAFT AND SAIL DOWNSTREAM"
],
"secret": [
"Blip-blop, in a pickle with a hiccup! Shmiggity-shmack"
]
}
}
Okay, what is the “secret” one? Can I use that? It turns out that I can’t use it at the beginning of the game. I still have to enter “start”. However, once the game is in play (which makes sense given all the other commands in this list are “in game” commands), I can use that secret to win the game.
>> Blip-blop, in a pickle with a hiccup! Shmiggity-shmack
'blip-blop, in a pickle with a hiccup! shmiggity-shmack' command not found. For a list of commands, type 'help'
>> start
YOU WAKE UP IN A FOREST.
You have 4 options!
HEAD NORTH
HEAD SOUTH
HEAD EAST
HEAD WEST
>> Blip-blop, in a pickle with a hiccup! Shmiggity-shmack
HTB{D3v3l0p3r_t00l5_4r3_b35t__t0015_wh4t_d0_y0u_Th1nk??}
You escaped the forest and won the game! Congratulations! Press restart to play again.
That’s it. Not “nothing”, but definitely “Very Easy” by Hack the Box standards, as advertised. Any questions, let me know!

This post, we are going to tackle a Hack the Box Sherlock called PhantomRing. You can find it 

This time, we’re going to tackle a Sherlock from Hack the Box called 






We’re going to break up our Hack the Box streak and switch over to doing a TryHackMe challenge this time called 

