路由器运行python脚本_写个Python脚本来登录小米路由器
这个脚本写起来难度并不是很大,博主还是一步步的分析下,这样思路会比较清晰,下次遇到类似系统脚本写起来也更快速。好了,一起来分析分析。
首先看下小米路由器的登录界面
可以看到只需要输入密码即可登录,博主这里为了演示,设置了简单的登录密码12345678,使用firebug记录登录的请求。当然,这里也可以使用Burp拦截请求,只不过有点大材小用了,来,我们尝试登录一下,看下做了哪些请求,使用正确的密码进行登录,post到服务端的数据如图所示
从图上很明显的可以看到,post了4个参数到这个地址:http://192.168.65.1/cgi-bin/luci/api/xqsystem/login 进行登录操作。
参数 username 的值为admin,这个很明显就是一个内置的用户名,也就是默认的用户名,所以页面只需要输入密码就可以正常登录。
参数 password 一眼看上去应该是个MD5加密后的密文
参数 logtype 的值为2,这个应该也是系统默认内置的一个登录类型
参数 nonce 看起来应该是 mac地址加时间戳加随机数的组合
登录成功之后的响应如图
上面对参数含义的推测不一定准确,为了了解真正的含义,博主决定去代码里面一探究竟,查看页面源代码,找到了处理登录的方法
function loginHandle ( e ) {
e.preventDefault();
var formObj = document.rtloginform;
var pwd = $( '#password' ).val();
if ( pwd == '') {
return;
}
var nonce = Encrypt.init();
var 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 ) {
$.pub('loading:stop');
var rsp = $.parseJSON( rsp );
if ( rsp.code == 0 ) {
var redirect,
token = rsp.token;
if ( /action=wan/.test(location.href) ) {
redirect = buildUrl('wan', token);
} else if ( /action=lannetset/.test(location.href) ) {
redirect = buildUrl('lannetset', token);
} else {
redirect = rsp.url;
}
window.location.href = redirect;
} else if ( rsp.code == 403 ) {
window.location.reload();
} else {
pwdErrorCount ++;
var errMsg = '密码错误';
if (pwdErrorCount >= 4) {
errMsg = '多次密码错误,将禁止继续尝试';
}
Valid.fail( document.getElementById('password'), errMsg, false);
$( formObj )
.addClass( 'shake animated' )
.one( 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
$('#password').focus();
$( this ).removeClass('shake animated');
} );
}
});
}
很容易就能明白代码的意思,博主稍微精简下,登录地址为
/cgi-bin/luci/api/xqsystem/login
参数为
var param = {
username: 'admin',
password: oldPwd,
logtype: 2,
nonce: nonce
};
password参数对应到oldPwd,找到oldPwd的生成方法
var oldPwd = Encrypt.oldPwd( pwd );
而nonce的生成方法也很容易找到
var nonce = Encrypt.init();
这两个参数都是由
Encrypt
这个类里面的方法生成的,找到这个类即可。而在登录的方法中还有个登录次数的限制,很显然,这个登录的次数也只是js变量控制的,并不是后端限制,很鸡肋,依然可以无限次登录。
找到上面两个参数的生成方法
var Encrypt = {
key: 'a2ffa5c9be07488bbb04a3a47d3c5f6a',
iv: '64175472480004614961023454661220',
nonce: null,
init: function(){
var nonce = this.nonceCreat();
this.nonce = nonce;
return this.nonce;
},
nonceCreat: function(){
var type = 0;
var deviceId = '00:88:65:3d:bd:22';
var time = Math.floor(new Date().getTime() / 1000);
var random = Math.floor(Math.random() * 10000);
return [type, deviceId, time, random].join('_');
},
oldPwd : function(pwd){
return CryptoJS.SHA1(this.nonce + CryptoJS.SHA1(pwd + this.key).toString()).toString();
},
newPwd: function(pwd, newpwd){
var key = CryptoJS.SHA1(pwd + this.key).toString();
key = CryptoJS.enc.Hex.parse(key).toString();
key = key.substr(0, 32);
key = CryptoJS.enc.Hex.parse(key);
var password = CryptoJS.SHA1(newpwd + this.key).toString();
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;
}
};
也是相当简单,值得注意的是这里生成的密码并不是MD5,而是由CryptoJS 这个库生成的可逆的密文,这跟我上面的推测有些差异,,nonce的生成在这段代码里面
var type = 0;
var deviceId = '00:88:65:3d:bd:22';
var time = Math.floor(new Date().getTime() / 1000);
var random = Math.floor(Math.random() * 10000);
return [type, deviceId, time, random].join('_');
类型+设备的mac地址+时间戳+10000以内的随机数,中间用下划线隔开。
搞明白每个参数的生成方法后模拟登录写起来可就简单多了。
利用requests模块进行登录,这里重点需要说明下密码的生成过程
CryptoJS.SHA1(this.nonce + CryptoJS.SHA1(pwd + this.key).toString()).toString();
密码+后端返回的一个key进行一次SHA1加密,转换成字符串之后与nonce相加再进行一个SHA1加密,最后进行一次字符串的转换就的到最终的密文。
好了,分析到这我们都已经清楚整个参数生成的原理,现在就要开始写Python了,首先需要知道要用哪些模块
运行脚本的时候需要直接带参数,所以需要sys模块
生成时间戳需要time模块
发送http请求需要requests模块
生成随机数需要random模块
接收服务端返回的数据并解析需要json模块
正则匹配获取key需要re模块
SHA1加密需要pycrypto模块
博主这里是Linux环境,自带的Python缺少requests模块,需要安装,具体安装方法不再累述
关于pycrypto模块的使用,可以参考链接 http://pythonhosted.org/pycrypto/
好了,下面开始脚本的编写,首先需要做的就是获取那个key,因为生成密码的时候要用到,这个key在登录页面初始化的时候就已经生成了,所以直接使用requests的get方法取回页面进行匹配就可以得到key,代码如下
host = sys.argv[1]
homeRequest = requests.get('http://'+ host +'/cgi-bin/luci/web/home')
key = re.findall(r'key: \'(.*)\',',homeRequest.text)[0]
这里的host直接由参数获得,请求回来的数据使用re进行匹配得到key,接着生成nonce,要用到time模块和random模块。
观察nonce生成规则发现所需要的mac地址真是本机的mac地址而不是路由器的mac,推测是在连接路由器的时候路由器就已经获取到的,登录页面初始化的时候会返回获取到的本机地址,所以直接从页面上抓取mac地址就可以了,同样适用re模块进行匹配
mac = re.findall(r'deviceId = \'(.*)\';',homeRequest.text)[0]
接下来就把获取到的mac地址带入拼接就可以生成nonce参数
nonce = "0_"+ mac +"_"+ str(int(time.time())) +"_"+str(random.randint(1000,10000))
有了nonce和key,那么生成密码的密文也就比较容易,两次SHA1加密就可以了,代码也很简单
pwdtext = sys.argv[2]
pwd = SHA.new()
pwd.update(pwdtext+key)
hexpwd1 = pwd.hexdigest()
pwd2 = SHA.new()
pwd2.update(nonce+hexpwd1)
hexpwd2 = pwd2.hexdigest()
原始明文密码直接由参数获得,密码生成之后进行param的组合,一般博主直接用一个json对象来把参数集合在一块,就像这样
data = {
"logtype":2,
"nonce":nonce,
"password":hexpwd2,
"username":"admin"
}
好了,参数都有了,咱们直接传过去吧,记得是post哦,代码如下
response = requests.post(url=aimurl,data=data,timeout = 5)
resjson = json.loads(response.content)
if resjson['code'] == 0:
print 'Login Success! Token is '+resjson['token']
else:
print 'Login Failed! Code is '+str(resjson['code'])
对于返回的数据,之前查看过是json格式,那么直接使用json模块进行解析即可,code返回0则为成功,会得到一个token,code为其他则失败,来看下运行截图
登录成功
登录失败
好了,到这咱们就已经成功实现了使用Python进行快速登录小米路由器的功能,下次咱们接着写,如何使用Python来对小米路由器进行设置和重启等。
补充
更多功能的脚本在 http://www.92ez.com/?action=show&id=23405
本文链接:https://www.92ez.com/?action=show&id=23373
!!! 转载请先联系non3gov@gmail.com授权并在显著位置注明作者和原文链接 !!! 小黑屋
提示:技术文章有一定的时效性,请先确认是否适用你当前的系统环境。
路由器运行python脚本_写个Python脚本来登录小米路由器相关推荐
- python 基于unittest写接口自动化脚本
已过时.如感兴趣,请移步这篇文章 https://blog.csdn.net/tomoya_chen/article/details/121550706 python 基于unittest写接口自动化 ...
- 小米路由器3是基于linux,XiaomiRouter自学之路(12-改造小米路由器3使之支持spi启动)...
题图:gratisography XiaomiRouter自学之路(12-改造小米路由器3使之支持spi启动) 上一章节已经说到小米路由器mini的Uboot.Openwrt都能够正常的启动了,现在想 ...
- python能写什么脚本_你用 Python 写过哪些牛逼的程序/脚本?
原标题:你用 Python 写过哪些牛逼的程序/脚本? [导读]:有网友在 Quora 上提问,「你用 Python 写过最牛逼的程序/脚本是什么?」.本文摘编了 3 个国外程序员的多个小项目,含代码 ...
- python编写一个程序、实现文件的复制_写个python 脚本实现文件的递归拷贝
<派森>(Python)3.13 win32 英文安装版 类型:编程工具大小:21M语言:英文 评分:8.7 标签: 立即下载 今天翻电脑时突然发现有个存了很多照片和视频的文件夹,想起来是 ...
- ctypes安装_用python amp; bat写软件安装脚本 + HM NIS Edit自动生成软件安装脚本
2019-03-11更新:原来NSIS脚本也可以禁用64位文件操作重定向的! 1.在安装脚本的开始处定义 LIBRARY_X64. !include "MUI.nsh" !incl ...
- python如何运行脚本_怎么执行python脚本文件
1.脚本式编程 将如下代码拷贝至 hello.py文件中:print ("Hello, Python!");python学习网,大量的免费python视频教程,欢迎在线学习! 通过 ...
- anaconda怎么运行python程序_第一个python程序,从安装python环境到人生第一个py脚本运行全过程...
文章目录 前言一.安装python运行环境 1.官网https://www.python.org下载安装包.exe 2.安装python二.python模块下载 1.配置pip环境变量 2.下载pyt ...
- python写一个服务_写一个Python的windows服务
1. 安装pywin32和pyinstaller pip install pywin32 pip install pyinstaller 2.写一个服务Demo # -*- coding: utf-8 ...
- python编写接口自动化脚本_简单的python http接口自动化脚本
摘抄:今天给大家分享一个简单的python脚本,使用python进行http的接口测试,脚本很简单,逻辑是:读取excel写好的测试用例,然后根据excel中的用例内容进行调用,判断预期结果中的返回值 ...
最新文章
- URI、URL以及URN的区别
- (function() {})();和(function(){}())
- PMCAFF推出咖啡日报 更多好内容等你来发现
- vnc服务器和客户端怎么配置文件,VNC服务器端与客户端配置
- Zabbix 企业级监控_
- Android studio3.0打开Device File Explore(文件管理器)的方法(图文教程)
- if嵌套while循环语句_Python学习笔记015--while循环嵌套
- 2018.09.28 hdu5435A serious math problem(数位dp)
- 到了姥姥家我在小点点c++
- 英世曼 | 动量是否具有行为性?
- 【遥感图像预处理方法】
- 加州大学计算机系统,盘点:美国加州大学系统值得申请的专业
- 边缘的容器化 — WasmEdge 与 seL4
- 医疗器械软件 软件生存周期过程
- Android Studio不使用数据线调试adb
- 鸿蒙系统和海思系统有什么区别,鸿蒙系统和安卓系统 到底有什么区别?
- daas 数据即服务_什么是daas
- 【Linux驱动编程】Linux中断上半部和下半部
- AlexNet模型详细分析
- 稳稳压二极管原理及主要参数