Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4481c24

Browse files
committedNov 26, 2024·
Fix lint
1 parent 2a63810 commit 4481c24

File tree

1 file changed

+20
-26
lines changed
  • content/blog/ctfzone2024-registry

1 file changed

+20
-26
lines changed
 

‎content/blog/ctfzone2024-registry/index.md

+20-26
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ summary: |
1616
We're given an Attack/Defense challenge containing 5 services:
1717

1818
- registration \
19-
A custom service written in Go, used to registering (adding to database) new accounts
19+
A custom service written in Go, used to registering (adding to database) new accounts
2020

2121
- auth \
22-
Authentication server for Docker, based on [cesanta/docker_auth](https://github.com/cesanta/docker_auth) project
22+
Authentication server for Docker, based on [cesanta/docker_auth](https://github.com/cesanta/docker_auth) project
2323

2424
- registry \
25-
Container images distribution server, based on official implementation of registry [distribution/distribution](https://github.com/distribution/distribution)
25+
Container images distribution server, based on official implementation of registry [distribution/distribution](https://github.com/distribution/distribution)
2626

2727
- image-builder \
28-
A custom service written in Python and Bash, used to rebuild and flatten container images
28+
A custom service written in Python and Bash, used to rebuild and flatten container images
2929

3030
- nginx \
31-
Reverse proxy, entry point to internal endpoints
31+
Reverse proxy, entry point to internal endpoints
3232

3333
The checker's flow is following:
3434

@@ -42,23 +42,23 @@ Auth policy allows to pull (push, delete, etc) an image only for its owner, so i
4242

4343
```yaml
4444
acl:
45-
- match: {ip: "127.0.0.0/8"}
45+
- match: { ip: "127.0.0.0/8" }
4646
actions: ["*"]
4747
comment: "Allow everything from localhost (IPv4)"
4848

49-
- match: {ip: "::1"}
49+
- match: { ip: "::1" }
5050
actions: ["*"]
5151
comment: "Allow everything from localhost (IPv6)"
5252

53-
- match: {account: "service-user"}
53+
- match: { account: "service-user" }
5454
actions: ["*"]
5555
comment: "Admin has full access to everything."
5656

57-
- match: {account: "/.+/", name: "${account}/*"}
57+
- match: { account: "/.+/", name: "${account}/*" }
5858
actions: ["*"]
5959
comment: "Logged in users have full access to images that are in their 'namespace'"
6060

61-
- match: {account: "/.+/", type: "registry", name: "catalog"}
61+
- match: { account: "/.+/", type: "registry", name: "catalog" }
6262
actions: ["*"]
6363
comment: "Logged in users can query the catalog."
6464
```
@@ -96,7 +96,7 @@ Due to deploy mistake all vulnboxes have the same password for `service-user` ac
9696
foufons1atxnrpia
9797
```
9898

99-
First blood by [dtl](https://ctftime.org/team/157017/) exploited this vulnerability. We supposed that the password *actually* was generated during the startup so didn't event checked this.
99+
First blood by [dtl](https://ctftime.org/team/157017/) exploited this vulnerability. We supposed that the password _actually_ was generated during the startup so didn't event checked this.
100100

101101
Since `service-user` has full access, it lead to destructive action: someone started to delete checker images from registry.
102102

@@ -182,9 +182,7 @@ The file `manifest.json` contains a path to config file:
182182
[
183183
{
184184
"Config": "blobs/sha256/b17d896ce1034251f2642caa5d4b9f42782a557598792d33e811d723f127d332",
185-
"RepoTags": [
186-
"vzlom:latest"
187-
],
185+
"RepoTags": ["vzlom:latest"],
188186
"Layers": [
189187
"blobs/sha256/75654b8eeebd3beae97271a102f57cdeb794cc91e442648544963a7e951e9558",
190188
"blobs/sha256/7ed7aa814b865edc71b766dcf2d45f0a47077c5752984b9f3a7beb1bbbab097e"
@@ -211,12 +209,8 @@ And config file contains the target `.rootfs.diff_ids` array:
211209
{
212210
"architecture": "amd64",
213211
"config": {
214-
"Env": [
215-
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
216-
],
217-
"Cmd": [
218-
"/bin/sh"
219-
],
212+
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
213+
"Cmd": ["/bin/sh"],
220214
"WorkingDir": "/",
221215
"ArgsEscaped": true
222216
},
@@ -364,13 +358,13 @@ The file `vzlomik.tar` is already presented in `.overlay` from the previous imag
364358
Since the image-builder was running from `root` user, we could easily get RCE just by replacing `/usr/bin/skopeo` with our custom binary or shell script, but [renbou](https://t.me/renbou) suggested another clever way: replace `auth_config.yml`. It was possible because volumes for all containers were mounted with readwrite access. We registered new `service_user` account and grant it full access:
365359

366360
```yaml
367-
- match: {account: "service-user"}
368-
actions: ["*"]
369-
comment: "Admin has full access to everything."
361+
- match: { account: "service-user" }
362+
actions: ["*"]
363+
comment: "Admin has full access to everything."
370364
371-
- match: {account: "service_user"}
372-
actions: ["*"]
373-
comment: "Admin has full access to everything."
365+
- match: { account: "service_user" }
366+
actions: ["*"]
367+
comment: "Admin has full access to everything."
374368
```
375369

376370
All that's left to do is to use this account and download all checker images.

0 commit comments

Comments
 (0)
Please sign in to comment.