Elektroda.pl
Elektroda.pl
X
Servizza
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Reverse Engineering w praktyce - część 2

ghost666 14 Lut 2017 19:47 5799 10
  • Reverse Engineering w praktyce - część 2
    W poprzedniej, pierwszej części artykułu opisaliśmy jak zidentyfikować port szeregowy w systemie, aby móc połączyć się z naszym urządzeniem - routerem. W części drugiej skupimy się na analizie firmware i systemu operacyjnego zastosowanego w urządzeniu.

    Port UART daje nam dostęp do powłoki Linuxa w routerze. Mamy taki sam dostęp jak developerzy oprogramowania, którzy w ten sposób debugują wewnętrzne oprogramowanie urządzenia, kontrolują system etc. Dostęp jest, jak się okazało, całkiem prosty - nie potrzebujemy żadnego wyrafinowanego sprzętu ani nic, aby skomunikować się z systemem. Teraz przejść możemy do analizy tego co znajduje się w systemie, aby móc lepiej zrozumieć jak działa system, jakie ciekawe informacje nam udostępnia itp. Pozwoli nam to także dostać się do czułych danych, zgromadzonych w routerze i być może odnaleźć też luki w jego zabezpieczeniach. Autor artykułu informuje, że jest w kontakcie z firmą Huawei, co pozwoliło upewnić się, że dane zaprezentowane poniżej nie są zbyt czułe i nie pozwalają na hackowanie tego rodzaju routerów (np. bez dostępu do portu UART w systemie).

    Zacznijmy tam, gdzie w poprzedniej części skończyliśmy, Udało nam się podłączyć do portu szeregowego w układzie:

    Reverse Engineering w praktyce - część 2


    Oraz nawiązać komunikację:

    Reverse Engineering w praktyce - część 2


    Po naciśnięciu entera dostaliśmy się do do linii poleceń ATP. Jak już udało nam się ostatnio ustalić dane do logowania są bardzo proste: admin, admin. Kiedy wpiszemy w linii poleceń Shell przejdziemy do powłoki - BusyBox (o niej później).

    Code:
    -------------------------------
    
    -----Welcome to ATP Cli------
    -------------------------------
    Login: admin
    Password:    #Password is ‘admin'
    ATP>shell
    BusyBox vv1.9.1 (2013-08-29 11:15:00 CST) built-in shell (ash)
    Enter 'help' for a list of built-in commands.
    # ls
    var   usr   tmp   sbin  proc  mnt   lib   init  etc   dev   bin


    Udało nam się poznać trzy warstwy firmware w systemie:

    * U-boot: bootloader urządzenia, który znając mapę pamięci układu zajmuje się załadowaniem systemu i innymi niskopoziomowymi operacjami.
    * Linux: na routerze pracuje Linux, który zasadniczo pełni taką rolę jak system operacyjny na komputerze; to pod opieką systemu działa ATP CLI oraz BusyBox.
    * BusyBox: to niewielka binarka, która w zasadzie jest linią komend w systemie; pełni ona rolę powłoki, która zajmuje się realizacją komend, jakie wydajemy systemowi.

    Zasadniczo wygodniej będzie nam korzystać z interfejsów wyższego poziomu - niskopoziomowe interfejsy są mało intuicyjne, mogą nie mieć dostępu do wszystkich danych a ponadto istnieje szansa uszkodzenia urządzenia, jeśli korzystamy z interfejsu niskiego poziomu.

    Analizę działania systemu zacznijmy od zbadania sekwencji ładowania systemu. Zazwyczaj developerzy prezentują podczas bootowania wiele ciekawych informacji, spójrzmy czy jest w nich coś, co nam się przyda.

    Informacje debugera podczas bootowania

    W czasie ładowania systemu możemy wyłowić z komunikatów wiele rozsianych tam przydatnych informacji. Znajdziemy tam przydatne informacje chociażby dotyczące algorytmów kompresji, wykorzystanych do ładowania segmentów systemu z pamięci flash:

    Reverse Engineering w praktyce - część 2


    Wiadomości o strukturze wewnętrznej pamięci flash bardzo nam się później przyda, gdy będziemy chcieli zanalizować jej zawartość.

    Reverse Engineering w praktyce - część 2
    [/center

    I jeszcze więcej informacji o pamięci:
    [center] Reverse Engineering w praktyce - część 2


    Wiemy, że partycja roota zapisana jest jako squashfs:

    Reverse Engineering w praktyce - część 2 [/center]

    Z tymi algorytmami kompresji 'zmierzyć' będziemy musieli się gdy zajmiemy się analizowaniem surowych danych z wewnętrznej pamięci flash w systemie. Dobrze, że wiemy które segmenty pamięci są do czego potrzebne.

    Czym są ATP CLI i BusyBox (trochę teorii).

    Analizowany router działa pod kontrolą systemu operacyjnego Linux, który kontroluje pamięć, równoległe wykonywanie procesów, opiekuje się systemem etc. W tym przypadku jest to Linux 2.6.21 SDK. ATP CLI to interfejs linii komend (ang. CLI), który działa na Linuxie i jest częścią jądra systemu. Zapewnia on pierwszą warstwę uwierzytelniania w systemie, ale zasadniczo jest on bardzo ograniczony:

    Code:
    ATP>help
    
    Welcome to ATP command line tool.
    If any question, please input "?" at the end of command.
    ATP>?
    cls
    debug
    help
    save
    ?
    exit
    ATP>


    Komenda help nie wspomina nic o komendzie shell, ale zazwyczaj taka występuje - jako shell lub sh. Samo ATP CLI ma mniej niż 10 komend i w zasadzie nie pozwala na żadną kontrolę systemu czy nawigację w strukturze plików. Tym zajmuje się BusyBox.

    BusyBox to jedna, prosta aplikacja, która zawiera w sobie podstawowe komendy unixa, dzięki czemu ułatwia życie developerom i pozwala na oszczędzanie pamięci. BusyBox odpowiada za wszystko: od ls i cd do top, System V init, pisania skryptów itp. Dzięki temu system operacyjny na tym urządzeniu będzie w zasadzie przypominał typowego Linuxa. Aby uruchomić BusyBoxa w ATP CLI wpisujemy komendę shell:

    Code:
    ATP>shell
    
    BusyBox vv1.9.1 (2013-08-29 11:15:00 CST) built-in shell (ash)
    Enter 'help' for a list of built-in commands.
    # ls
    var   usr   tmp   sbin  proc  mnt   lib   init  etc   dev   bin
    #
    # ls /bin
    zebra        swapdev      printserver  ln           ebtables     cat
    wpsd         startbsp     pppc         klog         dns          busybox
    wlancmd      sntp         ping         kill         dms          brctl
    web          smbpasswd    ntfs-3g      iwpriv       dhcps        atserver
    usbserver    smbd         nmbd         iwconfig     dhcpc        atmcmd
    usbmount     sleep        netstat      iptables     ddnsc        atcmd
    upnp         siproxd      mount        ipp          date         at
    upg          sh           mldproxy     ipcheck      cwmp         ash
    umount       scanner      mknod        ip           cp           adslcmd
    tr111        rm           mkdir        igmpproxy    console      acl
    tr064        ripd         mii_mgr      hw_nat       cms          ac
    telnetd      reg          mic          ethcmd       cli
    tc           radvdump     ls           equipcmd     chown
    switch       ps           log          echo         chmod
    #


    Więcej zalet BusyBoxa zauważymy eksplorując system plików routera. Układ posiada dowiązania symbioliczne w folderze z binarkami (/bin/). To dobrze dla nas - wszelkie ciekawe, wrażliwe informacje zawarte w tych binarkach nie będą częścią BusyBoxa.

    [b]Eksploracja systemu plików


    Rozejrzyjmy się najpierw po 'dysku' i zobaczmy jakie dostępne są komendy, jakie dane są w pamięci no i czy jest tam cokolwiek przydatnego dla nas. Chodzi nam póki co o ogólny ogląd systemu, więc nie będziemy pochylać się nad każdą drobiną danych.

    Komendy pozwalają nam na sprawdzenie jakie procesy zużywaj większość zasobów systemu: to dobry wskaźnik tego co jest ważne. Im dany proces ma wyższy priorytet, tym musi być ważniejszy. Gdy router idluje to widzimy tylko:

    Reverse Engineering w praktyce - część 2


    Jednym z procesów jest usbmount, tak więc router wspiera montowanie czegoś w porcie USB. Wepnijmy tam pendrive...

    Code:
    usb 1-1: new high speed USB device using rt3xxx-ehci and address 2
    
    [...]
    ++++++sambacms.c 2374 renice=renice -n +10 -p 1423


    Został on rozpoznany przez system i zamontowany w /mnt/usb1_1/. Uruchomiło to też serwer samby, dzięki czemu w /etc/samba/ widzimy:

    Code:
    # ls -l /etc/samba/
    
    -rw-r--r--    1 0        0             103 smbpasswd
    -rw-r--r--    1 0        0               0 smbusers
    -rw-r--r--    1 0        0             480 smb.conf
    -rw-------    1 0        0            8192 secrets.tdb
    # cat /etc/samba/smbpasswd
    nobody:0:XXXXXXXXXXXXXXXXXXX:564E923F5AF30J373F7C8_______4D2A:[U ]:LCT-1ED36884:


    Kontynuujemy zbieranie ciekawych informacji, wykorzystujemy netstata, iptables i wlancmd. Odwiedzamy poza tym:

    * /etc/profile
    * /etc/inetd
    * /etc/services
    * /var/: zawiera w sobie pliki wykorzystywane przez system podczas pracy.
    * /etc/: Pliki konfiguracyjnego systemu.

    Foldery /var/ i /etc/ zawierają w sobie zazwyczaj bardzo dużo wartościowych informacji. Niektóre z plików mają nawet bardzo dużo mówiące nazwy. Na przykład /etc/serverkey.pem - brzmi ciekawie, nie?

    Reverse Engineering w praktyce - część 2


    To nic nadzwyczajnego odnaleźć w systemie prywatne klucze TLS wbudowane w system. Dzięki wejściu na jedno urządzeń poznać możemy klucz, który ejst taki sam dla każdego routera z tej serii. To już realnie może przydać się do hackowania routerów. Dodatkowo, taki klucz przydać się może też do komunikacji z serwerami Huawei czy dostarczycielami internetu. W naszym przypadku, oprócz klucza prywatnego znajdujemy także dwa certyfikaty, wystawione na tą samą osobę:

    * /etc/servercert.pem: Najpewniej certyfikat klucza serwerowego.
    * /etc/root.pem: To może być certyfikat wykorzystany do łączenia się z serwerem - firmy Huawei lub ISP.

    Dodatkowo więcej informacji znajdujemy w /etc/ppp256/config i /etc/ppp258/config.

    Reverse Engineering w praktyce - część 2


    Te dane da się także uzyskać poprzez interfejs HTTP, więc możemy je podać publicznie, aczkolwiek nie w przypadku każdego routera dane te będą dostępne poprzez HTTP.

    Przy tak dużej ilości ciekawych plików jednakże trudne i czasochłonne może być przeglądanie ich na routerze. Dlatego możemy podejść zupełnie do tego inaczej...

    Podejście Rambo do zbierania informacji

    Skoro już podpięliśmy i zamontowaliśmy w systemie pendrive USB to to wykorzystajmy. Zgrajmy na dysk przenośny tyle danych z routera ile to tylko możliwe, wtedy będziemy mogli zastosować bardziej wyrafinowane techniki ich analizy.

    Po zgraniu danych na dysk odpalmy komputer i poszukajmy, na przykład wpisując find -name *.pam. Okazuje się, że nie ma już więcej certyfikatów TLS, ale co gdy wpiszemy grep -r -r password?

    Reverse Engineering w praktyce - część 2


    Widzimy całkiem sporo danych; większość to STUN, TR-069 i usług lokalnych. Możemy je opublikować, bo są one także dostępne poprzez interfejs HTTP, chociaż większość routerów nie chwali się nimi tak jawnie.

    Dane te dostępne są jako zwykły tekst lub zakodowane jako base64. Bez problemu możemy je odkodować wpisując na przykład:

    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Reverse Engineering w praktyce - część 2


    I jest to aktualne hasło do sieci WiFi.

    Dalsze poszukiwania pokazują nam dwa ciekawe pliki. Ciekawe nie tylko z uwagi na ich zawartość, ale także fakt, że są one krytyczne dla działania routera. są to:

    * /var/curcfg.xml: Aktualny plik konfiguracyjny. Znajdziemy tam między innymi hasło do WiFi zakodowane w base64.
    * /etc/defaultcfg.xml: Domyślny plik konfiguracyjny. To on zostanie wgrany do systemu, gdy będziemy chcieli wgrać ustawienia fabryczne. Jednakże w tym pliku nie znajdziemy domyślnego hasła do WiFi (o nim więcej w kolejnych częściach artykułu).

    Eksploracja ATP CLI

    ATP CLI nie ma zbyt wielu komend. Najciekawszą, oprócz shell, jest debug. To nie jest zwykły debuger; komenda ta wyświetla informacje na temat kolejnych komend: igmpproxy, cwmp, sysuptime i atpversion. Większość z nich nie zaprezentuje nam nic ciekawego, ale cwmp jest ciekawe - związane jest z zdalną konfiguracją routera.

    Reverse Engineering w praktyce - część 2


    Ponownie udało nam się odnaleźć ciekawe dane do uwierzytelniania (TR-069) wykorzystywane podczas zdalnej konfiguracji systemu. Nawet nie są zakodowane w jakikolwiek sposób. Pozostałe komendy ATP są w sumie bezwartościowe: czyszczenie ekranu, zapisanie ustawień do flasha czy menu pomocy.

    Eksploracja linii komend U-boot'a

    Linie poleceń bootloadera oferują niskopoziomowy dostęp do niektórych z obszarów pamięci. Niestety nie oferują nam bezpośredniego dostępu do układu flash, ale i tak warto je sprawdzić.

    Code:
    Please choose operation:
    
       3: Boot system code via Flash (default).
       4: Entr boot command line interface.
    You choosed 4
    Stopped Uboot WatchDog Timer.
    4: System Enter Boot Command Line Interface.
    U-Boot 1.1.3 (Aug 29 2013 - 11:16:19)
    RT3352 # help
    ?       - alias for 'help'
    bootm   - boot application image from memory
    cp      - memory copy
    erase   - erase SPI FLASH memory
    go      - start application at address 'addr'
    help    - print online help
    md      - memory display
    mdio   - Ralink PHY register R/W command !!
    mm      - memory modify (auto-incrementing)
    mw      - memory write (fill)
    nm      - memory modify (constant address)
    printenv- print environment variables
    reset   - Perform RESET of the CPU
    rf      - read/write rf register
    saveenv - save environment variables to persistent storage
    setenv  - set environment variables
    uip - uip command
    version - print monitor version
    RT3352 #


    Pod żadnym pozorem nie dotykajcie komend takich jak erase, mm, mw czy nm, jeśli nie wiecie DOKŁADNIE co robią. Najpewniej skończy się tylko na resecie, ale jest szansa że możemy nasz router 'scegłować' - wymazanie istotnych obszarów pamięci flash nie pozwoli mu już działać. Skupmy się na innych komendach: md (wyświetla zawartość pamięci) oraz printenv.

    Code:
    RT3352 # printenv
    
    bootcmd=tftp
    bootdelay=2
    baudrate=57600
    ethaddr="00:AA:BB:CC:DD:10"
    ipaddr=192.168.1.1
    serverip=192.168.1.2
    ramargs=setenv bootargs root=/dev/ram rw
    addip=setenv bootargs $(bootargs) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):$(netdev):off
    addmisc=setenv bootargs $(bootargs) console=ttyS0,$(baudrate) ethaddr=$(ethaddr) panic=1
    flash_self=run ramargs addip addmisc;bootm $(kernel_addr) $(ramdisk_addr)
    kernel_addr=BFC40000
    u-boot=u-boot.bin
    load=tftp 8A100000 $(u-boot)
    u_b=protect off 1:0-1;era 1:0-1;cp.b 8A100000 BC400000 $(filesize)
    loadfs=tftp 8A100000 root.cramfs
    u_fs=era bc540000 bc83ffff;cp.b 8A100000 BC540000 $(filesize)
    test_tftp=tftp 8A100000 root.cramfs;run test_tftp
    stdin=serial
    stdout=serial
    stderr=serial
    ethact=Eth0 (10/100-M)


    Environment size: 765/4092 bytes


    Widzimy wiele ciekawych informacji, takich jak chociażby prędkość interfejsu UART czy adresy interesujących obszarów pamięci, wykraczające poza pamięci flash. Pamięć flash adresowana jest trzema bajtami i ma adresy od 0x00000000 do 0x00FFFFFF.

    Mimo wszystko spójrzmy na niektóre z nich, chociażby po to, aby sprawdzić jakie możliwości da nam ten interfejs, co z kernel_addr=BFC40000?

    Reverse Engineering w praktyce - część 2


    Ta informacja mówi nam, że próbujemy odczytać nieprawidłowy obszar pamięci... ale tak na prawdę jest zakodowana w samej komendzie md, aby uniemożliwić dostęp do niektórych obszarów pamięci.

    Reverse Engineering w praktyce - część 2


    To są poprawne adresy, po prostu nie są dostępne z poziomu U-boota.

    Reverse Engineering w praktyce - część 2


    Pamiętajmy, że ładując U-boot'a zatrzymaliśmy ładowanie kernela, więc nie mamy dostępu do wysokopoziomowych interfejsów w systemie.

    Możemy próbować czytać dosyć losowe fragmenty pamięci poprzez md. Gdy spojrzymy na przykład na adres 0x000d0000:

    Kod: bash
    Zaloguj się, aby zobaczyć kod


    To widzimy nagłą zmianę w zapisie pamięci. To prawie już jak mieć wróbla w garści. Zobaczymy jak wygląda komenda md w akcji:



    Kolejne kroki

    W kolejnych częściach połączymy wiedzę na temat firmware i hardware. Pozwoli nam to zrozumieć przepływ danych w systemie i wyłapać wyciekające z systemu dane.

    Źródło: http://jcjc-dev.com/2016/04/29/reversing-huawei-router-2-scouting-firmware/


    Fajne! Ranking DIY
    Potrafisz napisać podobny artykuł? Wyślij do mnie a otrzymasz kartę SD 64GB.
  • Servizza
  • #2 15 Lut 2017 00:29
    szymon122
    Poziom 37  

    ghost666 napisał:
    bez dostępu do portu UART w systemie

    A czy coś takiego można jakoś przerobić jakoś w systemie? Nie dla radnych niecnych celów ale żeby np router był serwerem dla np arduino. Tak żeby na innym porcie podstawić serwer WWW pokazujący np stan czujników.

  • Servizza
  • #3 15 Lut 2017 00:34
    ghost666
    Tłumacz Redaktor

    szymon122 napisał:
    ghost666 napisał:
    bez dostępu do portu UART w systemie

    A czy coś takiego można jakoś przerobić jakoś w systemie? Nie dla radnych niecnych celów ale żeby np router był serwerem dla np arduino. Tak żeby na innym porcie podstawić serwer WWW pokazujący np stan czujników.


    Tam stoi Linux - w teorii nie widzę powodów, aby się nie dało czegoś wystawić gdzieś, o ile tam można zainstalować jakiś telnet czy coś... Python chyba nie pójdzie :D

  • #4 15 Lut 2017 07:10
    ADI-mistrzu
    Poziom 30  

    Swojego czasu także robiłem reverse engineering ale chińskiej kamery na układzie HI3516.
    W celu mocniej modyfikacji systemu zgrałem całą zawartość pamięci FLASH (jako RAW data, bajt po bajcie), a utworzony w ten sposób obraz można było już na komputerze z linuksem zamontować i sobie w nim dłubać. Dodatkowo dało to możliwość wgrania nowego oprogramowania na większą kość pamięci i rozbudowania systemu (np. zrobienie z kamery DVR do monitoringu zgrywający nagrania co 30min na domowy serwer FTP i kasujący stare pliki po przepełnieniu dysku).

    Czy zamierza autor także opisać tego typu metody? Czyli "wyrwanie" danych z pamięci i modyfikacja ich na innej maszynie?

  • #5 15 Lut 2017 09:18
    krisRaba
    Poziom 26  

    ghost666 napisał:
    dane zaprezentowane poniżej nie są zbyt czułe

    Nie wiem co tam było w oryginale, ale dane przeważnie są "wrażliwe", nie czułe ;)

  • #6 15 Lut 2017 09:56
    Bojleros
    Poziom 15  

    Cześć,

    szymon122 napisał:

    ghost666 napisał:
    bez dostępu do portu UART w systemie

    A czy coś takiego można jakoś przerobić jakoś w systemie? Nie dla radnych niecnych celów ale żeby np router był serwerem dla np arduino. Tak żeby na innym porcie podstawić serwer WWW pokazujący np stan czujników.


    W alternatywnych softach często się wykorzystuje lighthttpd. Jeżeli bootloader po wystartowaniu zwalnia port tak że os jest go w stanie użyć to możesz sobie czytać ardunio po rs232/485. Możesz także zrobić mastera 1wire w oparciu uart (w notach atmela jest przykład). Zasadniczo jeżeli soft się skompiluje, zmieści do ramu i flasha to powinien zadziałać. Musisz pamiętać, że w tego typu urządzeniach masz często bardzo okrojonego Linuxa i dość uproszczony hardware (busybox, uCLinux, SOC bez MMU). Zawsze możesz wybrać jakąś płytę Routerboard i wpakować tam WRT.

    Pozdrawiam,

  • #7 15 Lut 2017 10:24
    szymon122
    Poziom 37  

    Bojleros napisał:
    Jeżeli bootloader po wystartowaniu zwalnia port tak że os jest go w stanie użyć to możesz sobie czytać ardunio po rs232/485.

    Czy na takim routerze mogą być na raz dwa serwery? Np port 80 standardowo do konfiguracji a 81 z danymi odebranymi z UART? Nie chciałbym się "podpinać" pod oryginalną stronę konfiguracyjną (co oczywiście byłoby najprostsze, do kodu strony dodać skrypt wyświetlający dane z UART).

  • #8 15 Lut 2017 10:54
    Bojleros
    Poziom 15  

    Obecnie jedna "instalka" serwera aplikacyjnego może Ci hostować wiele stron i teoretycznie nie musisz otwierać dodatkowego portu. W twoim przypadku osobny port jest jednak sensowny. Poszukaj proszę pod słowem kluczem "VirtualHosts". O ile cpu/ramu nie braknie ....

    Teoretycznie otwierając stronę możesz wywoływać skrypt, który przy odpowiednio dobranych uprawnieniach będzie w stanie otworzyć urządzenie portu szeregowego i wysyłać zapytania bezpośrednio. Na początek napisz sobie jednak coś prostszego co zrzuci dane do csv/xml (choćby z crona co minutę). Analiza będzie prostsza a wyświetlić csv albo xml to nie jest trudne. Nie będziesz miał także problemów z tym że dwa zapytania wywołają kolizję na magistrali rs485. Dane będą szły z csv/xml które będzie stanowiło bardzo prosty cache. A może RRDTool ?

    Pozdrawiam,

  • #9 18 Lut 2017 15:16
    satanistik
    Poziom 27  

    Bardzo ciekawy artykuł, może opisał by Kolega przytoczoną w komentarzach metodę montowania obrazu pamięci np .bin lub .hex w systemie Linux tak aby można było odczytać partycje np ubifs?. Kiedyś próbowałem uruchomić program nandemulator ale ze względu na słabą znajomość Linuxa nic mi nie wyszło ;-).

  • #11 25 Kwi 2017 17:24
    Bojleros
    Poziom 15  

    Cześć,

    Jeżeli chcesz robić ekstrakcję danych z urządzeń blokowych to możesz zastosować dd do zrzucenia kopii obrazu z wymaganym offsetem. W tym momencie pracujesz bezpiecznie na kopii a nie bezpośrednio na danych. Możesz tak samo wykorzystać urządzenia loop do zmajstowania urządzenia blokowego wyciętego z innego urządzenia ale o konkretnym offsecie. Przykład z internetów, mamy plik raw z wirtualki na której system gościa założył sobie partycje do których musimy się dobrać:

    Code:
    $ /sbin/fdisk -lu disk.img
    
    You must set cylinders.
    You can do this from the extra functions menu.

    Disk disk.img: 0 MB, 0 bytes
    255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
    Units = sectors of 1 * 512 = 512 bytes

    Device Boot Start End Blocks Id System
    disk.imgp1 * 63 96389 48163+ 83 Linux
    disk.imgp2 96390 2056319 979965 82 Linux swap / Solaris
    disk.imgp3 2056320 78140159 38041920 5 Extended
    disk.imgp5 2056383 3052349 497983+ 83 Linux
    disk.imgp6 3052413 10859939 3903763+ 83 Linux
    disk.imgp7 10860003 68372639 28756318+ 83 Linux
    disk.imgp8 68372703 76180229 3903763+ 83 Linux
    disk.imgp9 76180293 78140159 979933+ 83 Linux

    #we want to get data from disk.imgp7
    # losetup /dev/loop0 disk.img -o $((10860003 * 512))
    # file -s /dev/loop0
    /dev/loop0: Linux rev 1.0 ext3 filesystem data
    # mount /dev/loop0 /mnt
    [...]
    # umount /mnt
    # losetup -d /dev/loop0


    Wydaje mi się że hex nie jest do tego najodpowiedniejszym formatem. Tu bardziej podpada bin. Zobacz na użycie polecenia file powyżej. Jeżeli bin to dane bajt po bajcie to bardzo możliwe, że montując przez loopa z offsetem dostaniesz się do tego czego szukasz. Pomocne mogą tu być narzędzia z pakietu binutils. Nie pamiętam już dokładnie ale jest takie które potrafi z .elf wytargać bin i hex. Zapewne da się tez w drugą stronę.

    PS. Nawet jeżeli bin to bajt po bajcie to może zostać jeszcze kwestia różnic endianess.