❌

Reading view

There are new articles available, click to refresh the page.

Hack The Box: Previous Machine Walkthrough – Medium Difficulty

By: darknite
Reading Time: 9 minutes

Introduction to Previous:

In this write-up, we will explore the β€œPrevious” machine from Hack The Box, categorised as an easy difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.

Objective:

The goal of this walkthrough is to complete the β€œPrevious” machine from Hack The Box by achieving the following objectives:

User Flag:

After thoroughly enumerating the Next.js application running on port 80, we discovered a critical path traversal vulnerability in the publicly exposed /api/download endpoint. Consequently, by crafting a specially designed payload, we were able to read sensitive system files. From these files, we extracted user information that revealed a valid account. Using the discovered credentials, we then gained SSH access as a standard user and, ultimately, successfully retrieved the user flag located in the home directory.

Root Flag:

With initial access secured, we enumerated the user’s sudo privileges and discovered the ability to run a specific Terraform command as root in a controlled directory. By leveraging a misconfiguration in the local Terraform setup, we first prepared a carefully crafted binary. Then, during the privileged Terraform operation, the binary was loaded, which in turn executed our payload and consequently granted elevated permissions. This allowed us to obtain a root shell and read the final root flag from the protected location.

Enumerating the Previous Machine

Reconnaissance:

Nmap Scan:

Begin with a network scan to identify open ports and running services on the target machine.

nmap -sC -sV -oA initial 10.10.11.83

Nmap Output:

β”Œβ”€[dark@parrot]─[~/Documents/htb/previous]
└──╼ $nmap -sC -sV -oA initial 10.10.11.83
# Nmap 7.94SVN scan initiated Sat Jan 10 03:28:37 2026 as: nmap -sC -sV -oA initial 10.10.11.83
Nmap scan report for 10.10.11.83
Host is up (0.045s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://previous.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan 10 03:28:48 2026 -- 1 IP address (1 host up) scanned in 11.13 seconds

Analysis:

  • 22/tcp: Open and running OpenSSH 8.9p1 on Ubuntu, providing secure shell access for remote login. The host exposes ECDSA and ED25519 keys for authentication.
  • Port 80/tcp: Open and serving HTTP via Nginx 1.18.0 on Ubuntu. The server header confirms the version, and the default page redirects to http://previous.htb

Exploitation on the Previous Machine

Web Application Exploration:

A screenshot of a computer

AI-generated content may be incorrect.

The browser displays the root path / as a fully public marketing landing page for PreviousJS. The page features a tagline about β€œthe technology of yesterday” and highlights three main benefits: β€œNo-Side Rendering”, β€œHeavyweight”, and β€œOpt-Out Middleware”.

During Gobuster directory enumeration with a small lowercase wordlist, /signinin emerges as the only accessible endpoint returning 200 OK, representing the actual login page with the double β€œin”. In contrast, /api, /docs, and numerous /api* variants (such as api3, api_test, apidoc, and apis) consistently return 307 Temporary Redirects. As a result, these requests are forwarded to the sign-in page with corresponding callbackUrl parameters.

A screenshot of a computer

AI-generated content may be incorrect.

Access to /signinin?callbackUrl=http://localhost:3000/api loads the login page (note the double β€œin” in path) with preserved localhost callbackUrl in the URL, confirming the application accepts and reflects this misconfigured origin

Authentication Flow Analysis on Prevous Machine

When requesting the root path / with an If-None-Match header matching the current ETag, the server returns 304 Not Modified. Meanwhile, the response continues to include the next-auth.callback-url cookie set to http://localhost:3000/api/download.

This shows a GET request to /_next/data/…/docs.json (a typical Next.js client-side data fetch route for static/SSG pages). The server responds with 307 Temporary Redirect and the custom header x-nextjs-redirect: /api/auth/signin?callbackUrl=%2Fdocs, forcing unauthenticated users to the sign-in page.

When accessing /api, the request triggers a redirect chain (307 β†’ 302) that ultimately leads to /api/auth/signinin?callbackUrl=%2Fapi. At the same time, the server sets the next-auth.callback-url cookie to http://localhost:3000/api/download. This behavior clearly indicates a NextAuth.js misconfiguration, caused by the application using the default development base URL.

Β CVE-2025-29927 Enumeration

GET request to /signinin?callbackUrl=http://localhost:3000/api returns 200 OK with the full login page HTML (title β€œSign In In”, input fields for Username and Password, and β€œSign in” button), preserving the suspicious localhost callback URL in the query string and continuing to carry the next-auth.callback-url=http://localhost:3000/api/download cookie, confirming the application fully accepts and reflects the development-origin misconfiguration in the authentication flow.

On the page, Next.js static chunks and scripts (e.g., _buildManifest.js, _ssgManifest.js) are loaded. Consequently, the localhost callback remains in the URL, and the persistent next-auth.callback-url cookie continues to point to http://localhost:3000/api/download.

A GET request to the Next.js data route /_next/data/…/docs.json triggers a 307 Temporary Redirect. The server includes a custom x-nextjs-redirect header that points to /api/auth/signinin?callbackUrl=%2Fdocs, proving that the application protects even client-side data fetches for the documentation page with authentication middleware. The persistent next-auth.callback-url cookie continues to reference http://localhost:3000/api/download

Path Traversal & Sensitive File Disclosure

The Next.js data route /_next/data/…/docs.json responds with 200 OK and returns the full rendered HTML of the PreviousJS documentation page. Additionally, the response includes a highly repeated X-Middleware-Subrequest header, with the middleware appearing five times.

The Next.js data route /_next/data/…/docs.json returns 200 OK. It delivers the full rendered HTML of the documentation overview page. The content prominently shows navigation links to β€œ/docs/getting-started” and β€œ/docs/examples”

Accessing /docs/content/examples via GET triggers a 307 Temporary Redirect. The custom x-nextjs-redirect header forwards the request to /api/auth/signinin?callbackUrl=%2Fdocs%2Fcontent%2Fexamples. This clearly shows that the nested documentation path stays protected by authentication middleware.

Accessing the path /docs/content/examples via GET results in a 307 Temporary Redirect. The custom x-nextjs-redirect header directs the request to /api/auth/signinin?callbackUrl=%2Fdocs%2Fcontent%2Fexamples. This clearly confirms that authentication middleware protects the nested documentation sub-route.

Path Traversal Vulnerability Discovery

A screenshot of a computer screen

AI-generated content may be incorrect.

The request includes a persistent next-auth.callback-url localhost cookie and repeated x-middleware-subrequest headers, indicating that the /api/download route bypasses authentication controls even though other application routes remain protected.

The response body contains the full contents of /etc/passwd. Exposed entries include standard system users such as root, bin, daemon, lp, sync, shutdown, halt, mail, uucp, operator, games, gopher, ftp, and nobody. Custom users like node (UID 1000) and nextjs (UID 1001) are also disclosed.

Sensitive File Disclosure

A request to /api/download?example=../../../../../../../../app/.env return a 200 OK response. The server replies with Content-Type: application/zip and a Content-Disposition header specifying filename=".env". This shows that the endpoint packages the requested file as a downloadable archive.

A screenshot of a computer screen

AI-generated content may be incorrect.

Accessing /api/download?example=../../../../../../../../app/.next/routes-manifest.json results in a 200 OK response. The server returns Content-Type: application/zip along with a Content-Disposition header specifying filename="routes-manifest.json".

Interaction with /api/download?example=../../../../../../../../app/.next/server/pages/api/auth/[...nextauth].js produces . Within the returned archive, the compiled NextAuth API route handler is exposed. This demonstrates that internal authentication logic can be retrieved as a downloadable file.

This leak confirms the intended credentials for login are:

  • Username: jeremy
  • Password: MyNameIsJeremyAndILovePancakes (as defined in ADMIN_SECRET)

Initial Access via SSH on Previous Machine

A screenshot of a computer screen

AI-generated content may be incorrect.

Successful SSH login as user jeremy to previous.htb (10.10.11.83) using the password obtained from the leaked NextAuth credentials code (MyNameIsJeremyAndILovePancakes), landing in a standard Ubuntu 22.04.5 LTS shell

Command execution on the target as user jeremy via SSH: cat user.txt displays the standard user flag format string

Escalate to Root Privileges Access

Privilege Escalation:

After running sudo -l as user jeremy on the target and entering the account password, the command reveals the following sudo privileges.

  • Matching Defaults entries include env_reset, env_delete+=PATH, mail_badpass, secure_path restricted to standard system bins, and use_pty.
  • User jeremy may run the following command as root without password: (root) /usr/bin/terraform -chdir=/opt/examples apply
A screenshot of a computer screen

AI-generated content may be incorrect.

Running /usr/bin/terraform without arguments as user jeremy displays the full Terraform CLI help output. The behavior confirms that Terraform is installed on the system. Its binary is accessible at /usr/bin/terraform.

Terraform as an Infrastructure‑as‑Code Tool

Terraform is an infrastructure‑as‑code (IaC) tool created by HashiCorp.

In other words, Terraform allows you to define and manage infrastructure through configuration files rather than manually clicking through dashboards.

The listing confirms that Jeremy has full control over his home directory and Terraform-related files relevant to the sudo rule. Direct read access to the user flag is available without requiring privilege escalation.

The configuration defines a dev_overrides block. This forces Terraform to load a local provider binary from /usr/local/go/bin.

Verification confirms that /bin/bash exists on the system. Typical permissions are set for a default shell on an Ubuntu‑based machine.

This file is clearly the intended local privilege escalation vector.

Commands executed as user jeremy: gcc dark.c -o terraform-provider-examples compiles the fixed exploit source into a binary named terraform-provider-examples, followed by chmod +x terraform-provider-examples to make it executable.

A computer screen with green text

AI-generated content may be incorrect.

Placement in /usr/local/go/bin allows Terraform to load the provider during the apply operation in /opt/examples. The dev_overrides setting in .terraformrc triggers this behavior. Together, these actions complete the setup for root privilege escalation.

Executing sudo /usr/bin/terraform -chdir=/opt/examples apply as user jeremy (after a password prompt) runs successfully as root, displaying the Terraform warning about active provider development overrides pointing to /usr/local/go/bin. Terraform refreshes state, finds no changes needed, and completes the apply with 0 resources added/changed/destroyed. The output confirms the custom provider was loaded without errors, and the malicious binary executed its payload (making /bin/bash SUID root), achieving full root privilege escalation via the dev override and sudo rule.

As a result of the exploit, the presence of s in both the owner and group execute bits (rwsr-sr-x) confirms that /bin/bash is now SUID root and SGID root. Consequently, any user can execute it and immediately gain a root shell, for example, by running bash -p. This is the direct result of the successful execution of the malicious Terraform provider binary, completing the root privilege escalation on the machine.

A black background with green and yellow letters

AI-generated content may be incorrect.

Execution of /bin/bash -p as user jeremy immediately spawns a new bash shell with the prompt changing to bash-5.1#, indicating successful privilege escalation to root shell via the now-SUID /bin/bash binary.

A green text on a black background

AI-generated content may be incorrect.

The root flag can be read successfully.

The post Hack The Box: Previous Machine Walkthrough – Medium Difficulty appeared first on Threatninja.net.

❌