Quantcast
Channel: Positive Technologies - learn and secure
Viewing all articles
Browse latest Browse all 198

Decipher Updates of a Popular 4G Modem: Dmitry Sklyarov’s Method

$
0
0

What could a reverse engineer do if trying to examine device code he couldn’t find anything except encrypted firmware files? Here is a real story how to meet the challenge with basic knowledge of computer science and mere logic.

We do not specify the modem vendor or exact names of the files deliberately — this article focuses on the challenge and an interesting approach to the solution. This method is not applicable to the latest models of the modem, but it might work with older ones and other vendors.

1. Identifying the structure

At first, we identify the structure of the firmware files. There are three update versions for the same modem:

  • v2.8_image.bin
  • v3.7_image.bin
  • v3.7.4_image.bin

The structure of all the files has the TLV (Tag-Length-Value) format. For instance, for v3.7.4_image.bin it looks as follows:


The values are all Little-endian, Tag is 16 bit long, Length is 32 bits.

Tag 0x7240 is located at the first nesting level, and its data occupies the whole file. Tag 0x0003 (0x0A bytes) takes the second level (inside the data of tag 0x7240); tag 0x0000 (0x4BDE0E bytes) goes next, then 0x0001 and 0x0002 (they didn’t fit in the screenshot). The third level (within the data of tag 0x0003) encapsulates tag 0x0002 that stores four-byte version number of the 030704FF file (3.7.4 if FF is skipped).

Other tags located at the second nesting level (0x0000, 0x0001, and 0x0002) store descriptions of separate files “packaged” in a single firmware file.

Each file has a name (tag 0x0001), flags (tag 0x0002), size (tag 0x0003), 16-byte value (tag 0x0004), and file data (tag 0x0005).

The following structure comes as a result of parsing the whole scope of the tags:


So it is possible to retrieve encrypted data for all the components (CPUImage, AutoInstall, and WebUI) from the firmware files. AutoInstall turned out to be the same for all three firmware versions, WebUI contents were the same for v3.7 and v3.7.4, and CPUImage was unique in every version.

2. Guesswork by algorithms

Tag 0x0004 at the third nesting level contains a 16-byte data set with high entropy. It might be a hash value, and the most popular 128-bit hash is MD5.

In the retrieved files, many bytes have the same values at the same offset. Below is the beginning of two files (differences are highlighted):


However, if you try to find the same sequences within a single file, there won’t be any long repeats.
This looks like a result of applying a constant semi-random gamma as long as the message. RC4 is the most popular cryptographic algorithm that functions this way.

3. Attacking a stream cipher with a constant key

If several messages are encrypted with the same key (i.e. gamma), XORing them may reveal their fragments: zero bytes will return plaintext.

The files AutoInstall and WebUI give interesting results:

00000000: EB 3C 90 6D 6B 64 6F 73 66 73 00 00 02 04 01 00  л<ђmkdosfs  ☻♦☺
00000010: 02 00 02 F8 0F F8 03 00 20 00 40 00 00 00 00 00  ☻ ☻ш☼ш♥   @
00000020: 00 00 00 00 00 00 29 6E 1F 3B 15 47 43 54 2D 4C        )n▼;§GCT-L
00000030: 54 45 20 20 20 20 46 41 54 31 32 20 20 20 0E 1F  TE    FAT12   ♫▼
00000040: BE 5B 7C AC 22 C0 74 0B 56 B4 0E BB 07 00 CD 10  ѕ[|¬"Аt♂Vґ♫»• Н►
00000050: 5E EB F0 32 E4 CD 16 CD 19 EB FE 54 68 69 73 20  ^лр2дН▬Н↓люThis
00000060: 69 73 20 6E 6F 74 20 61 20 62 6F 6F 74 61 62 6C  is not a bootabl
00000070: 65 20 64 69 73 6B 2E 20 20 50 6C 65 61 73 65 20  e disk.  Please
00000080: 69 6E 73 65 72 74 20 61 20 62 6F 6F 74 61 62 6C  insert a bootabl
00000090: 65 20 66 6C 6F 70 70 79 20 61 6E 64 0D 0A 70 72  e floppy and♪◙pr
000000A0: 65 73 73 20 61 6E 79 20 6B 65 79 20 74 6F 20 74  ess any key to t
000000B0: 72 79 20 61 67 61 69 6E 20 2E 2E 2E 20 0D 0A 00  ry again ... ♪◙
000000C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...
00008800: 02 43 44 30 30 31 01 00 00 20 00 20 00 20 00 20  ☻CD001☺
00008810: 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20

These two fragments suggest one file is the image of an FAT12 floppy disk, the other — a CD-ROM image.

4. Retrieving first gamma bits

For installation of drivers or supplemental software, modern cellular modems tend to create a virtual CD-ROM upon connection. The same concept is used in this case.

However, when the modem connects to up-to-date operating systems (Windows 7/8, Linux, MacOS X), the CD-ROM either does not appear at all or shows up for a second and then disappears. On a Windows XP laptop manufactured in 2002 and found specifically for the test, the CD-ROM shows up for the whole five seconds — quite enough to read all logical volume sectors and obtain an image, whose size is 606,208 = 0x94000 bytes and corresponds to the size of the AutoInstall file. The MD5 value of the image is 897279F34B7629801D839A3E18DA0345, which equals to the value of tag 0x0004.

Now we only need to XOR the AutoInstall file with the known CD-ROM image and obtain the gamma’s first 600 kB. This gamma can be used to decrypt the beginning of the files CPUImage and WebUI (as long as 4,971,976 and 2,093,056 bytes respectively).

5. Restructuring an FDD image

If you decipher the beginning (first 606,208 bytes) and zero-fill the rest of the WebUI file, and then interpret everything as an FAT image, you will see the file system structure and the contents of some files:

          Name           | Size |  Date  |Time
bru                      |Folder|31.05.12|22:17
cgi-bin                  |Folder|31.05.12|22:17
cors                     |Folder|31.05.12|22:17
css                      |Folder|31.05.12|22:17
eng                      |Folder|31.05.12|22:17
img                      |Folder|31.05.12|22:17
js                       |Folder|31.05.12|22:17
ru                       |Folder|31.05.12|22:17
name.html                |  2248|31.05.12|22:17
easyXDM.js               |101924|31.05.12|22:17
easyXDM.debug.js         |113900|31.05.12|22:17
easyXDM.min.js           | 19863|31.05.12|22:17
easyXDM.Widgets.js       | 11134|31.05.12|22:17
easyXDM.Widgets.debug.js | 11134|31.05.12|22:17
easyXDM.Widgets.min.js   |  3114|31.05.12|22:17
json2.js                 | 17382|31.05.12|22:17
easyxdm.swf              |  1758|31.05.12|22:17
MIT-license.txt          |  1102|31.05.12|22:17

If your modem is connected and you browse to the address http:///dir, you will see the same file system and will be able to download any file.

To restore the WebUI image, you need to place the files downloaded via the web interface in accordance with the boot, FAT table, and directory description data. The only difficulty is the ru sub-folder in the root directory. A cluster with folder content descriptions is out of the first 606,208 bytes, so its contents should be restored individually.

According to the web interface data, the ru directory must include the following files:

          Name           | Size |  Date  |Time
Manualupdate.html        |  3981|31.05.12|22:17
Index.html               |  5327|31.05.12|22:17
Network.html             |  3328|31.05.12|22:17

Fortunately, there is the eng folder in the root directory that contains files with the same names and creation dates. To obtain correct data for the ru folder, the following should be changed:

  • The number of the starting cluster of the current directory
  • The size of each file
  • The numbers of the starting clusters of all files

The root directory has the number of the cluster of the ru directory (0x213).
Use your web interface to learn the file sizes (3981 = 0xF8D, 5327 = 0x14CF, and 3328 = 0xD00 respectively).

The numbers of the starting clusters must be guessed, but that is easy. According to the boot data, each cluster occupies four sectors or 2,048 bytes. The ru directory requires one cluster only, the files Manualupdate.html and Network.html — two clusters, Index.html — three clusters. Since clusters are written on an empty disk sequentially, files will start in clusters 0x214, 0x216, and 0x219 respectively. Restored data for the ru directory are as follows:

00000000: 2E 20 20 20 20 20 20 20 20 20 20 10 00 00 2C AA  .          ►  ,к
00000010: BF 40 BF 40 00 00 2C AA BF 40 13 02 00 00 00 00  ┐@┐@  ,к┐@‼☻
00000020: 2E 2E 20 20 20 20 20 20 20 20 20 10 00 00 2C AA  ..         ►  ,к
00000030: BF 40 BF 40 00 00 2C AA BF 40 00 00 00 00 00 00  ┐@┐@  ,к┐@
00000040: 42 68 00 74 00 6D 00 6C 00 00 00 0F 00 56 FF FF  Bh t m l   ☼ V  
00000050: FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF                  
00000060: 01 6D 00 61 00 6E 00 75 00 61 00 0F 00 56 6C 00  ☺m a n u a ☼ Vl
00000070: 75 00 70 00 64 00 61 00 74 00 00 00 65 00 2E 00  u p d a t   e .
00000080: 4D 41 4E 55 41 4C 7E 31 48 54 4D 20 00 00 2C AA  MANUAL~1HTM   ,к
00000090: BF 40 BF 40 00 00 2C AA BF 40 14 02 8D 0F 00 00  ┐@┐@  ,к┐@¶☻Н☼
000000A0: 41 69 00 6E 00 64 00 65 00 78 00 0F 00 33 2E 00  Ai n d e x ☼ 3.
000000B0: 68 00 74 00 6D 00 6C 00 00 00 00 00 FF FF FF FF  h t m l         
000000C0: 49 4E 44 45 58 7E 31 20 48 54 4D 20 00 00 2C AA  INDEX~1 HTM   ,к
000000D0: BF 40 BF 40 00 00 2C AA BF 40 16 02 CF 14 00 00  ┐@┐@  ,к┐@▬☻╧¶
000000E0: 41 6E 00 65 00 74 00 77 00 6F 00 0F 00 98 72 00  An e t w o ☼ Шr
000000F0: 6B 00 2E 00 68 00 74 00 6D 00 00 00 6C 00 00 00  k . h t m   l
00000100: 4E 45 54 57 4F 52 7E 31 48 54 4D 20 00 00 2C AA  NETWOR~1HTM   ,к
00000110: BF 40 BF 40 00 00 2C AA BF 40 19 02 00 0D 00 00  ┐@┐@  ,к┐@↓☻ ♪
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Having burnt a disk image with the ru folder and all file contents (the first cluster corresponds to sector 0x23), we now have a plaintext version of the WebUI file, whose MD5 matches 48D1C3194E45472D28ABFBEB6BBF1CC6 from the firmware file header.

Therefore, we have the AutoInstall and WebUI files deciphered and we know gamma’s first 2,093,056 bytes.

6. Checking CPUImage

It is reasonable to start a disassembler when we have decrypted the first 2 MB of CPUImage. After identifying the processor’s command system (ARM Little-Endian), base download address (the first 0x34C bytes must be skipped) and finding update deciphering location, the following code is available:

ROM:0008ADD0 loc_8ADD0 
ROM:0008ADD0                 LDR             R1, =byte_2ADC60
ROM:0008ADD4                 LDRB            R2, [R1,R0]
ROM:0008ADD8                 LDRB            R1, [R4]
ROM:0008ADDC                 ADD             R0, R0, #1
ROM:0008ADE0                 ADD             R2, R2, R1
ROM:0008ADE4                 ADD             R2, R2, R6
ROM:0008ADE8                 AND             R6, R2, #0xFF
ROM:0008ADEC                 LDRB            R2, [R10,R6]
ROM:0008ADF0                 STRB            R2, [R4],#1
ROM:0008ADF4                 STRB            R1, [R10,R6]
ROM:0008ADF8                 MOV             R1, #0x15
ROM:0008ADFC                 BL              sub_27C0EC
ROM:0008AE00                 SUBS            R11, R11, #1
ROM:0008AE04                 AND             R0, R1, #0xFF
ROM:0008AE08                 BNE             loc_8ADD0

This is how the encryption key located at 0x2ADC60 and as long as 0x15 bytes is loaded to the RC4 algorithm. But 0x2ADC60 = 2,808,928, so the key is beyond the gamma we know.

In earlier firmware versions (3.7 and 2.8), the key is also outside the decrypted area (0x2AD70C and 0x2A852C respectively).

7. XORing again

If XORing CPUImage v3.7 and CPUImage v3.7.4, we obtain the string “SungKook "James" Shin” at the address 0x34C + 0x2AD70C = 0x2ADA58. This is the RC4 key used to encrypt all update files.

Now we only need to make sure that the RC4 gamma matches the gamma obtained earlier and CPUImage MD5 matches the value of the firmware file header.

Now we can examine the firmware itself, but this is quite a different story.

Author: Dmitry Sklyarov, Positive Research

Viewing all articles
Browse latest Browse all 198

Trending Articles