Skip to content

Independent research and modifications on the ZTE F6005 GPON ONT

Notifications You must be signed in to change notification settings

rgiorgiotech/ZTE-F6005-Modding

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

ZTE F6005 GPON ONT Modding

Introduction

This repository documents my independent research and progress in modding the ZTE F6005 GPON ONT. The goal is to unlock advanced functionalities, customize settings, and explore the firmware and hardware of this type of GPON devices.

For my study, it was essential to compare three different ONTs:

  • Nokia G-010G-T
  • ZTE F6005 (version distributed by Open Fiber)
  • ZTE F6005 (version distributed by TIM)

These three devices share the same hardware and derive from a common "parent," the CIG G-97CP; comparing the boards reveals an almost complete analogy, except for the SPI NOR Flash which, however, meet the same specifications and therefore differences in manufacturers do not lead to incompatibility when exchanging firmware.

  • ZTE F6005 TIM: Macronix MX25L12833F
  • ZTE F6005 Open Fiber: XMC XM25QH128C
  • Nokia G-010G-T: Winbond W25Q128JV

(Note: these are the SPI NOR Flash installed in my ONTs, but they may vary between different specimens)

However, opening the metal cage that protects the optical part reveals a crucial difference: the Nokia uses a different laser driver compared to the two ZTEs. This discrepancy is confirmed by the fact that, making a complete dump of the Nokia SPI flash and flashing it onto the ZTE, everything works – the kernel loads and the OS runs without issues – but the optical part does not operate correctly (LED "LOS" solid on and no optical connection).

  • Laser driver of the Nokia G-010G-T: SEMTECH 25L95
  • Laser driver of the ZTE F6005: 02099G-15

Each analyzed kernel only loads the drivers (kmodules) for which it was designed, making the optical parts incompatible between devices with different laser drivers. Since the firmware of the Nokia is already completely unlocked (Telnet and SSH at the OS level, serial port both in the bootloader and in the kernel), the initial idea was to try flashing a complete dump of the Nokia onto the ZTE. However, as already stated, due to the different laser driver, the ZTE did not respond to the optical signal.

The next step was to carefully analyze the dumps and apply reverse engineering logic to try to understand the specific functioning of each firmware.

I then proceeded to use various command-line tools, including:

  • binwalk and firmware-mod-kit, to analyze the content of dumps and extracted firmware;
  • flashrom, to flash the SPI NOR Flash;
  • cramfs-tools, to work with the CramFS filesystem used by the firmware;
  • jefferson, to work with the JFFS2 filesystem used by some configuration sectors.

(Base commands such as dd and file are excluded from this list)

Initial Results with Binwalk

The first interesting results obtained with binwalk on the complete dump allow understanding the structure, more or less common to all the analyzed ONTs, of the SPI NOR flash:

  • 0x404: Copyright text "Copyright 2008, Cambridge Industry Group (CIG), All Rights Reserved."
  • 0x16410 (ZTE) or 0x16470 (Nokia): uImage firmware image, about 93KB, which contains the bootloader (U-Boot) compressed in lzma and compiled for MIPS32 architecture, load address and entry point 0x81C00000, name "U-Boot 2011.12.NA-svn145404 for ]".
  • 0x80000: Configuration sectors, JFFS2 filesystem, big endian, size about 1.6MB.
  • 0x200000: First image ("imagea" in the bootloader) of the firmware, CramFS filesystem, big endian, size about 6.5MB and incorrect CRC check (we'll return to this later).
  • 0x900000: Second image ("imageb" in the bootloader) of the firmware, with the same specifications as the first image.

After an initial moment when I thought that the kernel was included in the uImage at 0x164X0 (they are usually used to contain the Linux kernel and other fundamental parts), I later understood instead that it corresponds to the "uImage" file contained in the two CramFS since the bootloader logs from the serial port suggest loading the CramFS image before the kernel is started.

We conclude then that the sector at 0x164X0 includes only the bootloader.

Kernel Modules and Bootloader

At this point, the analysis of the two CramFS – almost identical in their entire structure – was crucial to understand how the firmware was structured and which files the kernel relied on to operate the device correctly.

The first interesting discovery relates to the ".ko" files (e.g., gpon.ko) contained in some subfolders of the lib/modules directory: they appeared to be drivers, and this hypothesis was soon confirmed since they are Kernel Modules (they are not exactly drivers, but in this case, the concept is similar).

So why not replace the .ko files of the Nokia with those of the ZTE to allow the optical part to function with the Nokia firmware? I did, and the answer is: it will never work. As stated at the beginning, kernels are designed to work "in synergy" with the various files they rely on, including the kmodules, and feeding the ZTE kernel the Nokia kmodules is not a good idea: the result is a kernel panic and thus a bootloop.

So why not try replacing the Nokia kernel with the ZTE one to allow the kmodules to be recognized by their original kernel? Even in this case, I did, and the answer is: it will not work either. The kernel startup relies not only on kmodules but also on other components, and the bootloader plays a particular role in kernel startup. The Nokia bootloader (which, remember, has the unlocked serial port and was therefore my favorite for experiments) did not seem to get along perfectly with the ZTE kernel and vice versa. In these cases, I did not get a kernel panic but the system froze on "Starting kernel …". Initially, I thought it was a problem related to the serial port blocked at the ZTE kernel, but even waiting 2-3 minutes, the LOS and LAN LEDs did not turn on, indicating that the firmware was not loaded.

I experimented with other combinations, such as the Nokia bootloader with everything else ZTE, but I never got a positive result. This confirms that the bootloader – although the versions seemed to be the same between Nokia and ZTE – is evidently adapted by the specific manufacturer. Possibly, with the CIG bootloader, I could have achieved more success, but not having possession of the "pure" ONT, I could not delve deeper in that direction.

A note on the configuration sectors, which I have not forgotten: even swapping these sectors between Nokia and ZTE, to try to "align" them with the corresponding kernel, I did not achieve good results.

Firmware Study and Modification of setup.sh

The next step concerns studying the ZTE firmware to try to unlock Telnet, SSH, and the "upstream" serial port, without changing the bootloader or creating a mix between the two firmware.

Knowing broadly the structure of a Linux firmware and the purpose of the corresponding files and directories, I did not take too long to realize that a fundamental role, in terms of rules, is played by the file setup.sh, located in the sbin folder.

In particular, three lines stood out to me towards the end of the file:

#/bin/Console &
#/bin/telnetd
#/bin/dropbear 1>/dev/null 2>&1

Theoretically:

  • The first line should enable the serial port;
  • The second should enable Telnet;
  • The third should enable SSH.

I immediately noticed that all three were commented with #, so I proceeded to uncomment them to enable them. Moreover, the setup.sh file of the Nokia has all three lines uncommented, and this gave me further confirmation that what I found could be the solution.

CRAMFS, CRC, and Sizes

I then made this small modification and then recompiled the two CramFS, ensuring that the big endian property was respected (with macOS there was no way to recreate the CramFS in big endian, I had to use Linux with the mkfs.cramfs command and the right argument to force big endian). After that, I inserted the modified CramFS into the original ZTE dump. Nothing worked. By briefly inserting the Nokia bootloader (thanks to which I could at least understand if there were specific logs via the serial port), I noticed that U-Boot performs a CRC check on the CramFS:

Root Filesystem crc check error! srcCrc = ffffffff calcCrc = e52ae918

### CRAMFS LOAD ERROR<ffffffff> for uImage!

The CRC is a method of verifying data integrity and is based on a mathematical calculation that generates a checksum derived from the content itself; this value is compared with the expected one and determines, in our case, the correct loading of the CramFS by the bootloader. Having found discrepant documentation regarding CRC (in some cases it is located in the first 64 bytes of a file, in others at the very end, but in any case, it consists of 4 bytes), I went to trials until U-Boot accepted the file.

For convenience, the trials were not performed by flashing the entire dump each time, but I used the upgdimage command of U-Boot, which is used to update the CramFS directly from the bootloader via TFTP protocol (the bootloader particularly expects a cramfs.img.crc file) and performs the check in this case as well. I could not use the command to make everything work since the ZTE bootloader, as we know, has the serial port blocked and with the Nokia bootloader, I could not run the ZTE firmware, but it was very useful and practical.

After several tests, I concluded that U-Boot does not look at the CRC located in the first 64 bytes (which is instead the one displayed, for example, by the command file nomedump.bin and which eventually determines the "checksum error" of binwalk), but wants a specific CRC – which fortunately is written, as can be seen from the log above – at the end of the file, in the last 4 bytes.

But that's not all: before the error on the CRC, the upgdimage command checks the size of the CramFS and in all the tests I made, it always expected 4 bytes more:

RootFS CRAMFS size [0x651004] length [0x651000]
Cramfs image length is error 651004 3 651000

This is probably due to not handling alignment correctly or from the incorrectly placed CRC. In reality, I believe that the correct cause is the second, since these 4 extra bytes should be filled with the CRC that the bootloader wants.

Once the two problems were resolved, I reinserted the two CramFS (we are still talking about those with the modified setup.sh) using the usual dd command, already used several other times for the "cut and paste" I did with all the dumps, both in 0x200000 and in 0x900000.

Flashed everything and powered on the ONT... It works! The LOS and LAN lights come on. I immediately try to log in via Telnet (telnet 192.168.1.1) and... this also works! However, the credentials are not admin/admin as in the case of the web GUI, but root/admin: once again, I went to trials.

Unfortunately, neither SSH nor the serial port works. Regarding SSH, I believe the cause is to be found in the iptables rules or in the dropbear daemon not configured or not present in the ZTE firmware; concerning the serial port, I believe that the problem lies in the kernel, which blocks the port upstream even before any OS rules.

Final Considerations

It is interesting to note that, in the end, if I were to explain to someone how to act without recounting everything I did before, it would result in a relatively simple procedure (as long as they have the right prior knowledge and skills) and quick to apply. However, "the essence" lies rather in everything I did to reach the conclusion.

As already mentioned, the only function unlocked will be Telnet and thus SSH and serial port will remain blocked. Furthermore, the bootloader will not intend to communicate via serial port because it also blocks it.
Nevertheless, Telnet is all that one might need to authenticate the ONT since from there any command that would be given via SSH or via serial port (with OS loaded) can be issued.

An unlocked bootloader would allow doing many interesting things, including:

  • An upgrade of CramFS/kernel/bootloader without flashing the complete dump to the SPI flash;
  • A swap of boot images between 0x200000 and 0x900000 (which, however, is not necessary since I flashed the same CramFS in both sectors);
  • Other advanced operations.

However, for those who simply want to modify the parameters for their connection, Telnet is more than sufficient.

In the future, I will try to work on the ZTE kernel and the bootloader, to find any rules that currently block the serial port. I will also try to understand how to enable SSH on the OS side.

About

Independent research and modifications on the ZTE F6005 GPON ONT

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published