Logrotate
Every Linux system produces large amounts of log files. To prevent the hard disk from overflowing, a tool called logrotate
takes care of archiving or disposing of old logs.
Logrotate
has many features for managing these log files:
- the
size
of the log file, - its
age
, - and the
action
to be taken when one of these factors is reached.
The function of the rotation itself consists in renaming the log files. This tool is usually started periodically via cron
and controlled via the configuration file /etc/logrotate.conf
. Within this file, it contains global settings that determine the function of logrotate
.
To force a new rotation on the same day, we can set the date after the individual log files in the status file /var/lib/logrotate.status
. Example, forcing rotation on samba:
/etc/logrotate.d/
directory contains the corresponding configuration files for each service.
logrotten
There is a vulnerability on logrotate that allows a user with write permissions over a log file or any of its parent directories to make logrotatewrite a file in any location. If logrotate is being executed by root, then the user will be able to write any file in /etc/bash_completion.d/ that will be executed by any user that login.
To exploit logrotate
, we need some requirements that we have to fulfill.
1. we need write
permissions on the log files
2. logrotate must run as a privileged user or root
. This is the normal behaviour.
3. vulnerable versions: - 3.8.6 - 3.11.0 - 3.15.0 - 3.18.0
The general idea is that logrotate will archive the log file to the log directory, but there is a split second before this happens, and the exploit will replace the log directory with a symlink to /etc/bash_completion.d/, achieving write as root to /etc/bash_completion.d/.
For exploiting this, we need to locate which service is running the generation of log. One way to explore this is by printing the configuration of every service at /etc/logrotate.d/
.
The exploit is at: https://github.com/whotwagner/logrotten
Next, we need a payload to be executed.
In this example, we will run a simple bash-based reverse shell with the IP
and port
of our VM that we use to attack the target system.
However, before running the exploit, we need to determine which option logrotate
uses in logrotate.conf
.
If the output is "create", then we will use the exploit adapted to this function.
If the output is "compress", then we will use the exploit adapted to this function.
Wait for the reverse shell to spawn.
Trobleshooting: GLIBC Version
Troubleshooting when launching the command:
Output:
The issue is that the logrotten
binary compiled requires GLIBC 2.34, but the target system has an older version. Here’s how to fix this:
1. Check the Target System's GLIBC Version
Look at the first line. If the version is older than 2.34, we have two options:
Compile logrotten on the target system (if gcc is available).
Compile logrotten with an older GLIBC version on the attacking machine.
Compile logrotten with an Older GLIBC. Find an older system (or a Docker container) that matches the target. Compile logrotten on that system:
The -static flag ensures the binary doesn’t rely on the target system’s GLIBC.
Trobleshooting: no /etc/logrotate.conf
file
If there is no /etc/logrotate.conf
file, then logrotate relies on the configuration for each service contained at /etc/logrotate.d/
directory.
HTB lab
SH to (ACADEMY-LLPE-LOG) with user "htb-student" and password "HTB_@cademy_stdnt!". Escalate the privileges and submit the contents of flag.txt as the answer.
Connect via ssh to the target.
We run linpeas_linux_amd64 and notice the lines:
To exploit logrotate
, we need some requirements that we have to fulfill.
1. we need write
permissions on the log files
2. logrotate must run as a privileged user or root
. This is the normal behaviour.
3. vulnerable versions: - 3.8.6 - 3.11.0 - 3.15.0 - 3.18.0
Output is 3.11.
Craft the payload:
Run the exploit:
As an outcome (we need to run this even 3 times), we will obtain the flag.txt in our /home/htb-student folder.
Results: HTB{l0G_r0t7t73N_00ps}
Another way to do it:
We will generate a new user with root capabilities: