
바이너리 전용 펌웨어 히스토리안은 유사한 바이너리에서 알려진 함수를 추출하여 원시 바이너리 내 함수 위치를 학습하며, 임베디드 펌웨어 분석을 위해 디스어셈블리 없이 빠른 함수 매칭을 가능하게 합니다.
Polypyus는 유사한 바이너리에서 알려진 함수를 추출하여 원시 바이너리에서 함수 위치를 학습합니다. 따라서 펌웨어 역사가라고 할 수 있습니다. Polypyus는 이러한 바이너리를 역어셈블하지 않고 작동하므로, 역어셈블이 복잡하고 일반적인 도구가 함수를 놓치는 바이너리에 유리합니다. 또한 바이너리 전용 접근 방식은 매우 빠르며 몇 초 안에 실행됩니다. 그러나 이 접근 방식은 바이너리가 동일한 아키텍처이고 유사한 컴파일러 옵션을 가져야 합니다.
Polypyus는 Ghidra, IDA, BinDiff, Diaphora와 같은 기존 도구의 워크플로우에 통합됩니다. 예를 들어, 이전에 주석이 달린 함수를 가져와 학습할 수 있고, 발견된 함수를 내보내 IDA로 가져올 수 있습니다. Polypyus는 상당히 엄격한 임계값을 사용하므로 실험에서 정확한 일치만 찾았습니다. 이로 인해 기존 도구보다 결과가 적을 수 있지만, 이러한 일치 항목을 IDA에 로드하여 자동 분석 결과를 개선한 후 BinDiff를 실행하기 위한 좋은 시작점이 됩니다.
다양한 Broadcom 및 Cypress Bluetooth 펌웨어 버전의 원시 펌웨어 바이너리를 작업할 때, IDA 자동 분석이 함수 시작점을 잘못 식별하는 경우가 많았습니다. IDA Pro 6.8에서 자동 분석은 다소 공격적이어서 더 많은 결과를 제공했지만 더 많은 오탐지도 발생했습니다. 전반적으로 IDA Pro 7.2 는 더 보수적이었지만 많은 함수를 놓쳤습니다. 이로 인해 IDA Pro 6.8에서는 펌웨어 간에 몇 가지 BinDiff 일치만 있었고 IDA Pro 7.2에서는 유용한 일치가 전혀 발생하지 않았습니다.
흥미롭게도 BinDiff는 분기를 제외하고 바이트가 동일한 함수를 식별하는 데 종종 실패했습니다. Polypyus는 정확히 이러한 바이트 동일 함수를 검색합니다. BinDiff가 이러한 함수에서 실패하는 이유는 누락된 함수와 오탐지로 인한 다른 호출 그래프 때문이라고 가정합니다. 때로는 이러한 함수가 IDA에 의해 이미 인식되었지만, IDA가 이를 코드로 인식하지 못하거나 함수로 표시하지 않은 경우가 많았습니다. Diaphora도 유사한 문제가 있습니다. Diaphora는 추가 처리 전에 IDA가 식별한 함수를 내보내기 때문입니다. 다음은 CYW20735B1 Bluetooth 펌웨어 바이너리에 대한 벤치마크로, 다양한 디스어셈블러와 디스어셈블러 실패가 후속 차이 분석 문제로 이어지는 방식을 비교합니다.
또한 Amnesia가 많은 함수를 찾지만, 많은 오탐지도 찾는다는 것을 발견했습니다. 그러나 많은 함수는 시작 부분에 유사한 스택 프레임 설정을 가지고 있습니다. 따라서 Polypyus에는 주석이 달린 입력 바이너리에서 일반적인 함수 시작점을 학습하고 이를 다른 바이너리에 적용하여 함수 이름을 일치시키지 않고 식별하는 옵션이 있습니다. 이 선택적 단계는 이전에 함수가 위치하지 않은 영역에만 적용되므로, 일반 함수 시작 방법과 주요 함수 찾기가 충돌하지 않습니다.
이러한 매처는 원시 바이너리에서 작동하므로 디스어셈블러에 의존하지 않습니다. 이는 한 가지 중요한 단점도 있습니다: 컴파일러 옵션이 다르거나 대상 아키텍처가 다른 경우, Polypyus는 유사한 함수를 감지하지 못합니다. 또한 식별된 일치 항목은 매우 신뢰할 수 있지만, 함수 시작 식별은 약간 덜 신뢰할 수 있으므로 후자를 신중하게 사용하세요. 다음에서 Cypress 평가 키트는 서로 매우 유사하지만 MacBook 펌웨어는 매우 다르다는 것을 볼 수 있습니다.
Polypyus는 주석이 달린 펌웨어 바이너리 모음에서 공통 함수를 비교하여 퍼지 바이너리 매처를 생성합니다.
현재 다음 주석이 지원됩니다:
patch.elf 파일..symdefs 파일.firmware 폴더에 문서화된 형식의 .csv 파일.이러한 주석에는 알려진 함수의 주소, 크기 및 이름이 포함됩니다. 히스토리 컬렉션의 입력 바이너리에 공통점이 많을수록 Polypyus 성능과 결과가 향상됩니다. 약간 다른 여러 함수가 주어지면 Polypyus는 매우 좋은 매처를 생성합니다.
Polypyus는 Python 3 >= 3.6이 필요합니다. 다음 설치에서는 virtualenv 사용을 권장합니다. 이 저장소를 클론하고 이 폴더에서 다음 명령을 실행하세요:
pip install .
설치 후 다음 명령을 사용할 수 있습니다:
polypyus-guipolypyus-cliPolypyus는 그래픽 인터페이스와 명령줄 인터페이스를 통해 사용할 수 있습니다.
GUI polypyus-gui와 CLI polypyus-cli 모두 호출 시 다음 인수를 사용합니다:
--verbose 는 자세한 정도입니다. 기본적으로 경고를 표시합니다. -v는 정보를, -vv는 디버그 정보를 표시합니다.
--project 는 프로젝트 파일의 위치를 설정합니다. 파일 경로나 ":memory:" 중 하나입니다.
--help 도움말 메시지를 표시합니다.
프로젝트 옵션을 사용하면 다양한 컨텍스트에 대한 작업을 다른 파일에 저장하고 다시 열 수 있습니다.
일반적인 GUI 워크플로우는 창의 왼쪽에서 오른쪽으로 진행됩니다.
먼저 히스토리에 바이너리가 추가됩니다. 그런 다음 히스토리 항목에 심볼 주석이 추가됩니다.
그 후 대상 바이너리를 추가할 수 있습니다.
일치를 위해 Create matchers from history를 클릭하세요. 매처가 생성되면 단일 대상을
선택하거나 batch match를 선택하여 모든 대상을 일치시킬 수 있습니다.
마지막으로 결과를 .csv 파일로 내보낼 수 있습니다.
다음 데모 비디오에서 Polypyus가 두 개의 입력 바이너리에서 학습하고, 주석을 달고, 매처를 생성하고, 새로운 바이너리에 일치를 적용하는 데 몇 초 밖에 걸리지 않는 것을 볼 수 있습니다.
CLI 사용의 장점은 자동화할 수 있다는 것입니다. 현재 CLI의 출력 형식은 변경될 수 있습니다. 그러나 호출 예제는 다음과 같습니다:
polypyus-cli --history firmware/history/20819-A1.bin --annotation firmware/history/20819-A1_patch.elf --history firmware/history/20735B1.bin --annotation firmware/history/20735B1_patch.elf --project test.sqlite
polypyus-cli --target firmware/history/20739B1.bin --project test.sqlite
첫 번째 명령은 test.sqlite를 새 프로젝트 파일로 생성하고 20819-A1.bin 및 20735B1.bin을
해당 patch.elf 파일과 함께 가져옵니다.
두 번째 호출은 동일한 프로젝트 파일을 재사용하고 바이너리 20739B1.bin에 대해 일치를 수행합니다.
각 명령에 대해 --history와 --annotation의 수가 일치해야 합니다.
이 두 명령은 첫 번째 명령에 --target 인수를 추가하여 하나로 결합할 수도 있습니다.
내부를 설명하는 논문이 Workshop on Binary Analysis Research (BAR) 2021에 Polypyus - The Firmware Historian이라는 제목으로 게재되었습니다. 자세한 내용은 Jan의 석사 논문 최종 발표에도 포함되어 있으며, ARM Thumb2 모드에서 기존 바이너리 차이 분석 접근 방식을 사용할 때 발생하는 문제와 대체 바이너리 전용 접근 방식이 어떻게 작동하는지 설명합니다.
patch.elf 또는 .symdefs 형식의 유출된 심볼에는 함수 및
전역 변수 이름만 포함됩니다. 그러나 WICED Studio 6.2 및 6.4에는 몇 가지 .pdom Eclipse 프로젝트 파일도
있습니다. 여기에는 추가 유형 정보가 포함됩니다. Eclipse는 자동 완성, 함수 검색 등을 위해 내부적으로 이를 사용하며,
역분석에 이를 활용하여 유형 정보를 추가할 수 있습니다. .pdom 파일은 부분적이고 캐시된 정보만 포함하므로,
여러 파일을 결합하는 것이 도움이 될 수 있습니다.
첫 번째 단계로 .pdom 유형 정보를 SQLite 데이터베이스로 내보냅니다. 내보내기
에는 시간이 걸리지만 중단했다가 나중에 계속할 수도 있습니다. 내보내기는 다음과 같이 작동합니다:
java -jar pdom/export/export.jar -P BCM20739-B0.1462220149391.pdom
PDOM 가져오기는 IDA 데이터베이스에서 함수 이름을 검색하고, PDOM에서 유형 정보를 찾기 위해 조회한 후,
해당 유형 정보를 IDA 데이터베이스에 적용합니다. 따라서 IDA 데이터베이스에는 먼저 올바른 함수 이름이
포함되어 있어야 합니다. 원칙적으로 Polypyus의 import_export 스크립트를 사용하여
생성할 수 있습니다. 그러나 PDOM 가져오기를 지원하는 약간 더 고급 스크립트는 patch.elf 섹션도 처리할 수
있습니다. 가져오기를 다음과 같이 실행하세요:
T=0x1로 설정합니다 (Alt-g).patch.elf 파일을 선택합니다 (Select file).20739mapb0.h를 가져와 하드웨어 레지스터 이름을 지정할 수도 있습니다 (Import map.h).이 스크립트는 IDA Pro 7.4 및 7.5에서 테스트되었습니다.
내부 테스트 후 IDA Pro 및 Polypyus를 사용할 때 다음 워크플로우를 권장합니다:
Alt-g, T=0x1).0x0 (rx), RAM: 0x200000 (rwx) (최소한 Bluetooth 펌웨어의 경우).0x4에 있는 4바이트 오프셋입니다 (o).
CYW20735 펌웨어에서는 0x3bc+1을 가리킵니다. 한 바이트 뒤로 이동하여 함수를 만듭니다 (p)....이제 IDA 데이터베이스가 어느 정도 유용해질 수 있습니다 :) 여전히 ARM Thumb2 내에서 디스어셈블러가 실패하는 부분이 많지만 IDA만 사용할 때보다 훨씬 낫습니다.
firmware 폴더에는 심볼이 있거나 없는 다양한 펌웨어가 포함되어 있습니다.
history의 모든 항목에는 심볼이 있고, targets의 모든 항목에는 심볼이 없습니다.
삼성 시리즈의 경우 S8에는 Note 8 및 S8+ 등이 포함되며, S10/S20에는 S10e부터 Note 20 5G까지 모든 모델이 포함됩니다.
덤프 품질은 다양할 수 있으며 일부는 RAM이 있고 일부는 ROM만 있습니다. 이 목록에 있는 대부분의 장치에 액세스할 수 있습니다. 최신 패치 수준과 RAM을 포함한 덤프가 필요하면 언제든지 연락해 주세요.
논문에 언급된 일부 장치는 여기에 포함되지 않습니다. 이러한 장치는 연구 전용 장치가 아닐 수 있기 때문입니다. 또한 몇 가지 iPhone 및 MacBook도 누락되었습니다. 연구 전용 장치로 보유하고 있지만 원래 덤프가 그렇지 않았기 때문입니다. 이러한 장치는 곧 추가될 예정입니다 :)
이 저장소에는 .editorconfig 파일이 있습니다. 들여쓰기 스타일, 문자 집합 및 줄 구분 기호를 구성합니다. 기여 시 이 구성을 따르세요. .editorconfig용 IDE 플러그인을 사용하면 더 쉽게 따를 수 있습니다.
테스트 종속성을 설치하려면 다음을 실행하세요:
pip install '.[test]'
그러면 테스트 케이스 실행에만 필요한 패키지가 설치됩니다.
개발 종속성은 예를 들어 패키지 유형에 대한 스텁을 제공합니다. 설치하려면 다음을 실행하세요:
pip install '.[development]'
pytest가 모든 테스트를 실행합니다.
프로젝트는 tox를 사용하여 다양한 Python 버전에 대해 로컬에서 테스트를 실행합니다. Tox는 버전 3.6, 3.7, 3.8 및 3.9에 대해 테스트하도록 설정되어 있습니다. Tox를 실행하려면 테스트 종속성을 설치하고 언급된 4가지 Python 버전을 설치하세요. 여러 Python 버전을 설치하고 관리하는 권장 방법은 pyenv입니다.
단계:
pyenv install 3.9.1
pyenv install 3.8.6
pyenv install 3.7.9
pyenv install 3.6.12
pyenv virtualenv 3.9.1 polypyus
pyenv local polypyus 3.8.6 3.7.9 3.6.12
pip install '.[test]'
pip install '.[development]'
tox 실행Polypyus는 GitHub Actions를 사용하여 자동화된 테스트 실행과 일부 린팅을 수행합니다. 원한다면 pre-commit git 훅을 사용하여 로컬에서 린팅 단계를 실행할 수 있습니다.
새 커밋이 생성되기 전에 매번 린팅이 트리거되어 이 코드가 GitHub Actions 린팅 단계에서 실패하게 만드는 문제를 보여줍니다. 또한 변경된 파일을 black 으로 서식을 지정합니다.
pip install '.[development]'
pre-commit install
Polypyus 로고를 만든 Anna Stichling에게 감사드립니다. 또한 Christian Blichmann 및 Joxean Koret의 피드백에 감사드립니다.
Polypyus는 오픈소스이며 GPLv3에 따라 라이선스가 부여됩니다.
| 칩 | 장치 | 빌드 날짜 | 심볼 |
|---|
| BCM20703A2 | MacBook/iMac 2016-2017 | Oct 22 2015 | ✔ |
| CYW20719B1 | 평가 보드 | Jan 17 2017 | ✔ |
| CYW20735B1 | 평가 보드 | Jan 18 2018 | ✔ |
| CYW20819A1 | 평가 보드 | May 22 2018 | ✔ |
| 칩 | 장치 | 빌드 날짜 | 심볼 |
|---|
| BCM2046A2 | iMac Late 2009 | 2007? | - |
| BCM2070B0 | MacBook 2011, Thinkpad T420 | Jul 9 2008 | - |
| BCM20702A1 | Asus USB 동글 | Feb (?) 2010 | - |
| BCM4345B0 | iPhone 6 | Jul 15 2013 | - |
| BCM4335C0 | Google Nexus 5 | Dec 11 2012 | - |
| BCM4345B0 | Google Nexus 6P / Galaxy S6 | Oct 23 2014 | - |
| BCM43430A1 | Raspberry Pi 3 and Zero W | Jun 2 2014 | - |
| BCM4345C0 | Raspberry Pi 3+ and 4 | Aug 19 2014 | - |
| BCM4347B0 | Samsung Galaxy S8 시리즈 | Jun 3 2016 | - |
| BCM4375B1 | Samsung Galaxy S10/20 시리즈 | Apr 13 2018 | - |
| BCM4378B1 | iPhone 11/SE2 | Oct 25 2018 | Strings |