Chińska kamera IP BLK510 i Reverse Engineering

Opublikowano: 20-06-2019 17:33 | Autor: Dawid

Zmotywowany zabawą wideodomofonem, postanowiłem kupić chińską IP kamerkę opartą na tym samym układzie co domofon. Niestety, w opisie aukcji jest błąd i tak naprawdę kamerka przyszła na innym SoC, a zakupu dokonałem tylko w celu podmiany Firmware. Lepiej bawić się na produkcie w cenie za 49,50 zł, niż ponad 2000zł.

Kamera1Kamera2

AHWVE POE DIY IP Camera module Board with IRCUT

Tak naprawdę produkt jest oparty na SoC IPC 510a (ARMv7 Processor rev 1 (v7l)) posiadający 32MB RAM do dyspozycji. Całe Firmware zaszyte jest w kości W25Q64CV czyli 64MiB = 8MB. Domyślnym adresem IP jest 192.168.1.10, więc jako że mój wideodomofon ma taki adres IP na interfejsie sieciowym eth0 (nie ma możliwości zamiany), to w pierwszej kolejności musiałem zmienić ten adres. I tu spotkała mnie mała niespodzianka, web interfejs działa tylko z IE. W dodatku wymaga kontrolki AcitvX (naah).

Po udanej zamianie adresu IP przystąpiłem do dalszej zabawy. W pierwszej kolejności poleciał nmap:

[email protected]:~/$  sudo nmap -Pn -sV -p- 192.168.1.201
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-20 12:12 CEST
Nmap scan report for 192.168.1.201
Host is up (0.0021s latency).
Not shown: 65528 closed ports
PORT      STATE SERVICE       VERSION
80/tcp    open  http          uc-httpd 1.0.0
554/tcp   open  rtsp          H264DVR rtspd 1.0
8899/tcp  open  soap          gSOAP 2.7
9530/tcp  open  unknown
34567/tcp open  dhanalakshmi?

O proszę, brak telnet i tylko "standardowe porty" pootwierane.

  • 80 - web interfejs
  • 554 - strumien rtsp
  • 8899 - onvif
  • 9530 - nie mam pojęcia
  • 34567 - API oparte o JSON do zarządzanie kamerą (oczywiście dowiedziałem się tego znacznie później)

Próba wstrzyknięcia komend poprzez Onvif czy http również zakończyła się porażką.

Lutowanie kabelków i U-boot

Kamera3

No nic, port szeregowy musi ruszyć do akcji. Po kilku minutach szukania w Google znalazłem opis dostępnych pinów. Pierwsze przechwycenie boot-owania i kolejne zdziwienie. Po załadowaniu Kernela - nic, brak jakichkolwiek informacji. Kurcze.. naprawdę się postarali.

U-Boot 2014.04 (Dec 16 2016 - 14:37:27)

CPU: XM510
DRAM:  32 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dwmac.20040000
Press Ctrl+C to stop autoboot
### CRAMFS load complete: 1640256 bytes loaded to 0x81000000
## Booting kernel from Legacy Image at 81000000 ...
   Image Name:   Linux-3.0.101
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1640192 Bytes = 1.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Loading Kernel Image ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.

Przerwijmy boot systemu i zobaczmy co jest w U-BOOT, a dokładniej mówiąc jakie mamy "zmienne środowiskowe".

U-Boot> printenv
baudrate=115200
bootargs=mem=18M console=ttyAMA0,115200 root=/dev/mtdblock1 rootfstype=cramfs mtdparts=xm_sfc:256K(boot),3520K(romfs),2560K(user),1280K(web),256K(custom),320K(mtd)
bootcmd=cramfsload;bootm 0x81000000
bootdelay=1
cramfsaddr=0x40000
da=mw.b 0x81000000 ff 800000;tftp 0x81000000 u-boot.bin.img;sf probe 0;flwrite
dc=mw.b 0x81000000 ff 800000;tftp 0x81000000 custom-x.cramfs.img;sf probe 0;flwrite
dd=mw.b 0x81000000 ff 800000;tftp 0x81000000 mtd-x.jffs2.img;sf probe 0;flwrite
dr=mw.b 0x81000000 ff 800000;tftp 0x81000000 romfs-x.cramfs.img;sf probe 0;flwrite
du=mw.b 0x81000000 ff 800000;tftp 0x81000000 user-x.cramfs.img;sf probe 0;flwrite
dw=mw.b 0x81000000 ff 800000;tftp 0x81000000 web-x.cramfs.img;sf probe 0;flwrite
ethact=dwmac.20040000
ethaddr=00:12:16:cd:5f:9d
ipaddr=192.168.1.10
netmask=255.255.255.0
serverip=192.168.1.107
stderr=serial
stdin=serial
stdout=serial
telnetctrl=0
tk=mw.b 0x81000000 ff 800000;tftp 0x81000000 uImage; bootm 0x81000000
ua=mw.b 0x81000000 ff 800000;tftp 0x81000000 upall_verify.img;sf probe 0;flwrite
up=mw.b 0x81000000 ff 800000;tftp 0x81000000 update.img;sf probe 0;flwrite
verify=n

Pierwsza z ciekawszych która rzuciła mi się w oczy to telnetctrl=0 . Prawdopodobnie odpowiada za start telnet-a, zmieńmy ją i zobaczmy co się stanie:

U-Boot> setenv telnetctrl 1
U-Boot> saveenv
U-Boot> reset

Bingo, po chwili byłem w stanie się połączyć z użyciem telnet. Teraz wystarczyło odgadnąć hasło. Doświadczony z zabawy z wideodomofonem, spróbowałem użyć haseł z:

[https://gist.github.com/gabonator/74cdd6ab4f733ff047356198c781f27d](https://gist.github.com/gabonator/74cdd6ab4f733ff047356198c781f27d)

Pierwszy strzał "xmhdipc" i bingo jesteśmy w środku.

[email protected]:~/$ telnet 192.168.1.201 23
Trying 192.168.1.201...
Connected to 192.168.1.201.
Escape character is '^]'.
(none) login: root
Password:
~ #

Inne sposoby odczytywania haseł, których nauczyłem się w trakcie projektu:

U-Boot> cramfsload /etc/passwd
### CRAMFS load complete: 59 bytes loaded to 0x81000000
U-Boot> md 0x81000000
81000000: 746f6f72 2431243a 77495952 41526945    root:$1$RYIwEiRA
81000010: 367a7824 58787257 46535a52 2e41362f    $xz6WrxXRZSF/6A.

Przegląd systemu

/home # ls -la /
total 13
drwxr-x---    1 1000     232           1012 Jan  1  1970 bin
drwxr-x---    1 1000     232             20 Jan  1  1970 boot
drwxrwxrwt    3 root     root          1320 Jan  1  1970 dev
drwxr-x---    1 1000     232            184 Jan  1  1970 etc
drwxr-x---    4 1000     1000          4096 Jun 20  2019 home
drwxr-x---    1 1000     232            920 Jan  1  1970 lib
lrwxrwxrwx    1 1000     232             11 Jan  1  1970 linuxrc -> bin/busybox
drwxr-x---    1 1000     232             68 Jan  1  1970 mnt
dr-xr-xr-x   43 root     root             0 Jan  1  1970 proc
drwxr-x---    1 1000     232              0 Jan  1  1970 root
drwxr-x---    1 1000     232            488 Jan  1  1970 sbin
drwxr-xr-x   11 root     root             0 Jan  1  1970 sys
drwxr-xr-x    2 root     root             0 Jan  1  1970 tmp
drwxrwxr-x    1 527      15              84 Jan  1  1970 usr
drwxr-xr-x    3 root     root             0 Jan  1  1970 var

W systemach typu "embedded" cały system uproszczony jest do maksimum. Tak naprawdę wszystkie narzędzia wchodzące w skład GNU Coreutils są trzymane w jednym pliku wykonywalnym busybox. Ten znajdujący się kamerce jest obcięty do niezbędnego minimum, binarka zajmuje zaledwie 358k:

/bin # ls -la busybox
-rwxr-x---    1 1000     1000        358948 Jan  1  1970 busybox
/bin # ./busybox
BusyBox v1.22.1 (2016-03-10 17:02:14 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        [, [[, arp, arping, ash, awk, basename, cat, chmod, clear, cp, cttyhack, cut, date, devmem,
        dhcprelay, dumpleases, echo, egrep, env, false, fgrep, free, getty, grep, halt, head, hush,
        hwclock, ifconfig, init, insmod, iostat, kill, killall, klogd, linuxrc, ln, logger, login,
        logread, ls, lsmod, lsof, mdev, mkdir, mkfifo, mknod, modinfo, mount, mpstat, mv, netstat,
        ping, ping6, pmap, poweroff, ps, pwd, reboot, rm, rmdir, rmmod, route, sed, setfont, sh,
        sleep, sync, syslogd, telnetd, test, time, top, touch, true, tty, udhcpc, udhcpd, umount

To wyjaśnia dlaczego po wpisaniu komendy dmesg wyskoczył mi komunikat dmesg: applet not found . Ilość dostępnych komend jest zatrważająco mała.

Głównym programem obsługującym sensor kamery jest Sofia (własnościowy program o zamkniętym kodzie źródłowym). On tak naprawdę obsługuje wszystkie dostępne funkcje kamery tj: Web Server, RTSP Server, Onvif Server etc. Generalnie ta sama zasada co z busybox-em - wszystko w jednej binarce.

Kolejną ciekawą sprawą jest sposób przechowywani systemu. Tak naprawdę cały mieści się w kości flash (w tym wypadku SoC łączy się z kością używając interfejsu SPI) i jest odczytywany przez jądro systemu za pomocą urządzeń blokowych mtd. Można rzec, że to jest nasz "firmware". Większość urządzeń typu embeded wykorzystuję tą metodę przechowywania oprogramowania, tj: routery, switch-e, drukarki, kamerki etc. Kompilując sprawę jeszcze bardziej flash podzielony jest na obszary, które mogą być odczytywane przez jadro systemu jako różne systemy plików, przykładowo:

Odczyt zawartości flash - teoria

W ramach zabawy spróbujmy odczytać główny FS z flash-a używając "mtd". Dlaczego akurat główny FS, ano bo tam jest mój ukochany /etc/passwd. W przypadku tej kamerki mamy:

~ # ls -la /dev/mtdblock*
brw-rw----    1 root     root       31,   0 Jan  1  1970 /dev/mtdblock0
brw-rw----    1 root     root       31,   1 Jan  1  1970 /dev/mtdblock1
brw-rw----    1 root     root       31,   2 Jan  1  1970 /dev/mtdblock2
brw-rw----    1 root     root       31,   3 Jan  1  1970 /dev/mtdblock3
brw-rw----    1 root     root       31,   4 Jan  1  1970 /dev/mtdblock4
brw-rw----    1 root     root       31,   5 Jan  1  1970 /dev/mtdblock5

I teraz rodzi się pytanie, który blok za co odpowiada?. Można do tego dojść na kilka sposobów:

1. Odczytując zmienną bootargs z U-boot

bootargs=mem=18M console=ttyAMA0,115200 root=/dev/mtdblock1rootfstype=cramfs mtdparts=xm_sfc:256K(boot),3520K(romfs),2560K(user),1280K(web),256K(custom),320K(mtd)

Jak sama nazwa wskazuje, podane jak natacy (pogrubione). Dodatkowo kursywą zaznaczyłęm typ FS-a. Również według kolejności argumentów możemy przyjąć

  • mtdblock0 = 256K(boot)

  • mtdblock1 = 3520K(romfs)

  • mtdblock2 = 2560K(user)

  • mtdblock3 = 1280K(web)

  • mtdblock4 = 256K(custom)

  • mtdblock5 = 320K(mtd)

    Sumując daje nam 8192K = 8MB (nawiasem mówiąc mały ten ROM)

2. Odczytując /proc/mtd

~ # cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00040000 00010000 "boot"
mtd1: 00370000 00010000 "romfs" <--- To nas będzie iteresować
mtd2: 00280000 00010000 "user"
mtd3: 00140000 00010000 "web"
mtd4: 00040000 00010000 "custom"
mtd5: 00050000 00010000 "mtd"

3. Odczytując dmesg (uprzedzam fakty)

...
Creating 6 MTD partitions on "xm_sfc":
0x000000000000-0x000000040000 : "boot"
0x000000040000-0x0000003b0000 : "romfs"
0x0000003b0000-0x000000630000 : "user"
0x000000630000-0x000000770000 : "web"
0x000000770000-0x0000007b0000 : "custom"
0x0000007b0000-0x000000800000 : "mtd"
...

Odczyt zawartości flash - praktyka

Na nasze szczęście "devy" zostawili komendę mount. Zacznijmy od pod montowania wyeksportowanego FS-a mojego NAS-a pod kamerkę oraz stworzenia katalogu:

~ # mount -t nfs -o rw,nolock 192.168.1.5:/homes/dawid/xm510 /home
~ # cd home/
/home # mkdir flash
~ #

I teraz znowu mamy 2 sposoby "zrzucenia" cat badź dd. Niestety dd jest nie dostępne aczkolwiek podam komende (bieda busybox, patrz wyżej)

  1. ~ # cat /dev/mtdblock1 > /home/flash/rootfs.img

  2. ~ # dd if=/dev/mtdblock1 of=/home/flash/rootfs_dd.img bs=1M

Tak utworzony plik możemy sprawdzić komendą file:

[email protected]:~/nas/xm510/flash$  file rootfs.img
rootfs: Linux Compressed ROM File System data, little endian size 2912256 version #2 sorted_dirs CRC 0xafe8201e, edition 0, 1130 blocks, 153 files

Czyli by się zgadzało z tym co jest podane w bootargs U-boot. Plik zawiera w sobie/bądź jest cramfs. Dodatkowym narzędziem którym warto mieć w trakcie zabawy z FW, a nie wspominałem o nim jeszcze, jest binwalk. Przetestujmy:

[email protected]:~/nas/xm510/flash$  binwalk rootfs.img

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             CramFS filesystem, little endian, size: 2912256 version 2 sorted_dirs CRC 0xAFE8201E, edition 0, 1130 blocks, 153 files

Rozpakowanie cramfs-a

Do tego celu potrzebujemy dodatkowych narzędzi. Najprostszym sposobem w moim przypadku jest pobranie gotowego repo firmware-mod-kit z GitHub-a. Zestaw tych narzędzi wymaga kompilacji jako że są w postaci kodu źródłowego. Może się okazać, że prostszym sposobem dla Ciebie drogi czytelniku, będzie pobranie dystrybucji Kali Linux. Wszystkie narzędzia wymienione w tym artykule są "wbudowane" w tą dystrybucję.

Przechodząc do sedna. Do rozpakowania cfamfs-a mamy narzędzie uncramfs. Podstawowa składnia jest banalna: uncramfs <katalog> <plik_z_obrazem>. Stworzy nam to całą strukture katalogów i plików, tak samo jak na urządzeniu.

[email protected]:~/nas/xm510/flash$ uncrmfs rootfs rootfs.img
[Volume size: 0x370000]
[Volume serial: 1e20e8af000000006a04000099000000]
[Volume name: Compressed]

drwxrwx--- 1000/232          244(244)     /

/:
drwxr-x--- 1000/232         1012(1012)    bin
drwxr-x--- 1000/232           20(20)      boot
drwxr-x--- 1000/232            0(0)       dev
drwxr-x--- 1000/232          184(184)     etc
drwxr-x--- 1000/232            0(0)       home
drwxr-x--- 1000/232          920(920)     lib
lrwxrwxrwx 1000/232           11(23)      linuxrc -> bin/busybox
drwxr-x--- 1000/232           68(68)      mnt
drwxr-x--- 1000/232            0(0)       proc
drwxr-x--- 1000/232            0(0)       root
drwxr-x--- 1000/232          488(488)     sbin
drwxr-x--- 1000/232            0(0)       sys
drwxr-x--- 1000/232            0(0)       tmp
drwxr-x--- 1000/232           48(48)      usr
drwxr-x--- 1000/232            0(0)       var

/bin:
lrwxrwxrwx 1000/232            7(19)      [ -> busybox
lrwxrwxrwx 1000/232            7(19)      [[ -> busybox
lrwxrwxrwx 1000/232            7(19)      ash -> busybox
...
...
...
/usr/sbin:

/var:

[Summary:]
[Total uncompressed size:      4468058]
[Total compressed size:        2912892]
[Number of entries:                153]
[Number of files compressed:        50]
[Number of files expanded:         103]

Mając taki główny system plików moglibyśmy podmienić hasło root-a na własne, bardziej bezpieczne.

Ustawienie własnego hasła root-a

Nasz plik /etc/passwd wygląd tak:

root:$1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0:0:0:root:/:/bin/sh

Każde pole oddzielone jest dwukropkiem ":", więc rozkładając na czynniki pierwsze ten zapis będzie to wyglądać następująco:

użytkownik:hash hasła:uid:guid:dodadkow infromacje:katalog domowy:powłoka systemowa

Hash hasła składa się również z pól, aczkolwiek tym razem oddzielonych znakiem dolara "$":

  1. Algorytm hash w naszym przypadku jest to MD5, poniżej lista hash-ów jakie możemy spotkać:
    • $1 = MD5 hashing algorithm.
  1. "Zahashowane" hasło: d5iRRVQ5ZeRTrJwGjRy.B0

Spróbujmy je odtworzyć. Do tego celu użyjemy komendy w naszym systemie:

[email protected]:~$  openssl passwd -1 -salt RYIwEiRA
Password:
$1$RYIwEiRA$d5iRRVQ5ZeRTrJwGjRy.B0

Jak widzimy wszystko się zgadza. Ja wygenerowałem sobie znacznie dłuższe i bardziej skomplikowane hasło (oczywiście nie słownikowe). Następnie je podmieniłem. Teraz przyszła pora na "wrzucenie" tego z powrotem do kamerki.

Mała dygresja. Krótkie hasła bardzo szybko się łamie nawet metodą brutalforce. Sześcio znakowe hasło mojego wideodomofonu "padło" w ciągu niespełna 25 minut.

Flash-owanie kamerki.

Proces ten może się wydawać bardzo skomplikowany, jednakże postaram się go wytłumaczyć najlepiej jak umiem.

W moim przypadku cała kośc ma pojemność 8MB i jest podzielon na bloki (przez producenta). Jak już wyżej wspomniałem w artykule, nas będzie interesować blok - mtdblock1 = 3520K(romfs). Musimy znać jego adres początkowy oraz końcowy do poprawnego "sflashowania kamerki". Aby obliczyć te adresy, musimy wziąść pod uwagę długość pierwszego bloku mtd0 - jest to 256K (mtdblock0 = 256K(boot)).

256 KiloBytes = 262144 Bytes ---> szesnastkowo 0x40000

Jest to adres końcowy bloku mtd0, a zarazem początkowy mtd1. W drugiej kolejności policzymy długość bloku mtd1.

3520 KiloBytes = 3604480 Bytes ---> szesnastkowo 0x370000

Na samym końcu musimy je razem dodać, aby otrzymać końcowy adres bloku mtd1

262144+3604480=3866624 ---> szesnastkowo 0x3B0000

Mając te adresy jesteśmy gotowi do zbudowania obrazu. Zwróćcie uwagę, że moje wyliczenia dokładnie pokrywają się z tym co podaje nam system. Mam na myśli dział "Odczyt zawartości flash"

Budowanie obrazu cramfs

Aby zbudować obraz cramfs, będziemy potrzebowali dwóch narzędzi:

  1. mkcramfs - dostępne w paczce fimware-mod-kit

  2. mkimage - dostępne w pacze ArchLinux pod nazwą uboot-tools (pacman -S uboot-tools)

Dodatkowo musimy znać dokładny adress w pamięci flash gdzie znajduje się nasz rootfs. Obliczyliśmy to w poprzednim rozdziale.

Najpierw tworzymy plik z zawartością całego głownego systemu plików. Inaczej mówiąc, przywracamy do stanu dump-a. Przypominam, że hash hasła powinien być już podmieniony.

Składnia polecenia jest banalna: mkcramfs <katalog> <nazwa_noego_pliku>

[email protected]:~/nas/xm510/flash$  mkcramfs rootfs romfs-x.cramfs
Directory data: 3220 bytes
Everything: 2844 kilobytes
Super block: 76 bytes
CRC: 1973df0f
warning: gids truncated to 8 bits (this may be a security concern)

Następnie tworzymy właściwy obraz pliku poleceniem mkimage. Właśnie w ten sposób producenci urządzeń dostarczają nam swoje aktualizacje. Nie będę się rozpisywał na temat wszystkich przełączników polecenia bo jest ich sporo (mkimage -h : wyjasni wszystko). Chciałbym natomiast zwrócić uwagę na 2 dosyć istotne, a mianowicie:

  • -a 0x00040000 Load Adress

  • -e 0x003B0000 Entry Point

To są te adresy które wyliczaliśmy wcześniej. Dzięki nim U-Boot wie który obszar pamięci kości flash ma nadpisać. W trakcie tworzenia obrazu są one dołączane jako nagłówek o długości 64 bajtów.

[email protected]:~/nas/xm510/flash$ mkimage -A arm -O linux -T ramdisk -n "linux" -a 0x00040000 -e 0x003B0000 -d romfs-x.cramfs romfs-x.cramfs.img
Image Name: linux
Created: Fri Jun 21 12:19:25 2019
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 2912256 Bytes = 2844.00 KiB = 2.78 MiB
Load Address: 00040000
Entry Point: 003b0000

TFTP i przesyłanie obrazu

Tak przygotowany pliczek będziemy musieli przesłać do kamery. Do tego celu użyjemy protokołu TFTP. Ze względu na jego "prostotę", U-boot używa go jako podstawowego narzędzia do przesyłania/odbierania plików.

Ja do tego celu użyłem paczki tftp-hpa (pacman -S tftp-hpa). Sama konfiguracja jest dosyć prosta. W moim przypadku była to edycja pliku i wystartowaniu daemona.

[email protected]:~/nas/xm510/flash$  sudo cat /etc/conf.d/tftpd
TFTPD_ARGS="--secure /home/dawid/nas/xm510/flash"
[email protected]:~/nas/xm510/flash$  sudo systemctl start tftpd.service

Właściwe flash-owanie.

Jak można zauważyć w trakcie ładowania systemu poprzez U-boot wykorzystywana jest pamięć RAM od adresu 0x81000000 (ładowanie jądra systemu). My również wykorzystamy ten adres do załaowania obrazu. Następnie z tego adresu nastąpi właściwy zapis do kości flash. Ten proces jest podzielony na kilka etapów:

  1. mw.b 0x81000000 ff 800000 - wyczyszenie pamięci RAM. Wpisanie "FF" razy 0x800000. Przeliczając daje nam to 8.388.608 Bytes = 8,192 Kilobytes

  2. tftp 0x81000000 romfs-x.cramfs.img - załadowanie obrazu z servera TFTP

  3. sf probe 0 - inicjacja kosci flash

  4. flwrite - właściwe flash-owanie. Komenda ta odczytuje Load Adress oraz Entry Point z nagłówka obrazu. Dzieki temu wie, który dokładnie obszar kości ma nadpisać.

Tuż przed uruchomieniem tego procesu należy ustawić jeszcze adres IP kamery, maskę sieci oraz adres IP servera TFTP.

#------------ Ustawienia adresów IP --------
U-Boot> setenv ipaddr 192.168.1.201
U-Boot> setenv netmask 255.255.255.0
U-Boot> setenv serverip 192.168.1.89
#------------ Flashowanie ------------------
U-Boot> mw.b 0x81000000 ff 800000
U-Boot> tftp 0x81000000 romfs-x.cramfs.img
Speed: 100, full duplex
Using dwmac.20040000 device
TFTP from server 192.168.1.89; our IP address is 192.168.1.201
Filename 'romfs-x.cramfs.img'.
Load address: 0x81000000
Loading: ##################################################
2.3 MiB/s
done
Bytes transferred = 2912320 (2c7040 hex)
U-Boot> sf probe 0
U-Boot> flwrite

## Checking Image at 0x81000000 ...
hdr->ih_magic=0x56190527
   Header CRC Checking ... OK
   Image Name:   linux
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    2912256 Bytes = 2.8 MiB
   Load Address: 00040000
   Entry Point:  003b0000
   Data CRC Checking ... OK
Programing start at: 0x00040000
Programing end at: 0x003b0000
FLASH_ERASE-------[100%]
done.
Erased sectors.
Saving Image to Flash ...
FLASH_WRITE-------[100%]
done.
U-Boot> reset
resetting ...

Podsumowanie

Tym sposobem dobrnęliśmy do końca. Udało nam się poprawnie podmienić hasło root-a ze standardowego "xmhdipc" na własne. W następnym artykule postaram się wyjaśnić jak można "dorzucić" swoje oprogramowanie, bądź zmodyfikować istniejące. Mam tu na myśli busybox, zwiększenie ilości komend. Dodatkowo istnieje możliwość zarządzania kamerą bez używania web interfejsu ze śmieszną kontrolką ActiveX.