Difficulty: Medium
OS: Linux
Creator: Tensho
Release Date: January 8, 2026
Target IP: 10.129.39.53
Table of Contents#
- Reconnaissance
- Initial Foothold - Chrome Extension RCE
- User Access - SSH Key Discovery
- Privilege Escalation - Python Bytecode Cache Poisoning
- Flags
- Summary
Reconnaissance#
Port Scanning#
| |
Open Ports:
- Port 80: HTTP (Web Application)
- Port 22: SSH
Web Enumeration#
Add the target to /etc/hosts:
| |
Key Discoveries:
- Main site at
http://browsed.htballows uploading Chrome extensions (.zipfiles) - Gitea instance running at
browsedinternals.htb - Repository found:
larry/MarkdownPreviewathttp://browsedinternals.htb/larry/MarkdownPreview/src/branch/main/app.py - MarkdownPreview Flask app runs on
localhost:5000and has command injection vulnerability in the/routines/endpoint - Chrome is running with
--no-sandboxflag (vulnerable to extension-based attacks) - Chrome version is 134 (vulnerable to extension exploits)
Initial Foothold - Chrome Extension RCE#
Vulnerability Analysis#
The web application:
- Accepts Chrome extension uploads (
.zipfiles) - Extensions run with permissions to access
localhost - Can send requests to the MarkdownPreview Flask app on
127.0.0.1:5000 - The
/routines/endpoint is vulnerable to command injection via bash parameter expansion
Attack Vector#
Create a malicious Chrome extension that exploits the command injection vulnerability in the MarkdownPreview Flask app running on localhost.
Exploitation Steps#
Step 1: Create the exploit script
Save this as create_exploit.py:
| |
Step 2: Generate the malicious extension
| |
Output:
| |
Step 3: Set up listener
| |
Step 4: Upload the extension
- Navigate to
http://browsed.htb - Upload
shell_exploit.zip - Wait for the extension to be processed
Step 5: Catch the reverse shell
You should receive a shell as the larry user:
| |
Step 6: Stabilize the shell (optional)
| |
Alternative Manual Method#
If you prefer to create the extension manually:
Create manifest.json:
| |
Create background.js:
| |
Package and upload:
| |
User Access - SSH Key Discovery#
Enumeration#
Once you have a shell as larry, search for SSH keys:
| |
SSH Key Discovery#
The SSH private key uses ED25519 algorithm (not RSA):
| |
Establish Stable SSH Connection#
Step 1: Copy the private key to your attack machine
| |
Step 2: Save and set permissions on Kali
| |
Step 3: SSH as larry
| |
Successful connection:
| |
Privilege Escalation - Python Bytecode Cache Poisoning#
Enumeration#
Check sudo privileges:
| |
Examine the script and permissions:
| |
Key Finding:
- The
__pycache__directory is world-writable - Python uses
.pycbytecode cache files from this directory - The script imports
extension_utils.py - We can poison the cache with malicious bytecode that executes as root
Vulnerability: Python Bytecode Cache Poisoning#
Python uses cached bytecode (.pyc files) to speed up module imports. When a Python script runs:
- Python checks if a
.pycfile exists in__pycache__ - If the
.pycfile’s timestamp and size match the source.pyfile, Python uses the cached bytecode - Crucially: Python doesn’t verify the actual content matches
If we can write to __pycache__, we can inject malicious bytecode that will execute with root privileges when the script runs with sudo.
Exploitation Steps#
Step 1: Create the exploit script
| |
Step 2: Run the exploit
| |
Step 3: Trigger the malicious bytecode
When we run the extension tool with sudo, it loads our poisoned bytecode instead of the legitimate code:
| |
This executes our malicious code as root, creating /tmp/rootbash with SUID permissions.
Step 4: Get root shell
| |
The -p flag preserves the SUID privileges, giving us a root shell.
Step 5: Navigate and retrieve the root flag
| |
How the Attack Works#
- Size Matching: We pad our malicious code to exactly match the original file size
- Timestamp Spoofing: We copy the original file’s modification time to our malicious version
- Bytecode Compilation: We compile our code to
.pycbytecode - Cache Poisoning: We replace the legitimate
.pycin__pycache__ - Execution: When Python loads the module, it sees matching size/timestamp and uses our malicious bytecode
- SUID Creation: Our code creates a SUID copy of bash that we can execute for root access
Manual Alternative (Without Script)#
If you prefer step-by-step commands:
| |
Flags#
User Flag#
| |
Root Flag#
| |
Summary#
Attack Chain#
- Reconnaissance: Discovered Chrome extension upload functionality and Gitea repository containing MarkdownPreview Flask app source code
- Initial Foothold: Created malicious Chrome Manifest V3 extension that exploited command injection in the
/routines/endpoint via localhost access - User Access: Found ED25519 SSH private key in larry’s home directory for stable shell access
- Privilege Escalation: Exploited world-writable Python
__pycache__directory to inject malicious bytecode that executes as root, creating SUID bash for privilege escalation
Key Techniques#
- Chrome Extension Exploitation: Leveraging browser extensions with localhost permissions to access internal services
- Command Injection via Parameter Expansion: Exploiting bash parameter expansion
a[$(command)]for code execution - Python Bytecode Poisoning: Manipulating
.pyccache files to inject malicious code by matching file size and timestamps - SUID Binary Creation: Creating SUID copy of bash for privilege escalation
Vulnerabilities Exploited#
- Insecure Chrome Extension Handling: No validation or sandboxing of uploaded extensions
- Command Injection: User input directly interpolated into shell commands without sanitization
- World-Writable Cache Directory:
/opt/extensiontool/__pycache__/writable by all users - Sudo Misconfiguration: Ability to run Python script as root without password
- Weak Bytecode Validation: Python only checks file size and timestamp, not actual content integrity
Timeline#
- Initial Access: Achieved via malicious Chrome extension upload
- User Shell: Obtained reverse shell as
larryuser - Stable Access: Established via ED25519 SSH key
- Root Access: Gained through Python bytecode cache poisoning
Mitigation Recommendations#
Chrome Extensions:
- Implement strict validation of uploaded extensions
- Use Content Security Policy (CSP) to restrict extension capabilities
- Sandbox extension execution environment
- Validate extension manifests and code before installation
Command Injection Prevention:
- Never pass user input directly to shell commands
- Use parameterized functions like
subprocess.run()with lists instead of shell=True - Implement input validation and sanitization
- Use allowlists for acceptable input patterns
File System Permissions:
- Ensure
__pycache__directories are not world-writable - Set proper ownership (root:root) for system directories
- Use
chmod 755or more restrictive permissions
- Ensure
Sudo Configuration:
- Minimize sudo privileges to only necessary commands
- Implement bytecode integrity checking before execution
- Use
sudo -Erestrictions and validate PYTHONPATH - Consider using checksums or digital signatures for critical scripts
Python Security:
- Set PYTHONDONTWRITEBYTECODE=1 to disable bytecode caching
- Use
python -Bflag to ignore bytecode cache files - Implement file integrity monitoring for critical Python modules
- Restrict write permissions on Python library directories
Defense in Depth:
- Implement SELinux or AppArmor policies
- Use file integrity monitoring (AIDE, Tripwire)
- Regular security audits of file permissions
- Monitor for suspicious SUID file creation
References#
- Python Bytecode Cache Poisoning - matmul.net
- Chrome Extension Security Best Practices
- Synack: ZIP Embedding Attack on Chrome Extensions
- Python Documentation: Compiled Python Files
- OWASP Command Injection
Author Notes: This writeup demonstrates a realistic attack chain involving modern web technologies (Chrome extensions), internal service exploitation, and advanced privilege escalation through bytecode manipulation. The Python bytecode poisoning technique is particularly educational as it exploits Python’s caching mechanism in a creative way that’s not commonly seen in CTF environments.
The box effectively teaches:
- Modern browser security concepts
- Command injection exploitation techniques
- Python internals and bytecode compilation
- Linux privilege escalation methodologies
- The importance of proper file permissions in multi-user systems



