吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18942|回复: 174
上一主题 下一主题
收起左侧

[Web逆向] 新小米路由器 登录算法详解

    [复制链接]
跳转到指定楼层
楼主
330wang 发表于 2023-9-11 10:28 回帖奖励
本帖最后由 330wang 于 2023-9-11 10:48 编辑

0x00 从代码失效说起

小米路由器7000开售(202359日开售)以后入手了一个路由器,但是问题来了,之前的python登录代码失效了,搜遍了全网,找到的都是旧的登录代码(采用sha1运算)。于是乎,就有了这篇文章。
0x01 登录路由前的准备工作
先用电脑通过无线或有线的方式连接上小米路由器,具体怎么连接,这里不多介绍。电脑连接上路由后需要获取网关的地址(也就是说路由器的地址),用下面的命令:ipconfig,如下图所示:

1 获取电脑的默认网关

打开浏览器的调试模式(即按下键盘的F12,和浏览器无关,现在常用的浏览器都是用F12键打开调试模式),并在浏览器的地址栏中输入网关的地址(192.168.1.1),然后跟踪后续的流量,如图2所示:

2 地址栏输入网关后续有22个请求,最后定格到当前界面



可以看到,地址栏输入网关后回车,后续有22个请求。最后定格在http://192.168.1.1/cgi-bin/luci/web在这个界面输入后台管理密码后就可以对路由器进行配置管理、查看相关的信息等操作。在输入密码之前依次点击每一个请求,看看每个请求都是干什么用的。点完后可以看出例如.css是控制样式和布局用的,如图3所示:


3 双击第二个请求,显示的结果



其他的请求就不一一点击了,只需要知道的是,现在还没有输入后台的管理密码。下面重点关注一下图2中划圈的两个请求。.css负责界面和布局,一般不用分析,.js文件是相应的后台代码,某些文件需要着重分析。

4 http://192.168.1.1/cgi-bin/luci/web



5 http://192.168.1.1/cgi-bin/luci/api/xqsystem/init_info
以上是输入网关后得到的一些基本信息,而且图4和图5两个地址可以直接访问,也就是说在地址栏输入相应的地址就能返回如上图所示的内容。这些内容有什么用呢?对于图5来说,只需要在地址栏输入一个固定的请求,路由器就能返回诸如路由器的名称、ID路由ID、硬件版本、路由器的显示名称、语言包以及是否启用新加密模式(newEncryptMode)等重要信息。这个新加密模式后面再说,先埋个坑。

0x02 输入密码登录路由管理界面



关闭之前的页面,重新打开浏览器并在地址栏输入http://192.168.1.1/cgi-bin/luci/web,同时启用调试模式。输入路由器管理密码后点向右的箭头,登录路由器的后台,同时跟踪后续的各个请求,如下图所示:

6 输入密码后的管理界面



可以看到,从输入密码到登录到当前的管理界面一共有46个请求。先看第一个重要的请求,如图7所示:


7 POST请求




8 请求的表单数据


9 请求后的响应数据

综合图7、图8、图9得知:登录消息头标签告诉我们登录采用的请求:POST登录消息头标签告诉我们登录的网址:http://192.168.1.1/cgi-bin/luci/api/xqsystem/login登录消息头标签告诉我们请求头:可以参考截图上的内容填写登录请求标签的表单数据为:
[Asm] 纯文本查看 复制代码
1
2
3
username        "admin"
password        "6e7ba276d4b12533cb9b08e6013bd1dd012243fa09b094e915342cd0ff2eb5f3"logtype        "2"
nonce        "0_aa:af:b2:e0:e5:bf_1693890128_7030"
登录成功后的响应数据为:
[Asm] 纯文本查看 复制代码
1
2
3
url        "/cgi-bin/luci/;stok=286e314fb8233c6ff8d0cb1dbd3b4643/web/home"
token        "286e314fb8233c6ff8d0cb1dbd3b4643"
code        0
通过上面的分析知道,小米路由器验证密码后才能登录进管理界面,但是注意一下表单数据,我在登录界面输入的密码是test1234,很显然,返给路由器的并不是明文的密码,而是经过变换以后的字符串。再重新输入一个错误的登录密码,重复上面的步骤,例如,密码为330wang,这时请求标签的表单数据为:
[Asm] 纯文本查看 复制代码
1
2
3
4
username        "admin"
password        "2fd4eff94de247b5f59c150ca53293cc69df2c0d59d71cbc862cdd3a969e5d38"
logtype        "2"
nonce        "0_aa:af:b2:e0:e5:bf_1693896342_3009"
输入错误密码后的响应标签数据为:
[Asm] 纯文本查看 复制代码
1
2
code        401
msg        "not auth"
后续的各个操作需要在地址栏中附加密码正确后响应数据中的token。如图9所示。这个token是正确登录的标志,只要浏览器不关闭,都可以用这个token对路由器进行访问,可以对路由进行配置也可以读取路由器中的参数等。如果密码输入错误,响应数据不会返回token字段,只会返回“not match”的消息,也就没有后面的操作了。


0x03 表单数据的生成



通过上面的分析我们知道,要想对路由器进行后面的操作,例如读取配置WiFi信息、读取配置连网方式、设置IP地址等操作都需要正确的token,而token的产生是和password字段相关的。password字段与输入的路由器管理密码有直接的关系。如果想通过单纯在POST请求登录的话,一定要知道输入的路由器管理密码是怎么生成password的。通过图7我们知道,这个POST请求的上一个网页是http://192.168.1.1/cgi-bin/luci/web,现在就从这个网页入手,看看能不能得到相关的生成规则。在浏览器的地址栏中输入http://192.168.1.1/cgi-bin/luci/web,并按F12,打开调试模式,同时点击查看器标签,查看这个网页的源代码,如图10 所示:

10 查看/cgi-bin/luci/web的源代码



这里是此页面的源代码,包含普通的html代码、相关的css代码以及相应的js代码。可以看出,除了html外,其他代码都是折叠结构,可以在代码中用鼠标定位到相关的元素中,这里不多说了,也不是重点。在这个界面可以很方便地了解网页的布局。下面切换到调试器标签下,在这里详细地调试密码的生成过程。因为根据输入的管理密码生成了表单数据中的password,所以鼠标在调试器的代码位置点一下,使光标位于调试器下的源代码框中,然后按键盘的Ctrl+F弹出搜索框,在搜索框中输入要搜索的字符串password”,如图11所示,可以看到一共有29个搜索结果:


11 调试器代码中搜索password



按向下的箭头查看每一个可能的数据,直到定位到如图12所示的位置:


12 找到相关的位置



可以看到表单数据中的参数一共有4个,分别是usernamepasswordlogtypenonce前三个参数比较好理解,但是nonce是干什么用的呢?
Nonce,Number used once或Number once的缩写,在密码学中Nonce是一个只被使用一次的任意或非重复的随机数值,在加密技术中的初始向量和加密散列函数都发挥着重要作用,在各类验证协议的通信应用中确保验证信息不被重复使用以对抗重放攻击(Replay Attack)。在信息安全中,Nonce是一个在加密通信只能使用一次的数字。在认证协议中,它往往是一个随机伪随机数,以避免重放攻击Nonce也用于流密码以确保安全。如果需要使用相同的密钥加密一个以上的消息,就需要Nonce来确保不同的消息与该密钥加密的密钥流不同。
-- 以上信息来源于baidu百科:https://baike.baidu.com/item/Nonce/2525414



路由器web页面的中相关函数如下所示:   

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
function loginHandle ( e ) {
        e.preventDefault();
        var formObj = document.rtloginform;
        var pwd = $( '#password' ).val();       //取输入的密码,并放到pwd变量中
        if ( pwd == '') {
            return;
        }
        var nonce = Encrypt.init();         //nonce:Enctypt.init()函数生成
        var oldPwd = Encrypt.oldPwd( pwd ); //oldPwd:Encrypt.oldPwd(pwd)生成
        var param = {
            username: 'admin',
            password: oldPwd,
            logtype: 2,
            nonce: nonce
        };
        $.pub('loading:start');
        var url = '/cgi-bin/luci/api/xqsystem/login';
            $.post( url, param, function( rsp ) {       //执行POST请求
                $.pub('loading:stop');
              ......



具体解释请看每行代码 //后面的注释。通过上面的代码,可以看到最终POST4个参数的生成方式。
其中username参数为固定值:adminpassword参数为输入的管理密码由Encrypt.oldPwd()运算产生;logtype参数为固定值:2nonce参数由Encrypt.init()产生。下面定位到Encrypt函数,看一看这几个值是怎么产生的,方法是在搜索框中搜索字符串“Encrypt”,如图13所示:


13 Encrypt函数


Encrypt函数如下所示:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
var Encrypt = {
        key: 'a2ffa5c9be07488bbb04a3a47d3c5f6a',
        iv: '64175472480004614961023454661220',
        nonce: null,
        init: function () {  //nonce的产生代码
            var nonce = this.nonceCreat();
            this.nonce = nonce;
            return this.nonce;
        },
        nonceCreat: function () {
            var type = 0;
            var deviceId = 'aa:af:b2:e0:e5:bf';
            var time = Math.floor(new Date().getTime() / 1000);
            var random = Math.floor(Math.random() * 10000);
            return [type, deviceId, time, random].join('_');
        },
        oldPwd: function (pwd) {  //oldPwd代码
            if(newEncryptMode == 1){
                return CryptoJS.SHA256(this.nonce + CryptoJS.SHA256(pwd + this.key).toString()).toString();
            }else{
                return CryptoJS.SHA1(this.nonce + CryptoJS.SHA1(pwd + this.key).toString()).toString();
            }
 
        },
        newPwd: function (pwd, newpwd) {
            var key = CryptoJS.SHA1(pwd + this.key).toString();
            var password = CryptoJS.SHA1(newpwd + this.key).toString();
 
            key = CryptoJS.enc.Hex.parse(key).toString();
            key = key.substr(0, 32);
            key = CryptoJS.enc.Hex.parse(key);
            var iv = CryptoJS.enc.Hex.parse(this.iv);
            var aes = CryptoJS.AES.encrypt(
                password,
                key,
                {iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}
            ).toString();
            return aes;
        },
        newPwd256: function (pwd, newpwd) {
            var key = CryptoJS.SHA256(pwd + this.key).toString();
            var password = CryptoJS.SHA256(newpwd + this.key).toString();
 
            key = CryptoJS.enc.Hex.parse(key).toString();
            key = key.substr(0, 32);
            key = CryptoJS.enc.Hex.parse(key);
            var iv = CryptoJS.enc.Hex.parse(this.iv);
            var aes = CryptoJS.AES.encrypt(
                password,
                key,
                {iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7}
            ).toString();
            return aes;
        }
    };
nonce的生成规则
先看代码:
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
nonceCreat: function () {
            var type = 0;
            var deviceId = 'aa:af:b2:e0:e5:bf';
            var time = Math.floor(new Date().getTime() / 1000);
            var random = Math.floor(Math.random() * 10000);
            return [type, deviceId, time, random].join('_');
},
返回typedeviceIdtimerandom的值并用“_”相连接。如下图,经调试所产生的nonce值:其中,type是固定值,目前为0deviceId值目前也是明文值,这个值是后台取的设备的ID,这里是“aa:af:b2:e0:e5:bf”;time值是使用Date().getTime()函数得到的当前时间戳(值除以1000,取秒值)random值是调用Math.random()函数得到的值再*10000得到的数值。

14 nonce示例
password的生成规则
根据loginHandle()password是由Encrypt().oldPwd(pwd)函数生成的。代码如下:
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
oldPwd: function (pwd) {
    if(newEncryptMode == 1){
        return CryptoJS.SHA256(this.nonce + CryptoJS.SHA256(pwd + this.key).toString()).toString();
    }else{
        return CryptoJS.SHA1(this.nonce + CryptoJS.SHA1(pwd + this.key).toString()).toString();
    }
 },
如果newEncryptMode的值为1,则调用sha256算法,其他情况则使用sha1算法。一共做两次哈希。
第一次哈希
具体是对用户输入的密码(pwd)key值做相关的哈希运算。
key值参考代码一开始的常量,如下所示:
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
    var Encrypt = {
        key: 'a2ffa5c9be07488bbb04a3a47d3c5f6a',
        iv: '64175472480004614961023454661220',
        nonce: null,
        init: function () {
......

http://192.168.1.1/cgi-bin/luci/api/xqsystem/init_info中我们可以获得newEncryptMode的值,此值为1,所以password的生成采用sha256
第二次哈希

用上一步产生的nonce加上第一次产生的哈希结果再做一次sha256,最后的结果就是password的值,如图16所示。我们验证一下图8所产生的数据。第一次哈希:密码为test1234key值为“a2ffa5c9be07488bbb04a3a47d3c5f6a”,所以第一次sha256的结果为(取小写字母)sha256(‘test1234a2ffa5c9be07488bbb04a3a47d3c5f6a’)如下图所示:
15 第一次的sha256哈希运行

16 第二次sha256后的结果
和图8的结果一致。POSThttp://192.168.1.1/cgi-bin/luci/api/xqsystem/login中的表单数据就分析到此。剩下的就是编写登录代码了。

代码
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# -*- coding: utf-8 -*-
import re
import time
from routers.utils import hash_sha1, hash_sha256
from routers.router_spider import Router
 
 
class XiaoMi7000(Router):
 
    def login(self):
        url = f'http://{self.ip}/cgi-bin/luci/web'
        self.headers = {
            "Connection": "keep-alive",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/90.0.4430.72 Safari/537.36"
        }
        r = self.session.get(url=url, headers=self.headers)
        r_data = r.text.replace('\r', '').replace('\n', '').replace('\t', '')
        key = re.compile('key:.*?\'(.*?)\',').findall(r_data)[0]
        device_id = re.compile('deviceId = \'(.*?)\';').findall(r_data)[0]
 
        init_info_url = f'http://{self.ip}/cgi-bin/luci/api/xqsystem/init_info'
        init_info_r = self.session.get(url=init_info_url, headers=self.headers)
        init_info_data = init_info_r.json()
        # {"code":0,"isSupportMesh":1,"secAcc":1,"inited":1,"connect":0,"modules":{"replacement_assistant":"1"},"hardware":"RC06","support160M":1,"language":"zh_cn","romversion":"1.0.111","countrycode":"CN","routerId":"5dddb********3c7c","id":"44********41","routername":"Xiaomi_C84F","showPrivacy":0,"displayName":"Xiaomi路由器7000","imei":"","moduleVersion":"","maccel":"1","model":"xiaomi.router.rc06","wifi_ap":1,"bound":0,"newEncryptMode":1,"isRedmi":0}
        hardware = init_info_data.get("hardware")
        rom_version = init_info_data.get("romversion")
        serial_number = init_info_data.get("id")
        router_name = init_info_data.get("routername")
 
        self.data = {
            "hardware": hardware,
            "rom_version": rom_version,
            "serial_number": serial_number,
            "router_name": router_name,
        }
        new_encrypt_mode = init_info_data.get("newEncryptMode")
        pwd = self.password
        nonce = f'0_{device_id}_{str(int(time.time()))}_962'
        if new_encrypt_mode and int(new_encrypt_mode) == 1:
            a = hash_sha256(pwd + key)
            pass_word = hash_sha256(nonce + a)
        else:
            a = hash_sha1(pwd + key)
            pass_word = hash_sha1(nonce + a)
 
        log_url = f'http://{self.ip}/cgi-bin/luci/api/xqsystem/login'
        data = {
            "username": "admin",
            "password": pass_word,
            "logtype": "2",
            "nonce": nonce
        }
        res = self.session.post(url=log_url, headers=self.headers, data=data)
        cookie = res.raw.headers.getlist('Set-Cookie')[0]
        self.headers["Cookies"] = cookie.split(';')[0]
        self.token = res.json()['token']
        self.path = res.json()['url']
        self.stok = re.compile(';stok=(.*?)/').findall(self.path)[0]
 
    def get_device_info(self):
 
        d_name = self.session.get(url=f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/web/home', headers=self.headers)
        d_name_html = d_name.text
        mapModel = {
            'R1D': '小米路由器',
            'R2D': '小米路由器2',
            'R3D': '小米路由器HD',
            'R1CM': '小米路由器MINI',
            'R1CL': '小米路由器青春版',
            'R3': '小米路由器3',
            'R3L': '小米路由器3C',
            'R3P': '小米路由器3 Pro',
            'R3A': '小米路由器3A',
            'R3G': '小米路由器3G',
            'R4': '小米路由器4',
            'R4C': '小米路由器4Q',
            'R4CM': '小米路由器4C',
            'D01': '小米路由器Mesh',
            'R4AC': '小米路由器4A',
            'R4A': '小米路由器4 v2',
            'R3Gv2': '小米路由器3G',
            'R2600': '小米路由器2600',
            'R2100': '小米路由器AC2100',
            'R1500': '小米路由器1500',
            'R3600': '小米AIoT路由器 AX3600',
            'R1800': '小米AIoT路由器 AX1800',
            'RA72': '小米路由器 AX6000',
            'RA80': '小米路由器 AX3000',
            'RA81': 'Redmi路由器 AX3000',
            'RB08': 'Xiaomi HomeWiFi',
            'RC01': 'Xiaomi万兆路由器',
            'RC06': 'Xiaomi路由器7000'
        }
        d_name_r = ''
        d_type = ''
        wan_mac = ''
 
        if re.compile('hardwareVersion.*?\'(.*?)\'').findall(d_name_html):
            d_name_r = mapModel[re.compile('hardwareVersion.*?\'(.*?)\'').findall(d_name_html)[0]]
            d_type = re.compile('hardwareVersion.*?\'(.*?)\'').findall(d_name_html)[0]
        if re.compile("""#routermac'\).text\('(.*?)'\);""").findall(d_name_html):
            wan_mac = re.compile("""#routermac'\).text\('(.*?)'\);""").findall(d_name_html)[0]
        index_url = f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/api/xqnetwork/pppoe_status'
        ip_r = self.session.get(url=index_url, headers=self.headers)
        # {'proto': 'dhcp', 'dns': ['192.168.1.3'], 'code': 0, 'status': 0, 'gw': '192.168.1.3', 'ip': {'mask': '255.255.255.0', 'address': '192.168.1.35'}}
        ip_r_data = ip_r.json()
 
        name_url = f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/api/xqnetwork/wifi_detail_all'
        name_r = self.session.get(url=name_url, headers=self.headers)
        # {'bsd': 0, 'info': [{'ifname': 'wl1', 'channelInfo': {'bandwidth': '0', 'bandList': [], 'channel': 10}, 'encryption': 'mixed-psk', 'bandwidth': '0', 'kickthreshold': '0', 'status': '1', 'mode': 'Master', 'txbf': '0', 'weakthreshold': '0', 'device': 'mt7603e.network1', 'hidden': 0, 'password': '12345678', 'channel': '0', 'txpwr': 'max', 'weakenable': '0', 'ssid': 'Xiaomi_52F5', 'signal': 0}, {'ifname': 'wl0', 'channelInfo': {'bandwidth': '0', 'bandList': [], 'channel': 149}, 'encryption': 'mixed-psk', 'bandwidth': '0', 'kickthreshold': '0', 'status': '1', 'mode': 'Master', 'txbf': '0', 'weakthreshold': '0', 'device': 'mt7612.network1', 'hidden': 0, 'password': '12345678', 'channel': '0', 'txpwr': 'max', 'weakenable': '0', 'ssid': 'Xiaomi_52F5_5G', 'signal': 0}], 'code': 0}
        name_r_data = name_r.json()
 
        # 序列号
        serial_number = ''
        if self.data.get("serial_number"):
            serial_number = self.data.get("serial_number")
        # 设备名称
        product_number = name_r_data["info"][0]["ssid"]
        run_time = ''
        # WAN网口
        wan_port = ''
        # 链接方式
        link_method = ip_r_data["proto"]
        pppoe_user = ''
        pppoe_pwd = ''
        if 'dhcp' not in link_method:
            pppoe_status = self.session.get(url=f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/api/xqnetwork/pppoe_status', headers=self.headers)
            pppoe_status_data = pppoe_status.json()
            pppoe_user = pppoe_status_data['pppoename']
            pppoe_pwd = pppoe_status_data['password']
 
        ip = ip_r_data["ip"]["address"]
        # 子网掩码
        mask = ip_r_data["ip"]["mask"]
        # 网关地址
        gateway = ip_r_data["gw"]
        # 主DNS地址
        main_dns = ip_r_data["dns"][0] if ip_r_data["dns"] else ''
 
        slave_dns = ''
        cfg_url = f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/api/misystem/status'
        cfg_res = self.session.get(url=cfg_url, headers=self.headers)
        # {'dev': [{'mac': '18:****:87', 'maxdownloadspeed': '30351', 'upload': '137281', 'upspeed': '0', 'downspeed': '0', 'online': '298', 'devname': 'DESKTOP-D6GLNBH', 'maxuploadspeed': '12451', 'download': '266417'}], 'code': 0, 'mem': {'usage': 0.38, 'total': '128MB', 'hz': '1200MHz', 'type': 'DDR3'}, 'temperature': 0, 'count': {'all': 1, 'online': 1}, 'hardware': {'mac': '64:64****:52:F5', 'platform': 'R4A', 'version': '2.28.65', 'channel': 'release', 'sn': '21894/22358114'}, 'upTime': '408.31', 'cpu': {'core': 4, 'hz': '880MHz', 'load': 0.0045}, 'wan': {'downspeed': '571', 'maxdownloadspeed': '34500', 'history': '1003,838,711,1146,206,732,1568,5676,0,195,154,154,725,121,537,321,1423,181,202,195,0,1691,364,346,0,1134,1331,1462,0,1137,365,730,228,569,154,0,1187,0,0,487,338,1261,627,617,1163,229,7392,235,142,918', 'devname': 'eth1', 'upload': '166582', 'upspeed': '347', 'maxuploadspeed': '12322', 'download': '484827'}}
        cfg_data = cfg_res.json()
        mac = cfg_data["hardware"]["mac"]
        device_info_base_data = {
            "device_name": d_name_r,
            "device_type": d_type,
            "serial_number": serial_number,
            "run_time": run_time,
            "connection_type": link_method,
            "wan_ip": "",
            "wan_mac": wan_mac,
            "lan_ip": "",
            "lan_mac": "",
            "ipv4_wan_ip": "",
            "ipv4_lan_ip": "",
            "ipv4_gateway": "",
            "ipv4_dns_server": "",
            "ipv6_wan_ip": "",
            "ipv6_lan_ip": "",
            "ipv6_gateway": "",
            "ipv6_dns_server": "",
            "ip": ip,
            "mac": mac,
            "gateway": gateway,
            "mask": mask,
            "dns_server": main_dns,
            "pppoe_user": pppoe_user,
            "pppoe_pwd": pppoe_pwd,
            "wifi2_ssid": name_r_data['info'][0]['ssid'],
            "wifi2_key": name_r_data['info'][0]['password'],
            "wifi5_ssid": name_r_data['info'][1]['ssid'],
            "wifi5_key": name_r_data['info'][1]['password'],
            "pin": "",
            "encryption_mode": name_r_data['info'][0]['encryption'],
        }
        return device_info_base_data
 
    def get_device_host_info(self):
        device_ulr = f'http://{self.ip}/cgi-bin/luci/;stok={self.stok}/api/misystem/devicelist'
        r = self.session.post(url=device_ulr, headers=self.headers)
        data = r.json()
        device_list = []
        for one_device in data["list"]:
            status = 1
            device_info = {
                "ip": one_device['ip'][0]['ip'],
                "mac": one_device['mac'],
                "name": one_device['name'],
                "on_line_status": status,
            }
            device_list.append(device_info)
        return device_list



免费评分

参与人数 62威望 +2 吾爱币 +165 热心值 +56 收起 理由
zpbz + 1 + 1 我很赞同!
baimuda + 1 + 1 写得很详细,感谢分享
yiyiwangru + 1 + 1 我很赞同!
MatrixLau + 1 + 1 谢谢@Thanks!
dingfeifei + 1 + 1 我很赞同!
zhangtaisen + 1 + 1 热心回复!
trust123 + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
zzyeva + 1 + 1 我很赞同!
cheersw + 1 + 1 谢谢@Thanks!
agunner + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
你可真傻 + 1 + 1 热心回复!
wangyou918918 + 1 + 1 谢谢@Thanks!
Dlian + 1 + 1 我很赞同!
phbd + 1 + 1 我很赞同!
ElliottNumb + 2 + 1 我很赞同!
xianuo + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Zayre + 1 用心讨论,共获提升!
birdnofeet + 1 我很赞同!
selectcc + 1 + 1 用心讨论,共获提升!我去实验一下
YunLong3rice + 1 + 1 我很赞同!
Headhunterz + 1 我很赞同!
fssxb + 1 + 1 用心讨论,共获提升!
梦旅意中人 + 1 + 1 用心讨论,共获提升!
loop_ + 1 + 1 我很赞同!
YCmodest + 1 + 1 我很赞同!
13008186186 + 1 + 1 热心回复!
小朋友呢 + 2 + 1 我很赞同!
bingma0 + 1 + 1 我很赞同!
穿透骨頭撫摸妳 + 1 + 1 谢谢@Thanks!
xiaomanzai12 + 1 + 1 我很赞同!
fjk2001 + 1 谢谢@Thanks!
elan + 1 + 1 用心讨论,共获提升!
a3859495 + 1 + 1 谢谢@Thanks!
xq2581 + 1 + 1 我很赞同!
jipinfeiche + 1 谢谢@Thanks!
1MajorTom1 + 1 热心回复!
OYyunshen + 1 + 1 我很赞同!
v.n.lee + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
awen1344 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
无痕567 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
涛之雨 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
txt + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
回归本心 + 1 + 1 我很赞同!
Lananann + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
AirTed + 1 + 1 用心讨论,共获提升!
单曲循环丶T + 1 + 1 热心回复!
WAxuexi + 1 + 1 我很赞同!
leezhifu + 1 + 1 鼓励转贴优秀软件安全工具和文档!
muhefeng + 1 + 1 谢谢@Thanks!
guhuishou + 1 + 1 谢谢@Thanks!
dxiaolong + 1 + 1 用心讨论,共获提升!
dgsx61 + 1 我很赞同!
杨辣子 + 1 + 1 热心回复!
cc0207 + 1 + 1 谢谢@Thanks!
BonnieRan + 1 + 1 谢谢@Thanks!
amd123 + 1 + 1 我很赞同!
xljya + 1 热心回复!
三滑稽甲苯 + 2 + 1 用心讨论,共获提升!
wystudio + 2 + 1 用心讨论,共获提升!
四哥! + 1 + 1 用心讨论,共获提升!
bamboo52 + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
ask0wizard 发表于 2024-3-6 16:48
以前用苹果时间胶囊(3Ty硬盘版)各种稳定,就是无线SMB传输速度始终不超过10兆,后来换AX9000,速度上来了,当然价格也上了。正好没来的及看算法,楼主此文甚好,得空要试试。。感谢楼主
推荐
kingofforest 发表于 2023-9-23 05:12
刚好我家路由器也是小米的,验证了一下发现没有init_info这个文件,可能是版本不一样吧,也就是说,也许我这个还是采用的旧的sha1加密。文章简洁明了,感谢分享。
沙发
slslsl 发表于 2023-9-11 11:36
3#
四哥! 发表于 2023-9-11 11:47
写得很详细,感谢分享
4#
枫叶工作室 发表于 2023-9-11 12:27
很棒,我分析了tp-link没有获取到post
5#
ysjd22 发表于 2023-9-11 12:27
正好可以试试手
6#
mcse2006 发表于 2023-9-11 12:54
不懂就问,这样做了有啥用?
7#
lj3689622 发表于 2023-9-11 14:15
不懂就问,这是干嘛
8#
Piz.liu 发表于 2023-9-11 14:28
这个用来做什么呢
9#
吓猴蹲 发表于 2023-9-11 14:53
写的不错,就是字号再大点就好了,字太小瞅着眼睛难受
10#
吓猴蹲 发表于 2023-9-11 14:54
写的不错,就是字号再大点就好了,字太小瞅着眼睛难受
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-1 01:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表