Mother’s Secret -TryHackme- (Detailed explanation)

OwenW
5 min readSep 18, 2023

Hi, today we are going to talk about a interesting ctf box in Tryhackme called ‘Mother’s Secret’.

The main point of this box is Code Analysing & Application Security. Before we start the machine, the creator already give some hint in the Operating Manual.

What is the number of the emergency command override?
100375

This number is called override so it must be useful later, it may be a variable or a filename. Then we need to download the configure document which is called ‘router(2).txt’. It contains two comfiguration file. After we start the machine and start the basic enumeration, only port 22 and port 80 is open. Here is the main page when you connect web port.

It is a good habit to enumerate the basic information or dirbuster the website, but in this box, those method didn’t give me any good information. So we back to analysis the code. The first configuration file inside the download text is called yaml.js. Here is the code of the file.

import express from "express";
import yaml from "js-yaml";
import fs from "fs";
import { attachWebSocket } from "../websocket.js";

const Router = express.Router();

const isYaml = (filename) => filename.split(".").pop() === "yaml";

Router.post("/", (req, res) => {
let file_path = req.body.file_path;
const filePath = `./public/${file_path}`;

if (!isYaml(filePath)) {
res.status(500).json({
status: "error",
message: "Not a YAML file path.",
});
return;
}

fs.readFile(filePath, "utf8", (err, data) => {
if (err) {
res.status(500).json({
status: "error",
message: "Failed to read the file.",
});
return;
}

res.status(200).send(yaml.load(data));

attachWebSocket().of("/yaml").emit("yaml", "YAML data has been processed.");
});
});

export default Router;

We can get some important information from here. This router is based on the POST type request and it use a function called ‘isYaml()’ to check the file parameter (here is ‘file_path’) is a yaml file or not. If the return is Yes, it will read the file and return the javascript data to the client in the path:/yaml.

So the first thing I did is go to the client path which is http://MACHINE-IP/yaml to check there is a client or not. Isuccessed to get there but it return us the message is we hit the wrong route. So I decide to use Burpsuit to capture the package and test. Here is the original package in /yaml.

Send this to repeater and change the GET to POST. Then add the following changes to the package.

We find the return message is change and it is follow the configuration file before. So now we need a right payload to get the information we want. Yes, it is exactly the first question answer ‘100375’, this is the yaml file name. So we have the following change and get some information we need.

What is the special order number?
937

So now we need to go to the next router which is called ‘nostormo’, and the location is api/nostromo and the file we need to find is 0rd3r937.txt. This router config is also in the text file we download before.

import express from "express";
import fs from "fs";
// import { attachWebSocket } from "../../mothers_secret_challenge/websocket.js";
import { attachWebSocket } from "../websocket.js";
import { isYamlAuthenticate } from "./yaml.js";
let isNostromoAuthenticate = false;

const Router = express.Router();

Router.post("/nostromo", (req, res) => {
let file_path = req.body.file_path;
const filePath = `./public/${file_path}`;

fs.readFile(filePath, "utf8", (err, data) => {
if (err) {
res.status(500).json({
status: "error",
message: "Science Officer Eyes Only",
});
return;
}

isNostromoAuthenticate = true
res.status(200).send(data);

attachWebSocket()
.of("/nostromo")
.emit("nostromo", "Nostromo data has been processed.");
});
});

Router.post("/nostromo/mother", (req, res) => {

let file_path = req.body.file_path;
const filePath = `./mother/${file_path}`;

if(!isNostromoAuthenticate || !isYamlAuthenticate){
res.status(500).json({
status: "Authentication failed",
message: "Kindly visit nostromo & yaml route first.",
});
return
}

fs.readFile(filePath, "utf8", (err, data) => {
if (err) {
res.status(500).json({
status: "error",
message: "Science Officer Eyes Only",
});
return;
}

res.status(200).send(data);

// attachWebSocket()
// .of("/nostromo")
// .emit("nostromo", "Nostromo data has been processed.");
});
});

export default Router;

Well it is pretty same as the yaml.js but add another authenticate method called ‘isNostromoAuthenticate’. This value is set as False initially, but when our POST request is under the /nostromo, the value will auto be True. That is a good news, so we can do the same thing in nostromo router but this time we don’t need the file must be yaml file. Here is my BrupSuit in this router, we send our request and get the secret.

What is the hidden flag in the Nostromo route?
Flag{X3n0M0Rph}

If we back to our main page, we will find the page is change after we sent this package.

What is the name of the Science Officer with permissions?
Ash

What are the contents of the classified "Flag" box?
THM_FLAG{0RD3R_937}

Look at the previous manual operation, there is a hint “Can you guess what is /api/nostromo/mother/secret.txt?” So we use the same method to look at it and here is what we got.

Where is Mother's secret?
/opt/m0th3r

This seem a file in /opt directly of the system. We can discover it using the ‘/../’ same as LFI. So we can get the file and the final flag.

What is Mother's secret?
Flag{Ensure_return_of_organism_meow_meow!}

Hi, this is OwenW.

This is my first public blog in Medium. I hope you like it. From todays on, I will publish more interesting CTF box blog and some related cybersecurity knowledge.

Feel free to give me your feedback or comment. Welcome to follow me, your follows will be my motivation to create better blog.

--

--