Linuxバイナリが場所に依存しないコードでコンパイルされたかどうかをテストする方法は?

Linuxバイナリが場所に依存しないコードでコンパイルされたかどうかをテストする方法は?

私は最近(少なくともFedoraとRed Hat Enterprise Linuxでは)位置独立実行ファイル(PIE)でコンパイルされた実行ファイルがより強力なASLR(アドレス空間ランダム化)保護を受けていることに気づきました。

だから:特定の実行可能ファイルが場所に依存しない実行可能ファイルにコンパイルされたかどうかをLinuxでテストする方法は?

答え1

perlパッケージに含まれるスクリプトを使用できますhardening-checkFedoraで利用可能そしてダーバン(のようにhardening-includes)。これを読んでくださいDebian Wiki ページ確認するコンパイルフラグの詳細。これはDebianに固有のものですが、理論はRed Hatにも当てはまります。

例:

$ hardening-check $(which sshd)
/usr/sbin/sshd:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

答え2

fileバイナリで使用してください。

$ file ./pie-off
./pie-off: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0dc3858e9f0334060bfebcbe3e854909191d8bdc, not stripped
$ file ./pie-on
./pie-on: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=962235df5bd188e1ec48c151ff61b6435d395f89, not stripped

LSB情報の後に印刷されるさまざまな種類に注意してください。

答え3

file5.36は非常に明確です

file5.36 実際に実行可能ファイルがPIEであることを明確に印刷します。たとえば、PIE 実行可能ファイルは次のように表示されます。

main.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, not stripped

非PIEは次のとおりです。

main.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

この機能は5.33で導入されましたが、簡単なchmod +x確認のみを行います。以前はPIE用にのみ印刷していましたshared object

5.34では、より特殊化されたELFメタデータのチェックを開始する必要がありましたが、実装のバグがDF_1_PIE実際に問題を引き起こし、GCC PIE実行可能ファイルですshared objects

fileエラーを含むソースコードと検査するELF形式の正確なバイトを以下の詳細で説明しました。https://stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object-instead-of-an-executable-binary-according-to/55704865#55704865

文書5.36の動作を簡単にまとめると、次のようになります。

  • もしElf32_Ehdr.e_type == ET_EXEC
    • 印刷executable
  • そうでなければElf32_Ehdr.e_type == ET_DYN
    • DT_FLAGS_1動的部分項目が存在する場合
      • DF_1_PIE次のように設定されている場合DT_FLAGS_1
        • 印刷pie executable
      • その他
        • 印刷shared object
    • その他
      • ファイルがユーザー、グループ、または他の人によって実行可能かどうか
        • 印刷pie executable
      • その他
        • 印刷shared object

GDBは実行ファイルを2回実行し、ASLRを表示します。

あなたができる非常に簡単なことの1つは、GDBを介して実行可能ファイルを2回実行し、ASLRによって実行中にアドレスが変更されることを確認することです。

以下でこれを行う方法について詳しく説明しました。https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld/51308031#51308031

これは必ずしも最も実用的な解決策ではなく、実行可能ファイルを信頼していない場合は不可能ですが、興味深く、私たちが本当に興味を持っている最終チェック(Linuxカーネル/動的ローダーが実行可能ファイルを変更したかどうか)を実行します。場所かどうか。

答え4

BashスクリプトがありますGithubのchecksec.sh実行可能な緩和属性(RELRO、Stack Canary、NXビット、PIE、RPATH、RUNPATH、Fortify Sourceなど)を確認してください。

checksec-f(ファイル入力)引数として実行:

$ checksec -f /usr/bin/bash

RELRO           STACK CANARY      NX            PIE             RPATH     RUNPATH      FORTIFY Fortified Fortifiable
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH    YES      13        33

関連情報