当前位置: 首页 > 编程日记 > 正文

路由器运行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授权并在显著位置注明作者和原文链接 !!! 小黑屋

提示:技术文章有一定的时效性,请先确认是否适用你当前的系统环境。

相关文章:

PHP定时执行任务的实现

2019独角兽企业重金招聘Python工程师标准>>> ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行. set_time_limit(0);// 通过set_time_limit(0)可以让程序无限制的执行下去 $interval60*30;// 每隔半小时运行 do{//这里是你要执行的代码 sleep($i…

Spring事务管理 与 SpringAOP

1,Spring事务的核心接口 Spring事务管理的实现有许多细节,如果对整个接口框架有个大体了解会非常有利于我们理解事务,下面通过讲解Spring的事务接口来了解Spring实现事务的具体策略。   Spring事务管理涉及的接口的联系如下: 1.…

iso镜像文件烧写到U盘

iso镜像文件烧写到U盘 windows rufus-3.1.exe 百度云盘链接:https://pan.baidu.com/s/16p1O4lXMVTUltTvCm0DnHA 提取码:inzj 文件格式一般选择默认的就行,如果起不来,就换一个, linux 1、dd命令 2、系统自带 usb-creator-gtk工具 命令行输入&#x…

webgl 游戏_30个令人惊叹的WebGL示例和演示

WebGl仍在增长,尽管大多数现代浏览器都支持它,但它也可能需要在旧的浏览器上工作。在本文中,我遇到了很多WebGL的示例和演示,它们可以增进您对这项新技术的理解。因此,请坐下来放松身心,使用最新的浏览器&a…

IE8下的VML显示问题解决方案

最近在维护一个使用VML画曲线的网站,在不同的IE下浏览效果不一样,特别是在IE8下,出现莫名其妙的样式显示问题: 1.曲线不可见!在IE9或IE7下,曲线正常绘制,但是在IE8下,不见坐标轴和曲…

创新工场有哪些失败项目?不要只看着成功

创新工场有哪些失败项目?不要只看着成功 李开复 ,创新工场CEO回答:失败或碰到挑战的项目也不少。这里不点名,不谈细节,但是谈谈碰到什么挑战(有些已经失败,有些还在努力)&#xff1a…

彻底解决Linux索引节点(inode)占用率高的告警

今天邮箱里发现有一封某服务器inode使用率发生告警的邮件 登录到服务器上df -i查看,发现/路径下91%,磁盘使用率却不高,猜测可能是某个目录下的小文件过多,进而造成inode占用率过高,但不清楚根路径下各文件夹里的文件数…

镜像打包工具clonezilla

镜像打包工具clonezilla clonezilla 百度云盘链接:https://pan.baidu.com/s/1LOEPqNE9O0Z4QJmNExlgeA 提取码:zlso 使用方法: 1、将镜像直接烧入U盘 2、U盘启动

python数据分析设置_Python 数据分析系列之如何安装和设置 Python

由于人们用 Python 所做的事情不同,所以没有一个普适的 Python 及其插件包的安装方案,接下来我将详细介绍各个操作系统上 Python 科学计算环境部署。我推荐免费的 Anaconda 安装包,Anaconda 提供 Python 2.7 和 3.6 两个版本,以后…

javamail gmail

http://www.programfan.com/club/showpost.asp?id27614转载于:https://www.cnblogs.com/yqskj/archive/2013/01/11/2855715.html

robots.txt文件的解析及过滤

什么是robots.txt文件? robots.txt(统一小写)是一种存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不能被搜索引擎的漫游器获取的&#xf…

CF949C Data Center Maintenance(建图+强联通分量)

题意 有 n 个信息中心,第 i 个信息中心要在第 ti 个小时维护,维护期间信息不能被获得。 每个用户的数据都有两份备份,第 i 个用户的数据放在信息中心 c(i,1) 和 c(i,2)。 现在要挑选一个尽量小的信息中心集合,使得将这个集合的维护…

fabric 启动peer_编写 Fabric 链码的一般准则

我相信智能合约(链码)是 Hyperledger Fabric 区块链网络的核心。正确开发链码可以真正发挥一个安全区块链的优势,反之则会带来灾难性的后果。在这篇文章里我不打算探讨 Hyperledger Fabric 链码设计的特定模式的好与坏,而是希望分享我在开发若干 Hyperle…

Qt pro文件下跨平台宏的使用(windows/linux 以及x86 和 arm的区分)

#Qt pro文件下跨平台宏的使用(windows/linux 以及x86 和 arm的区分) 在pro文件中添加: #仅在linux 系统下, 硬件平台无关的内容 unix{HEADERS \SOURCES \Manager.cpp \ }#arm64 的编译宏 contains(QMAKE_HOST.arch, aarch64){…

数论(一)——素数,GCD,LCM

这是一个数论系列:) 一、素数 费马小定理 Theorem: 设 p 是一个素数,a 是一个整数且不是 p 的倍数,那么 很遗憾,费马小定理的逆定理是不成立的。对 a 2,满足的非素数 n 是存在的。 比如 n 341 11 31 对于整数 a,称满足的合数为以 a 为底的…

java自学 day1

1.数据类型 基本数据类型(存放数据本身) 分为数值型(int,double等) 字符型(char)布尔型(boolean) 引用数据类型(存放数据的地址)分为类&#xff0…

Qt下一行代码就可以使用的稳定易用的日志log类

Qt下一行代码就可以使用的稳定易用的日志类 此日志类是基于Qt 自带的 扩展的一个易用的日志类, 使用的是Qt自带的日志输出形式, 已长期运行在许多实际项目中,稳定可靠,而且跨平台, 在windows和linux 上都能稳定运行 …

apue读书笔记-第十二章

1 可重入,线程安全,异步信号安全之间的区别? 可重入:可以重复进入,不会引起问题(这个概念最宽) 线程安全:被多个线程使用时,不会出问题,也就是可以被多个进程…

取出url中的字符_如何在JavaScript中解析URL:例如主机名,路径名,查询,哈希?...

统一资源定位符(缩写URL)是对Web资源(网页,图像,文件)的引用。URL指定资源位置和检索资源的机制(http,ftp,mailto)。例如,这是此博客文章的URL&am…

SQL Server 2008中的Pivot和UnPivot

SQL Server 2008中SQL应用系列--目录索引 今天给新成员讲解PIVOT 和 UNPIVOT示例,顺便整理了一下其用法。这是自SQL Server 2005起提供的新功能。 官方示例:http://msdn.microsoft.com/zh-cn/library/ms177410%28vsql.105%29.aspx 首先看PIVOT示例&#…

leetcode python 032 识别最长合法括号

# 给定一个只包含字符(和)的字符串,# 找到最长的有效(格式良好)括号子字符串的长度。# 对于“(()”,最长的有效括号子串是“()”,其长…

Android窗口管理服务WindowManagerService计算Activity窗口大小的过程分析

在Android系统中,Activity窗口的大小是由WindowManagerService服务来计算的。WindowManagerService服务会根据屏幕及其装饰区的大小来决定Activity窗口的大小。一个Activity窗口只有知道自己的大小之后,才能对它里面的UI元素进行测量、布局以及绘制。本文…

pcl需要注意的编译问题

pcl需要注意的编译问题 不要在头文件里 using namespace pcl 这会导致编译错误,而且根本分析不到错误在哪 不要在编译选项 里加 -marchnative 这个是让编译器根据你当前的cpu类型进行特定的编译优化, 例如 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdc11 -march…

linux python版本_linux下更新Python版本并修改默认版本

linux下更新Python版本并修改默认版本,有需要的朋友可以参考下。很多情况下拿到的服务器python版本很低,需要自己动手更改默认python版本1、从官网下载python安装包(这个版本可以是任意版本3.3 2.7 2.6等等)wget http://python.org/ftp/python/2.7/Pytho…

基于HTML5的Google水下搜索

这次愚人节的时候,Google推出了水下搜索,当然,这只是一个愚人的小把戏,不过效果非常不错,进入页面后,第一眼是一个水面的效果,水下的鲨鱼在游来游去,然后Google logo和搜索框从水面上…

windows下rpc框架thrift的环境配置

windows下rpc框架thrift的环境配置 引用链接: https://www.cnblogs.com/49er/p/7193829.html 最近在弄windows下 的Facebook的rpc 框架 thrift , 网上东西看了很多, 但是大都不能一篇到位, 这里总结了一下, 也记一下自己遇到的问题和解决的方法 这里把我在实际过程中遇见的问…

CentOS 6.3 安装 samba 共享

PHP环境在linux下,但是开发的时候用的是windows,于是我用了samba将linux的一个目录共享,然后在windows上做映射,这样就可以直接在windows下编辑linux上的文件了 首先,安装samba软件,我采用的是yum安装&…

微信小程序 长按图片不出现菜单_微信更新,新功能上了热搜

微信在推出新功能方面相当克制,但每一次总能引起全网关注。昨天,微信又因为一个小功能的改进再次上了热搜,在安卓最新的 7.0.17 版本当中,微信取消了两分钟内删除功能。在新版微信中,发出的消息在两分钟内只有撤回功能…

windows下配置java环境jdk

Windows系统下搭建java的开发环境和配置环境变量 具体步骤打开链接地址:https://www.cnblogs.com/lijuntao/p/6694483.html转载于:https://www.cnblogs.com/ccw869476711/p/9401468.html

mysql 分区_搞懂MySQL分区

一.InnoDB逻辑存储结构首先要先介绍一下InnoDB逻辑存储结构和区的概念,它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成。段段就是上图的segment区域,常见的段有数据段、索引段、回滚段等,在In…