Skip to content

Instantly share code, notes, and snippets.

@thedroidgeek
Last active April 26, 2025 04:47
Show Gist options
  • Save thedroidgeek/80c379aa43b71015d71da130f85a435a to your computer and use it in GitHub Desktop.
Save thedroidgeek/80c379aa43b71015d71da130f85a435a 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
#
# 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')
@SanketRohilla
Copy link

Hey Anbody help me i am facing this error

PS C:\Users\The Lost Gaming Club\Desktop> python nokia.py -d OYdLWUVDdKQTPaCIeTqniA==

Traceback (most recent call last):
File "C:\Users\The Lost Gaming Club\Desktop\nokia.py", line 221, in
print('\ndecrypted: ' + RouterCrypto().decrypt(base64.b64decode(sys.argv[2])).decode('UTF-8') + '\n')
^^^^^^^^^^^^^^
File "C:\Users\The Lost Gaming Club\Desktop\nokia.py", line 50, in init
from Crypto.Cipher import AES
ModuleNotFoundError: No module named 'Crypto'
Untitled

@MrJithil
Copy link

MrJithil commented Jul 5, 2023

I am able to access the shell with root.

Now, how can we customise my router to enable all the features? I am unable to add new profiles. So, instead of changing the xml values, what should be the right way to make this changes?

@cantonalex
Copy link

@MrJithil What router is this for?

@MrJithil
Copy link

MrJithil commented Jul 6, 2023

@MrJithil What router is this for?

G-2425G-A

@benjaminlhai
Copy link

Has anyone figured out a way to enable the back up and restore function on G-2425G-B or get any access to the SuperAdmin account?

@TheLazyHatGuy I haven't been able to find this out either, keep me posted if you find out!

@isayyed1
Copy link

I am unable to use the python script on 3FE49362JJIJ50
when I run the commands as per your instructions I get the below mentioned error

D:\nokia router -unlocker.py>python nokia.py

Nokia/Alcatel-Lucent router backup configuration tool

unpack (cfg to xml)

nokia.py -u config.cfg

pack (xml to cfg)

nokia.py -pb config.xml 0x13377331 # big endian, no encryption, fw_magic = 0x13377331
nokia.py -pl config.xml 0x13377331 # little endian, ...
nokia.py -pbe config.xml 0x13377331 # big endian, with encryption, ...
nokia.py -ple config.xml 0x13377331 # ...

decrypt/encrypt secret values within xml (ealgo="ab")

nokia.py -d OYdLWUVDdKQTPaCIeTqniA==
nokia.py -e admin

D:\nokia router -unlocker.py>python nokia.py -d OYdLWUVDdKQTPaCIeTqniA==

decrypted: admin

D:\nokia router -unlocker.py>python nokia.py -u config.cfg

-> little endian CPU detected
-> fw_magic = 0xffffffff
Traceback (most recent call last):
File "D:\nokia router -unlocker.py\nokia.py", line 138, in
xml_data = zlib.decompress(compressed)
zlib.error: Error -3 while decompressing data: incorrect header check

not sure what can I do next?

@theshapguy
Copy link

serial_number=ALCLFC0F3CE2 model_name=Nokia WiFi Beacon 1.1 model_number=3FE49236EAAA

NT_TYPE=beacon1_1 PON_MODE=ETHERNET SOFTWAREVERSION=HJI.I87p02 PRODUCTCLASS=beacon1_1 RELEASE=0.0.0 BUILDSTAMP= BUILDDATE=20210402_2046 COPYRIGHT=ASB WHOBUILD=buildmgr IMAGEVERSION=3FE49474HJII87 NODE=754bb9d584dc1e1dcd3b48a72a6e30800aaa69b5

ONTUSER:$1$gN5WP2Fo$6B.xGzm6kfpDOpYlY89Wp. wlinkuser:$1$IqXCkA2G$tD4LETpI3JuGqyMaxR5SH1 ONTUSER:$1$bgSEInSR$9mz9d01z5KeEqWCQDIXsw0 superadmin:$1$V2wemcad$2B/LkUQZ104dYCsTrdc5/1 ONTUSER:$1$bXtpwU3/$Qmlta87ByJOEnX0AllVJK1 superadmin:$1$JA/Lupt4$z9IvJy2VgUGL8n86.0dLx. ONTUSER:$1$4FG1vq0m$sbBHlJ44Nmoz0ADg6KKle1 superadmin:$1$8hB6r2PN$Zkl7rydE7syXwnC/V.rZc. superadmin:$1$MrZrEVDK$YqxsGcD7cYVz3.9wh2lzM1 ONTUSER:$1$Tyn/Cgvs$RdQuR6PUyfiwkwO167pDn. superadmin:$1$sfCosGGu$LKd9MUE6aJmpPy7vTHMdN1 root:$1$GTMUOzhf$mjhy6wET5re92IB4KHqXz.

web username :admin Password for this device only :KQ5bthrLZD i have dumped the firmware and shared to you

Could you share the firmware here?

@iamprashu
Copy link

please make a code for "3FE49362JJIJ54"

@abizardholfar
Copy link

Hi @Padke9 , I have Nokia Airtel G-2425G-A router with Software Version
3FE49362JJIJ50 . Can you please provide the Python script for this software version? Thanks.

@cantonalex
Copy link

anyone know how to do this for Fastmile 3.2 wifi 6 version?

@cantonalex
Copy link

cantonalex commented Oct 8, 2023

serial_number=ALCLFC0F3CE2 model_name=Nokia WiFi Beacon 1.1 model_number=3FE49236EAAA

(https://drive.google.com/file/d/1nrRQD-6ftSW1DlC0cpiG7CfsgFZGWa2R/view?usp=drive_link)

can I pay you to do this @Padke9 Prakesh, do you have twitter?

@Padke9
Copy link

Padke9 commented Oct 10, 2023

This is Locked to carrier
I dont have this hardware with me to reverse

Fastmile 3.2 wifi 6 version

But here is some thing you can see on other version
https://eddiez.me/hacking-the-nokia-fastmile/

@Banaune
Copy link

Banaune commented Oct 12, 2023

serial_number=ALCLFC0F3CE2 model_name=Nokia WiFi Beacon 1.1 model_number=3FE49236EAAA

NT_TYPE=beacon1_1 PON_MODE=ETHERNET SOFTWAREVERSION=HJI.I87p02 PRODUCTCLASS=beacon1_1 RELEASE=0.0.0 BUILDSTAMP= BUILDDATE=20210402_2046 COPYRIGHT=ASB WHOBUILD=buildmgr IMAGEVERSION=3FE49474HJII87 NODE=754bb9d584dc1e1dcd3b48a72a6e30800aaa69b5

ONTUSER:$1$gN5WP2Fo$6B.xGzm6kfpDOpYlY89Wp. wlinkuser:$1$IqXCkA2G$tD4LETpI3JuGqyMaxR5SH1 ONTUSER:$1$bgSEInSR$9mz9d01z5KeEqWCQDIXsw0 superadmin:$1$V2wemcad$2B/LkUQZ104dYCsTrdc5/1 ONTUSER:$1$bXtpwU3/$Qmlta87ByJOEnX0AllVJK1 superadmin:$1$JA/Lupt4$z9IvJy2VgUGL8n86.0dLx. ONTUSER:$1$4FG1vq0m$sbBHlJ44Nmoz0ADg6KKle1 superadmin:$1$8hB6r2PN$Zkl7rydE7syXwnC/V.rZc. superadmin:$1$MrZrEVDK$YqxsGcD7cYVz3.9wh2lzM1 ONTUSER:$1$Tyn/Cgvs$RdQuR6PUyfiwkwO167pDn. superadmin:$1$sfCosGGu$LKd9MUE6aJmpPy7vTHMdN1 root:$1$GTMUOzhf$mjhy6wET5re92IB4KHqXz.

web username :admin Password for this device only :KQ5bthrLZD i have dumped the firmware and shared to you

Very happy to see someone from our country doing these stuff. Keep it up bro.

@Banaune
Copy link

Banaune commented Oct 18, 2023

@Padke9 Did you succeed to extract the squashfs filesystem. Or if any new update?

@krausar791
Copy link

krausar791 commented Oct 19, 2023

This is Locked to carrier I dont have this hardware with me to reverse

Fastmile 3.2 wifi 6 version

But here is some thing you can see on other version https://eddiez.me/hacking-the-nokia-fastmile/

This is Locked to carrier I dont have this hardware with me to reverse

Fastmile 3.2 wifi 6 version

But here is some thing you can see on other version https://eddiez.me/hacking-the-nokia-fastmile/
Bro do you know shell password of Nokia G-120W-F or have clean firmware for it?
@Padke9

@Padke9
Copy link

Padke9 commented Oct 19, 2023

@krausar791
the password should be
username:ONTUSER
Password:SUGAR2A041

or (username will be given by isp)pass =ALC#FGU

@krausar791
Copy link

@krausar791 the password should be username:ONTUSER Password:SUGAR2A041

or (username will be given by isp)pass =ALC#FGU

@Padke9 do you have clean firmware of this ont?

@r10p
Copy link

r10p commented Oct 21, 2023

@Padke9 I was not able to extract all the contents of the firmware you provided. In particular the squashfs files are not being able to be extracted. I ran foremost, binwalk, unsquashfs with default flags to try to extract them. Nothing worked.

@Banaune
Copy link

Banaune commented Oct 21, 2023

@Padke9 I was not able to extract all the contents of the firmware you provided. In particular the squashfs files are not being able to be extracted. I ran foremost, binwalk, unsquashfs with default flags to try to extract them. Nothing worked.
@r10p

Save this as fixOOB.py

      import sys
      
      def split_file(input_file, output_prefix):
      
        with open(input_file, "rb") as file_in:
          with open(f"{output_prefix}_0", "wb") as file_out:
            buff = file_in.read()
      
            for x in range (0,len(buff),0x800 + 0x40):
              file_out.write(buff[x:x+0x800])
      
        file_in.close()
        file_out.close()
      
      if __name__ == "__main__":
        input_file = sys.argv[1]
        output_prefix = sys.argv[2]
      
        split_file(input_file, output_prefix)

Then run python3 fixOOB.py "Firmware.bin" "NewFilename"
NewFilename is the extractable firmware.

@r10p
Copy link

r10p commented Oct 22, 2023

Thank you @Banaune . It worked.
By the way are you guys able to decrypt the newer router config? @Banaune @Padke9

@Padke9
Copy link

Padke9 commented Oct 25, 2023

@Banaune
I cannot fix from your script

Screenshot 2023-10-25 143427

is there any good passwordlist to attack this hash faster,it is taking me very long more than a month.

@Banaune
Copy link

Banaune commented Nov 1, 2023

@Padke9 You can use the script I gave above, in the firmware file. Regarding password cracking, I am not able to help as I am unknown about it.

@Banaune
Copy link

Banaune commented Nov 1, 2023

Thank you @Banaune . It worked. By the way are you guys able to decrypt the newer router config? @Banaune @Padke9

@r10p Yes,you can use this fork of this repo which is updated for latest configs: Updated Gist Link

@Padke9
Copy link

Padke9 commented Nov 8, 2023

@Banaune @r10p finally found password of super user

model_name=Nokia WiFi Beacon 1.1

Username=superadmin
Password=Telc@Admin2#

@r10p
Copy link

r10p commented Nov 9, 2023

@Padke9

sai ho bro

@sodapng
Copy link

sodapng commented Nov 10, 2023

Help, please, find out the PPPoE password. Device name: G-1425G-B
image

@mehradraissi
Copy link

mehradraissi commented Dec 4, 2023

@Padke9 @Banaune @r10p @r10p @krausar791 Hi, Anyone has latest firmware for unlock factory Nokia FastMile 3.1 by any chance ?, thank you

@ETCHDEV
Copy link

ETCHDEV commented Dec 25, 2023

I am getting this error -> little endian CPU detected
-> fw_magic = 0xffffffff
Traceback (most recent call last):
File "/Users/arjun/Downloads/nokia-router-cfg-tool.py", line 137, in
xml_data = zlib.decompress(compressed)
zlib.error: Error -3 while decompressing data: incorrect header check

@ETCHDEV
Copy link

ETCHDEV commented Dec 25, 2023

help

@hhejkhalkfahjahsf
Copy link

hhejkhalkfahjahsf commented Jan 7, 2024

https://www.youtube.com/watch?v=taA0P52jUXw
Worked for XS-2426G-A 3FE49385HJJI85(1.2201.185)

Maybe someone will be able to update the script?

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