Pokażę tutaj jak można użyć komendy binwalk do analizy zrzutu pamięci flash na przykładzie starego dekodera DVB-T2. W ramach demonstracji wypakujemy z jego pamięci flash kilka strumieni skompresowanych przez LZMA oraz jego logo (obrazek JPG). W celu ułatwienia zabawy dla początkujących całość wykonany na systemie Windows dzięki użyciu WSL.
Użyte środowiska i narzędzia
W temacie użyję następujących narzędzi:
- programator SPI CH341 Black (warto poczytać o jego modyfikacji napięcia zasilania) kupiony za 35 zł
- program Neoprogrammer na Windowsa - do obsługi odczytu i zapis pamięci SPI, używam wersji NeoProgrammer 2.1.0.18
- linuxowe środowisko WSL zainstalowane na Windowsie - w celu wygodnego operowania linuxowymi komendami, jest ono w pełni darmowe i łatwe do postawienia na W10
Do prezentacji użyłem również samej kości pamięci flash z firmware przypadkowo znalezionego odbiornika DBV-T2, którego już prezentowałem w temacie Stary dekoder DVB-T2 - STB HD N6 - wnętrze, potencjał przeróbki na DIY zegar
Odczyt flash
Przygodę rozpoczynamy od odczytania zawartości pamięci Flash. W teorii powinno dać się to zrobić bez lutowania dzięki klamrze zawartej w zestawie z programatorem CH341, ale w praktyce często nie chce mi to działać, więc po prostu wylutowuję układ.
W tym przypadku też tak zrobiłem. Najpierw nakładam spoiwo ołowiowe i topnik na nóżki by lepiej fabryczny bezołowiowy lut się topił:
Potem grzeję, powinno się grzać gorącym powietrzem, ale czasem po prostu rozgrzewam oba rzędy nóżek grotem i też daję radę:
Ważne by nie urwać padów, układ można ruszyć dopiero gdy całkiem zacznie pływać.
Na koniec lutuje układ na podstawkę od programatora:
Swego czasu z asystentką zrobiliśmy videotutorial pokazujący ten właśnie proces:
Po stronie komputera korzystam z NeoProgrammer 2.1.0.18. Program ten jest w stanie samodzielnie odczytać konkretne ID pamięci flash i określić jej rozmiar. Całą zawartość pamięci odczytuję i zapisuję do pliku.
Pierwsze użycie binwalk
Mamy już zgrany wsad w postaci pliku binarnego 4MB_Flash_for_MSD7T01.bin, po otwarciu go edytorem hex (np. moim ulubionym xvi32) może wydawać się on całkiem niezrozumiały:
Ale nic bardziej mylnego - może nam pomóc komenda binwalk.
Najpierw może być potrzeba zainstalowania jej poprzez apt-get:
sudo apt-get install binwalk
Następnie można jej już użyć do analizy dowolnego pliku:
binwalk 4MB_Flash_for_MSD7T01.bin
Rezultat:
Komenda przeanalizowała zrzut pamięci i wykryła w nim cztery bloki o podanych offsetach. Pierwszy blok to stałe używane do liczenia sumy kontrolnej. Kolejne bloki są skompresowanymi danymi za pomocą algorytmu LZMA. Zaraz spróbujemy je wypakować, ale jeszcze warto spróbować użyć komendy z przełącznikiem I:
binwalk -I 4MB_Flash_for_MSD7T01.bin
Przełącznik -I, jak sama nazwa wskazuje ("invalid") wyświetla wszystkie znalezione wyniki, nawet te które zostały przez program określone jako niepoprawne:
Wypakowanie paczek LZMA i automatyzacja wypakowania
Teraz spróbujmy najpierw wydzielić a potem wypakować te partycje. Wydzielić je można za pomocą komendy dd a wypakować komendą lzma. Na piechotę wyglądałoby to mniej więcej tak:
dd if=source.bin of=target.bin bs=1 skip=4096 count=128
if to skrót od 'input file', plik źródłowy, of to skrót od 'output file', plik wyjściowy, bs to skrót od 'block size', rozmiar bloku (przy kopiowaniu), tutaj 1 bajt, skip to ile bajtów jest pomijanych na poczatku a count to ilość bloków do skopiowania.
Potem można by zdekompresować dane komendą lzma:
lzma -d file.bin
Ale łatwiej jest zrobić to skryptem:
Kod: Bash
Skrypt uruchamiamy poprzez:
./extract_lzma.sh
Jeśli brakuje mu uprawnień, nadajemy je poprzez chmod. Jeśli otrzymujemy dziwne błędy w postaci:
./extract_lzma.sh: line 2: $'\r': command not found
./extract_lzma.sh: line 5: $'\r': command not found
./extract_lzma.sh: line 8: $'\r': command not found
./extract_lzma.sh: line 11: $'\r': command not found
./extract_lzma.sh: line 13: syntax error near unexpected token `$'{\r''
'/extract_lzma.sh: line 13: `extract_lzma_block() {
to świadczy o tym, że format końców linii nie jest zgodny z naszym systemem, musimy zmienić EOL format na Linuxowy. To będzie konsekwencją tworzenia pliku na Windowsie i otwierania go na WSL. Zmiany można dokonać np. w Notepad++:
Po tym skrypt powinien zadziałać:
Analiza wypakowanych bloków
Mamy już wypakowane bloki ale to dopiero początek przygody. Przechodzimy do folderu z ich zawartością:
cd output_files
a następnie powtarzamy komendę binwalk:
binwalk block_65792
Rezultat:
Znalezione zostały pliki JPG, TIFF, ścieżki oraz też bootloader U-Boot w wersji 1.1.6 (Oct 8 2015).
Analiza pozostałych plików:
Analiza bloku 327708 jako tekst ze względu na długość:
tester@DESKTOP-6SD9MUK:/mnt/w/GIT/FlashDumps/Sat/STB HD N6/output_files$ binwalk block_327708
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 eCos kernel exception handler, architecture: MIPSEL, exception vector table base address: 0x80587700
640 0x280 eCos kernel exception handler, architecture: MIPSEL, exception vector table base address: 0x80587700
1975980 0x1E26AC gzip compressed data, has 2055 bytes of extra data, last modified: 1970-01-01 00:00:00 (null date)
2240652 0x22308C gzip compressed data, has 2056 bytes of extra data, last modified: 1989-02-23 12:58:42 (bogus date)
4596152 0x4621B8 Unix path: /home/mstar/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/msos/ecos/MsOS_ecos.c
4596227 0x462203 eCos RTOS string reference: "ecos/../../mxlib/msos/ecos/MsOS_ecos.c"
4596249 0x462219 eCos RTOS string reference: "ecos/MsOS_ecos.c"
4596259 0x462223 eCos RTOS string reference: "ecos.c"
4597516 0x46270C Unix path: /home/mstar/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/drv/miu/drvMIU.c
4597591 0x462757 eCos RTOS string reference: "ecos/../../mxlib/drv/miu/drvMIU.c"
4743480 0x486138 CRC32 polynomial table, little endian
4754452 0x488C14 Unix path: /dev/sda/1
5149500 0x4E933C Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cy
5149541 0x4E9365 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/smp.hxx"
5149559 0x4E9377 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/smp.hxx"
5149689 0x4E93F9 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mempolt2.inl"
5149707 0x4E940B eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mempolt2.inl"
5149841 0x4E9491 eCos RTOS string reference: "eCospro/packages/services/memalloc/common/v2_0_60/src/malloc.cxx"
5149949 0x4E94FD eCos RTOS string reference: "eCospro/packages/io/fileio/v2_0_60/src/misc.cxx"
5150748 0x4E981C Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/fs/fat/v2_0_60/src/fatfs_supp.c
5150789 0x4E9845 eCos RTOS string reference: "eCospro/packages/fs/fat/v2_0_60/src/fatfs_supp.c"
5152008 0x4E9D08 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/fs/fat/v2_0_60/src/fatfs_ncache.c
5152049 0x4E9D31 eCos RTOS string reference: "eCospro/packages/fs/fat/v2_0_60/src/fatfs_ncache.c"
5152376 0x4E9E78 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/fs/fat/v2_0_60/src/fatfs_blib.c
5152417 0x4E9EA1 eCos RTOS string reference: "eCospro/packages/fs/fat/v2_0_60/src/fatfs_blib.c"
5153424 0x4EA290 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/io/disk/v2_0_60/src/disk.c
5153465 0x4EA2B9 eCos RTOS string reference: "eCospro/packages/io/disk/v2_0_60/src/disk.c"
5155516 0x4EAABC Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/hal/common/v2_0_60/src/hal_misc.c
5155557 0x4EAAE5 eCos RTOS string reference: "eCospro/packages/hal/common/v2_0_60/src/hal_misc.c"
5155801 0x4EABD9 eCos RTOS string reference: "eCos][CPU INFO] : CPU Clock = %d : RTC Period = %d"
5156260 0x4EADA4 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/kernel/v2_0_60/src/common/clock.cxx
5156301 0x4EADCD eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/common/clock.cxx"
5156661 0x4EAF35 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/common/kapi.cxx"
5156757 0x4EAF95 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/thread.inl"
5156775 0x4EAFA7 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/thread.inl"
5157408 0x4EB220 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/kernel/v2_0_60/src/common/thread.cxx
5157449 0x4EB249 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/common/thread.cxx"
5157745 0x4EB371 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/common/except.cxx"
5157932 0x4EB42C Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/kernel/v2_0_60/src/intr/intr.cxx
5157973 0x4EB455 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/intr/intr.cxx"
5158633 0x4EB6E9 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/sched/mlqueue.cxx"
5159229 0x4EB93D eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/sched/sched.cxx"
5159896 0x4EBBD8 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/kernel/v2_0_60/src/sync/cnt_sem.cxx
5159937 0x4EBC01 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/sync/cnt_sem.cxx"
5160161 0x4EBCE1 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/sync/flag.cxx"
5160629 0x4EBEB5 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/mboxt2.inl"
5160647 0x4EBEC7 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/kernel/mboxt2.inl"
5161525 0x4EC235 eCos RTOS string reference: "eCospro/packages/kernel/v2_0_60/src/sync/mutex.cxx"
5162249 0x4EC509 eCos RTOS string reference: "eCospro/packages/services/memalloc/common/v2_0_60/src/dlmalloc.cxx"
5163009 0x4EC801 eCos RTOS string reference: "eCospro/packages/language/c/libc/setjmp/v2_0_60/src/longjmp.cxx"
5163201 0x4EC8C1 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/stream.inl"
5163219 0x4EC8D3 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/stream.inl"
5163481 0x4EC9D9 eCos RTOS string reference: "eCospro/packages/language/c/libc/stdio/v2_0_60/src/common/stream.cxx"
5163593 0x4ECA49 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/streambuf.inl"
5163611 0x4ECA5B eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/streambuf.inl"
5164641 0x4ECE61 eCos RTOS string reference: "eCospro/packages/language/c/libc/stdio/v2_0_60/src/input/fgetc.cxx"
5165208 0x4ED098 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/language/c/libc/string/v2_0_60/src/strtok.cxx
5165249 0x4ED0C1 eCos RTOS string reference: "eCospro/packages/language/c/libc/string/v2_0_60/src/strtok.cxx"
5165673 0x4ED269 eCos RTOS string reference: "eCospro/packages/io/fileio/v2_0_60/src/fd.cxx"
5165817 0x4ED2F9 eCos RTOS string reference: "eCospro/packages/io/fileio/v2_0_60/src/file.cxx"
5166257 0x4ED4B1 eCos RTOS string reference: "eCospro/packages/io/fileio/v2_0_60/src/dir.cxx"
5166409 0x4ED549 eCos RTOS string reference: "eCospro/packages/io/fileio/v2_0_60/src/select.cxx"
5166525 0x4ED5BD eCos RTOS string reference: "eCospro/packages/language/c/libc/startup/v2_0_60/src/main.cxx"
5166817 0x4ED6E1 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/stdiofiles.inl"
5166835 0x4ED6F3 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/libc/stdio/stdiofiles.inl"
5169936 0x4EE310 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/language/c/libc/stdio/v2_0_60/src/common/setvbuf.cxx
5169977 0x4EE339 eCos RTOS string reference: "eCospro/packages/language/c/libc/stdio/v2_0_60/src/common/setvbuf.cxx"
5170121 0x4EE3C9 eCos RTOS string reference: "eCospro/packages/language/c/libc/startup/v2_0_60/src/_exit.cxx"
5170265 0x4EE459 eCos RTOS string reference: "eCospro/packages/language/c/libc/startup/v2_0_60/src/atexit.cxx"
5171620 0x4EE9A4 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/fs/ntfs/v2_0_60/src/ntfs_blib.c
5171661 0x4EE9CD eCos RTOS string reference: "eCospro/packages/fs/ntfs/v2_0_60/src/ntfs_blib.c"
5183860 0x4F1974 Unix path: /home/mstar/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/hal/kriti/audio/halAUDIO.c
5183935 0x4F19BF eCos RTOS string reference: "ecos/../../mxlib/hal/kriti/audio/halAUDIO.c"
5188372 0x4F2B14 Unix path: /home/stb/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/hal/kriti/dac/halDAC.c
5188445 0x4F2B5D eCos RTOS string reference: "ecos/../../mxlib/hal/kriti/dac/halDAC.c"
5216260 0x4F9804 Unix path: /home/mstar/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/hal/kriti/mvd/halMVD.c
5216335 0x4F984F eCos RTOS string reference: "ecos/../../mxlib/hal/kriti/mvd/halMVD.c"
5241796 0x4FFBC4 eCos RTOS string reference: "eCos Newhost"
5259548 0x50411C Unix path: /home/stb/PERFORCE/THEALE/utopia_release/UTPA-24.0.x_Kriti/project/kriti_ecos/../../mxlib/hal/kriti/ve/mhal_tvencoder.c
5259621 0x504165 eCos RTOS string reference: "ecos/../../mxlib/hal/kriti/ve/mhal_tvencoder.c"
5548068 0x54A824 SHA256 hash constants, little endian
5549576 0x54AE08 CRC32 polynomial table, little endian
5553672 0x54BE08 CRC32 polynomial table, big endian
5590368 0x554D60 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/infra/v2_0_60/src/pure.cxx
5590409 0x554D89 eCos RTOS string reference: "eCospro/packages/infra/v2_0_60/src/pure.cxx"
5590545 0x554E11 eCos RTOS string reference: "eCospro/packages/services/memalloc/common/v2_0_60/src/kapi.cxx"
5590925 0x554F8D eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mfiximpl.inl"
5590943 0x554F9F eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mfiximpl.inl"
5591713 0x5552A1 eCos RTOS string reference: "eCospro/Kriti/LIB_eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mvarimpl.inl"
5591731 0x5552B3 eCos RTOS string reference: "eCos_fileio_posix_fat_ntfs_jffs2_v3_c++_kriti_34kf_install/include/cyg/memalloc/mvarimpl.inl"
5610692 0x559CC4 Unix path: /home/vansen.yang/PERFORCE/THEALE/Uranus/eCospro/packages/language/c/libc/i18n/v2_0_60/src/locale.cxx
5610733 0x559CED eCos RTOS string reference: "eCospro/packages/language/c/libc/i18n/v2_0_60/src/locale.cxx"
5612165 0x55A285 eCos RTOS string reference: "eCospro/packages/language/c/libc/time/v2_0_60/src/strftime.cxx"
7451843 0x71B4C3 Boot section Start 0x7040000 End 0x-FFF9
Wypakowanie obrazka
Na próbę można wypakować jeden z obrazków. W celach demonstracji użyjemy komendy dd:
dd if=block_65792 of=output.jpg bs=1 skip=7812
Pora zobaczyć, co to za plik został wypakowany:
Wygląda na to, że poprawnie wypakowaliśmy plik JPG. Jest to logo wyświetlane przez dekoder na starcie. W ramach zabawy można by spróbować je podmienić potem na inny plik.
Wypakowanie całego pliku
Na stacku można znaleźć informację, że binwalk powinien wypakować wszystko z pliku gdy użyjemy komendy:
binwalk -e -c block_65792
u mnie jednak nie chciało to działać, nic nie było tworzone bez komunikatów o błędzie.
Rozwiązaniem okazało się użycie zapisu z dd:
binwalk --dd=".*" block_65792
Rezultat:
Tak wypakowane pliki są gotowe do analizy w innych narzędziach, przykładowo we frameworku Ghidra.
Podsumowanie
WSL, czyli Windows Subsystem for Linux pozwala nam wygodnie odpalać linuxowe komendy na Windowsie. Jedną z przydatnych komend do analizy zgranego wsadu flash jest binwalk. Komendy tej można używać na różne sposoby, do płytszej lub głębszej analizy pliku binarnego, a również do jego wypakowania. Zrzut pamięci można również rozdzielić na osobne pliki komendą dd, natomiast ich wypakowywanie odbywa się różnie, wedle ich formatu, przykładowo w temacie pokazałem wypakowanie lzma.
Po pełną dokumentację binwalk odsyłam na Github:
https://github.com/ReFirmLabs/binwalk/wiki/Usage
Temat można by pociągnąć dalej, zresztą w podobny sposób wypakowywałem już i edytowałem wsad kamery internetowej, ale w jej przypadku użyty był system plików squashfs, do którego dostępne są odpowiednie narzędzia. W jej przypadku udało mi się wypakować, zmodyfikować a potem spakować z powrotem system plików. Być może to na jej przykładzie pokaże wkrótce co można zrobić dalej, już po analizie z binwalk.
Wracając do tematu - czy korzystaliście z komendy binwalk, a jeśli tak, to w jakim celu? W ramach zabawy zapraszam również do spróbowania swoich sił z plikiem z tego tematu - załączony jest on do pobrania tutaj
Fajne? Ranking DIY Pomogłem? Kup mi kawę.