New Xiaomi Router AC2100

as soon as mine will arrive I can help testing things!

The settings backup is a tar.gz with two files, cfg_backup.mbu and cfg_backup.des. The des file contains a json string describing which info is in the backup. The mbu file is binary, seems encrypted and only applicable on device with the same serial i would guess.

The web interface doesn't leave much room for exploiting it, they've already patched the known holes. There're not many ways to interact with it, just some wifi and timezone settings. Lots of different json api endpoints you can get info from, but not post. I did just discover it has a different init.html page after a factory reset, to set it up if you don't use the app. I'm going to try poking at that next.

I've not been able to extract all contents of the factory firmware yet. Especially the ubifs is a problem. If someone can upload it somewhere (or point me to a working version of binwalk) that would be very much appreciated.

Ok, so I managed to access the console by changing the bootdelay and fixing the ECC data. I found the official tool to generate the ECC data in the Mediatek APSoC SDK. If your data is the same as mine you can just use my calculated ECC else you have to find the SDK on your own or contact me.

Modified bootdelay with matching ECC

I think this might help:

python Nand-dump-tool.py -i ac2100.bin -o ac2100_clean.bin -I C8D18095 #https://github.com/Hitsxx/NandTool to remove ECC data
binwalk -Me ac2100_clean.bin
cd _ac2100_clean.bin.extracted
ubireader_extract_images A00000.ubi #https://github.com/jrspruitt/ubi_reader to extract ubi image
binwalk -Me ubifs-root/A00000.ubi/img-1106443240_vol-ubi_rootfs.ubifs
1 Like

Can you recommend a (cheap) Nand programmer?

What about the BOOTP, anyone tried it already?

Really depends. You could go the ultra cheap route and use a Teensy + TSOP48 socket for about 10€ together.

But its more of a DIY solution

If you have a bigger budget or think that you someday might need a programmer for something else you could go with a Tl866ii which supports a lot of different chips and has better software.

Thanks! I go the cheap way :smiley:
The router shipment will take longer anyway - so I will get the programmer parts from china.
Maybe you guys find a way how to bypass the manual programing before it arrives, if not I will give it a try.

Still waiting for my Tl866ii and teensy got delayed with the Year of the Rat..

Here is what I extracted (for the rm2100)

Would you mind sharing the the config files?

Config file:

I tried to upload initframs image from mir3g. It failed because router is checking uploaded image.

TRX MAGIC error!
Header check error!
Image verify failed!

Bootp failed log

#Reset_MT7530
set LAN/WAN WLLLL

NetTxPacket = 0x87FE4200

KSEG1ADDR(NetTxPacket) = 0xA7FE4200

NetLoop,call eth_halt !

NetLoop,call eth_init !
Trying Eth0 (10/100-M)

Waitting for RX_DMA_BUSY status Start... done

ETH_STATE_ACTIVE!!
BOOTP broadcast 1

NetOurIP

NetOurIP
BOOTP broadcast 2
DHCPHandler: got packet: (src=67, dst=68, len=300) state: 3
Filtering pkt = 0
DHCPHandler: got DHCP packet: (src=67, dst=68, len=300) state: 3
DHCP: state=SELECTING bp_file: "miwifi.bin"
TRANSITIONING TO REQUESTING STATE
*** Unhandled DHCP Option in OFFER/ACK: 28
Bootfile: miwifi.bin
DhcpSendRequestPkt: Sending DHCPREQUEST
Transmitting DHCPREQUEST packet: len = 343
DHCPHandler: got packet: (src=67, dst=68, len=300) state: 4
Filtering pkt = 0
DHCPHandler: got DHCP packet: (src=67, dst=68, len=300) state: 4
DHCP State: REQUESTING
*** Unhandled DHCP Option in OFFER/ACK: 28
Bootfile: miwifi.bin
DHCP client bound to address 192.168.1.50
TFTP from server 192.168.1.2; our IP address is 192.168.1.50
Filename 'miwifi.bin'.

TIMEOUT_COUNT=10,Load address: 0x82000000
Loading: Got ARP REPLY, set server/gtwy eth addr (00:27:13:69:06:04)
Got it
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########################################
done
Bytes transferred = 3540915 (3607b3 hex)
LoadAddr=82000000 NetBootFileXferSize= 003607b3
TRX MAGIC error!
Header check error!
Image verify failed!
========Upgrade fail!========

Bootp factory fimware uploading is working.

Factory firmware bootp log

#Reset_MT7530
set LAN/WAN WLLLL

NetTxPacket = 0x87FE4200

KSEG1ADDR(NetTxPacket) = 0xA7FE4200

NetLoop,call eth_halt !

NetLoop,call eth_init !
Trying Eth0 (10/100-M)

Waitting for RX_DMA_BUSY status Start... done

ETH_STATE_ACTIVE!!
BOOTP broadcast 1

NetOurIP
BOOTP broadcast 2

NetOurIP

NetOurIP
BOOTP broadcast 3
DHCPHandler: got packet: (src=67, dst=68, len=300) state: 3
Filtering pkt = 0
DHCPHandler: got DHCP packet: (src=67, dst=68, len=300) state: 3
DHCP: state=SELECTING bp_file: "miwifi.bin"
TRANSITIONING TO REQUESTING STATE
*** Unhandled DHCP Option in OFFER/ACK: 28
Bootfile: miwifi.bin
DhcpSendRequestPkt: Sending DHCPREQUEST
Transmitting DHCPREQUEST packet: len = 343
DHCPHandler: got packet: (src=67, dst=68, len=300) state: 4
Filtering pkt = 0
DHCPHandler: got DHCP packet: (src=67, dst=68, len=300) state: 4
DHCP State: REQUESTING
*** Unhandled DHCP Option in OFFER/ACK: 28
Bootfile: miwifi.bin
DHCP client bound to address 192.168.1.50
TFTP from server 192.168.1.2; our IP address is 192.168.1.50
Filename 'miwifi.bin'.

TIMEOUT_COUNT=10,Load address: 0x82000000
Loading: Got ARP REPLY, set server/gtwy eth addr (00:27:13:69:06:04)
Got it
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
######################################################Got ARP REQUEST, return our IP
###########
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#############################################################
done
Bytes transferred = 17284660 (107be34 hex)
LoadAddr=82000000 NetBootFileXferSize= 0107be34
CRC verify success!
RSA signature verify success!
..ranand_erase: start:80000, len:20000
..Done!
done
Upgrade xiaoqiang_version...
Upgrade uImage.bin...
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: 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
.(5192)offs=5373952 piece=0 piece_size=113231 rc=0
Done!
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
.(5192)offs=9568256 piece=0 piece_size=113231 rc=0
Done!
proc_xqimage.c xqimage_upgrade 526 start:0x820002a4,subh->flash_addr:0xffffffff,len:0x33ba4f
Upgrade root.ubi...
ranand_erase: start:a00000, len:3400000
................................................................................................................................................................................................................................................................................................................................................................................................................................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
..ranand_erase: start:1140000, len:20000
..ranand_erase: start:1160000, len:20000
..ranand_erase: start:1180000, len:20000
..ranand_erase: start:11a0000, len:20000
..ranand_erase: start:11c0000, len:20000
..ranand_erase: start:11e0000, len:20000
..ranand_erase: start:1200000, len:20000
..ranand_erase: start:1220000, len:20000
..ranand_erase: start:1240000, len:20000
..ranand_erase: start:1260000, len:20000
..ranand_erase: start:1280000, len:20000
..ranand_erase: start:12a0000, len:20000
..ranand_erase: start:12c0000, len:20000
..ranand_erase: start:12e0000, len:20000
..ranand_erase: start:1300000, len:20000
..ranand_erase: start:1320000, len:20000
..ranand_erase: start:1340000, len:20000
..ranand_erase: start:1360000, len:20000
..ranand_erase: start:1380000, len:20000
..ranand_erase: start:13a0000, len:20000
..ranand_erase: start:13c0000, len:20000
..ranand_erase: start:13e0000, len:20000
..ranand_erase: start:1400000, len:20000
..ranand_erase: start:1420000, len:20000
..ranand_erase: start:1440000, len:20000
..ranand_erase: start:1460000, len:20000
..ranand_erase: start:1480000, len:20000
..ranand_erase: start:14a0000, len:20000
..ranand_erase: start:14c0000, len:20000
..ranand_erase: start:14e0000, len:20000
..ranand_erase: start:1500000, len:20000
..ranand_erase: start:1520000, len:20000
..ranand_erase: start:1540000, len:20000
..ranand_erase: start:1560000, len:20000
..ranand_erase: start:1580000, len:20000
..ranand_erase: start:15a0000, len:20000
..ranand_erase: start:15c0000, len:20000
..ranand_erase: start:15e0000, len:20000
..ranand_erase: start:1600000, len:20000
..ranand_erase: start:1620000, len:20000
..ranand_erase: start:1640000, len:20000
..ranand_erase: start:1660000, len:20000
..ranand_erase: start:1680000, len:20000
..ranand_erase: start:16a0000, len:20000
..ranand_erase: start:16c0000, len:20000
..ranand_erase: start:16e0000, len:20000
..ranand_erase: start:1700000, len:20000
..ranand_erase: start:1720000, len:20000
..Done!
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
..ranand_erase: start:3120000, len:20000
..Done!
proc_xqimage.c xqimage_upgrade 526 start:0x8233bd24,subh->flash_addr:0xffffffff,len:0xd40000
..ranand_erase: start:80000, len:20000
..Done!
done
========Upgrade success!========
..ranand_erase: start:80000, len:20000
..Done!
done

1 Like

would be interesting to see what happens if you exchange the header of the 3g with the one for the ac2100.

It doesn't work. Even one bit change in factory firmware stops upgrade. After downloading image from bootp router checks CRC and RSA signature of the image.

1 Like

Did you manage to install OpenWrt after the modification?

I never compiled OpenWrt for a new device, so I concentrated on searching possible exploits. If you have any tips on how I might reuse some existing configs, so I don't have to start from scratch I'm thankful for suggestions.

Honestly I am not experienced at all when it comes to add support for a new device.
It might be good to use the Xiaomi 3Pro config as a base, it is very similar regarding the hardware (CPU and wireless).

I am counting on your exploits searching skills - would be nice to avoid the nand flashing! :smiley: fingers crossed!

@Percy

i did the port for the xiaomi router 3 pro (MIR3P).... it was the first time for me too...
it's actually quite easy. you need to have some understanding about what all that stuff is all about, but most of it (especially at the beginning) can be copy+paste...

look through the git log to see the PR where mir3p support was added... then look at the diffs that i had to put in (i think there was a follow-on push and some other stuff in the .dts file changed... so might as well start with the current .dts and modify that)...

there's also a page somewhere on the openwrt site about porting new devices... it's helpful.

the most important thing is: setup a tftp server and just tftp-boot your test images (the on that's called initramfs.bin ... that way you're not constantly writing to your NAND and you're just a reboot away from sanity in case something goes wrong :wink:

PM me if there are any particular questions you have... i probably don't know every answer, but i'll try to help.

1 Like

There may be some potential exploiting dnsmasq. From what i can tell it runs 2.71 which contains some bugs (see https://security.googleblog.com/2017/10/behind-masq-yet-more-dns-and-dhcp.html), though i didn't succeed in making it crash using the PoC code. Perhaps the mips executable isn't susceptible.
Even if it would work, someone would still have to craft some MIPS assembler to i.e. modify nvram or open a shell which is far beyond my experience.

1 Like

did you try this one:

Nice find but it doesn't support MIPS architecture

damn should have read it properly before ... :crazy_face: