Great news! I believe we have a method to flash any NR7101 without knowing any password. I finally took the time to decompile their closed source part of the bootloader to reverse engineer the "Multiboot" feature you might bave noticed on the console while booting these devices. This is a protocol allowing direct flashing using multicast. With absolutely no authentication at all...
My initial work-in-progress code with protocol docs is here: https://github.com/bmork/firmware-utils/commit/dd4ce54ee35cb36197ee61f1e979be4264513e55
There are still some unknown parts of the protocol, but I believe I have enough of it covered to make it safe for firmware flashing. Bootloader flashing is not recommended, and is disabled by default in the tool.
This will work on almost any ZyXEL router. But not the switches are excepted. That would be a security risk. It's bad enoough for the routers
I just tested the code on one of my NR7101s. Started the tool on a host connected to the LAN port of the NR7101:
bjorn@idefix:/tmp$ /tmp/zycast -i eth0.10 -f openwrt-snapshot-r22900-abec62a54268-ramips-mt7621-zyxel_nr7101-initramfs-recovery.bin -t 10
Press Ctrl+C to stop before rebooting target after upgrade
^C
Closing all files
And then I powered on the NR7101. Console output:
dcache: sets:256, ways:4, linesz:32 ,total:32768
##### The CPU freq = 880 MHZ ####
estimate memory size =256 Mbytes
#Reset_MT7530
.## Starting application at 0x8402A800 ...
Z-LOADER V1.30 | 06/03/2020 08:39:30
Hit ESC key to stop autoboot: 1
NetLoop,call eth_halt !
NetLoop,call eth_init !
Trying Eth0 (10/100-M)
Waitting for RX_DMA_BUSY status Start... done
ETH_STATE_ACTIVE!!
Multiboot Listening...
3Receive first multiboot packet
Received RAS packet ID: 0x3f13
Roll back to receive previous RAS packet ID: 0x023f
gEngCleanROMD = 0
------MultiBoot Download Finish------
Upgrading Ras...
Firmware with RAS format.
trx_exist = 1
RAS header checksum: 0x2e168055 vs caculation checksum: 0x2e168055
Image checksum: 0xfd86d98f vs caculation checksum: 0xfd86d98f
Image checking PASS! Start upgrading...
Upgrade firmware from memory 0x89140000 to flash 0x00140000, file length 16535069, file type=1
ranand_erase: start:140000, len:20000
..ranand_erase: start:160000, len:20000
..ranand_erase: start:180000, len:20000
..ranand_erase: start:1a0000, len:20000
..ranand_erase: start:1c0000, len:20000
..ranand_erase: start:1e0000, len:20000
..ranand_erase: start:200000, len:20000
..ranand_erase: start:220000, len:20000
..ranand_erase: start:240000, len:20000
..ranand_erase: start:260000, len:20000
..ranand_erase: start:280000, len:20000
..ranand_erase: start:2a0000, len:20000
..ranand_erase: start:2c0000, len:20000
..ranand_erase: start:2e0000, len:20000
..ranand_erase: start:300000, len:20000
..ranand_erase: start:320000, len:20000
..ranand_erase: start:340000, len:20000
..ranand_erase: start:360000, len:20000
..ranand_erase: start:380000, len:20000
..ranand_erase: start:3a0000, len:20000
..ranand_erase: start:3c0000, len:20000
..ranand_erase: start:3e0000, len:20000
..ranand_erase: start:400000, len:20000
..ranand_erase: start:420000, len:20000
..ranand_erase: start:440000, len:20000
ranand_erase: attempt to erase a fact bad block at 0x00440000
.bad block: 440000, try next: 460000
ranand_erase: start:460000, len:20000
..ranand_erase: start:480000, len:20000
..ranand_erase: start:4a0000, len:20000
..ranand_erase: start:4c0000, len:20000
..ranand_erase: start:4e0000, len:20000
..ranand_erase: start:500000, len:20000
..ranand_erase: start:520000, len:20000
..ranand_erase: start:540000, len:20000
..ranand_erase: start:560000, len:20000
..ranand_erase: start:580000, len:20000
..ranand_erase: start:5a0000, len:20000
..ranand_erase: start:5c0000, len:20000
..ranand_erase: start:5e0000, len:20000
..ranand_erase: start:600000, len:20000
..ranand_erase: start:620000, len:20000
..ranand_erase: start:640000, len:20000
..ranand_erase: start:660000, len:20000
..ranand_erase: start:680000, len:20000
..ranand_erase: start:6a0000, len:20000
..ranand_erase: start:6c0000, len:20000
..ranand_erase: start:6e0000, len:20000
..ranand_erase: start:700000, len:20000
..ranand_erase: start:720000, len:20000
..ranand_erase: start:740000, len:20000
..ranand_erase: start:760000, len:20000
..ranand_erase: start:780000, len:20000
..ranand_erase: start:7a0000, len:20000
..ranand_erase: start:7c0000, len:20000
..ranand_erase: start:7e0000, len:20000
..ranand_erase: start:800000, len:20000
..ranand_erase: start:820000, len:20000
..ranand_erase: start:840000, len:20000
..ranand_erase: start:860000, len:20000
..ranand_erase: start:880000, len:20000
..ranand_erase: start:8a0000, len:20000
..ranand_erase: start:8c0000, len:20000
..ranand_erase: start:8e0000, len:20000
..ranand_erase: start:900000, len:20000
..ranand_erase: start:920000, len:20000
..ranand_erase: start:940000, len:20000
..ranand_erase: start:960000, len:20000
..ranand_erase: start:980000, len:20000
..ranand_erase: start:9a0000, len:20000
..ranand_erase: start:9c0000, len:20000
..ranand_erase: start:9e0000, len:20000
..ranand_erase: start:a00000, len:20000
..ranand_erase: start:a20000, len:20000
..ranand_erase: start:a40000, len:20000
..ranand_erase: start:a60000, len:20000
..ranand_erase: start:a80000, len:20000
..ranand_erase: start:aa0000, len:20000
..ranand_erase: start:ac0000, len:20000
..ranand_erase: start:ae0000, len:20000
..ranand_erase: start:b00000, len:20000
..ranand_erase: start:b20000, len:20000
..ranand_erase: start:b40000, len:20000
..ranand_erase: start:b60000, len:20000
..ranand_erase: start:b80000, len:20000
..ranand_erase: start:ba0000, len:20000
..ranand_erase: start:bc0000, len:20000
..ranand_erase: start:be0000, len:20000
..ranand_erase: start:c00000, len:20000
..ranand_erase: start:c20000, len:20000
..ranand_erase: start:c40000, len:20000
..ranand_erase: start:c60000, len:20000
..ranand_erase: start:c80000, len:20000
..ranand_erase: start:ca0000, len:20000
..ranand_erase: start:cc0000, len:20000
..ranand_erase: start:ce0000, len:20000
..ranand_erase: start:d00000, len:20000
..ranand_erase: start:d20000, len:20000
..ranand_erase: start:d40000, len:20000
..ranand_erase: start:d60000, len:20000
..ranand_erase: start:d80000, len:20000
..ranand_erase: start:da0000, len:20000
..ranand_erase: start:dc0000, len:20000
..ranand_erase: start:de0000, len:20000
..ranand_erase: start:e00000, len:20000
..ranand_erase: start:e20000, len:20000
..ranand_erase: start:e40000, len:20000
..ranand_erase: start:e60000, len:20000
..ranand_erase: start:e80000, len:20000
..ranand_erase: start:ea0000, len:20000
..ranand_erase: start:ec0000, len:20000
..ranand_erase: start:ee0000, len:20000
..ranand_erase: start:f00000, len:20000
..ranand_erase: start:f20000, len:20000
..ranand_erase: start:f40000, len:20000
..ranand_erase: start:f60000, len:20000
..ranand_erase: start:f80000, len:20000
..ranand_erase: start:fa0000, len:20000
..ranand_erase: start:fc0000, len:20000
..ranand_erase: start:fe0000, len:20000
..ranand_erase: start:1000000, len:20000
..ranand_erase: start:1020000, len:20000
..ranand_erase: start:1040000, len:20000
..ranand_erase: start:1060000, len:20000
..ranand_erase: start:1080000, len:20000
..ranand_erase: start:10a0000, len:20000
..ranand_erase: start:10c0000, len:20000
..ranand_erase: start:10e0000, len:20000
..ranand_erase: start:1100000, len:20000
....ranand_erase: start:1120000, len:20000
.(5230)offs=17956864 piece=0 piece_size=19997 rc=0
Done!
Upgrade firmware from memory 0x89140000 to flash 0x02140000, file length 16535069, file type=1
ranand_erase: start:2140000, len:20000
..ranand_erase: start:2160000, len:20000
..ranand_erase: start:2180000, len:20000
..ranand_erase: start:21a0000, len:20000
..ranand_erase: start:21c0000, len:20000
..ranand_erase: start:21e0000, len:20000
..ranand_erase: start:2200000, len:20000
..ranand_erase: start:2220000, len:20000
..ranand_erase: start:2240000, len:20000
..ranand_erase: start:2260000, len:20000
..ranand_erase: start:2280000, len:20000
..ranand_erase: start:22a0000, len:20000
..ranand_erase: start:22c0000, len:20000
..ranand_erase: start:22e0000, len:20000
..ranand_erase: start:2300000, len:20000
..ranand_erase: start:2320000, len:20000
..ranand_erase: start:2340000, len:20000
..ranand_erase: start:2360000, len:20000
..ranand_erase: start:2380000, len:20000
..ranand_erase: start:23a0000, len:20000
..ranand_erase: start:23c0000, len:20000
..ranand_erase: start:23e0000, len:20000
..ranand_erase: start:2400000, len:20000
..ranand_erase: start:2420000, len:20000
..ranand_erase: start:2440000, len:20000
..ranand_erase: start:2460000, len:20000
..ranand_erase: start:2480000, len:20000
..ranand_erase: start:24a0000, len:20000
..ranand_erase: start:24c0000, len:20000
..ranand_erase: start:24e0000, len:20000
..ranand_erase: start:2500000, len:20000
..ranand_erase: start:2520000, len:20000
..ranand_erase: start:2540000, len:20000
..ranand_erase: start:2560000, len:20000
..ranand_erase: start:2580000, len:20000
..ranand_erase: start:25a0000, len:20000
..ranand_erase: start:25c0000, len:20000
..ranand_erase: start:25e0000, len:20000
..ranand_erase: start:2600000, len:20000
..ranand_erase: start:2620000, len:20000
..ranand_erase: start:2640000, len:20000
..ranand_erase: start:2660000, len:20000
..ranand_erase: start:2680000, len:20000
..ranand_erase: start:26a0000, len:20000
..ranand_erase: start:26c0000, len:20000
..ranand_erase: start:26e0000, len:20000
..ranand_erase: start:2700000, len:20000
..ranand_erase: start:2720000, len:20000
..ranand_erase: start:2740000, len:20000
..ranand_erase: start:2760000, len:20000
..ranand_erase: start:2780000, len:20000
..ranand_erase: start:27a0000, len:20000
..ranand_erase: start:27c0000, len:20000
..ranand_erase: start:27e0000, len:20000
..ranand_erase: start:2800000, len:20000
..ranand_erase: start:2820000, len:20000
..ranand_erase: start:2840000, len:20000
..ranand_erase: start:2860000, len:20000
..ranand_erase: start:2880000, len:20000
..ranand_erase: start:28a0000, len:20000
..ranand_erase: start:28c0000, len:20000
..ranand_erase: start:28e0000, len:20000
..ranand_erase: start:2900000, len:20000
..ranand_erase: start:2920000, len:20000
..ranand_erase: start:2940000, len:20000
..ranand_erase: start:2960000, len:20000
..ranand_erase: start:2980000, len:20000
..ranand_erase: start:29a0000, len:20000
..ranand_erase: start:29c0000, len:20000
..ranand_erase: start:29e0000, len:20000
..ranand_erase: start:2a00000, len:20000
..ranand_erase: start:2a20000, len:20000
..ranand_erase: start:2a40000, len:20000
..ranand_erase: start:2a60000, len:20000
..ranand_erase: start:2a80000, len:20000
..ranand_erase: start:2aa0000, len:20000
..ranand_erase: start:2ac0000, len:20000
..ranand_erase: start:2ae0000, len:20000
..ranand_erase: start:2b00000, len:20000
..ranand_erase: start:2b20000, len:20000
..ranand_erase: start:2b40000, len:20000
..ranand_erase: start:2b60000, len:20000
..ranand_erase: start:2b80000, len:20000
..ranand_erase: start:2ba0000, len:20000
..ranand_erase: start:2bc0000, len:20000
..ranand_erase: start:2be0000, len:20000
..ranand_erase: start:2c00000, len:20000
..ranand_erase: start:2c20000, len:20000
..ranand_erase: start:2c40000, len:20000
..ranand_erase: start:2c60000, len:20000
..ranand_erase: start:2c80000, len:20000
..ranand_erase: start:2ca0000, len:20000
..ranand_erase: start:2cc0000, len:20000
..ranand_erase: start:2ce0000, len:20000
..ranand_erase: start:2d00000, len:20000
..ranand_erase: start:2d20000, len:20000
..ranand_erase: start:2d40000, len:20000
..ranand_erase: start:2d60000, len:20000
..ranand_erase: start:2d80000, len:20000
..ranand_erase: start:2da0000, len:20000
..ranand_erase: start:2dc0000, len:20000
..ranand_erase: start:2de0000, len:20000
..ranand_erase: start:2e00000, len:20000
..ranand_erase: start:2e20000, len:20000
..ranand_erase: start:2e40000, len:20000
..ranand_erase: start:2e60000, len:20000
..ranand_erase: start:2e80000, len:20000
..ranand_erase: start:2ea0000, len:20000
..ranand_erase: start:2ec0000, len:20000
..ranand_erase: start:2ee0000, len:20000
..ranand_erase: start:2f00000, len:20000
..ranand_erase: start:2f20000, len:20000
..ranand_erase: start:2f40000, len:20000
..ranand_erase: start:2f60000, len:20000
..ranand_erase: start:2f80000, len:20000
..ranand_erase: start:2fa0000, len:20000
..ranand_erase: start:2fc0000, len:20000
..ranand_erase: start:2fe0000, len:20000
..ranand_erase: start:3000000, len:20000
..ranand_erase: start:3020000, len:20000
..ranand_erase: start:3040000, len:20000
..ranand_erase: start:3060000, len:20000
..ranand_erase: start:3080000, len:20000
..ranand_erase: start:30a0000, len:20000
..ranand_erase: start:30c0000, len:20000
..ranand_erase: start:30e0000, len:20000
....ranand_erase: start:3100000, len:20000
.(5230)offs=51380224 piece=0 piece_size=19997 rc=0
Done!
RAS upgrade done!
Upgrade firmware finished and please restart system !!
Then I could stop the zycast client (important, or it will continue to flash the router on every boot....), and reboot the NR7101 into OpenWrt.
Nice, eh?