medium.com

Misstep VulNyx — Official Writeup

TirexV2

TirexV2

Press enter or click to view image in full size

Introduction

Welcome to Misstep! This machine was designed to be a fun and educational experience, simulating a series of realistic misconfigurations in a modern DevOps and web development environment. Each step of the way, a small oversight or “misstep” allows us to move deeper into the system. Our path will take us from a modern web application vulnerability to credential reuse, container inspection, and finally, a misconfigured automation tool to gain root.

1. Reconnaissance & Enumeration

Press enter or click to view image in full size

We need to add misstep.nyx to /etc/hosts

Press enter or click to view image in full size

nmap -sC -sV -p- misstep.nyx

The scan reveals two open ports:

  • Port 22/tcp (SSH): Running OpenSSH. This will likely be useful once we find some credentials.
  • Port 80/tcp (HTTP): Running Nginx. This is our initial entry point.

Press enter or click to view image in full size

We navigate to http://misstep.nyx

Press enter or click to view image in full size

2. Foothold: From Web to www-data Shell

Our goal now is to find a vulnerability in the web application

Discovery: Finding and Analyzing the API

We run Firexobuster to discover hidden directories

 feroxbuster -u http://misstep.nyx -E

Press enter or click to view image in full size

We found some 403 HTTP Codes, which means we have /admin path but it is forbidden

Press enter or click to view image in full size

With the web application showing Cannot GET /Our next step is to probe for hidden functionality

We run curl -v http://misstep.nyx

Press enter or click to view image in full size

In the response headers, we spot a custom header left by the developers:

< X-Powered-By: Express
< X-API-Endpoint: /api/update/settings

Endpoint Name: /api/update/settings strongly implies an action that changes data, which is typically handled by POST requests in an API.

Server Technology: The X-Powered-By: Express header tells us it's a modern Node.js application, which almost always uses JSON for API communication

Press enter or click to view image in full size

Exploitation: JavaScript Prototype Pollution

Now that we understand how the endpoint works, we move from enumeration to exploitation. For a Node.js application that processes user-controlled JSON objects, a primary vulnerability to test for is JavaScript Prototype Pollution.

Get TirexV2’s stories in your inbox

Join Medium for free to get updates from this writer.

We craft the classic payload for this attack. First, we get a valid session cookie (connect.sid) from our browser's developer tools. Then, we send the payload:

curl -X POST http:
-H "Content-Type: application/json" \
-b "connect.sid=<YOUR_COOKIE_HERE_FROM_CONSOLE>" \
-d '{"__proto__": {"isAdmin": true}}'

Press enter or click to view image in full size

This command silently promotes our session to have admin privileges. We can now access the previously forbidden /admin page

Press enter or click to view image in full size

3. Privilege Escalation: www-data ➡️ dev

Since the terminal can execute commands inside the system machine, we first check who we are in the system we used:

id

Press enter or click to view image in full size

We are in the webroot, /var/www/html. One of the first things we should always do here is list all files, including hidden ones

ls -la

Press enter or click to view image in full size

Pivot: Password Reuse

Right away, a file stands out: .env. These files are commonly used by developers to store configuration variables and secrets

Press enter or click to view image in full size

Developers often reuse passwords. We’ll bet that the dev user's system password is the same as their database password. Instead of using su our fragile web shell, we can now get a proper, stable shell by connecting directly via SSH from our attacker machine.

Press enter or click to view image in full size

4. Privilege Escalation: dev ➡️ sysadmin

As the dev user, we again start by enumerating the home directory (/home/dev) for clues.

Press enter or click to view image in full size

A script named push_to_registry.sh immediately catches our eye

Exploitation: Leaked Secrets in Container Metadata

which contains a DOCKER_API_KEY. We should also check our own permissions with the id command, which reveals we are part of the docker group. This means we can run docker commands. We can inspect a local image named legacy-app for secrets that might have been left in its configuration.

id
docker inspect echocorp/legacy-app | grep ADMIN_PASS

Press enter or click to view image in full size

This command reveals a plain-text password for the `sysadmin` user

5. Privilege Escalation: sysadmin ➡️ root

This is the final step. As sysadminWe start by enumerating the home directory. /home/sysadmin.

We find a log file: infra_chat.log. Reading it gives us our final breadcrumb.

Press enter or click to view image in full size

  • An Ansible playbook is being used for automation.
  • It’s in the /opt/ansible/ directory.
  • It’s “running on schedule,” which strongly implies a cron job.
  • We have “group perms to edit it,” which is a direct hint to check the file permissions.

We can confirm the cron job by runningpspy, which shows ansible-playbook /opt/ansible/maintenance.yml running as root. Then, we check the permissions:

Press enter or click to view image in full size

webserver to share pspy64

Press enter or click to view image in full size

Start pspy and give it chmod +x

Press enter or click to view image in full size

Target ansible cronjob

Press enter or click to view image in full size

Check file permissions

Exploitation: Hijacking the Ansible Playbook

  • We start our final Netcat listener on port 4444.
  • We edit the /opt/ansible/maintenance.yml file and append a new task to execute our reverse shell.

Press enter or click to view image in full size

We save the file and wait. Within a minute, the cron job runs, Ansible executes our task, and a root shell lands on our listener.

Press enter or click to view image in full size

Conclusion

We are the root! Misstep was a fantastic journey through a modern, realistic chain of vulnerabilities. From prototype pollution in a Node.js app to password reuse, secrets in Docker images, and finally, a writable Ansible playbook, each step required careful enumeration and a clear understanding of the technology involved. Thanks for reading!