Code Analysis

REHAN SAYYEDREHAN SAYYED
6 min read

Introduction

Upon accessing the MU-TH-UR6000 computer, AKA Mother, you will see the Mother UI server. However, since you only have a "Crew" Member level role, you only have read access to limited resources. But there are other ways to access it. Can you find them and uncover Mother's secret?

Equipment Check

Download the files attached to this task to review the code.

  1. Explore the available endpoints of the Mother Server and try to find any clues that can reveal mother's secret.

  2. Search for a file that contains essential information about the ship's activities.

  3. Exploit the vulnerable code to download the secrets from the server. Can you spot the vulnerable code?

  4. Capture all the hidden flags you encounter during your exploration. Only Mother holds this secret.

Operating Manual

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!

Can you guess what is /api/nostromo/mother/secret.txt?

IP: 10.10.119.18

Let’s first check whether we’ve connected to the machine.

ping -c3 10.10.119.18

Let’s now download the file.

Let’s now check what we have in this text file.

gedit routes\(2\)-1694024181296.txt

So, we’ve been provided with a code that will be needed during the code analysis.

Inside the text file we have two separate “files” and this is what they do. Let’s start by looking at the first

yaml.js

This file defines an Express router that processes YAML files. It reads a specified YAML file, parses its content, and sends the parsed data in the response while emitting a WebSocket message to notify that the YAML data has been processed. The POST command expects an file_path in the request body, checks if the file is a YAML file, and then reads and parses it.

Nostromo.js

This file defines an Express router with routes to handle specific file operations related to Nostromo. It reads specified files, checks authentication flags, and sends the file content in the response, while also emitting WebSocket messages to notify about the processing status. The POST command for /nostromo expects a file_path in the request body, reads the file, and sets an authentication flag. The POST command for /nostromo/mother also expects a file_path, checks authentication flags, and reads the file if the checks pass.

Question 1: What is the number of the emergency command override?

Ans: 100375

Now let’s move on to looking at the code. Since we are working with javascript let’s open up and see if there’s any website.

Visiting the IP we can see that there’s a webpage running some directory bruteforcing doesn’t help much as well so we’re back with our source code analysis. looking at the ‘Alien loader’ we see that the function parses and loads YAML data.

So, the first configuration file inside the downloaded text is ‘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;

So what we’ll do now is go and check the client path i.e. http://10.10.119.18/yaml.

And it gives us a message that we hit the wrong route. Let’s open this in burpsuite to test further.

Let’s send it to the repeater tab.

If we look back at the file name we remember that it needs a post request and not a get request, so let’s change the request method.

It says that “Not a YAML file path”. so let’s modify the request by setting the file_path variable header.

No luck here either. But if we look at the hints that were provided to us we got a command emergency override number i.e. 100375 so let’s try that as our YAML file. Also changing the Content-Type to JSON format.

We now finally have some info that seems to be useful like ORDER: 0rd3r937.txt. let’s try to use this as the special order number.

Question 2: What is the special order number?

Ans: 937

So now we need to go to the next router which is called Nostromo 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 downloaded 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;

As noted above this file looks pretty similar to the previous file we looked at but has authentication. So let’s hit this endpoint and intercept it in our burp suit repeater. Once again set the request to a POST request and set our file to the text file that we just received 0rd3r937.txt

And we got our flag here.

Flag: Flag{X3n0M0Rph}

Question 3: What is the hidden flag in the Nostromo route?

Ans: Flag{X3n0M0Rph}

It’s good to note that sending a POST request here bypassed the authentication. Now let’s forward the request to the browser and see if we can interact with the UI as a science officer.

Visiting the Home page again.

Now we are authenticated with scientist credentials named Ash.

Question 4: What is the name of the Science Officer with permissions?

Ans: Ash

Question 5: What are the contents of the classified "Flag" box?

Ans: 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.

Question 6: Where is Mother's secret?

Ans: /opt/m0th3r

I thought it would be as easy as putting it in the browser but they were smarter than that.

After taking a closer look at the code I noticed the {file_path} parameter is vulnerable to LFI attacks and I got a promising response by setting the file to "../../../../opt/m0th3r".

And we got our final flag.

Question 7: What is Mother's secret?

Ans: Flag{Ensure_return_of_organism_meow_meow!}

0
Subscribe to my newsletter

Read articles from REHAN SAYYED directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

REHAN SAYYED
REHAN SAYYED

Passionate cybersecurity enthusiast and red teamer, exploring the depths of offensive security. From secure code reviews to red team operations, I share insights, strategies, and hands-on experiences to help others dive into the world of cyber offense. Join me as I navigate the complexities of cybersecurity on my journey to professional red teaming.