查看原文
其他

Python | 自动登录路由器,获取所有信息

马鹏飞 计算机与网络安全 2022-06-01

一次性进群,长期免费索取教程,没有付费教程。

教程列表见微信公众号底部菜单

进微信群回复公众号:微信群;QQ群:16004488


用 Python 自动登录TP-LINK路由器,获取信息,重启等操作。


1、 做任何操作,首先得登录到路由器


界面上面默认只有一个“密码”输入框,这里随便输入一个123密码发现,TP-LINK提交后的密码为加密后的,分析js就可以看到加密方法(下面会附上代码),再把加密后的密码提交就搞定啦。


路由器登录post信息截图(TP-LINK关掉了页面右键功能,可以手动打开浏览器的开发者工具,网络部分查看):


附上 Python 实现登录的方法

#!/usr/bin/env python# -*- coding:utf8 -*-''' Author : mafei Date   : 18/1/20 '''import requests import json# 加密提交后的密码,可以把自己的密码提交到这个方法,再跟TP-LINK页面中实际提交的密码值做比对def encrypt_pwd(password):    input1 = "RDpbLfCPsJZ7fiv"    input3 = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW"    len1 = len(input1)    len2 = len(password)    dictionary = input3    lenDict = len(dictionary)    output = ''    if len1 > len2:        length = len1    else:        length = len2    index = 0    while index < length:        # 十六进制数 0xBB 的十进制为 187        cl = 187        cr = 187        if index >= len1:            # ord() 函数返回字符的整数表示            cr = ord(password[index])        elif index >= len2:            cl = ord(input1[index])        else:            cl = ord(input1[index])            cr = ord(password[index])        index += 1        # chr() 函数返回整数对应的字符        output = output + chr(ord(dictionary[cl ^ cr]) % lenDict)    return output# 提交登录请求的方法def login(password=''):    encrypt_password = encrypt_pwd(password)    url = 'http://192.168.1.1/'    headers = {'Content-Type': 'application/json; charset=UTF-8'}    payload = '{"method":"do","login":{"password":"%s"}}' % encrypt_password    response = requests.post(url, data=payload, headers=headers)    response_body = json.loads(response.text)    return response_bodyif __name__ == '__main__':    print(login(password='xxx'))        # 返回的数据样例,error_code为0表示登录成功,stok是动态生成的key {u'error_code': 0, u'stok': u'xxx'}

2、获取登录之后的设备信息

先观察规律会发现,每次TP-LINK提交到后台的URL中都有一个stok的变量,是TP-LINK生成的动态key,每次登陆都会重新生成一个,这个stok在上一步登陆之后我们已经获取到了,后面就直接提交相应的json请求就可以了,到此已经已经全部搞定。

def get_all_host(password):    stok = login(password).get('stok')    payload = '{"hosts_info":{"table":"host_info"},"method":"get"}'    headers = {'Content-Type': 'application/json; charset=UTF-8'}    url = '%sstok=%s/ds' % ('http://192.168.1.1/', stok)    response = requests.post(url, data=payload, headers=headers)    return response.text if __name__ == '__main__':    print(get_all_host(password='xxx'))# 返回的样例数据# { "hosts_info": { "host_info": [ { "host_info_1": { "mac": "4c-32-75-29-5a-f3", "type": "1", "blocked": "0", "ip": "192.168.1.104", "hostname": "mafeiMBP", "up_speed": "3487", "down_speed": "5733", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "1", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } }, { "host_info_4": { "mac": "48-d2-24-ed-51-a4", "type": "1", "blocked": "0", "ip": "192.168.1.103", "hostname": "Lenovo%2DPC", "up_speed": "5733", "down_speed": "1975", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "0", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } }, { "host_info_2": { "mac": "90-8d-6c-0a-a6-8d", "type": "1", "blocked": "0", "ip": "192.168.1.101", "hostname": "iPad%2D2", "up_speed": "0", "down_speed": "0", "up_limit": "0", "down_limit": "0", "cfg_valid": "0", "is_cur_host": "0", "ssid": "", "wifi_mode": "0", "plan_rule": [ ] } } ] }, "error_code": 0 }

这里附上完整源代码

#!/usr/bin/env python# -*- coding:utf8 -*-''' Author : mafei Date   : 18/1/20 '''import requestsimport jsonclass LoginTpLink(object):    def __init__(self):        self.password = 'xxx'        self.stok = self.login(self.password)  # 初始化类的时候就自动登录,获取到stok(动态key)    # 加密密码的方法    def encrypt_pwd(self, password):        input1 = "RDpbLfCPsJZ7fiv"        input3 = "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgMLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ1xtXcPcf1aT303wAQhv66qzW"        len1 = len(input1)        len2 = len(password)        dictionary = input3        lenDict = len(dictionary)        output = ''        if len1 > len2:            length = len1        else:            length = len2        index = 0        while index < length:            # 十六进制数 0xBB 的十进制为 187            cl = 187            cr = 187            if index >= len1:                # ord() 函数返回字符的整数表示                cr = ord(password[index])            elif index >= len2:                cl = ord(input1[index])            else:                cl = ord(input1[index])                cr = ord(password[index])            index += 1            # chr() 函数返回整数对应的字符            output = output + chr(ord(dictionary[cl ^ cr]) % lenDict)        return output    # 登录方法    def login(self, password=''):        encryptPwd = self.encrypt_pwd(password)        url = 'http://192.168.1.1/'        headers = {'Content-Type': 'application/json; charset=UTF-8'}        payload = '{"method":"do","login":{"password":"%s"}}' % encryptPwd        response = requests.post(url, data=payload, headers=headers)        stok = json.loads(response.text)['stok']        return stok    # 获取所有主机信息的方法    def all_host_info(self):        payload = '{"hosts_info":{"table":"host_info"},"method":"get"}'        response = self.post_tp_link(payload)        return response.text    # 重启路由器的方法    def reboot(self):        payload = '{"system":{"reboot":null},"method":"do"}'        response = self.post_tp_link(payload)        return response.text    # 为了通用,封装的post方法    def post_tp_link(self, payload):        headers = {'Content-Type': 'application/json; charset=UTF-8'}        url = '%sstok=%s/ds' % ('http://192.168.1.1/', self.stok)        response = requests.post(url, data=payload, headers=headers)        return responseif __name__ == '__main__':    login_tp_link = LoginTpLink()    result = login_tp_link.reboot()    import pprint    pprint.pprint(json.loads(result))

【推荐书籍】

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存