
自動的にフォールトインジェクション攻撃を発見し実行する
▄▖ ▜ ▗ ▄▖ ▘ ▗ ▘ ▄▖▘ ▌
▙▖▀▌▌▌▐ ▜▘ ▐ ▛▌ ▌█▌▛▘▜▘▌▛▌▛▌ ▙▖▌▛▌▛▌█▌▛▘
▌ █▌▙▌▐▖▐▖ ▟▖▌▌ ▌▙▖▙▖▐▖▌▙▌▌▌ ▌ ▌▌▌▙▌▙▖▌
▙▌
このリポジトリは、私たちのフォールトインジェクション攻撃プロジェクトのソフトウェア側です。ハードウェア側は、このリポジトリ を確認してください。
このプロジェクトの目標は、プログラムの実行中にスキップ/NOP化されたときにセキュリティ問題を引き起こす命令を見つけることです。
targets/tooling.pyスクリプトとFPGAを使用して、ターゲット上で命令をテストする。以下の1つ以上を行うことでセキュリティ問題を調査します:
フォールトを注入するために、私たちは crowbar glitching を選択しました。これは、SI 2302 NチャネルMOSFETを搭載したFPGAを使用して実現しました。FPGAツールへのリンクはこちらです。 詳細は targets にあります。
トリガーとしては、FPGAへのGPIO入力を使用しました。テストコードではLEDをトグルしますが、トリガーのために電力分析を実行することもできます。
依存関係は requirements.txt にリストされています。 pip install -r requirements.txt でインストールしてください。
usage: main.py [-h] [-s INDEX] [-i MAX_ITERATIONS] [-o EXPECTED_OUTPUT] [-e EXPECTED_EXIT] [-d DESIRED_PC] [-v] [-n] [-t TYPES] [-b BINARY_ADDR]
[-u OUTPUT_DIR] [-f BEGIN_ADDR] [-g END_ADDR]
binary_path input_path
Automatically finds hardware security vulnerabilities in binaries. Only support ARM.
positional arguments:
binary_path The binary to examine
input_path The path to the input to the program
options:
-h, --help show this help message and exit
-s, --simulate INDEX Runs a Unicorn simulation with the fault at an nth instruction issue. Ignores all other flags besides --max_iterations and
--verbose.
-i, --max-iterations MAX_ITERATIONS
The maximum number of instructions to run in the binary before ending early
-o, --expected-output EXPECTED_OUTPUT
The expected output of the program on a successful security incident
-e, --expected-exit EXPECTED_EXIT
The expected exit of the program on a successful security incident
-d, --desired-pc DESIRED_PC
The program counter we desire to achieve if possible. In hex or decimal. Keep in mind that this is the absolute address,
not relative to the binary.
-v, --verbose Verbosity: warning, info, debug
-n, --no-thumb Whether or not to run in thumb mode
-t, --types TYPES Which types of instructions to focus on. 0) Brute force: every issue. 1) Recommended defaults. 2) Only conditional
branches. 3) Only compare/tests. 4) Only returns. 5) Only branches, calls, returns, and compares
-b, --binary-addr BINARY_ADDR
The address to flash the binary to. Defaults to 0x1000000. Can be in hex or decimal.
-u, --output-dir OUTPUT_DIR
The directory to store faults that were found.
-f, --begin-addr BEGIN_ADDR
The starting address of the instructions that should be considered for skipping. (inclusive.) If set, -g must also be set.
-g, --end-addr END_ADDR
The ending address of the instructions that should be considered for skipping. (inclusive.) If set, -f must also be set.
python3 main.py ./binaries/sha256.bin ./inputs/sha256.bin -o ./expecteds/sha256.bin -v
攻撃目標を達成したかどうかを確認するために出力をチェックします。
python3 main.py ./binaries/aes_ecb.bin ./inputs/aes_ecb.bin -d 0x100045c -v -u outputs/aes_ecb
aes_ecb バイナリをテストし、カスタムの「到達不能」関数にジャンプして、入力をディレクトリに保存します。
python3 main.py ./binaries/aes_ecb.bin ./outputs/aes_ecb/solved_pc_188.bin -s 188
この特定のグリッチサイクルと入力に対してUnicornシミュレーションを実行します。この場合、プログラムカウンタ制御からの出力を使用します。
binaries/sources に含まれるコードはテスト用です。実際のハードウェアを対象としておらず、ツールのテスト専用です。
デバイスを対象とした特定のバイナリを実行するには、単純なI/O以外のペリフェラルへの呼び出しを行わないように、バイナリの関連部分を抽出する必要があります。例えば、バイナリがUARTを使用している場合、UARTへの呼び出しを binaries/stubs にある _read および _write スタブへの呼び出しに置き換えてバイナリをパッチすることができます。さらに、必要に応じてGPIOを _trigger への呼び出しに置き換えることもできます。ツールを通じてコードを実行するには、パッチを適用したバイナリを含む main シンボルを作成し、それを binaries/startup.s コードとリンクします。これにより、ツールが起動してバイナリを実行できるようになります。
具体的な例については、TIMSPM0L2228でこのプロセスを示している targets ディレクトリを確認してください。
ターゲットで実行されているバイナリを反映したバイナリを作成するには、同じバージョンのコンパイラと同一のコンパイルフラグ/手順を使用する必要があります。自分でプログラムを作成してテストする場合、これは問題ありません。しかし、攻撃対象のターゲットのソースコードしかない場合、実行されている正確なバイナリにコンパイルできる可能性は低いです。したがって、可能な限りターゲットで実行されている正確なバイナリを使用することをお勧めします。