Athena

Break all security and compromise the machine. - by MatheuZSec

Recon

Scanning our target with Nmap we can discover four open ports, of which on each of them runs a different service. On Port 22 SSH, on 80 a web server, and on 139/445 SMB.

We start with a directory scan on the web server, but do not find any interesting directories.

Visiting the site just gives us a static page with no working links.

Inspecting the source of the page confirms that there is nothing of interest.

We head on to the SMB service and enumerate it. We see two public shares, one of which public is accessible.

After connecting to the public share, we see a message for the administrator. By checking it out, it reveals a directory that our directory listing with our given wordlist was not able to find.

We get a page that is under development. A tool to ping other devices using the server.

User Flag

By providing a valid IP address, like localhost, we get the result of the ping.

The results are presented on a new page.

By trying to chain the commands using &, | or ; we get the message "Attempt hacking!". So a simple command chain to inject our payload like a reverse shell does not work here.

Another way to inject commands is to make use of command substitution.

In command substitution, it captures the output of one command and passes it as input or uses it in another command. Command substitution can be done by using $(your_command) in your command. So when the command line is parsed, everything inside $() gets executed first and the result is passed.

For example, in the command line:

cat $(cat test) 

cat test in the parentheses is executed first and passed to cat at the beginning. See the example below:

Now, we have to test if command substitution works here. For this, we use the Burp Suite Repeater module. We first placed 127.0.0.1 -c1 into the parameter IP and got our desired result. We used -c1 to get just one response for a fast result and for confirmation using sleep, seeing a delay. Next, we repeat that by adding a sleep command via command substitution 127.0.0.1 -c1$(sleep 5).

We execute it, and we get our results five seconds later.

We are now able to inject our commands, but at least the characters &, | and ; are being filtered.

Most of the reverse shells contain those characters, and URL encoding and double URL encoding did not work in this case.

So, we try it with a simple bind shell:

bind shell using nc
nc -lp 4445 -e /bin/bash

We place the command for a bind shell in the substituted command part and do not get a response. The listener seems to be running on the machine.

We are able to connect to the target machine using nc on port 4445. We are www-data. No flags were found with this user.

For convenience, we upgrade our shell.

SHELL=/bin/bash script -q /dev/null
STRG+Z
stty raw -echo && fg

Next, we start a python web server on our machine to provide the target with useful enumeration tools.

In this case, we used linpeas.sh and pspy64.

We were not able to find anything interesting with Linpeas. But pspy64 reveals that there is running something regularly (like a cronjob), executed by the user with the UID 1001. It is a backup script located at /usr/share/backup/backup.sh.

By checking out the passwd file, we see it is the user athena.

At /usr/share/backup/ we see that backup.sh is writable by the user www-data.

Since we have upgraded our shell, we are able to use vi to edit the backup.sh script. We replaced the code entirely with a nc mkfifo reverse shell and set up a listener on port 4446 on our machine.

After a short duration, the reverse shell connects and we are the user athena in the root directory. From there, we upgrade our shell again.

We head directly to /home/athena for the user flag and find it here.

Root Flag

While enumerating the user athena we immediately noticed the entry under sudo -l. We are able to execute insmod with sudo permissions without providing a password by loading a specific kernel module placed at /mnt/.../secret/venom.ko. The insmod command is a Linux shell command used to manually insert or load kernel modules into the running Linux kernel. Kernel modules are pieces of code that can be dynamically loaded into the kernel to extend its functionality.

The room tags already gave us a hint that this machine might be about reversing and rootkits. So we set up a Python web server on the target machine to be able to retrieve venom.ko, a kernel module, which we want to first know what it does.

For the analysis of the venom.ko file, we use Ghidra. In the functions list, we get a first impression of what we are dealing with here. Diamorphine.

Upon researching Diamorphine we get the following explanation:

Diamorphine is a rootkit that changes program behaviour by modifying kernel data structures. Among other things, it hides itself from lsmod, a command that lists all loaded modules. When Diamorphine loads itself, it modifies the modules linked list inside the kernel space to ensure it stays hidden

So it is a rootkit that is not detected after loading, it hides itself and modifies existing modules. Upon searching for a Diamorphine LKM rootkit, we found something on GitHub that modifies the kill syscall to gain root. The steps are provided in the README:

So let's try to figure out what it does.

At line 27 we see puVar2 a pointer to the system call table.

Looking at the lines 29 to 31 we see that the original function addresses of getdents, getdents64 and kill are referenced and stored.

Now, at lines 33 and 34 the entries for kill and getdents of the system call table are assigned to the addresses of hacked_getdents64 and hacked_kill. This effectively redirects any calls to the killsystem call to the hacked_kill function, allowing the rootkit to intercept and modify the behavior of the kill system call.

For reference the system call table:

The hacked_kill function is defined to handle incoming signals.

It checks the value of iVar3, which is the signal number provided as an argument to the kill system call.

Depending on the value of iVar3, it performs various actions:

  • If iVar3 is 0x39, it calls the give_root function. This suggests that a specific signal number (0x39) triggers a privilege escalation action.

  • If iVar3 is 0x3f, it toggles the module's hidden status. This appears to hide or reveal the presence of the rootkit module.

The give_root function appears to be performing actions that could result in privilege escalation. It creates a new cred structure, modifies specific fields within it, and commits the new credentials. So we have to provide the hacked_kill function with the value 0x39 to reach the give_root function to eventually escalate privileges.

So, we load the module via sudo /usr/sbin/insmod /mnt/.../secret/venom.ko and see that it is not present when using lsmod.

Thus, once the module is loaded, we should be able to interact with it, but how?

A big shoutout to EduW and Alexander87 for giving me a good hard push by providing me the source of MatheuZSec showcasing the LKM Rootkit Diamorphine.

We are able to interact with it by calling kill with the desired signal number and targeting all processes by specifying 0 as the process group or process ID.

By providing 63 (in hex 0x3f, recalling the analysis of the hacked_kill function) in the kill command to all processes, we are now able to see the venom module is present using lsmod. The module got successfully loaded, and we are able to control it using kill to propagate signals to it. This step is not necessary to gain root, but helps to see that the module is actually there.

So, now we continue and execute kill -57 0 (57 in hex is 0x39, recalling the analysis of the hacked_kill function), we become root and are able to access the root flag.

Last updated