一部のファイル記述子がある場合は、「chroot(2)」以降の古いルートを復元する方法は?

一部のファイル記述子がある場合は、「chroot(2)」以降の古いルートを復元する方法は?

chroot(2)開いたファイル記述子を提供した後、古いルートをどのように再インポートしますか?

以下のプログラムでは、/まずファイル記述子を開き、chroot(2)次に開きます。.chdir(2)/

chdir(2)しかし、以前のルートディレクトリに移動すると、fdPythonは現在の作業ディレクトリがgetcwd()存在しないため印刷できないと文句を言います。

現在の作業ディレクトリを以前のルートディレクトリに変更して印刷できないのはなぜですか?

これが「pivot_root()」と「chroot()」がある理由で、どちらも目的の操作を実行するために使用できます。新しいルートを別の場所にマウントしてから、chroot(またはピボットルート)します。次に 'chdir("/")' を実行して cwd を新しいルートに移動します。 (その後、以前のルートを「失います」。ファイル記述子が開いている場合は、実際に再インポートして見つけることができます。)。

https://yarchive.net/comp/linux/pivot_root.html

プログラム:

import os

print(f'cwd: {os.getcwd()}')

fd = os.open('/', os.R_OK, os.X_OK)

os.chroot('.')
os.chdir('/')

print(f'cwd: {os.getcwd()}')

os.chdir(fd)

print(f'cwd: {os.getcwd()}')

出力:

$ sudo python3 chdir_fd.py
cwd: /home/admin/projects/linux-pwn
cwd: /
Traceback (most recent call last):
  File "chdir_fd.py", line 14, in <module>
FileNotFoundError: [Errno 2] No such file or directory

答え1

3つの問題があります。

  • chdir(2)ファイル記述子を使用しています。正しいシステムコールは次のようになります。fchdir(2)

    Pythonはおそらくそれを使用するのと同じくらい賢いでしょうfchdir()

  • それを使用した後、再fchdir(2)実行するchroot(2)必要があります現在のディレクトリが再表示されます。~へ現在「知られている空間」木。

  • 結果を区別できませんgetcwd()。どちらの場合も/同じでなくても結果が得られます/。たとえば、inode番号(同じファイルシステムであると仮定して比較結果が維持されます)または異なる可能性がある他の項目を表示できます。

ここでは、上記の変更に基づいてdebian Bullseye / sidからLXC Busterコンテナのルートディレクトリにルートを変更しました。私が2回見せるもの/etc/debian_version

import os

print(f'cwd: {os.getcwd()}')

fd = os.open('/', os.R_OK, os.X_OK)

os.chroot('.')
os.chdir('/')

print(f'cwd: {os.getcwd()}')

debfd=open("/etc/debian_version","r")
print(debfd.read())
debfd.close()

os.fchdir(fd)
os.chroot('.')

print(f'cwd: {os.getcwd()}')

debfd=open("/etc/debian_version","r")
print(debfd.read())
debfd.close()

結果:

root@glasswalker:/var/lib/lxc/buster-amd64/rootfs# /tmp/chrootback.py 
cwd: /var/lib/lxc/buster-amd64/rootfs
cwd: /
10.8

cwd: /
bullseye/sid

面倒なこと

「不明な空間」を悪用して脱出できるchroot() いいえファイル記述子は予約されています。 2005年このページでは、次のように説明します。

chroot() 刑務所から出る方法

#include <stdlib.h>与えられたコードの2つの問題(そのうちの1つは62行の二重引用符のスペルエラーを追加して修正する必要がある)に加えて、fprintf()今日のDebian(もちろんいくつかの* nix)ではまだうまくいきます。

私が理解したところによると、「不明な空間」にいるとき(例:西ドイツ現在の外部)それから私たちは盲目的に実際の状況に戻ることができます。

関連情報