
자동으로 오류 주입 공격을 찾고 실행합니다.
▄▖ ▜ ▗ ▄▖ ▘ ▗ ▘ ▄▖▘ ▌
▙▖▀▌▌▌▐ ▜▘ ▐ ▛▌ ▌█▌▛▘▜▘▌▛▌▛▌ ▙▖▌▛▌▛▌█▌▛▘
▌ █▌▙▌▐▖▐▖ ▟▖▌▌ ▌▙▖▙▖▐▖▌▙▌▌▌ ▌ ▌▌▌▙▌▙▖▌
▙▌
이 저장소는 결함 주입 공격 프로젝트의 소프트웨어 부분입니다. 하드웨어 부분은 이 저장소를 확인하세요.
이 프로젝트의 목표는 프로그램 실행 중 건너뛰거나 NOP 처리될 때 보안 문제를 일으키는 명령어를 찾는 것입니다.
targets/tooling.py 스크립트와 FPGA를 사용하여 대상에서 명령어 테스트다음 중 하나 이상을 수행하여 보안 문제를 검색합니다:
오류를 주입하기 위해 크로우바 글리칭을 선택했습니다. 이는 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
특정 글리치 사이클 및 입력에 대해 유니콘 시뮬레이션을 실행합니다. 이 경우 프로그램 카운터 제어의 출력입니다.
binaries/sources에 포함된 코드는 테스트용일 뿐입니다. 실제 하드웨어를 대상으로 하지 않으며, 도구 테스트를 위한 것입니다.
장치를 대상으로 하는 특정 바이너리를 실행하려면, 단순한 IO 외의 주변 장치 호출이 없도록 바이너리의 관련 부분을 추출해야 합니다. 예를 들어, 바이너리가 UART를 사용하는 경우, UART 호출을 binaries/stubs에 있는 _read 및 _write 스텁 호출로 대체하여 바이너리를 패치할 수 있습니다. 또한 GPIO는 원하는 경우 _trigger 호출로 대체할 수 있습니다. 도구를 통해 코드를 실행하려면, 패치된 바이너리를 포함하는 main 심볼을 만든 다음 binaries/startup.s 코드와 링크합니다. 이렇게 하면 도구가 시작되어 바이너리를 실행할 수 있습니다.
구체적인 예는 TIMSPM0L2228에서 이 과정을 보여주는 targets 디렉토리를 확인하세요.
대상에서 실행 중인 바이너리를 반영하는 바이너리를 만들려면 동일한 버전의 컴파일러와 동일한 컴파일 플래그/단계를 사용해야 합니다. 자신만의 프로그램을 만들어 테스트하는 경우에는 괜찮습니다. 그러나 공격 대상의 소스 코드만 있는 경우, 실행 중인 정확한 바이너리로 컴파일할 가능성이 낮습니다. 따라서 가능하면 대상에서 실행 중인 정확한 바이너리를 사용하는 것이 좋습니다.