Skip to content

Instantly share code, notes, and snippets.

@rajkosto
Forked from thedroidgeek/nokia-router-cfg-tool.py
Last active June 5, 2025 10:05
Show Gist options
  • Save rajkosto/e2b2455d457cc2be82dbb5c85e22d708 to your computer and use it in GitHub Desktop.
Save rajkosto/e2b2455d457cc2be82dbb5c85e22d708 to your computer and use it in GitHub Desktop.
Nokia/Alcatel-Lucent router backup configuration tool
#!/usr/bin/env python3
#
# Nokia/Alcatel-Lucent router backup configuration tool
# G2425 support added by rajkosto on 20/11/2022
# XS-2426G-B support added by rajkosto on 28/02/2023
#
# Features:
# - Unpack/repack .cfg files generated from the backup and restore functionnality
# in order to modify the full router configuration
# - Decrypt/encrypt the passwords/secret values present in the configuration
#
# Original author blog post: https://0x41.cf/reversing/2019/10/08/unlocking-nokia-g240wa.html
#
# Released under the MIT License (http://opensource.org/licenses/MIT)
# Copyright (c) Sami Alaoui Kendil (thedroidgeek)
# Copyright (c) Rajko Stojadinovic (rajkosto)
#
import io
import sys
import zlib
import struct
import base64
import binascii
import datetime
import hashlib
import secrets
big_endian = True
encrypted_cfg = False
def u32(val):
return struct.unpack('>I' if big_endian else '<I', val)[0]
def p32(val):
return struct.pack('>I' if big_endian else '<I', val)
def checkendian(cfg):
if (cfg[0:4] == b'\x00\x12\x31\x23'):
return True
elif (cfg[0:4] == b'\x23\x31\x12\x00'):
return False
else:
return None
class RouterCrypto:
def __init__(self):
from Crypto.Cipher import AES
# key and IV for AES
key = '3D A3 73 D7 DC 82 2E 2A 47 0D EC 37 89 6E 80 D7 2C 49 B3 16 29 DD C9 97 35 4B 84 03 91 77 9E A4'
iv = 'D0 E6 DC CD A7 4A 00 DF 76 0F C0 85 11 CB 05 EA'
# create AES-128-CBC cipher
self.cipher = AES.new(bytes(bytearray.fromhex(key)), AES.MODE_CBC, bytes(bytearray.fromhex(iv)))
def decrypt(self, data):
output = self.cipher.decrypt(data)
# verify and remove PKCS#7 padding
padLen = ord(output[-1:])
if padLen <= 0 or padLen > 16: #cannot be 0 or > blocksize
return None
padBytes = output[-padLen:]
validPad = all(padByte == padLen for padByte in padBytes)
if validPad:
return output[:-padLen]
else:
return None
def encrypt(self, data):
# add PKCS#7 padding for 128-bit AES
pad_num = (16 - (len(data) % 16))
data += chr(pad_num).encode() * pad_num
return self.cipher.encrypt(data)
class PKCSPassCrypto(RouterCrypto):
def __init__(self, pkcsPass, pkcsSalt):
from Crypto.Cipher import AES
from hashlib import pbkdf2_hmac
keyLen = 32 #AES-256
ivLen = 16 #AES blocksize
if not isinstance(pkcsPass, bytes):
pkcsPass = pkcsPass.encode()
pkcs = pbkdf2_hmac('sha256', pkcsPass, pkcsSalt, 10, dklen=keyLen+ivLen)
keyBytes = pkcs[:keyLen]
ivBytes = pkcs[keyLen:]
self.cipher = AES.new(keyBytes, AES.MODE_CBC, ivBytes)
#G2425 and newer config pkcs password
PKCSPasswords = ["S23l7nZm47XyMGs6y6oJpN9CR4nbfIZHJ4VRwp7HcdV6o2YvUmeNYFlz08Otwz78"]
#
# unpack xml from cfg
#
if (len(sys.argv) == 3 and sys.argv[1] == '-u'):
# line feed
print('')
# read the cfg file
cf = open(sys.argv[2], 'rb')
cfg_data = cf.read()
# check cfg file magic (0x123123) and determine endianness
big_endian = checkendian(cfg_data)
if big_endian == None:
# check if config is encrypted
decrypted = None
try:
# decrypt and check validity
decrypted = RouterCrypto().decrypt(cfg_data)
big_endian = checkendian(decrypted)
except ValueError:
pass
# if decryption failed, or still invalid, bail out
if big_endian == None:
print('invalid cfg file/magic :(\n')
exit()
# set decrypted cfg buffer and encryption flag
print('-> encrypted cfg detected')
cfg_data = decrypted
encrypted_cfg = True
# log endianness
if big_endian:
print('-> big endian CPU detected')
else:
print('-> little endian CPU detected')
# get the size of the compressed data
data_size = u32(cfg_data[0x04:0x08])
large_header = False
if data_size == 0:
data_size = u32(cfg_data[0x08:0x0C])
large_header = True
if data_size == 0:
print('\nERROR: config data size is 0!\n')
exit()
# get fw_magic (unknown, could be fw version/compile time, hw serial number, etc.)
fw_magic = 0
if large_header:
fw_magic = u32(cfg_data[0x20:0x24])
else:
fw_magic = u32(cfg_data[0x10:0x14])
print('-> fw_magic = ' + hex(fw_magic))
# get the compressed data
compressed = []
if large_header:
compressed = cfg_data[0x28 : 0x28 + data_size]
else:
compressed = cfg_data[0x14 : 0x14 + data_size]
# get the checksum of the compressed data
checksum = 0
if large_header:
checksum = u32(cfg_data[0x10:0x14])
else:
checksum = u32(cfg_data[0x08:0x0C])
# verify the checksum
if (binascii.crc32(compressed) & 0xFFFFFFFF != checksum):
print('\nCRC32 checksum failed :(\n')
exit()
uncomp_size = 0
if large_header:
uncomp_size = u32(cfg_data[0x18:0x1C])
else:
uncomp_size = u32(cfg_data[0x0C:0x10])
# unpack the config
xml_data = None
try:
xml_data = zlib.decompress(compressed)
pkcsPass = None
except zlib.error:
encData = None
pkcsSalt = None
tryPasswords = []
if compressed[0] == 0xFF: #pkcs encrypted payload
tryPasswords = PKCSPasswords
with io.BytesIO(compressed) as payload:
payload.seek(1)
pkcsSalt = payload.read(8)
encData = payload.read()
for currPass in tryPasswords:
decryptor = PKCSPassCrypto(currPass,pkcsSalt)
compressed = decryptor.decrypt(encData)
if compressed is None: #pkcs padding verification failed, key is wrong
continue
try:
xml_data = zlib.decompress(compressed)
pkcsPass = currPass
except zlib.error:
pass
if xml_data is None:
if len(tryPasswords):
raise RuntimeError('Exhausted all known encryption passwords')
else:
raise
if len(xml_data) != uncomp_size:
print('WARNING: uncompressed size does not match value in header!')
# output the xml file
out_filename = 'config-%s.xml' % datetime.datetime.now().strftime('%d%m%Y-%H%M%S')
if xml_data[0] != ord('<'):
out_filename = out_filename.replace('.xml','.ini')
of = open(out_filename, 'wb')
of.write(xml_data)
print('\nunpacked as: ' + out_filename)
recompInfo = ('-pb' if big_endian else '-pl')
if large_header:
recompInfo += '64'
if encrypted_cfg or pkcsPass:
recompInfo += 'e'
if pkcsPass:
recompInfo += pkcsPass
print('\n# repack with:')
print('%s %s %s %s\n' % (sys.argv[0], recompInfo, out_filename, hex(fw_magic)))
cf.close()
of.close()
#
# generate cfg from xml
#
elif (len(sys.argv) == 4 and (sys.argv[1][:3] == '-pb' or sys.argv[1][:3] == '-pl')):
fw_magic = 0
try:
# parse hex string
fw_magic = int(sys.argv[3], 16)
# 32-bit check
p32(fw_magic)
except:
print('\ninvalid magic value specified (32-bit hex)\n')
exit()
big_endian = sys.argv[1][:3] == '-pb'
large_header = False
param_len = 3
if sys.argv[1][3:5] == '64':
large_header = True
param_len += 2
elif sys.argv[1][3:5] == '32':
large_header = False
param_len += 2
encrypted_cfg = False
if len(sys.argv[1]) > param_len and sys.argv[1][param_len] == 'e':
encrypted_cfg = True
param_len += 1
pkcsPass = None
if encrypted_cfg and len(sys.argv[1]) > param_len:
pkcsPass = sys.argv[1][param_len:]
encrypted_cfg = False
out_filename = 'config-%s.cfg' % datetime.datetime.now().strftime('%d%m%Y-%H%M%S')
# read the xml file
xf = open(sys.argv[2], 'rb')
xml_data = xf.read()
xf.close()
# compress using default zlib compression
compressed = zlib.compress(xml_data)
# pkcs encrypt the inner data if needed
extraDecompLen = 1 #non pkcs encrypted configs have +1 to decomp len
if pkcsPass is not None:
extraDecompLen = 0
with io.BytesIO() as payload:
payload.write(b'\xFF')
pkcsSalt = secrets.token_bytes(8)
payload.write(pkcsSalt)
cryptor = PKCSPassCrypto(pkcsPass,pkcsSalt)
payload.write(cryptor.encrypt(compressed))
compressed = payload.getvalue()
## construct the header ##
# magic
cfg_data = p32(0x123123)
if large_header:
cfg_data += p32(0)
# size of compressed data
cfg_data += p32(len(compressed))
if large_header:
cfg_data += p32(0)
# crc32 checksum
cfg_data += p32(binascii.crc32(compressed) & 0xFFFFFFFF)
if large_header:
cfg_data += p32(0)
# size of xml file
cfg_data += p32(len(xml_data) + extraDecompLen)
if large_header:
cfg_data += p32(0)
# fw_magic
cfg_data += p32(fw_magic)
if large_header:
cfg_data += p32(0)
# add the compressed xml
cfg_data += compressed
# encrypt overall file if necessary
if encrypted_cfg:
cfg_data = RouterCrypto().encrypt(cfg_data)
# write the cfg file
of = open(out_filename, 'wb')
of.write(cfg_data)
of.close()
print('\npacked as: ' + out_filename + '\n')
#
# decrypt/encrypt secret value
#
elif (len(sys.argv) == 3 and (sys.argv[1] == '-d' or sys.argv[1] == '-e')):
decrypt_mode = sys.argv[1] == '-d'
if decrypt_mode:
# base64 decode + AES decrypt
print('\ndecrypted: ' + RouterCrypto().decrypt(base64.b64decode(sys.argv[2])).decode('UTF-8') + '\n')
else:
# AES encrypt + base64 encode
print('\nencrypted: ' + base64.b64encode(RouterCrypto().encrypt(sys.argv[2].encode())).decode('UTF-8') + '\n')
else:
print('\n#\n# Nokia/Alcatel-Lucent router backup configuration tool\n#\n')
print('# unpack (cfg to xml)\n')
print(sys.argv[0] + ' -u config.cfg\n')
print('# pack (xml to cfg)\n')
print(sys.argv[0] + ' -pb config.xml 0x13377331 # big endian, no encryption, fw_magic = 0x13377331')
print(sys.argv[0] + ' -pl config.xml 0x13377331 # little endian, ...')
print(sys.argv[0] + ' -pbe config.xml 0x13377331 # big endian, with encryption, ...')
print(sys.argv[0] + ' -ple config.xml 0x13377331 # ...\n')
print('# decrypt/encrypt secret values within xml (ealgo="ab")\n')
print(sys.argv[0] + ' -d OYdLWUVDdKQTPaCIeTqniA==')
print(sys.argv[0] + ' -e admin\n')
@AtashiHatake
Copy link

I am having the same "Upload Failed: File Invalid!" Issue can anyone share the Boolean values? I think that might be a problem.

@siddhu2310
Copy link

What is the password2 for shell access?

@ArialCCAA
Copy link

Hello, I have a G-0425G-C, it uses the SW version 3FE49568IJJL06. I am able to use the decryption tool and managed to get the AdminGPON login, but the password for the PPPoE is base64 encoded. I tried changing the text on the base64 part to text, encrypt it back and upload to the ONT, but that didn't work. When I extract it and decrypt it, the string with base64 is back there and the password for the PPPoE is still encrypted. Feel like I am really close to getting internet access and replace the ONT. I managed to clone the information into the ONU and get O5, the last stage is getting the PPPoE password it seems.

@ArialCCAA
Copy link

the bin/sh trick was patched after 3FE49362IJHK46 you can still change the password for ONTUSER by setting ONTUSER as the username in TelnetSshAccount section, and whatever password you want, and then enabling ONTUSER to drop into busybox instead of vtysh by setting LimitAccount_ONTUSER to false if you are getting invalid config when importing, make sure you are using the exact commandline the script tells you to use when you unpacked (important, because it contains the key to encrypt with) otherwise, you can try just naming it config.cfg

Oh damn this worked. I'm kind of clueless now what commands do I do as aont root to get the PPPoE password?

@rajkosto
Copy link
Author

rajkosto commented Aug 28, 2024

Oh damn this worked. I'm kind of clueless now what commands do I do as aont root to get the PPPoE password?

cat /etc/ppp/options_ppp111
the ppp111 suffix might be different for you, but its not just /etc/ppp/options as that has just general information, not connection-specific like username/password
btw, you could have just decrypted the base64 password from the config using this exact script and the -d option as well (which someone put a screenshot of their attempt in the SECOND COMMENT).

@ArialCCAA
Copy link

ArialCCAA commented Aug 28, 2024

Oh damn this worked. I'm kind of clueless now what commands do I do as aont root to get the PPPoE password?

cat /etc/ppp/options_ppp111 the ppp111 suffix might be different for you, but its not just /etc/ppp/options as that has just general information, not connection-specific like username/password btw, you could have just decrypted the base64 password from the config using this exact script and the -d option as well (which someone put a screenshot of their attempt in the SECOND COMMENT).

Oh great! Thank you. This worked for my G-0425-C, however, this just confirmed to me that your python script did, in fact, decrypt the encrypted PPPoE password and that what I was seeing was the already decrypted password. So I am left clueless as to how to solve this situation (I want to replace the ONT from my ISP, which has been causing issues with my access points), with an ONU of my own. I feel like I have come so far and am so close to getting to the solution, but I fell short. I cloned the ONT's settings into the new ONU and it now gives out O5, but trying a connection with the given PPPoE credentials just does not give internet access.
Could it maybe be that the ISP has locked down the access to the onboard router's MAC address? If so, what command could I use on AONT root to extract that?

@Gor995
Copy link

Gor995 commented Sep 21, 2024

Hello, i'm having problem with the secets library,
image
And when i try to install the library:
image
image
I have already tried reinstalling cryptography library, manually reinstalling openssl and nothing works, if you are able to guide me would be lovely.

@Rusty77
Copy link

Rusty77 commented Sep 22, 2024

Python -m venv venv
Pip install openssl secrets

In a fresh virtual environment you might have more luck?

@udaravima
Copy link

SLT - Sri Lanka Telecom Nokia GPON G 1425 G B

  • Thank you for your work @rajkosto

  • I extracted two squashfs and a ubi partition in there (ubi partition with current modifications) etc/passwd and etc/shadow there is additional account administrator that's the one who connects with vtysh, How should I proceed?

  • administrator : AU121BM213CH38E5

  • ONTUSER and root passwords are unknown

  • Link to NAND dump of G1425_G & gitpage

@taronhov
Copy link

taronhov commented Oct 26, 2024

Reverse engineered the firmware, it's in an encrypted file in /etc, keys for which differ for each fw ver, but this password is still consistent across firmwares and even newer models, if they change it I'll have to obtain newer firmware and reverse engineer it again

Hi @rajkosto !

Thank you for the great work done! I just wanted to ask you for a small guide/how-to about the process of PKCSPasswords extraction
from newer Nokia firmware (e.g. 3FE49568IJJK06(1.2203.406))... I have already dumped and extracted the firmware from a
locked Nokia ONT router (G-1425G-A, provided by my ISP) and have found the "config_encryption.cfg" file, but the script posted here
was not able to decrypt it and now I do not know how to move forward...
Can you, please, help with the reverse engineering process to find the new/suitable PKCSPasswords?
Also, the magic value/header in my config file is different (Hex 24 41 12 00). After correcting that (to Hex 23 31 12 00), I get this error:


Traceback (most recent call last):
File "C:\Users\taronhov\Downloads\mtd6_mtd7\nokia-router-cfg-tool.py", line 205, in
xml_data = zlib.decompress(compressed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
zlib.error: Error -3 while decompressing data: incorrect header check

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\taronhov\Downloads\mtd6_mtd7\nokia-router-cfg-tool.py", line 232, in
raise RuntimeError('Exhausted all known encryption passwords')
RuntimeError: Exhausted all known encryption passwords


Thanks!

@ArialCCAA
Copy link

C:\Users\Yan\Downloads\Python 3>python nokia-router-cfg-tool.py -u config.cfg

-> little endian CPU detected
-> fw_magic = 0xffffffff

unpacked as: config-04112024-131752.xml

repack with:

nokia-router-cfg-tool.py -pleS23l7nZm47XyMGs6y6oJpN9CR4nbfIZHJ4VRwp7HcdV6o2YvUmeNYFlz08Otwz78 config-04112024-131752.xml 0xffffffff

C:\Users\Yan\Downloads\Python 3>nokia-router-cfg-tool.py -pleS23l7nZm47XyMGs6y6oJpN9CR4nbfIZHJ4VRwp7HcdV6o2YvUmeNYFlz08Otwz78 config-04112024-131752.xml 0xffffffff

C:\Users\Yan\Downloads\Python 3>
[main 2024-11-04T17:18:00.481Z] update#setState idle
[main 2024-11-04T17:18:01.953Z] Extension host with pid 5492 exited with code: 0, signal: unknown.

Hello, I am facing this issue trying to run the script recently. Any idea on how to fix it? It just opens VScode when I try repacking

@mytot
Copy link

mytot commented Nov 12, 2024

Reverse engineered the firmware, it's in an encrypted file in /etc, keys for which differ for each fw ver, but this password is still consistent across firmwares and even newer models, if they change it I'll have to obtain newer firmware and reverse engineer it again

Hi @rajkosto !

Thank you for the great work done! I just wanted to ask you for a small guide/how-to about the process of PKCSPasswords extraction from newer Nokia firmware (e.g. 3FE49568IJJK06(1.2203.406))... I have already dumped and extracted the firmware from a locked Nokia ONT router (G-1425G-A, provided by my ISP) and have found the "config_encryption.cfg" file, but the script posted here was not able to decrypt it and now I do not know how to move forward... Can you, please, help with the reverse engineering process to find the new/suitable PKCSPasswords? Also, the magic value/header in my config file is different (Hex 24 41 12 00). After correcting that (to Hex 23 31 12 00), I get this error:

Traceback (most recent call last): File "C:\Users\taronhov\Downloads\mtd6_mtd7\nokia-router-cfg-tool.py", line 205, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Users\taronhov\Downloads\mtd6_mtd7\nokia-router-cfg-tool.py", line 232, in raise RuntimeError('Exhausted all known encryption passwords') RuntimeError: Exhausted all known encryption passwords

Thanks!

@taronhov
Can you share the process for extracting the firmware, my isp also upgraded similar software version and currently completely locked

@taronhov
Copy link

taronhov commented Nov 27, 2024

@mytot
Hi, I have dumped the firmware from NAND IC (SPI memory chip), using a programmer...
Then used binwalk tol to examine it, and information provided here to extract mtd6 and mtd7 partitions (search these names here),
Then ubidump and ubi-readerr tools can be used to extract file-systems...
For other partitions you may want ot use sqashfs tools, etc.

@siddhu2310
Copy link

Is it Possible to Convert this ONT GPON to EPON, I have there is Huawei ONU can be changed from GPON to EPON Updating Firmware

@ckfu37186
Copy link

How to ru file mobile to termux

@Pritam11638
Copy link

Pritam11638 commented Jan 27, 2025

Hello sir @rajkosto,
I have a Nokia G2425G-A, with software version 3FE49362IJHK46 and hardware version 3FE48299DEAA. I downloaded the cfg file, decrypted it and edited it by following this yt video: https://youtu.be/yRFqs7CZGdg?si=UyJBETyQ-bbnRAPy but after i import it to the router, after reboot, i cant connect to the router anymore.

@SamuelGaona
Copy link

❯ python .\nokia-router-cfg-tool.py -u config.cfg

-> little endian CPU detected
-> fw_magic = 0xfffffffe
Traceback (most recent call last):
  File "nokia-router-cfg-tool.py", line 137, in <module>
    xml_data = zlib.decompress(compressed)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
zlib.error: Error -3 while decompressing data: incorrect header check

@mistressAlisi
Copy link

Hi there!
I have a Nokia G1425 from Telemex (Mexican ISP):
Chipset: MTK7528
Hardware: 3FE77771BEAA
Software: 3FE49568IJLJ07(1.2402.307)
Made in Nov 1, 2024.
This one does not let me decode, I get the dreaded:
-> little endian CPU detected
-> fw_magic = 0xfffffffe
Traceback (most recent call last):
File "/home/alisi/Downloads/nokia.py", line 137, in
xml_data = zlib.decompress(compressed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
zlib.error: Error -3 while decompressing data: incorrect header check

I understand this is a decoding problem (I use Python and these libraries myself!) - The question here is, is there anything I can do to help the project/community to get this version of the firmware cracked?

I am more than willing to share my config.cfg with someone if needed; the credentials are non-relevant outside Telmex's network anyway:
https://drive.google.com/file/d/1NEp0mSZUdCpTH5w9QxykT00Mxmmgn1aj/view?usp=sharing

Thanks in advance!
-Alisi

@smootok
Copy link

smootok commented Mar 19, 2025

Hello, sir @rajkosto . It worked, thanks! One thing though I want to set a static ARP.

When I run arp -s xxx xxx, it works, but after a reboot, I lose the changes.

Is there any way to persist this ARP?

I tried modifying init.d inside /etc, but /etc is not persisted. I also tried using cron, but nothing worked. If you have any ideas, I'd appreciate it. Thanks!

@carlos-chavez-p
Copy link

Hi there! I have a Nokia G1425 from Telemex (Mexican ISP): Chipset: MTK7528 Hardware: 3FE77771BEAA Software: 3FE49568IJLJ07(1.2402.307) Made in Nov 1, 2024. This one does not let me decode, I get the dreaded: -> little endian CPU detected -> fw_magic = 0xfffffffe Traceback (most recent call last): File "/home/alisi/Downloads/nokia.py", line 137, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check

I understand this is a decoding problem (I use Python and these libraries myself!) - The question here is, is there anything I can do to help the project/community to get this version of the firmware cracked?

I am more than willing to share my config.cfg with someone if needed; the credentials are non-relevant outside Telmex's network anyway: https://drive.google.com/file/d/1NEp0mSZUdCpTH5w9QxykT00Mxmmgn1aj/view?usp=sharing

Thanks in advance! -Alisi

I am getting this exact same error. I guess the new firmware changed something. Any luck? Here is my device info:

Device name
G-1425G-A
Vendor
Nokia
Serial Number:
ALCLFE08B0A0
Hardware Version:
3FE77771BEAA
Boot Version
Bootbase1.1-Jul-02-2024--22:11:45
Software Version:
3FE49568IJLJ07(1.2402.307)
Chipset
MTK7528
Lot Number
Nov 01 2024

@alexceltare2
Copy link

PSA: You need pycryptodome library installed from pip for this script to work! Remove any previously installed crypto libraries.

@carlos-chavez-p
Copy link

PSA: You need pycryptodome library installed from pip for this script to work! Remove any previously installed crypto libraries.

That is already installed:
(base) cursor@MacBookPro temp % pip show pycryptodome
Name: pycryptodome
Version: 3.22.0
Summary: Cryptographic library for Python
Home-page: https://www.pycryptodome.org
Author: Helder Eijs
Author-email: [email protected]
License: BSD, Public Domain
Location: /Users/cursor/micromamba/lib/python3.9/site-packages

I can run the script with the -D option and get back: decrypted: admin

But when running with the -u option I get an error:

-> little endian CPU detected
-> fw_magic = 0xfffffffe
Traceback (most recent call last):
File "/Users/cursor/temp/nokia-router-cfg-tool.py", line 201, in
xml_data = zlib.decompress(compressed)
zlib.error: Error -3 while decompressing data: incorrect header check

From what I have read this is probably because of the firmware revision of the modem.

@enineboyuna06
Copy link

Do anyone has a full flash dump of G-2426G-A?

@ArialCCAA
Copy link

Hey @rajkosto sorry for the long text, but I think this write up is gonna help a lot of people here:

First of all, starting as to why I have done this. The Nokia G0425G-C stopped my acess points from working correctly for some reason, cutting out the signal a lot and adding additional latency. I also for some reason couldn't put it into bridge mode and even when I managed to put it in bridge mode, it still stopped the router from doing the PPPoE dialing, so the best course of action was indeed to replace it.

To start out with, the login the ISP deploys is not really all that useful, they wont let you even change local IPs nor DNS.
I had asked previously about the more low level login and they did provide it to me, but I couldn't find it since the chat got deleted and my server where I had it logged in corrupted it's ssd from a bad ram setting.
So I looked online and found the lower level login for this ONT, which they forgot to change from the default, which is:
Login: AdminGPON
Password: ALC#FGU

From there, I managed to get it to export it's backup config file, which allowed me, after decryption with a python code (https://gist.github.com/rajkosto/e2b2455d457cc2be82dbb5c85e22d708), to change the telnet access to the ONT, however, this was not strictly necessary to the setup at hand, but it also allowed me to get access to the PPPoE credentials once I got in. The PPPoE credentials, even with the lower access account wouldn't reveal the PPPoE password.

Other than that, I also extracted from the WEB UI a few details that are necessary for the cloning, then I flashed them into the new replacement ONU via telnet, which also is able to run a custom firmware from O3labs (https://www.tripleoxygen.net/post/intelbras-onu-r1-v2-custom-firmware/), which automatically runs a command (setcons), which redirects the flash output to the current terminal, before soldering of the contacts in the ONU's PCB was needed to get confirmation of whether or not your commands worked, you also didnt get a return on the current terminal when doing a (omcicli mib get 84), necessary to get the VLANs available for you to access.

mib set LOID ""
mib set LOID_PASSWD ""
flash set GPON_PLOAM_PASSWD ALCLFC
flash set OMCI_OLT_MODE 3
flash set PON_VENDOR_ID ALCL
flash set OMCI_SW_VER1 3FE49568IJJL06
flash set OMCI_SW_VER2 3FE49568IJJL06
flash set GPON_ONU_MODEL G-0425G-C
flash set HW_HWVER 3TN00057BDAA
flash set OUI (First 6 digits of the mac, without spacing and lower case)
flash set HW_SERIAL_NO (mac add)
flash set ELAN_MAC_ADDR MAC
flash set OMCC_VER 128
flash set GPON_SN ALCLFC0000B0 (example, varies from device to device)

In the case you wanna check on the intelbras R1 ONU whether or not your commands worked as intended, you can run a (mib show), which will show all stored values for mib flash.

After flashing the information into the new ONU, you run (omcicli mib get 84), which will list your VLANs available to the device, if you get a bunch of XXXXXX it just means the informations cloned arent enough for the ONU to be recognized by the OLT.
So you go into the ONU's WEB UI and set the IPV6 settings to whatever is compatible with the ISP you have, in the case of LIGUE/GIGA+, it's as follows:
VLAN ID: 200
NAPT: on
MTU: 1492
IGMP-proxy: off
IPV4 (PPPoE): login (LIGUE) | Password (random string of characters,really long)
Authentication: auto
IPV6: DHCPv6 - request address + request prefix

From there the internet connection happened and everything was amazing.

@Louisthexv
Copy link

Hi there! I have a Nokia G1425 from Telemex (Mexican ISP): Chipset: MTK7528 Hardware: 3FE77771BEAA Software: 3FE49568IJLJ07(1.2402.307) Made in Nov 1, 2024. This one does not let me decode, I get the dreaded: -> little endian CPU detected -> fw_magic = 0xfffffffe Traceback (most recent call last): File "/home/alisi/Downloads/nokia.py", line 137, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check

I understand this is a decoding problem (I use Python and these libraries myself!) - The question here is, is there anything I can do to help the project/community to get this version of the firmware cracked?

I am more than willing to share my config.cfg with someone if needed; the credentials are non-relevant outside Telmex's network anyway: https://drive.google.com/file/d/1NEp0mSZUdCpTH5w9QxykT00Mxmmgn1aj/view?usp=sharing

Thanks in advance! -Alisi

hello, i'm having same issue and same model on nokia g1425-B and telmex ISP, did you were able to fix it or how did you solve it?

@ckfu37186
Copy link

ckfu37186 commented May 24, 2025 via email

@Louisthexv
Copy link

❯ python .\nokia-router-cfg-tool.py -u config.cfg

-> little endian CPU detected
-> fw_magic = 0xfffffffe
Traceback (most recent call last):
  File "nokia-router-cfg-tool.py", line 137, in <module>
    xml_data = zlib.decompress(compressed)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
zlib.error: Error -3 while decompressing data: incorrect header check

hey, did you were able to resolve this?

@Louisthexv
Copy link

Louisthexv commented May 24, 2025

Hi there! I have a Nokia G1425 from Telemex (Mexican ISP): Chipset: MTK7528 Hardware: 3FE77771BEAA Software: 3FE49568IJLJ07(1.2402.307) Made in Nov 1, 2024. This one does not let me decode, I get the dreaded: -> little endian CPU detected -> fw_magic = 0xfffffffe Traceback (most recent call last): File "/home/alisi/Downloads/nokia.py", line 137, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check
I understand this is a decoding problem (I use Python and these libraries myself!) - The question here is, is there anything I can do to help the project/community to get this version of the firmware cracked?
I am more than willing to share my config.cfg with someone if needed; the credentials are non-relevant outside Telmex's network anyway: https://drive.google.com/file/d/1NEp0mSZUdCpTH5w9QxykT00Mxmmgn1aj/view?usp=sharing
Thanks in advance! -Alisi

I am getting this exact same error. I guess the new firmware changed something. Any luck? Here is my device info:

Device name G-1425G-A Vendor Nokia Serial Number: ALCLFE08B0A0 Hardware Version: 3FE77771BEAA Boot Version Bootbase1.1-Jul-02-2024--22:11:45 Software Version: 3FE49568IJLJ07(1.2402.307) Chipset MTK7528 Lot Number Nov 01 2024

did you were able to resolve this?

@ckfu37186
Copy link

ckfu37186 commented May 24, 2025 via email

@ckfu37186
Copy link

ckfu37186 commented May 24, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment