New Xiaomi router AC2100


Did someone test if the BootRom DL Mode is disabled ?

The pppd binary, the (Not strictly necessary but nice to have), and the memory map that gets spit out to messages when you crash it with a normal payload of all 'A' in the registers. (Assuming the mappings are different)

First two you can extract from the squashfs ín the ubifs image (assuming you can get ubireader to work, I never could and just used Percy's dumps), last one you can get from the device logs (

There might be a little bit of messing around as I guessed the stack address by just going down by 0x200 until it landed somewhere in the nop sled.

I shouldn't have called it the AC2100 either, it's really the R2100 isn't it. Confusing model naming all round.

Yes, that's confusing. My ax3600 is also called R
3600. Could you please tell me how to confirm if this exploit is fixed in R3600? Unfortunately this is the only way which may get ssh access on 3600 now, because of the high price of a tosp-48 programer

  1. Opening up the pppd binary and uclibc one in a disassembler.
  2. Checking that this hasn't been implemented yet
  3. Checking that bcopy/memcpy/memmove does not call a FORTIFY_SOURCE version
  4. Checking that they are not position independent executables.
  5. Crying if you find out they actually did do it properly by virtue of using Qualcomm's BSP?
  1. That's strange. I can't find this eap_request function, also the string:EAP: trimming really long peer name down
  2. Moreover, R3600 use musl not uclibc, i don't know how to check FORTIFY_SOURCE calling
  3. Sadly, it is PIE.
    Maybe i can ready to cry?? :sob: :sob:

The `pppd` and `` file:

Yeah, they have stack guards on in there too.

At least Qualcomm have shown to have their BSP up to date on their flagship chipsets... :slight_smile: (The only reason it works on the ramips hardware is because they have pretty much every single mitigation turned off, no stack guards, no pie, rwx stacks, etc.)

current master compiled for ac2100:

There are a couple things that I see in your patch that would probably need to be changed before doing a pull request and getting it supported properly.

Most of it should be covered here

The stuff I spotted:
Do we need to rename the device? I'm not sure if we need a different DTS for the two devices since they're so very similar hardware wise. Probably just call the white one the RM2100 and the cylinder one R2100 like Xiaomi do? Check with one of the devs I guess

You have a duplicate DTS file that does nothing

Remember to preserve alphabetical order when you add the device to lists

memory@0 { device_type = "memory"; /*reg = <0x0 0x10000000>;256Mbyte*/ reg = <0x0 0x8000000>; };

I don't think this is needed anymore after

lan3_amber {
label = "ac2100:amber:lan3";
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;

            lan2_amber {
                    label = "ac2100:amber:lan2";
                    gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;

            lan1_amber {
                    label = "ac2100:amber:lan1";
                    gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;

I think these may require updates for DSA?

Eg. and

License needs to be added to the top of the dts

The comments in the dts might need to be moved to the commit message?

And uhh, instructions to flash for those who manage to get root on stock?

Edit: I wrote "the white one and the white one", that makes no sense. Derp.

Have you managed to test exploit from @namidairo ? If yes, what is the result? I would like to try but do not know where to start... @namidairo, can you help me to test exploit?

Nope and I don't think I can test it in the near future as I need the router ...

I changed the necessary parts for DSA. I will post the patches later. Timewise I am quite restricted in the next days. In case somebody wants to take care of an PR feel free to do with my patches as I don't know when I will be able to do it ...

@namidairo the reboot payload works fine on ac2100 (black cylinder) but shell doesn't open. Not sure if i'm doing something wrong, it doesn't seem to crash either. But I can't get the logs, the url you mentioned only gives a json response that logs are saved somewhere on the device?

It should give you a link to a tar.gz archive for you to download. The messages will be inside somewhere in the /data path on there. From what I've noticed, it don't spit out the mappings or useful information except when it sigsegv's.

As in you replaced stg3_SC with reboot_shell or you just uncommented the registers and return address I had commented out under "Debug Reboot"? And it actually rebooted?

If the former actually reboots, there's no reason why it shouldn't work. If it's the latter, then the addresses the modules are correct and maybe the last stack address I jump to is wrong?

I replaced stg3_SC with reboot_shell and it reboots, can see it happen on the serial console. For the shell i have nc -lvp 31337 running on a client with ip on a lan port but nothing happens. I don't have a fully working pppoe-server setup but it seems sufficient to initiate a connection without establishing it.

Can't believe i didn't even try to download the logs, assuming it was just on the device not accessible by the webserver. I don't think it segfaults as i still see pppoe traffic in wireshark but who knows, it may get restarted. I'll spend some more time on it after the weekend.

DSA & kernel 5.4 on ramips sounds like a total cluster$%^& at the moment with many devices not booting.

Maybe give it a while before uploading any images based on 5.4 you aren't certain actually boots...

That and the instructions for flashing these devices in the commit message are going to be as long as my arm.

The device boots perfectly with the image I made. There may be some gpio things that are not perfectly implemented, but as far as I can tell the device runs smoothly and everything seems to work.

Regarding the the flashing instructions you are totally right. I think we have to wait a bit to get a good working method without NAND soldering external flashing etc. and describe it properly.

added to my GitHub:

by the way:
I changed the patch to address most of the changes you suggested.

The instructions once you get root and bring the files over should be the sameish as the mir3g instructions. Ie.

mtd write rm2100-squashfs-kernel1.bin kernel1
mtd write rm2100-squashfs-rootfs0.bin rootfs0
nvram set flag_try_sys1_failed=1
nvram commit

Well there's a decent amount of room for the payload in the exploit. One could somewhat easily change it to curl busybox off your pc, chmod a+x it, and startup telnetd all in one go. It was just that a reverse connect shell was easily available at the time. I'd imagine it would be something along the lines of

lui/ori $t0 half words to make up the parameters
sw $t0,offset $sp 
move $a0, $sp
lui/ori $t9 half words that make up the system() address
jalr $t9

Then rinse and repeat for each command

Although come to think of it, people probably shouldn't use these devices with PPPoE if they don't trust their ISP...

We're probably okay in terms of brick protection, as the stock kernel will still let you tftp over a signed stock image, but I'm not too sure how that's triggered and whether it works after setting flag_try_sys1_failed in order to boot OpenWRT. Does the device uboot just boot kernel0 to do recovery when you hold reset on boot or does one need working uart in order to flip the flag back first?


hold reset and power on will trigger router entering recovery mode. in recovery mode, router try to get ip and boot image from bootp server. preparing stock firmware and a bootp server will help you to de-brick the router.
Xiaomi even offers a recovery tool which runs on Windows. So you only need to download the recovery tool and stock firmware. However, I remember that recovery tool comes with Chinese user interface.

1 Like

i need help.

I buy one AC2100, but i try to make a login in a website of the router, and i dont no the password to login,


Can confirm the exploit by @namidairo works on ac2100!

It sometimes takes a couple of retries before it works but i just run the script in a loop which also works well to restart it when the shell gets killed. Sometimes after mere seconds other times it seems to keep running forever.