would be also interested in this and how the injection would work - command wise ...
Its going to be a bit harder to find injection weakpoints, as they use custom compiled lua code, instead of the old lua scripts. They seem to also use a custom luaL_loadfile
implementation to load them and switch some bytes. Need to dig into it deeper.
But, it looks like if a ota firmware fails for some reason, console access can be enabled, with some button test points. Gotta dive into the binaries and look deeper - need to dig deeper!
/lib/preinit/31_restore_nvram
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: squashfs-root/lib/preinit/31_restore_nvram
───────┼────────────────────────────────────────────────────────
1 │ #!/bin/sh
2 │
3 │ . /lib/functions.sh
4 │
5 │ xqdefaults="/usr/share/xiaoqiang/xiaoqiang-defaults.txt"
6 │ hwv="`/sbin/hwversion`"
7 │ do_xiaoqiang_defaults() {
8 │ cat "${xqdefaults}" | while read line
9 │ do
10 │ nvram set "$line"
11 │ done
12 │ }
13 │
14 │
15 │ do_nvram_corrupt() {
16 │ cat "${xqdefaults}" | while read line
17 │ do
18 │ nvram set "$line"
19 │ done
20 │ }
21 │
22 │ do_flag_override() {
23 │ local flag="$1"
24 │ b_val=`bdata get $flag`
25 │ n_val=`nvram get $flag`
26 │ [ "$b_val" = "$n_val" ] && return 0
27 │ [ "$b_val" = "1" ] && nvram set "$flag"=1
28 │ }
29 │
30 │ flag_override() {
31 │ do_flag_override uart_en
32 │ do_flag_override ssh_en
33 │ do_flag_override telnet_en
34 │ do_flag_override boot_wait
35 │ }
36 │
37 │ do_set_default_ssid() {
38 │ num=`nvram get wl1_ssid | cut -b 7-10`
39 │ temp=0x"$num"
40 │ newnum="000"`printf "%x\n" $((0xffff-$temp))`
41 │ pos=`expr length $newnum - 4`
42 │ newnum=`echo ${newnum:$pos:4} | tr [a-z] [A-Z]`
43 │ ssid2G=`nvram get wl1_ssid`
44 │ result2G=`echo $ssid2G"_"$newnum`
45 │ nvram set wl1_ssid=$result2G
46 │
47 │ has5G=`uci get misc.wireless.if_5G 2>/dev/null`
48 │
49 │ # D01 2/5G same ssid
50 │ suf="_5G"
51 │ model="`cat /proc/xiaoqiang/model`"
52 │ [ "$model" = "D01" ] && {
53 │ suf=""
54 │ }
55 │
56 │ if [ -n "$has5G" ]; then
57 │ ssid5G=`nvram get wl0_ssid | cut -b -10`
58 │ result5G=`echo ${ssid5G}"_"${newnum}${suf}`
59 │ nvram set wl0_ssid=$result5G
60 │ fi
61 │ }
62 │
63 │
64 │ restore_nvram () {
65 │ restore=`nvram get restore_defaults`
66 │ if [ "$restore" = "1" ]; then
67 │ flag_name=`uci get misc.mount_bind_etc.flag_name`
68 │ nvram set $flag_name=1
69 │ mtd erase overlay
70 │ rec_mtd=$(find_mtd_part cfg_bak)
71 │ [ -n "$rec_mtd" ] && mtd erase cfg_bak
72 │ fi
73 │
74 │ ft_mode=`cat /proc/xiaoqiang/ft_mode`
75 │ if [ "$ft_mode" != "1" ]; then
76 │ sn=`nvram get SN`
77 │ wl1_ssid=`nvram get wl1_ssid`
78 │ countrycode=`nvram get CountryCode`
79 │ if [ -z "$sn" -o -z "$wl1_ssid" -o -z "$countrycode" ]; then
80 │ nvram_corrupt=1
81 │ fi
82 │ fi
83 │
84 │ # skip restore wifi radio flag from defaults if factory mode
85 │ if [ "$ft_mode" = "1" ]; then
86 │ wl1_val=`nvram get wl1_radio`
87 │ wl0_val=`nvram get wl0_radio`
88 │ fi
89 │
90 │ #restore: 1, 恢复出厂设置;2,ota升级
91 │ #nvram_corrupt: 1, nvram被破坏
92 │ if [ "$nvram_corrupt" = "1" ]; then
93 │ do_nvram_corrupt
94 │ bdata sync
95 │ nvram set nvram_corrupt=1
96 │ fi
97 │
98 │ # restore to factory setting
99 │ if [ "$restore" = "1" ]; then
100 │ nvram unset nvram_corrupt
101 │ nvram clear /usr/share/xiaoqiang/xiaoqiang-reserved.txt
102 │ do_xiaoqiang_defaults
103 │ bdata sync
104 │ do_set_default_ssid
105 │ fi
106 │
107 │ # OTA upgrade
108 │ if [ "$restore" = "2" ]; then
109 │ do_xiaoqiang_defaults
110 │ flag_override
111 │ fi
112 │
113 │ if [ "$ft_mode" = "1" ]; then
114 │ [ "$wl1_val" != "" -a -n "$wl1_val" ] && nvram set wl1_radio=$wl1_val
115 │ [ "$wl0_val" != "" -a -n "$wl0_val" ] && nvram set wl0_radio=$wl0_val
116 │ fi
117 │
118 │ nvram commit
119 │ }
120 │
121 │ boot_hook_add preinit_main restore_nvram
───────┴────────────────────────────────────────────────────────
I think if this script is run, and 5G SSID is set to
something123 ; telnetd ; something456
there is a chance that telnetd could be executed
that seems pretty promising to me too. also more user-friendly than physically changing the bits on NAND.
i guess the question is "what is the default action?" to tftp-boot or to flash-from-tftp as in:
Please choose the operation:
1: Load system code to SDRAM via TFTP.
2: Load system code then write to Flash via TFTP.
if i were designing it, i'd probably have "option 1" be the default. (but then... who knows what sicks minds are out there).
given that this is a MT7621 with 128MB RAM and 128MB NAND, i'd probably try the initramfs.bin
for the MIR3Gv2 for starters (it might keel over, it might not. i bet it will boot and get to the point where it starts probing for the SPI ;)). but porting this should be a real breeze. the real question is whether the "holding reset while booting" is going to work or not.
anyone feeling up to try this? (looks like we'll need to configure bootp+tftp server... not rocket science). i know at least some of you out there have openwrt routers
https://wiki.commotionwireless.net/doku.php/development_resources/router/tftp_bootp_server_setup
FWIW, here's (apparently) what worked for MIR3
* http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/web/home#router
* http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/xqnetwork/set_wifi_ap?ssid=Xiaomi&encryption=NONE&enctype=NONE&channel=1%3Bnvram%20set%20ssh%5Fen%3D1%3B%20nvram%20commit
* http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/xqnetwork/set_wifi_ap?ssid=Xiaomi&encryption=NONE&enctype=NONE&channel=1%3Bsed%20%2Di%20%22%3Ax%3AN%3As%2Fif%20%5C%5B%2E%2A%5C%3B%20then%5Cn%2E%2Areturn%200%5Cn%2E%2Afi%2F%23tb%2F%3Bb%20x%22%20%2Fetc%2Finit.d%2Fdropbear
* http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/xqnetwork/set_wifi_ap?ssid=Xiaomi&encryption=NONE&enctype=NONE&channel=1%3B%2Fetc%2Finit.d%2Fdropbear%20start
* http://192.168.31.1/cgi-bin/luci/;stok=<STOK>/api/xqsystem/set_name_password?oldPwd=<OLD_PASSWORD>&newPwd=<NEW_PASSWORD>
as a guy who discovered another xiaomi device a few days ago (miwifi mesh), i can say that probably no telnetd is available inside the stock firmware
telnetd busybox applet for my device never run, no matter which value telnet_en 0 or 1, it just start and exit, probably telnet code replaced with dummy {} to prevent any kind of enabling it.
also no dropbear included in "stable" firmware usually, so uart is a single way to access device from inside, but as transmit to router disabled by default, you need to force it into tftp recovery mode using reset buttons and interrupt first boot at u-boot, enable uart_en, boot to stock firmware and modify any startup script to set uart_en to 1 at every boot (for example you can use /etc/rc.local)
to get a working telnetd, you need standalone static busybox binary with telnetd compiled for your target arch
nice!
i was just looking at the "miwifi mesh" forum, and i saw that you had managed to tftp boot but it wasn't clear what you were doing... it looks like you tftp booted the official firmware (and that did a lot of stuff) but it also looked like you tftp booted random initramfs images?
i'm asking because if you were able to boot initramfs images (ie, not only xiaomi-signed/verified binaries) then this should be a breeze.
as i said before, tftp recovery mode was required to get uart trasmit access (it enabled only first time after recovery), so after ive got working serial, ive booted initramfs images using bootp/bootm commands, no image signing required
I've managed to flash the factory firmware using tftp but still unable to do anything at the uboot prompt at first boot
And you still cant access command prompt at first boot after recovery?
I "binwalked" through the firmwareupdate file for the router and there is at least a link from telnetd to busybox:
thorsten@vsdaads:~/MOD/_miwifi_r2100_firmware_64288_2.0.376.bin.extracted/_2E4.extracted/_594080.extracted/cpio-root/usr/sbin$ ls -lh
total 1.6M
lrwxrwxrwx 1 thorsten thorsten 17 Jan 29 00:12 brctl -> ../../bin/busybox
-rwxrwxr-x 1 thorsten thorsten 4.2K Jan 29 00:12 btnd
lrwxrwxrwx 1 thorsten thorsten 17 Jan 29 00:12 dnsd -> ../../bin/busybox
-rwxrwxr-x 1 thorsten thorsten 594K Jan 29 00:12 hexdump
lrwxrwxrwx 1 thorsten thorsten 17 Jan 29 00:12 httpd -> ../../bin/busybox
-rwxr-xr-x 1 thorsten thorsten 883K Jan 29 00:12 mkxqimage
-rwxrwxr-x 1 thorsten thorsten 11K Jan 29 00:12 mtd
-rwxrwxr-x 1 thorsten thorsten 35K Jan 29 00:12 nanddump
-rwxr-xr-x 1 thorsten thorsten 7.5K Jan 29 00:12 nvram
-rwxr-xr-x 1 thorsten thorsten 4.0K Jan 29 00:12 rd
lrwxrwxrwx 1 thorsten thorsten 17 Jan 29 00:12 telnetd -> ../../bin/busybox
-rwxrwxr-x 1 thorsten thorsten 16K Jan 29 00:12 ubiattach
-rwxrwxr-x 1 thorsten thorsten 47K Jan 29 00:12 ubiformat
lrwxrwxrwx 1 thorsten thorsten 17 Jan 29 00:12 udhcpd -> ../../bin/busybox
-rwxr-xr-x 1 thorsten thorsten 691 Jan 29 00:12 xqled
My device also had it, but it was dummy
maybe stupid question, but can we alter the firmware in a way and install it, how is this verification / signing working?
We need a private key to sign, but firmware contains only public
I see
The update process finishes and when i reapply power it boots as normal with commandline uart_en=0 factory_mode=0
try to press enter
very fast several times right after applying power after recovery
Upd, its an mt762x, so press 4 instead of enter
Tried a couple of times, it zooms past the uboot menu so no time to press anything, the delay must be disabled.
Maybe is it possible to backup and restore config in factory firmware?
If backup is not signed nor encrypted, we could try to play with it
Anyone already succeeded in dumping the nand and modifying the bootdelay? I already tried it multiple times without luck. But I just realized that changing the bootdelay would mess up the ECC data of the nand. Anyone got experience how to calculate ECC data for MT7621 chips?
After every 512 bytes of data there are 16 bytes of ECC of which only 52 bits are changing. This plus the ECC requirement of 4bit/528Byte for the nand led me to believe it is a BCH code with m=13 and 4bit correction similar(but not compatible) to this: https://github.com/ak-hard/brcm-nand-bch.