Reverse engineering Hikvision camera firmware and LiteOS bootloader
Asked Answered
A

0

6

I have a Hikvision IP camera that I'm doing security research on. (Model DFI6257E, looks like a Taiwan exclusive model. )

After dumping firmware from its flash and analyze it with binwalk, I found it intriguingly difficult to understand how its working. Almost like they are trying to hide things.

Dumped firmware : https://drive.google.com/file/d/1x9JiVbnZo4zNNnX8V8JS1MGsK4wmHFM6/view?usp=sharing

Here's the output of binwalk:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
36392         0x8E28          LZMA compressed data, properties: 0x5D, dictionary size: 16777216 bytes, uncompressed size: -1 bytes
10092544      0x9A0000        JFFS2 filesystem, little endian
16318544      0xF90050        Zlib compressed data, compressed
16318764      0xF9012C        Zlib compressed data, compressed
16319000      0xF90218        Zlib compressed data, compressed
16319136      0xF902A0        Zlib compressed data, compressed
16319592      0xF90468        Zlib compressed data, compressed
16320424      0xF907A8        Zlib compressed data, compressed
16320864      0xF90960        Zlib compressed data, compressed
16321796      0xF90D04        Zlib compressed data, compressed
16322380      0xF90F4C        Zlib compressed data, compressed
16322560      0xF91000        Zlib compressed data, compressed
16323100      0xF9121C        Zlib compressed data, compressed
16324028      0xF915BC        Zlib compressed data, compressed
16324556      0xF917CC        Zlib compressed data, compressed
16325336      0xF91AD8        Zlib compressed data, compressed
16326072      0xF91DB8        JFFS2 filesystem, little endian
16326276      0xF91E84        Zlib compressed data, compressed
16327348      0xF922B4        JFFS2 filesystem, little endian
16328220      0xF9261C        Zlib compressed data, compressed
16328684      0xF927EC        JFFS2 filesystem, little endian
16329344      0xF92A80        Zlib compressed data, compressed
16329840      0xF92C70        JFFS2 filesystem, little endian
16330528      0xF92F20        Zlib compressed data, compressed
16330992      0xF930F0        JFFS2 filesystem, little endian
16331632      0xF93370        Zlib compressed data, compressed
16332212      0xF935B4        JFFS2 filesystem, little endian
16332416      0xF93680        Zlib compressed data, compressed
16332680      0xF93788        JFFS2 filesystem, little endian
16333240      0xF939B8        Zlib compressed data, compressed
16333528      0xF93AD8        JFFS2 filesystem, little endian
16334148      0xF93D44        Zlib compressed data, compressed
16334188      0xF93D6C        JFFS2 filesystem, little endian
16334896      0xF94030        Zlib compressed data, compressed
16335076      0xF940E4        Zlib compressed data, compressed
16335412      0xF94234        Zlib compressed data, compressed
16335520      0xF942A0        Zlib compressed data, compressed
16335708      0xF9435C        Zlib compressed data, compressed
16335984      0xF94470        Zlib compressed data, compressed
16336320      0xF945C0        Zlib compressed data, compressed
16336888      0xF947F8        Zlib compressed data, compressed
16337540      0xF94A84        Zlib compressed data, compressed
16337852      0xF94BBC        Zlib compressed data, compressed
16338032      0xF94C70        Zlib compressed data, compressed
16338288      0xF94D70        Zlib compressed data, compressed
16339092      0xF95094        Zlib compressed data, compressed
16339748      0xF95324        Zlib compressed data, compressed
16339792      0xF95350        JFFS2 filesystem, little endian

The first thing I noticed is that there is no uboot header or uImage header that's often seen in other embedded device firmware. The bootloader is located in the decompressed LZMA data at 0x8E28 (Known by comparing what I see from UART console output and output of strings 8E28)

But again it's not a usual U-boot program as binwalk failed to detect U-boot when I used binwalk to analyze it.

I really want to know how I can process this data at 0x8E28 so I can do some RE on IDA or ghidra and sort out how this device works internally.

The camera's web service is running on Angular (yet another unusual feature in embedded device.) but there are no Angular binaries to be found in the firmware even after binwalk extraction. Web interface password is not stored in ipc_db as most other Hikvision products do.

(The provided firmware file is dumped after I edited admin password to "HikHiktest", so the entry "admin:12345" in ipc_db is not the correct one which web interface is looking for authentication.)

And there are also a lot of cryptic stuff happening in this firmware.

My guess for now is decryption is done in uboot and other stuff is handled by Huawei LiteOS powering this device, but in order to do further research I will need to first extract these two and the binaries in use from the firmware.

Can anyone share how I might achieve my goal? Any advice is appreciated.

Some part of console boot log, if it's useful:

Uncompress..............Ok


System startup


U-Boot 2010.06-396122 (Jun 12 2018 - 14:17:54)

SPI Nor: 16MB
DDR: 64MB
Erasing SPI flash, offset 0x00060000 size 64K ...done
Writing to SPI flash, offset 0x00060000 size 64K ...done
[Uboot] In release mode!
Hit Ctrl+u to stop autoboot:  0
MAC:   68-6D-BC-7D-81-EC
PHY not link.
TFTP server auto connect disabled

booting from sys part...
Load kernel to 0x81ffffc0 ...
Done!
Succeed!
## Booting kernel from Legacy Image at 81ffffc0 ...
   Image Name:   LiteOS-0.1.0-e3
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    5997539 Bytes = 5.7 MiB
   Load Address: 80000000
   Entry Point:  80000000
   Uncompressing Kernel Image ... OK

Starting kernel ...

********hello Huawei LiteOS ARM926********

version : Huawei LiteOS V200R001C10B039
open-version : Huawei LiteOS 1.4.11
build data : Dec 11 2018 10:44:09

**********************************
osAppInit
uart init ...
spi bus init ...
dmac init
i2c bus init ...
random dev init ...
hw random dev init ...
mem dev init ...
porc fs init ...
Mount procfs finished.
Mount ramfs finished.
cxx init ...
spi nor flash init ...
Spi Nor ID:0xC8 0x40 0x18 0xC8 0x40 0x18 0xC8 0x40
Spi Nor Flash Info:
Name:"GD25Q128" Size:16MB Block:64KB
gpio init ...
base module init success.
RS485_CTRL         MUXCTRL(37)  FCN0  GPIO3_0   OUTPUT   LOW_LEVEL
RS485_RXD          MUXCTRL(36)  FCN1  NO_GPIO
RS485_TXD          MUXCTRL(34)  FCN1  NO_GPIO
UART2_RXD          MUXCTRL(49)  FCN2  NO_GPIO
UART2_TXD          MUXCTRL(50)  FCN2  NO_GPIO
SENSOR_RST         MUXCTRL(14)  FCN1  NO_GPIO
SENSOR_CLK         MUXCTRL(15)  FCN1  NO_GPIO
PHY_RST            MUXCTRL(48)  FCN1  NO_GPIO
I2C0_SDA           MUXCTRL(11)  FCN3  NO_GPIO
I2C0_SCL           MUXCTRL(12)  FCN3  NO_GPIO
I2C1_SDA           MUXCTRL(8 )  FCN1  NO_GPIO
I2C1_SCL           MUXCTRL(9 )  FCN1  NO_GPIO
SPI0_CSN           MUXCTRL(13)  FCN1  NO_GPIO
SPI1_SCLK          MUXCTRL(53)  FCN1  NO_GPIO
SPI1_MOSI          MUXCTRL(51)  FCN1  NO_GPIO
SPI1_MISO          MUXCTRL(53)  FCN1  NO_GPIO
SPI1_CSN0          MUXCTRL(57)  FCN1  GPIO7_3   OUTPUT   HIGH_LEVEL
SPI1_CSN1          MUXCTRL(58)  FCN1  GPIO7_4   OUTPUT   HIGH_LEVEL
ALARM_OUT1         MUXCTRL(62)  FCN0  GPIO0_1   OUTPUT   LOW_LEVEL
ALARM_IN2          MUXCTRL(61)  FCN0  GPIO0_0   INPUT    LOW_LEVEL
ALARM_OUT2         MUXCTRL(22)  FCN0  GPIO1_6   OUTPUT   LOW_LEVEL
IRCUT_1            MUXCTRL(7 )  FCN0  GPIO6_0   OUTPUT   LOW_LEVEL
IRCUT_2            MUXCTRL(6 )  FCN0  GPIO6_1   OUTPUT   LOW_LEVEL
IRCUT/ZOOM_FB      MUXCTRL(55)  FCN1  GPIO7_1   INPUT    LOW_LEVEL
ABF/FOCUS_FB       MUXCTRL(56)  FCN1  GPIO7_2   INPUT    LOW_LEVEL
MFOCUS             MUXCTRL(60)  FCN1  GPIO7_6   INPUT    LOW_LEVEL
IRIS_SET           MUXCTRL(35)  FCN0  GPIO3_2   OUTPUT   LOW_LEVEL
IRIS_PWM           MUXCTRL(3 )  FCN1  NO_GPIO
FAR_IR_PWM         MUXCTRL(1 )  FCN1  NO_GPIO
NEAR_IR_PWM        MUXCTRL(2 )  FCN1  NO_GPIO
PHOTO_FB           MUXCTRL(63)  FCN1  NO_GPIO
PIR/TEMP_IN        MUXCTRL(64)  FCN1  NO_GPIO
USB_PWREN          MUXCTRL(25)  FCN1  NO_GPIO
WORK_LED           MUXCTRL(21)  FCN0  GPIO1_5   OUTPUT   LOW_LEVEL
START_LED          MUXCTRL(16)  FCN0  GPIO1_0   OUTPUT   LOW_LEVEL
ETHERNET_LED       MUXCTRL(18)  FCN0  GPIO1_2   OUTPUT   LOW_LEVEL
BCMDHD_OOB         MUXCTRL(65)  FCN0  GPIO8_2   INPUT    LOW_LEVEL
MRESET             MUXCTRL(59)  FCN1  GPIO7_5   INPUT    LOW_LEVEL
<6>Successfully insmod exact_timer module!
hik_core module init success.
enter pwm init
<6>init hikio.
watchdog_init success.
rtc init success
tcpip init ...

Calling lwIPRegSecSspCbk
net init ...
enter hisi_eth_init!

hisi_eth init begin.
hisi_eth: User did not set phy mode, use default=rmii
hisi_eth: User did not set phy addr, auto scan...
Detected phy addr 3, phyid: 0x1cc816
s
# g_sys_mem_addr_end=0x81f00000,
done init!
Date:Dec 18 2018.
Time:12:51:58.
osal_proc_mkdir - parent is NULL! proc=0x8109a860
mem_start=0x80000000, MEM_OS_SIZE=31M, MEM_USB_SIZE=0M, mmz_start=0x81f00000, mmz_size=33M
mmz param= anonymous,0,0x81f00000,26556K:ddr0,0,0x838ef000,7236K
<6>Hisilicon Media Memory Zone Manager
load sys.ko...OK!
load region.ko...OK!
load vgs.ko...OK!
load viu.ko...OK!
ISP Mod init!
load vpss.ko...OK!
load rc.ko ...OK!
ModuleParam: VencMaxChnNum(0) is illegal,should be [1, 16]
load venc.ko ...OK!
load chnl.ko...OK!
load vedu.ko ...OK!
ModuleParam: check H264eVBSource(0) illegal
load h264e.ko ...OK!
ModuleParam: H265eVBSource(0) is illegal,should be [1, 2]
load h265e.ko ...OK!
load jpege.ko ...OK!
sensor dev init OK.
load pwm.ko OK!
load hi_mipi driver successful!
Load hi_cipher.ko success.
load aio.ko ...OK!
load ai.ko OK!
load ao.ko OK!
load aenc.ko OK!
load adec.ko OK!
load acodec.ko...OK!
load ive.ko...OK!
SDK init ok...
Load power ok.
power on.
Unload power success.
Armoire answered 23/6, 2020 at 8:37 Comment(5)
You said binwalk didn't detect uboot on the decompressed lzma data, but did it detect anything there? What are the first bytes?Mckie
@Mckie Binwalk only detect some few fasle positives and minor stuffs like "SHA256 hash constants, little endian" or "crc32 polynomial table". First four bytes are \x17 \x04 \x00 \xEAArmoire
I am not entirely sure about your boot loader issue. I am working on a different device right now that has Huawei LiteOS and it does have U-Boot and clearly shows it in binwalk. I captured the firmware via mitm, not from a flash dump. Also I believe LiteOS is an RTOS. So I think the actual OS image has all of the files clumped together in the image, possibly showing all of the files as binwalk sees the header (just an idea really haven't looked into it)? If you really want to extract the data at that address, you can always dd it out. Good luck!Ratsbane
Have you been able to go any further? I'm facing the same challenge, and yes, there's definitely an encryption going on the main image.Rummage
@Rummage Yes, my friend and I found that the firmware image is encrypted even in the flash chip itself. The decryption key is in the OTP zone of the processor and it's decrypted on boot. (Hence a very long boot time) we don't think it's possible to retrieve the key in programmatic way (except using something like a chip whisperer.) But we do found a vulnerability in other parts of the boot process that allow us to gain access to decrypted firmware image :)Armoire

© 2022 - 2024 — McMap. All rights reserved.