Athena
Break all security and compromise the machine. - by MatheuZSec
Last updated
Break all security and compromise the machine. - by MatheuZSec
Last updated
The following post by 0xb0b is licensed under CC BY 4.0
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.
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 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:
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.
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.
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 kill
system 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.