Mother’s Secret is a room in TryHackMe platform. In this machine we have to get some flags as well as answer some questions about the process. It requires basic hacking methodology and reading source code.
First thing we would want to do is to enumerate the provided IP with nmap
, but we won’t obtain nothing special. We I’ll skip it.
There are a few instructions provided in the same room description:
Below are some sequences and operations to get you started. Use the following to unlock information and navigate Mother:
– Emergency command override is 100375. Use it when accessing Alien Loaders.
– Download the task files to learn about Mother’s routes.
– Hitting the routes in the right order makes Mother confused, it might think you are a Science Officer!
Code Analysis Challenge – Mother’s Secret
It’s important to read and understand everything as well as download the attached file. One of the answers is there.
Accessing the website we obtain the following, where some fields are missing and role we have is “Crew member“:
There is nothing special on it, we can just use UP and DOWN keys to shoe different information. What we need to check is the provided script in task with description of the routes.
Fro the “/
” route we have the following code:
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.");
});
});
From it we can observe the endpoint process a file_path
parameter in a POST
request. It made two checks and fails in any of the following:
file_path
parameter has no .yaml
extension.- file name is valid but file doesn’t exist.
Finally, it would return 200 response code and send a “yaml” string to the “/yaml” socket. That’s what we want to happen.
We need to find the correct file_path
. We can try to guess or use or fuzze until we find it. There are some options for it, for example Postman
(try specific name) and ffuf
(fuzzing).
For fuzzing we just need to create a word list and run a command like follows:
ffuf -u http://10.10.4.24/yaml -H "Content-Type: application/json" -X POST -d '{"file_path":"FUZZ.yaml"}' -w wordlist.txt
Similar for Postman, we just need to change the file name to desired one and set their respective HTTP headers, and we should get a 200 response:
*As a hint, file_path
is related to the Emergency command override.
Don’t forget to run the request on “/api/nostromo“, which is the one which provides the access to the “/api/nostromo/mother” API endpoint and gives us more information to follow the room:
In the response, we see a filename that has a flag and the special order number.
We also can see a change in the webpage: our role was updated and we have a flag value:
We can know that authorization from “/api/nostromo” endpoint is required because of the following code:
if(!isNostromoAuthenticate || !isYamlAuthenticate){
res.status(500).json({
status: "Authentication failed",
message: "Kindly visit nostromo & yaml route first.",
});
return
}
If not authenticated, we got:
There is one way to know what could be happening in the backend: getting the JavaScript code. If we see the source code of the webpage, we can see and interesting JS file:
<script src="./index.min.js"></script>
It is minified, but it could be reversed online, for example here. The problem is code seems to be obfuscated:
There’s also a solution for that, it can be deobsfuscated online on a site like here.
All above mentioned is not required, for I think it could help to see what’s really happening behind the scenes.
At this point, we have a different role and more permissions, for example before mentioned endpoint “/nostromo/mother“. In the routes file when can see we have to provide another file_path
:
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.");
});
});
Again, we can try to guess the value or brute force the endpoint until we get the right name. Room task asks about guessing what is “/api/nostromo/mother/secret.txt“. Maybe a gentle hint?
Making the request using Postman
with the right parameter should give the following response:
Response is a weird file path, if we try it as as web request, we don’t get response but: {"status":"You just hit the wrong route."}
.
That seems to be more like a file system path. How could we retrieve its content?
Remembering how we get that value, we sent a filename to the API endpoint, also remembering the endpoint source code, we have that filePath
searched is the concatenated value of the sent value to “./mother/“:
const filePath = `./mother/${file_path}`;
It’s possible that endpoint is vulnerable to Directory traversal attack. So what we could do it the append multiple “/..” and then the file we want:
And we got it. We have the final flag.
This was a really funny room. It took a some time to finish it but it was amazing, it involves different techniques from debugging and fuzzing to directory traversal attack.