-
-
Save thedroidgeek/80c379aa43b71015d71da130f85a435a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3 | |
# | |
# Nokia/Alcatel-Lucent router backup configuration tool | |
# | |
# 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 | |
# | |
# 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) | |
# | |
import sys | |
import zlib | |
import struct | |
import base64 | |
import binascii | |
import datetime | |
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) | |
# remove PKCS#7 padding | |
return output[:-ord(output[-1:])] | |
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) | |
# | |
# 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 fw_magic (unknown, could be fw version/compile time, hw serial number, etc.) | |
fw_magic = u32(cfg_data[0x10:0x14]) | |
print('-> fw_magic = ' + hex(fw_magic)) | |
# get the size of the compressed data | |
data_size = u32(cfg_data[4:8]) | |
# get the compressed data | |
compressed = cfg_data[0x14 : 0x14 + data_size] | |
# get the checksum of the compressed data | |
checksum = u32(cfg_data[8:12]) | |
# verify the checksum | |
if (binascii.crc32(compressed) & 0xFFFFFFFF != checksum): | |
print('\nCRC32 checksum failed :(\n') | |
exit() | |
# unpack the config | |
xml_data = zlib.decompress(compressed) | |
# output the xml file | |
out_filename = 'config-%s.xml' % datetime.datetime.now().strftime('%d%m%Y-%H%M%S') | |
of = open(out_filename, 'wb') | |
of.write(xml_data) | |
print('\nunpacked as: ' + out_filename) | |
print('\n# repack with:') | |
print('%s %s %s %s\n' % (sys.argv[0], ('-pb' if big_endian else '-pl') + ('e' if encrypted_cfg else ''), 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' | |
encrypted_cfg = sys.argv[1][3:] == 'e' | |
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) | |
## construct the header ## | |
# magic | |
cfg_data = p32(0x123123) | |
# size of compressed data | |
cfg_data += p32(len(compressed)) | |
# crc32 checksum | |
cfg_data += p32(binascii.crc32(compressed) & 0xFFFFFFFF) | |
# size of xml file | |
cfg_data += p32(len(xml_data) + 1) | |
# fw_magic | |
cfg_data += p32(fw_magic) | |
# add the compressed xml | |
cfg_data += compressed | |
# encrypt 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') |
Any Idea where i can Find the list of OperatorID in the router itself ? Also for anyone Looking Info on Nokia G-1425-MA specially from Classictech : Web Username : classicadmin Web Password : Cr3d3nti@lofNok!aONT0061_P@SSW)RD https://github.com/diwash5/nokia_G-1425-MA
@diwash5
Hi Friend,
Thank you very much for this very useful information! Could you, please, also share your firmware dump?
I want to extract the kernel (and maybe u-boot) partitions from it and replace these partitions in my firware dump.
My ONT has updated (newer) firmware, in which Nokia has disabled Serial console (UART port access)...
To reactivate it, I need an older firmware's kernel with active UART, which, jugdging from you bootlog, is active on your unit!
Thank you!
@UCWQv_nlzS9C2gr7h8nJOBTg Report issues at https://termux.dev/issues
~ $ cd /storage/emulated/0/nokia/
.../0/nokia $ python nokia-router-cfg-tool.py
Nokia/Alcatel-Lucent router backup configuration tool
unpack (cfg to xml)
nokia-router-cfg-tool.py -u config.cfg
pack (xml to cfg)
nokia-router-cfg-tool.py -pb config.xml 0x13377331 # big endian, no encryption, fw_magic = 0x13377331
nokia-router-cfg-tool.py -pl config.xml 0x13377331 # little endian, ...
nokia-router-cfg-tool.py -pbe config.xml 0x13377331 # big endian, with encryption, ...
nokia-router-cfg-tool.py -ple config.xml 0x13377331 # ...
decrypt/encrypt secret values within xml (ealgo="ab")
nokia-router-cfg-tool.py -d OYdLWUVDdKQTPaCIeTqniA==
nokia-router-cfg-tool.py -e admin
.../0/nokia $ python nokia_tool.py -u config.cfgpython: can't open file '/storage/emulated/0/nokia/nokia_tool.py': [Errno 2] No such file or directory
.../0/nokia $ python nokia-router-cfg-tool.py -u config.cfg
-> little endian CPU detected
-> fw_magic = 0xffffffff
unpacked as: config-16122024-155528.xml
repack with:
nokia-router-cfg-tool.py -pleS23l7nZm47XyMGs6y6oJpN9CR4nbfIZHJ4VRwp7HcdV6o2YvUmeNYFlz08Otwz78 config-16122024-155528.xml 0xffffffff
.../0/nokia $
Repack not working 😭 😞
hey so i got a nokia g-240w-f router from a isp and i disconnected the router from them and so currently its not use for me so what i was trying to do is trying to make it a access point for my main router the problem is i cant change the gateway ip and such i dont know why the isp disabled those is there a way that i can reflash the firmware and if so where do i find a firmware also my gpon dashboard does not have a update firmware option on the maintance tab
here is the lan tab
i managed it to disable the dhcp by removing the disable tag from the inspect menu so currently dhcp is not there but i tried to do the same on the IPv4 Address and it gives me error lan ip as a alert
hey so i got a nokia g-240w-f router from a isp and i disconnected the router from them and so currently its not use for me so what i was trying to do is trying to make it a access point for my main router the problem is i cant change the gateway ip and such i dont know why the isp disabled those is there a way that i can reflash the firmware and if so where do i find a firmware also my gpon dashboard does not have a update firmware option on the maintance tab
here is the lan tab
i managed it to disable the dhcp by removing the disable tag from the inspect menu so currently dhcp is not there but i tried to do the same on the IPv4 Address and it gives me error lan ip as a alert
Hey I have the same router and my DHCP is enabled by default and the setting to turn it off is greyed out, neither am I able to allocate any static IPs, please help.
what i did was use the inspect menu and remove the disabled tag and save and it works for the disableing the dhcp and the nat but not the subnets and other things
@achiragaming hey man, thanks for the reply! I did the same and removed disabled from save button and the DHCP checkbox, but after clicking on save it says "The normal user is not allowed to do this!)". Maybe they patched it to needing superuser auth?
https://drive.google.com/file/d/1iXzdb1HwwtGxB5JYywYvdZRQDtlRcGmX/view TRCL firmware G-2426G-A FE49226IJJJ09
I need shell password2
'; /bin/sh; #
LA(ImvZx%8
SUGAR2A041
Does not work unable to dump config it's fully locked uart access requires password can anyone help me?
Successfully extracted the firmware into folders but don't know where to look at.
try this- nE7jA%5m
try this- nE7jA%5m
It says password invalid.
TRCL preconfiguration: https://raw.githubusercontent.com/tolgagazii/tolga/refs/heads/main/preconfiguration_global_TRCL.xml
hello, i have a nokia G140W-F
software ver. 3FE47150IJJL04(1.2204.504)
whenever i try running the python script to unpack my config file it giving me this error please help me
ERROR:
PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>python nokia-router-cfg-tool.py -u config.cfg
-> big endian CPU detected
-> fw_magic = 0xffffffff
Traceback (most recent call last):
File "C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0\nokia-router-cfg-tool.py", line 137, in
xml_data = zlib.decompress(compressed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
zlib.error: Error -3 while decompressing data: incorrect header check
PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>
hello, i have a nokia G140W-F software ver. 3FE47150IJJL04(1.2204.504)
whenever i try running the python script to unpack my config file it giving me this error please help me
ERROR: PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>python nokia-router-cfg-tool.py -u config.cfg
-> big endian CPU detected -> fw_magic = 0xffffffff Traceback (most recent call last): File "C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0\nokia-router-cfg-tool.py", line 137, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>
I'm getting the exact same error, did you have any luck finding a fix for it?
hello, i have a nokia G140W-F software ver. 3FE47150IJJL04(1.2204.504)
whenever i try running the python script to unpack my config file it giving me this error please help me
ERROR: PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>python nokia-router-cfg-tool.py -u config.cfg
-> big endian CPU detected -> fw_magic = 0xffffffff Traceback (most recent call last): File "C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0\nokia-router-cfg-tool.py", line 137, in xml_data = zlib.decompress(compressed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -3 while decompressing data: incorrect header check PS C:\Users\kenka\OneDrive\Desktop\nokia new\80c379aa43b71015d71da130f85a435a-fc00533292eb1233b391de06481099ca69fe92a0>I'm getting the exact same error, did you have any luck finding a fix for it?
I'm stuck here too.
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
can we extract username and password from nokia config file?
PSA: You need pycryptodome
library installed from pip for this script to work! Remove any previously installed crypto libraries.
Hi,
That "genpwd_longpasswd" should return the default password printed on the bottom sticker/label (10 symbols, unique for each device, used as default password for both Wi-Fi and Web user account).
There is also fri="genpwd_wlanpasswd" function, the exact meaning of which I have not yet found...
Do you have any information about that?
Also, this blog post/article is a very good resource!
https://git.lsd.cat/g/nokia-keygen
https://git.lsd.cat/g/nokia-keygen/src/branch/master/poc