/var/mychoot
と同じファイルシステムにディレクトリがあり、プログラムを起動した/
ため、プログラムはEUID 0で実行されます/var/mychroot/prog
。sudo chroot /var/mychroot /prog
プログラムが実行されるとchdir("..") エスケープ技術その後、chrootを脱出して内部のすべてを見ることができます/
。 (Linux 4.18でこれを確認しました。)
私はそのような脱出を防ぎたい。実際、私はさまざまなchrootエスケープを避けたいのですが、この質問では何をすべきかについてのみ興味があります。chdir("..") エスケープ技術これは、最新のLinuxシステムでは回避できます。そのために代替案を探しています。chroot(2)システムコール。
2つの解決策が見つかりました。ピボットルートそしてMS_モバイルただし、/var/mychroot
マウントポイントの場合にのみ機能するため、/var/mychroot
ファイルシステムのサブディレクトリの場合は失敗します/
。この場合、他の解決策はありますか?
LD_PRELOAD
技術の使用を避け(LD_PRELOAD
静的にリンクされた実行可能ファイルは影響を受けません)、技術を使用したいと思います。トラック(2)(もしそうなら、私はstrace
chrootで実行できません、トラック(2)プロセスがクラッシュしたり停止したり、真の仮想化(パフォーマンスのオーバーヘッドや柔軟性の低いメモリ構成など)を正しく実行するのは難しいです。
要約すると、以下が必要です。
- の代替chroot(2)システムコール、
- ルートはこれを使用して、ルート(EUID 0)で実行されるプロセスを制限します。
- ファイルシステムのサブディレクトリとして
/
、 - これは防ぎますchdir("..") エスケープ技術、
- 使用し
LD_PRELOAD
ない - トラック(2)または
- 仮想化(例:Xen、KVM、QEMU)
- 最新のLinuxシステムで動作し、
- パッチされたカーネルがある場合とない場合。
存在しますか?
答え1
上記の特定のエスケープ技術を回避するには、ロックしてchdir("..")
再実行する機能を放棄するだけです。エスケープ技術を再度呼び出す必要があるため、これをブロックするだけでは機能しません。chroot(2)
/var/mychroot
chroot()
Linux機能を使用してこれを行うことができます。CAP_SYS_CHROOT
必要な機能を削除するだけですchroot(2)
。
たとえば、
outside# chroot /var/mychroot
inside# capsh --drop=cap_sys_chroot --
inside# ./escape_chroot
chroot(baz): Operation not permitted
(chroot内の2番目のプロンプトは生成されたシェルから来ますcapsh
。たとえば、を使用して別のコマンドを実行させることができますcapsh --drop=cap_sys_chroot -- -c 'exec ./escape_chroot'
。)
しかし、より良い技術は、予防できないpivot_root
他の多くの攻撃を防ぐことができるためにのみ使用することです。chroot(2)
マウントポイントの場合にのみ機能すると言いましたが、/var/mychroot
単にバインドマウントしてマウントポイントにすることができます。
pivot_root
刑務所を作成するにはマウントネームスペースを作成する必要があることに注意してください。それ以外の場合は、ファイルシステム内のすべてのプロセスのルートディレクトリを変更しようとします。これはあなたが望むものとは異なる可能性が高いです。
したがって、全体の順序は次のようになります。
outside# unshare -m
outside# mount --bind /var/mychroot /var/mychroot
outside# cd /var/mychroot
outside# mkdir old_root
outside# pivot_root . old_root
limbo# exec chroot .
inside# umount /old_root
(やはり、これらのコマンドの多くは新しいシェルを生成します。それはそれ自体で行われます。unshare
コマンドを追加のchroot
引数として渡すことでこれらの問題を解決できます。場合によってはスクリプト全体を渡すこともsh -c '...'
できます。)
この時点で、あなたは別のマウントネームスペースの刑務所の中にいます。これが単に元のルート(別のデバイスやループデバイスのマウントではない)であるというpivot_root
事実は実際には動作を妨げません。/var/mychroot
マウントを中央にバインドします。
エスケープコードを実行すると、刑務所が期待どおりに機能することがわかります(エスケープコードに別の方法で指定されていますが)。
inside# touch /inside_jail
inside# ./escape_chroot
Exploit seems to work. =)
inside# ls -ld /inside_jail /old_root
-rw-r--r--. 1 0 0 0 Jan 5 23:45 /inside_jail
dr-xr-xr-x. 20 0 0 4096 Jul 5 23:45 /old_root
ご覧のように、まだ刑務所の中にあります...エクスプロイトコードは少し素朴で、(chroot
、chdir
)仕事が成功すれば刑務所を脱出するのに十分であると仮定していますが、そうではありません。 。
chroot
したがって、この技術を使用して内部タスクをブロックするためにLinux機能を使用する必要がなく、より優れた刑務所を作成することを検討してください(たとえば、刑務所でchroot
実際にやりたいことよりも重要な追加機能を作成するなど)。
答え2
/var/mychrootがマウントポイントの場合にのみ機能するため、/var/mychrootが/ファイルシステムのサブディレクトリの場合は失敗します。
任意のディレクトリをマウントポイントに設定できますmount --rbind /var/mychoot /var/mychoot
。
このステップと必要なその他のステップについてはここで説明します。
実際、私はいろいろなchroot脱出を防ぎたいと思います。
上記の内容をユーザーの名前空間と組み合わせます。
または、seccomp
。mount()
たとえば、Dockerを含むプロセス呼び出しを防ぐ方法は次のとおりです。 (ブロックデバイスを2番目にマウントすると、ファイルシステムの2番目のビューが表示され、これはややエスケープと見なされます。)Dockerが許可するシステムコールのリストをコピーします。ルートを脱出する方法はさまざまです。
https://docs.docker.com/engine/security/seccomp/
https://github.com/moby/moby/blob/master/profiles/seccomp/default.json