chroot(2)
開いたファイル記述子を提供した後、古いルートをどのように再インポートしますか?
以下のプログラムでは、/
まずファイル記述子を開き、chroot(2)
次に開きます。.
chdir(2)
/
chdir(2)
しかし、以前のルートディレクトリに移動すると、fd
Pythonは現在の作業ディレクトリが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年このページでは、次のように説明します。
#include <stdlib.h>
与えられたコードの2つの問題(そのうちの1つは62行の二重引用符のスペルエラーを追加して修正する必要がある)に加えて、fprintf()
今日のDebian(もちろんいくつかの* nix)ではまだうまくいきます。
私が理解したところによると、「不明な空間」にいるとき(例:西ドイツ現在の外部根)それから私たちは盲目的に実際の状況に戻ることができます。根。