Why would I need to invest my time in trying to dump the firmware of a cable modem?

The short explanation: that specific firmware was urgently needed to be deployed on more devices (many) in order to correct a critical failure. The official procedure through the vendor support channel was unlikely to be successful within an acceptable time.

I decided to explore the telnet CLI to figure out whether there was a simple way to upload the firmware to another machine using TFTP or FTP, but there is nothing similar. However, theCM/Flash directory looked promising:

CM/Flash>?
autoTest cfi_show close configRegion deinit 
erase init open read readDirect 
show write writeArray
CM/Flash> show
Block kB Address Offset Offset Region Allocation
 — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -
   0 32 0x1badf1a5 0 0 Bootloader
   1 32 0x1bae71a5 0x8000 0x8000 Bootloader (65536 bytes)
   2 64 0x1baef1a5 0x10000 0 Permanent NonVol (65536 bytes)
   3 64 0x1baff1a5 0x20000 0 Image1
…
 128 64 0x1c2cf1a5 0x7f0000 0x7d0000 Image1 (8257536 bytes)
 129 64 0x1c2df1a5 0x800000 0 Image2
…
 254 64 0x1caaf1a5 0xfd0000 0x7d0000 Image2 (8257536 bytes)
 255 64 0x1cabf1a5 0xfe0000 0 Dynamic NonVol
 256 64 0x1cacf1a5 0xff0000 0x10000 Dynamic NonVol (131072 bytes)

Good news! It is possible to perform read queries on the device flash memory:

CM/Flash> open image1
Opening the flash driver…
Flash driver opened.
CM/Flash> read 4 64 0
Reading 64 bytes as 4-byte entities, starting at an offset of 0 bytes into the region:
a0410005 00030000 54002665 00499cc4 80004000 65333932 352d4531 302d352d 63313230 30723535 
39332d31 34303832 39632e62 696e0000 00000000 00000000

Great! I could write a simple program to read out the whole area of memory and then generate the binary firmware file. But…

How could I validate that I’m doing well?

The size of each memory area is ~8MB when images of this specific modem are ~2Mb. In other words, I’d have to process the header of the image to find its size. At this point it was a huge help this awesome post from @bernardomr and to have access to other versions of firmware to reverse engineering.

header

After some research I came to the following:

  • The LZMA file begins at the position 0x5c (0x5d000010 …).
  • The 3 bytes in yellow represent the file size: 0x1c0fbc (1,839,036 bytes).
  • So I need to read the flash to the byte 0x5c + 0x1c0fbc = 0x1c1018.

Finally, I wrote brcm_firmware_dump.py and was able to get the firmware 🙂

brcm_firmware_dump

Advertisements

One thought on “How to dump firmware images from Broadcom-based cable modems

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s