Search code examples
pythonlinuxbashsudopenetration-testing

Stuck on a machine for pen-testing learning, possible sudo exploit?


I'm struggling with a machine (it's intended to be used for pen-testing training, it has been given by the university professor).

I've got a foothold into the machine and I've passed from www-data to developer, and there is another user called jamal with clearly important information to get root, who's the objective of the study.

I managed to find a folder /opt/scripts where there two files, utils.sh and backup.py. I can't edit neither of them since I don't have privileges (even the folder is protected).

Besides, I've sudo permission on utils.sh like this:

Matching Defaults entries for developer on app4:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User developer may run the following commands on app4:
    (jamal) SETENV: NOPASSWD: /opt/scripts/utils.sh

So I think I can use the program for getting into jamal. For what I tried, creating another echo in another folder with a reverse shell, changing the $PATH and then run it whit sudo -E doesn't work. Any suggestions?

Here's the code for utils and backup:

utils.sh

#!/bin/bash

view_users()
{
    /usr/bin/w
}

view_crontab()
{
    /usr/bin/crontab -l
}


backup_web()
{
    if [ "$EUID" -eq 1001 ]
    then
        echo "Running backup script..."
        /opt/scripts/backup.py &
    else
        echo "Insufficient privileges."
    fi
}


# Non-interactive way
if [ $# -eq 1 ]
then
    option=$1
    case $option in
        1) view_users ;;
        2) view_crontab ;;
        3) backup_web ;;

        *) echo "Unknown option." >&2
    esac

    exit 0
fi


# Interactive way, to be called from the command line
options=("View logged in users"
         "View crontab"
         "Backup web data"
         "Quit")

echo
echo "[[[ System Administration Menu ]]]"
PS3="Choose an option: "
COLUMNS=11
select opt in "${options[@]}"; do
    case $REPLY in
        1) view_users ; break ;;
        2) view_crontab ; break ;;
        3) backup_web ; break ;;
        4) echo "Bye!" ; break ;;

        *) echo "Unknown option." >&2
    esac
done

exit 0

backup.py

#!/usr/bin/python3

from shutil import make_archive

src = '/var/www/html/'

dst = '/tmp/backup'

make_archive(dst, 'gztar', src)

PS: the file that backup.py create doesn't contain anything useful: it's all information I already got.


Solution

  • This looks dangerous to me:

        (jamal) SETENV: NOPASSWD: /opt/scripts/utils.sh
                ^^^^^^^
    

    Your user developer can run /opt/scripts/utils.sh as Jamal, but also choose all environment variables while that script is being run. sudoers(5) explicitly warns about this:

    Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner.

    How is that a vulnerability? utils.sh only executes commands using absolute paths and functions from its local scope, so an exploit using the PATH variable is out of the question. However, there are several other options.

    Preloading a library with LD_PRELOAD is one way: the library is loaded as soon as a shell is started to run utils.sh. You can compile your own dynamic library with initialization code that does whatever you need.

    An even easier approach is to exploit PYTHONPATH to provide your own shutil.py module, with an implementation of make_archive that contains your payload.

    The exact implementation is left as an exercise to the reader ;)