Beyond
This is the beyond page that an additional post enumeration and assessment are conducted as the root
user after compromising the target system.
Cron
root@download:~# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
Surprisingly, the crontab of the root
user is empty
Service
root@download:~# ll /etc/systemd/system/
total 80
drwxr-xr-x 18 root root 4096 jul 19 16:06 ./
drwxr-xr-x 5 root root 4096 jul 19 15:35 ../
drwxr-xr-x 2 root root 4096 jul 19 15:35 cloud-init.target.wants/
lrwxrwxrwx 1 root root 40 jul 19 12:39 dbus-org.freedesktop.ModemManager1.service -> /lib/systemd/system/ModemManager.service
lrwxrwxrwx 1 root root 44 Apr 23 2020 dbus-org.freedesktop.resolve1.service -> /lib/systemd/system/systemd-resolved.service
lrwxrwxrwx 1 root root 36 apr 20 14:57 dbus-org.freedesktop.thermald.service -> /lib/systemd/system/thermald.service
lrwxrwxrwx 1 root root 45 Apr 23 2020 dbus-org.freedesktop.timesync1.service -> /lib/systemd/system/systemd-timesyncd.service
drwxr-xr-x 2 root root 4096 jul 19 15:35 default.target.wants/
-rw-r--r-- 1 root root 357 apr 21 15:36 download-site.service
drwxr-xr-x 2 root root 4096 jul 19 15:35 emergency.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 getty.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 graphical.target.wants/
lrwxrwxrwx 1 root root 38 Apr 23 2020 iscsi.service -> /lib/systemd/system/open-iscsi.service
-rw------- 1 root root 222 apr 21 14:33 management.service
drwxr-xr-x 2 root root 4096 jul 19 15:35 mdmonitor.service.wants/
lrwxrwxrwx 1 root root 38 Apr 23 2020 multipath-tools.service -> /lib/systemd/system/multipathd.service
drwxr-xr-x 2 root root 4096 jul 19 16:06 multi-user.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 network-online.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 open-vm-tools.service.requires/
drwxr-xr-x 2 root root 4096 jul 19 15:35 paths.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 rescue.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 sleep.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 16:06 sockets.target.wants/
drwxr-xr-x 2 root root 4096 jul 19 15:35 'sshd-keygen@.service.d'/
lrwxrwxrwx 1 root root 31 apr 20 14:57 sshd.service -> /lib/systemd/system/ssh.service
drwxr-xr-x 2 root root 4096 jul 19 15:35 sysinit.target.wants/
lrwxrwxrwx 1 root root 35 Apr 23 2020 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x 2 root root 4096 jul 19 16:06 timers.target.wants/
lrwxrwxrwx 1 root root 41 Apr 23 2020 vmtoolsd.service -> /lib/systemd/system/open-vm-tools.service
Instead, there is a service file that can only be access from the root
user, /etc/systemd/system/management.service
root@download:~# cat /etc/systemd/system/management.service
[Unit]
Description=DBMS Management
After=postgresql.service
[Service]
Type=simple
ExecStart=/root/venv/bin/python3 /root/management.py
WorkingDirectory=/root
User=root
Restart=always
[Install]
WantedBy=multi-user.target
It executes a Python script; /root/management.py
/root/management.py
root@download:~# cat /root/management.py
import paramiko
import time
import os
while True:
print("Deleting files")
for file_name in os.listdir("/var/lib/postgresql/"):
if file_name != "12":
os.remove(os.path.join("/var/lib/postgresql/", file_name))
# This gives people 60 seconds to get their payload within .bashrc
time.sleep(60)
print("SSHing")
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("localhost", username="root", password="QzN6j#aP#N6!7knrXkN!B$7kq")
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.invoke_shell()
chan.send(b'/bin/bash -i ./manage-db\n')
time.sleep(5)
chan.send(b"psql\n")
time.sleep(30)
if not chan.closed:
chan.close()
The Python script performs a number tasks with an interval of 95 seconds;
- Wipes everything in the
/var/lib/postgresql/
directory, except for one named,12
- SSH through the localhost address with the hard-coded CLEARTEXT credential;
root
:QzN6j#aP#N6!7knrXkN!B$7kq
- Opens up an interactive bash shell session to execute the
manage-db
file - Invokes the psql binary
- Ensures the SSH channel is closed if not already done
manage-db
root@download:~# cat ./manage-db
#!/bin/bash -i
echo "[*] Checking status of database"
SYSTEMD_PAGER= systemctl status postgresql
echo "[*] Checking status of webserver"
SYSTEMD_PAGER= systemctl status download-site
echo "[*] Entering postgres user, use 'psql' to enter DB"
su -l postgres
The manage-db
file is a Bash script that;
- calls
systemctl status postgresql
- calls
systemctl status download-site
- switches the current UID to the
postgres
user with the vulnerablesu -l
command
Weird linker with psql
root@download:/tmp# sudo -u postgres psql
I thought psql being called with a linker was a strange behavior but it does that by default..