UTS Namespace

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 μ§€μ›ν•˜κΈ°

Basic Information

A UTS (UNIX Time-Sharing System) namespace is a Linux kernel feature that provides i두 μ‹œμŠ€ν…œ μ‹λ³„μžμ˜ 격리: the hostname and the NIS (Network Information Service) domain name. 이 격리λ₯Ό 톡해 각 UTS λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” 자체 독립적인 hostname 및 NIS 도메인 이름을 κ°€μ§ˆ 수 있으며, μ΄λŠ” 각 μ»¨ν…Œμ΄λ„ˆκ°€ 자체 hostname을 κ°€μ§„ λ³„λ„μ˜ μ‹œμŠ€ν…œμ²˜λŸΌ 보이도둝 ν•΄μ•Ό ν•˜λŠ” containerization ν™˜κ²½μ—μ„œ 특히 μœ μš©ν•©λ‹ˆλ‹€.

How it works:

  1. When a new UTS namespace is created, it starts with a copy of the hostname and NIS domain name from its parent namespace. This means that, at creation, the new namespace sμƒμœ„ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ™€ λ™μΌν•œ μ‹λ³„μžλ₯Ό κ³΅μœ ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ„€μž„μŠ€νŽ˜μ΄μŠ€ λ‚΄μ—μ„œ hostnameμ΄λ‚˜ NIS 도메인 이름에 λŒ€ν•œ 이후 변경은 λ‹€λ₯Έ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— 영ν–₯을 μ£Όμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  2. Processes within a UTS namespace can change the hostname and NIS domain name using the sethostname() and setdomainname() system calls, respectively. μ΄λŸ¬ν•œ 변경은 λ„€μž„μŠ€νŽ˜μ΄μŠ€ 둜컬이며 λ‹€λ₯Έ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‚˜ 호슀트 μ‹œμŠ€ν…œμ— 영ν–₯을 μ£Όμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  3. Processes can move between namespaces using the setns() system call or create new namespaces using the unshare() or clone() system calls with the CLONE_NEWUTS flag. ν”„λ‘œμ„ΈμŠ€κ°€ μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ μ΄λ™ν•˜κ±°λ‚˜ μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μƒμ„±ν•˜λ©΄ ν•΄λ‹Ή λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— μ—°κ΄€λœ hostname 및 NIS 도메인 이름을 μ‚¬μš©ν•˜κΈ° μ‹œμž‘ν•©λ‹ˆλ‹€.

Lab:

Create different Namespaces

CLI

sudo unshare -u [--mount-proc] /bin/bash

By mounting a new instance of the /proc filesystem if you use the param --mount-proc, you ensure that the new mount namespace has an ν•΄λ‹Ή λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— νŠΉν™”λœ ν”„λ‘œμ„ΈμŠ€ 정보λ₯Ό μ •ν™•ν•˜κ³  격리된 κ΄€μ μœΌλ‘œ λ³Ό 수 μžˆλ„λ‘.

Error: bash: fork: Cannot allocate memory

When unshare is executed without the -f option, an error is encountered due to the way Linux handles new PID (Process ID) namespaces. The key details and the solution are outlined below:

  1. 문제 μ„€λͺ…:
  • Linux 컀널은 ν”„λ‘œμ„ΈμŠ€κ°€ unshare μ‹œμŠ€ν…œ μ½œμ„ μ‚¬μš©ν•΄ μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 것을 ν—ˆμš©ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μƒˆλ‘œμš΄ PID (Process ID) λ„€μž„μŠ€νŽ˜μ΄μŠ€ 생성을 μ‹œμž‘ν•œ ν”„λ‘œμ„ΈμŠ€(이λ₯Ό β€œunshare” ν”„λ‘œμ„ΈμŠ€λΌκ³  칭함)λŠ” μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ λ“€μ–΄κ°€μ§€ μ•ŠμœΌλ©°, 였직 κ·Έ μžμ‹ ν”„λ‘œμ„ΈμŠ€λ“€λ§Œ λ“€μ–΄κ°‘λ‹ˆλ‹€.
  • Running %unshare -p /bin/bash% starts /bin/bash in the same process as unshare. Consequently, /bin/bash and its child processes are in the original PID namespace.
  • μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ—μ„œ /bin/bash의 첫 번째 μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ PID 1이 λ©λ‹ˆλ‹€. 이 ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜λ©΄(λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€κ°€ 없을 경우) λ„€μž„μŠ€νŽ˜μ΄μŠ€ 정리가 νŠΈλ¦¬κ±°λ©λ‹ˆλ‹€. PID 1은 κ³ μ•„ ν”„λ‘œμ„ΈμŠ€λ₯Ό μΈκ³„ν•˜λŠ” νŠΉμˆ˜ν•œ 역할을 κ°€μ§€κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. κ·Έ ν›„ Linux 컀널은 ν•΄λ‹Ή λ„€μž„μŠ€νŽ˜μ΄μŠ€μ—μ„œ PID 할당을 λΉ„ν™œμ„±ν™”ν•©λ‹ˆλ‹€.
  1. κ²°κ³Ό:
  • μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ—μ„œ PID 1의 μ’…λ£ŒλŠ” PIDNS_HASH_ADDING ν”Œλž˜κ·Έμ˜ μ •λ¦¬λ‘œ μ΄μ–΄μ§‘λ‹ˆλ‹€. 이둜 인해 alloc_pid ν•¨μˆ˜κ°€ μƒˆ ν”„λ‘œμ„ΈμŠ€ 생성 μ‹œ μƒˆλ‘œμš΄ PIDλ₯Ό ν• λ‹Ήν•˜μ§€ λͺ»ν•˜κ³  β€œCannot allocate memory” 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.
  1. ν•΄κ²°μ±…:
  • 이 λ¬Έμ œλŠ” unshare에 -f μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λ©΄ ν•΄κ²°λ©λ‹ˆλ‹€. 이 μ˜΅μ…˜μ€ μƒˆλ‘œμš΄ PID λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“  ν›„ unshareκ°€ μƒˆ ν”„λ‘œμ„ΈμŠ€λ₯Ό fork ν•˜κ²Œ λ§Œλ“­λ‹ˆλ‹€.
  • %unshare -fp /bin/bash%λ₯Ό μ‹€ν–‰ν•˜λ©΄ unshare μžμ‹ μ΄ μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ—μ„œ PID 1이 λ©λ‹ˆλ‹€. 그러면 /bin/bash와 κ·Έ μžμ‹ ν”„λ‘œμ„ΈμŠ€λ“€μ€ 이 μƒˆ λ„€μž„μŠ€νŽ˜μ΄μŠ€ 내에 μ•ˆμ „ν•˜κ²Œ ν¬ν•¨λ˜μ–΄ PID 1의 μ‘°κΈ° μ’…λ£Œλ₯Ό λ°©μ§€ν•˜κ³  정상적인 PID 할당이 κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.

unshareλ₯Ό -f ν”Œλž˜κ·Έμ™€ ν•¨κ»˜ μ‹€ν–‰ν•˜λ„λ‘ ν•˜λ©΄ μƒˆ PID λ„€μž„μŠ€νŽ˜μ΄μŠ€κ°€ μ˜¬λ°”λ₯΄κ²Œ μœ μ§€λ˜μ–΄ /bin/bash와 κ·Έ ν•˜μœ„ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ λ©”λͺ¨λ¦¬ ν• λ‹Ή 였λ₯˜ 없이 λ™μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Docker

docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash

ν”„λ‘œμ„ΈμŠ€κ°€ μ–΄λ–€ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— μžˆλŠ”μ§€ 확인

ls -l /proc/self/ns/uts
lrwxrwxrwx 1 root root 0 Apr  4 20:49 /proc/self/ns/uts -> 'uts:[4026531838]'

λͺ¨λ“  UTS namespaces μ°ΎκΈ°

sudo find /proc -maxdepth 3 -type l -name uts -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name uts -exec ls -l  {} \; 2>/dev/null | grep <ns-number>

UTS namespace에 λ“€μ–΄κ°€κΈ°

nsenter -u TARGET_PID --pid /bin/bash

호슀트 UTS 곡유 μ•…μš©

μ»¨ν…Œμ΄λ„ˆκ°€ --uts=host둜 μ‹œμž‘λ˜λ©΄, 격리된 UTS λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ–»λŠ” λŒ€μ‹  호슀트의 UTS λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— ν•©λ₯˜ν•©λ‹ˆλ‹€. --cap-add SYS_ADMIN 같은 κΆŒν•œμ΄ μžˆμ„ 경우, μ»¨ν…Œμ΄λ„ˆ λ‚΄μ˜ μ½”λ“œλŠ” sethostname()/setdomainname()을 톡해 호슀트의 hostname/NIS name을 λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

docker run --rm -it --uts=host --cap-add SYS_ADMIN alpine sh -c "hostname hacked-host && exec sh"
# Hostname on the host will immediately change to "hacked-host"

호슀트 이름을 λ³€κ²½ν•˜λ©΄ 둜그/μ•Œλ¦Όμ„ μ‘°μž‘ν•  수 있고, ν΄λŸ¬μŠ€ν„° 검색을 ν˜Όλž€μ‹œν‚€κ±°λ‚˜ 호슀트 이름을 κ³ μ •(pin)ν•œ TLS/SSH 섀정을 깨뜨릴 수 μžˆμŠ΅λ‹ˆλ‹€.

ν˜ΈμŠ€νŠΈμ™€ UTSλ₯Ό κ³΅μœ ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆ 감지

docker ps -aq | xargs -r docker inspect --format '{{.Id}} UTSMode={{.HostConfig.UTSMode}}'
# Shows "host" when the container uses the host UTS namespace

μ£„μ†‘ν•˜μ§€λ§Œ μ €λŠ” 둜컬 νŒŒμΌμ΄λ‚˜ 리포지토리에 직접 μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ²ˆμ—­ν•˜λ €λŠ” src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md 파일의 λ‚΄μš©μ„ μ—¬κΈ° λŒ€ν™”μ°½μ— λΆ™μ—¬λ„£μ–΄ μ£Όμ‹œκ² μ–΄μš”? λΆ™μ—¬λ„£μ–΄ μ£Όμ‹œλ©΄ μš”μ²­ν•˜μ‹  κ·œμΉ™(μ½”λ“œΒ·νƒœκ·ΈΒ·κ²½λ‘œ 보쑴 λ“±)을 μ§€μΌœ μ •ν™•ν•˜κ²Œ ν•œκ΅­μ–΄λ‘œ λ²ˆμ—­ν•΄ λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.