Pod koniec lutego zrobiło się głośno o błędach w urządzeniach D-Linka (CVE-2016-1558 oraz CVE-2016-1559) znalezionych za pomocą tytułowego frameworku. Od początku ochoczo zabrałem się do testów, jednak nauczony doświadczeniem, że sporo projektów na GitHubie umiera po pierwszym commicie, postanowiłem wstrzymać się z jego opisaniem. Na szczęście projekt nie umarł i ma się całkiem dobrze (na dzień pisania posta, ostatni commit poczyniony został cztery dni temu).
Firmadyne jest dzieckiem ludzi z CMU oraz Boston University. Jego głównymi zaletami są: bardzo duże uproszczenie konfiguracji środowiska do analizy (proces ten opisywałem w poście “Debugowanie aplikacji w architekturze MIPS #1 – Środowisko”) oraz gotowe skrypty pozwalające na szybkie przetestowanie danego obrazu firmware.
Jak piszą jego autorzy:
In our 2016 Network and Distributed System Security Symposium (NDSS) paper, titled Towards Automated Dynamic Analysis for Linux-based Embedded Firmware, we evaluated the FIRMADYNE system over a dataset of 23,035 firmware images, of which we were able to extract 9,486. Using 60 exploits from the Metasploit Framework, and 14 previously-unknown vulnerabilities that we discovered, we showed that 846 out of 1,971 (43%) firmware images were vulnerable to at least one exploit, which we estimate to affect 89+ different products
Całkiem nieźle jak na projekt w początkowej fazie developmentu 🙂
Po nieco przydługim wstępie, zamiast przedstawiać proces instalacji oraz konfiguracji, który jest bardzo dobrze opisany, opiszę parę sztuczek zwiększających skuteczność rozpakowywania i testowania obrazów.
Tip #1 – Zwiększenie głębokości i szerokości przeszukiwania extractora firmware
Konfigurację tych parametrów znajdziemy w pliku: {firmadyne_dir}/sources/extractor/extractor.py
Zalecam ustawienie minimum dwa razy większych wartości (linie zaznaczone w listingu) – zwłaszcza oprogramowanie kamerek internetowych to niezłe “matrioszki” i dopiero zmiana tych parametrów powoduje poprawne wypakowanie.
class ExtractionItem(object):
"""
Class that encapsulates the state of a single item that is being extracted.
"""
# Maximum recursion breadth and depth
RECURSION_BREADTH = 10
RECURSION_DEPTH = 7
Tip #2 – Zwiększenie timeoutu konfiguracji sieci wirtualnej
Plik: {firmadyne_dir}/scripts/inferNetwork.sh
Mało oczywiste rozwiązanie problemu braku generacji pliku run.sh do podniesienia obrazu. Czasami po prostu procedura rozruchu obrazu trwa na tyle długo, że skrypt timeoutuje się przed poprawnym zakończeniem konfiguracji. Czas w sekundach modyfikujemy w zaznaczonej linijce. Polecam tylko w przypadku analizy pojedyńczych obrazów 😉
echo "Running firmware ${IID}: terminating after 60 secs..."
timeout --preserve-status --signal SIGINT 60 "${SCRIPT_DIR}/run.${ARCH}.sh" "${IID}"
sleep 1
Tip #3 – Skrypt do prostego montowania obrazów firmware
Plik: {firmadyne_dir}/scripts/mount.sh
Skrypt używany “wewnętrznie” przez firmadyne służący, do montowania obrazów, może zostać użyty do dostarczenia do emulowanego obrazu przydatnych binarek – polecam prekomplikowane binarki GDB dla MIPS / MIPSEL.
Użycie jego jest bardzo proste:
./mount.sh {firmware_id}
**Tip #4 – Automatyczne pobieranie obrazów firmware **
Autorzy firmadyne niestety nie chwalą się tym głośno – w osobnym repozytorium, jest umieszczony skrypt do szybkiego pobierania dużych ilości obrazów firmware ze stron 37-miu producentów.
Wystarczy wydać polecenia:
# Instalacja zależności
pip install psycopg2 scrapy
git clone https://github.com/firmadyne/scraper
A następnie (przykład dla D-Linka, pliki dla reszty producentów znajdują się w folderze {firmadyne_scraper_dir}/firmware/spiders):
scrapy crawl dlink
Pobrane pliki będą znajdować się folderze: {firmadyne_scraper_dir}/firmware/output
Jak widać, można wyciągnąć zdecydowanie więcej z frameworka niż wynika z dokumentacji. Trzymam kciuki za rozwój projektu, gdyż jest dla mnie niesamowitym ułatwieniem podczas “zabawy” z nowymi obrazami, a wszystkim sceptykom radzę spróbować 🙂