Nokia G-2425G-g - Unlock/Root ~ Step by Step detailed guide
Disclaimer : I'm not responsible if you brick your router in-between the process.
1. Open 192.168.1.1 in any browser
default username password both is admin
2. Go to Maintenance->backup and restore->export config file on your desktop
it will be saved as config.cfg
3. Download & install python on your pc
also download this file(python script) on your desktop
#!/usr/bin/env python3 # # Nokia/Alcatel-Lucent router backup configuration tool # G2425 support added by rajkosto on 20/11/2022 # # 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 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 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 = 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 # 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) recompInfo = ('-pb' if big_endian else '-pl') 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' encrypted_cfg = sys.argv[1][3:4] == 'e' pkcsPass = None if encrypted_cfg and len(sys.argv[1]) > 4: pkcsPass = sys.argv[1][4:] 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) # 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) + extraDecompLen) # fw_magic cfg_data += p32(fw_magic) # 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')
Keep in mind that in order to restore a config to G2425, the file MUST be named
config.cfg
or it will just do nothing with it.4. Open cmd
type
python C:\Users\XXXXX\Desktop\Nokia-router-cfg-tool.py (replace xxxxx with your windows user)
(4b) now lets decrypt your cfg file first
type
python nokia-router-cfg-tool.py -d OYdLWUVDdKQTPaCIeTqniA==
(4c) now unpack you cfg file to xml
type
python nokia-router-cfg-tool.py -u config.cfg
5. A new file is created on your desktop .xml format
right click & select edit.
(5a) press control+f and type TelnetSshAccount in searchbox then hit enter
now change the values same as below
<TelnetSshAccount. n="TelnetSshAccount" t="staticObject">
<Enable rw="RW" t="boolean" v="True"></Enable>
<UserName ml="64" rw="RW" t="string" v="admin"></UserName>
<Password ml="64" rw="RW" t="string" v="OYdLWUVDdKQTPaCIeTqniA==" ealgo="ab"></Password>
press control s to save the file & close it
6. Go back to cmd & check for repack command to encrypt the edited xml file back to cfg
it will look like this something like this :
type
python nokia-router-cfg-tool.py -ple config-XXXXXXX-XXXXXX.xml 0x4924ea42
(6a) a new cfg file will be created on your desktop.
7. Now go back to router login page 192.168.1.1
(7a) go to Maintenance->backup and restore & click "select" then browse newly created cfg file from your desktop then click import
wait for the router to reboot itself.
8. Now login again 192.168.1.1
Go to Security->Access control and allow both telent & ssh(Wan & Lan)
9. Download MobaXterm_Portable_v21.5 link below
10. Open Mobaxterm & click on Start local terminal
type
telnet 192.168.1.1
user: admin
password: admin
11. After that lets first copy this in your clipboard: '; /bin/sh; #
(11a) go back to mobaxterm
type
enable
type
shell
it will ask for password2, press shift+insert button on your keyboard and hit enter
BOOM now you've root access
(11b) to take the current backup of airtel settings
type
cfgcli dump
type
ritool dump
& save the file by going terminal->save terminal text.
(11c) now to unlock settings
type
ritool set OperatorID ALCL
12. Go back your router login on your browser 192.168.1.1 and BOOOOOOM everything is unlocked, you'll see changes right away
Important : If you plan to stick with everything unlocked using airtel fiber then let it as it is.
Important: If you plan to use this router with any other fiber connection just do a factory reset.
Doing a factory reset will erase, reset & unlock everything. The default router login address will change to 192.168.1.254 with username AdminGPON and password as ALC#FGU
I've personally myself tested this whole process & successfully unlocked 3 routers.
I wish you all good health.
type
python C:\Users\XXXXX\Desktop\Nokia-router-cfg-tool.py (replace xxxxx with your windows user)
(4b) now lets decrypt your cfg file first
type
python nokia-router-cfg-tool.py -d OYdLWUVDdKQTPaCIeTqniA==
(4c) now unpack you cfg file to xml
type
python nokia-router-cfg-tool.py -u config.cfg
5. A new file is created on your desktop .xml format
right click & select edit.
(5a) press control+f and type TelnetSshAccount in searchbox then hit enter
now change the values same as below
<TelnetSshAccount. n="TelnetSshAccount" t="staticObject">
<Enable rw="RW" t="boolean" v="True"></Enable>
<UserName ml="64" rw="RW" t="string" v="admin"></UserName>
<Password ml="64" rw="RW" t="string" v="OYdLWUVDdKQTPaCIeTqniA==" ealgo="ab"></Password>
press control s to save the file & close it
6. Go back to cmd & check for repack command to encrypt the edited xml file back to cfg
it will look like this something like this :
type
python nokia-router-cfg-tool.py -ple config-XXXXXXX-XXXXXX.xml 0x4924ea42
(6a) a new cfg file will be created on your desktop.
7. Now go back to router login page 192.168.1.1
(7a) go to Maintenance->backup and restore & click "select" then browse newly created cfg file from your desktop then click import
wait for the router to reboot itself.
8. Now login again 192.168.1.1
Go to Security->Access control and allow both telent & ssh(Wan & Lan)
9. Download MobaXterm_Portable_v21.5 link below
10. Open Mobaxterm & click on Start local terminal
type
telnet 192.168.1.1
user: admin
password: admin
11. After that lets first copy this in your clipboard: '; /bin/sh; #
(11a) go back to mobaxterm
type
enable
type
shell
it will ask for password2, press shift+insert button on your keyboard and hit enter
BOOM now you've root access
(11b) to take the current backup of airtel settings
type
cfgcli dump
type
ritool dump
& save the file by going terminal->save terminal text.
(11c) now to unlock settings
type
ritool set OperatorID ALCL
12. Go back your router login on your browser 192.168.1.1 and BOOOOOOM everything is unlocked, you'll see changes right away
Important : If you plan to stick with everything unlocked using airtel fiber then let it as it is.
Important: If you plan to use this router with any other fiber connection just do a factory reset.
Doing a factory reset will erase, reset & unlock everything. The default router login address will change to 192.168.1.254 with username AdminGPON and password as ALC#FGU
I've personally myself tested this whole process & successfully unlocked 3 routers.
I wish you all good health.
Status>Overview
G-2425G-A
ImportError: No module named Crypto
pip3 install pycryptodome
add python keyword
nokia-router-cfg-tool.py -pleS23l7nZm47XyMGs6y6oJpN9CR4nbfIZHJ4VRwp7HcdV6o2YvUmeNYFlz08Otwz78 config-28112022-155759.xml 0xffffffff
when resoter name must be config only
https://gist.github.com/thedroidgeek/80c379aa43b71015d71da130f85a435a
--------------------
worked
config2 did not worked invalid cf only config worked
After reboot
Enable ssh and telnet access on lan side
Open putty or any other ssh client
ONTUSER
admin
Got root ?
Yes
If u factory reset
You need to do this again
First run
ritool dump
Copy all the data
cfgcli dump
ritool set OperatorID ALCL
Unlock done bro thanks a lot
When trying to create new profile any solution
error set xpon_struct
Factory reset
http://192.168.1.254
AdminGPON
ALC#FGU
Comments
Post a Comment