开始之前咱们先了解一下TPLINK WR885N这款设备,官方地址为 http://www.tp-link.com.cn/product_368.html 针对官方介绍,这里博主做个简短的讲解
首先看到的是官方的路由器图片
外观还是不错的,博主手上拿到的设备就是那款黑色的,接着来看下官方介绍的管理界面
嗯,看起来似乎非常不错的样子,但是实际测试发现,其实不是这样的,还是很久以前那种传统的管理界面,这个先按住不说。关于其他的各种参数以及优点之类的博主就不多说了,不是本文的重点。
好的,现在开始实战。
登录界面是这样的
相信有很多同学对这个登录界面已经是非常熟悉了,只需要一个密码即可登录,这跟之前博主写的那篇登录小米路由器登录的那个登录界面一样,所以理论上来说应该是默认使用的admin账户登录。
当然,推测终究是推测,咱们肯定是要先得证明一下推测的正确性。好的,这里咱们直接查看页面源代码。
右键查看页面源代码(火狐浏览器)......额,竟然禁用了鼠标右键,好吧,这么鸡肋的功能我也是醉了,博主推荐安装一个火狐浏览器的小工具Web Deverloper Toolbar 这个工具很实用,后面会用到。
安装完之后会在浏览器上面看到一条工具栏,这里查看源代码就直接点击 Web Deverloper Toolbar 的View Source选择View Source选项即可
当然也可以按快捷键Alt + Shift + U查看源代码,总之是非常好使的工具。
查看源代码就很容易看到页面里面做了什么动作了,下面这段代码就是禁用鼠标右键的
function Click(){return false;} document.oncontextmenu=Click; function doPrev(){history.go(-1);}
这段代码博主也不知道为何要写上去,禁用右键的目的是什么呢?是怕别人看出代码写的太渣?
来接着看代码,javascript部分写了一些登录的操作,下面方法是生成base64编码,推测登录的时候是有用到base64编码
function Base64Encoding(input) { var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } return output; }
略过一些鸡肋方法之后找到登录的方法
function PCSubWin() { if(CheckPswLength() == true ) { var password = $("pcPassword").value; var auth = "Basic "+Base64Encoding("admin:"+password); document.cookie = "Authorization="+escape(auth)+";path=/"; location.reload(); } }
嗯,根据方法的逻辑是先检查密码的长度,咱们在脚本中就没必要检查了,所以剩下的就简单了,先制造一个字符串作为Cookie的值
"Basic "+Base64Encoding("admin:"+password);
注意看这里,默认的用户是admin,证明了之前的推测是没错的,登录用户是admin写死的,将用户和密码组合一下进行一次base64加密,然后接着看
document.cookie = "Authorization="+escape(auth)+";path=/";
这里往Cookie里面写入值,注意上面生成的那个base64编码需要调用escape方法进行一个url编码,然后刷新页面就好了,登录过程如此简单,比小米的登录简单多了
那么看到这有的同学就说了,这样的设计是很不科学的,很容易造成爆破,因为用户名都不用猜,只需要爆破密码就可以了,真的是这样吗?
博主就用错误的密码登录了数次之后出现了这个提示
密码错误已达10次,请两小时后再尝试 看来还是有做一些防御的,防止爆破嘛,博主决定研究下这个防御有没有起到实际作用
于是继续看代码
function pageLoad() { document.cookie = "Authorization=;path=/"; var ErrNum = httpAutErrorArray[0]; switch(ErrNum) { case 1: isShowReset = true; $("errMsg").innerHTML = "密码错误,请重新输入。"; $("errMsg").style.visibility = "visible"; $("resetMsg").style.visibility = "visible"; setPswDisable(false); break; case 2: isShowReset = true; $("errMsg").innerHTML = "密码错误已达10次,请两小时后再尝试。"; $("errMsg").style.visibility = "visible"; $("resetMsg").style.visibility = "visible"; setPswDisable(true); break; case 0: default: isShowReset = false; $("errMsg").style.visibility = "hidden"; $("resetMsg").style.visibility= "hidden"; setPswDisable(false); break; } var loginBtn = $("loginBtn"); loginBtn.onmouseover = function(){ loginBtn.style.background = "url(../login/loginBtnH.png)"; }; loginBtn.onmouseout = function(){ loginBtn.style.background = "url(../login/loginBtn.png)"; }; $("officialLink").onclick = function(){ window.open(httpAutErrorArray[1]); }; }
这段代码里面有提到关键字,所以就研究这段吧,这个pageLoad方法是页面加载完成后立刻执行的方法,看关键部分
var ErrNum = httpAutErrorArray[0]; switch(ErrNum) { .... case 2: isShowReset = true; $("errMsg").innerHTML = "密码错误已达10次,请两小时后再尝试。"; $("errMsg").style.visibility = "visible"; $("resetMsg").style.visibility = "visible"; setPswDisable(true); break; ... }
那个密码次数达到10次的提示就是这里生成的,看上去跟 httpAutErrorArray 这个数组里面的值有关系,找到这个数组所在的方法
var httpAutErrorArray=new Array(2,"http:////www.tp-link.com.cn",0,0 );
这段js代码是页面加载的时候自动生成的,很显然是服务端直接生成的,而需要的值就是httpAutErrorArray数组的第一个值,这里很显然是2,根据上面方法,状态时密码次数10次,正常登录的时候第一个值为0,这样才不会出现那个提示。这里咱们尝试修改第一个值试下,那么问题来了,怎么改?这个是服务端传过来的,拦截response?这么做是可以的,使用神器burp就能做到,但是这里使用burp未免显得大材小用,博主使用常用的小工具Firebug即可,首先调出firebug,调出console控制台,如图
博主用荧光笔写This的区域就是控制台区域,可以在这里写js代码并运行。
好了,开始,这里需要执行的操作就是修改httpAutErrorArray的第一个值,然后执行pageLoad方法即可,在控制台这么写就好了
httpAutErrorArray[0] = 0; pageLoad();
点击执行之后再看页面就变成了这个样子
是不是一下子就兴奋了起来呢?
试下登录吧,输入正确的密码后点击登录,出现这个界面
OH ,Fuck!看来是服务端也有限制了
不过没关系,不妨碍咱们的研究,上面提到了登录是直接向Cookie里面写入拼接好的字符串即可,那咱们就直接往cookie里面写不就好了,这里有两种方法
第一种就是使用firebug直接执行登录的方法
另外一种就是使用开始提到的那个Web Deverloper Toolbar工具
点击工具栏的Cookies
选择View cookies Infomation进入Cookies的编辑界面
点击下面的Edit按钮就可以开始编辑了
这里咱们需要编辑的是Value字段,根据js代码中的登录方法得到值应该是Base加空格加base64(admin:密码)的形式,博主这里使用的密码是666888,所以得到的值为Base YWRtaW46NjY2ODg4 然后进行url编码,得到的结果是Base%20YWRtaW46NjY2ODg4
URL编码和解码的网站 http://tool.chinaz.com/tools/urlencode.aspx
Base64加密解密的网站 http://www1.tc711.com/tool/BASE64.htm
写入Cookie值之后保存刷新登录界面,不出意外的话就登录成功了,当然博主这里还是处于密码输入错误的状态,需要两个小时后再试
好了,趁着这段等待的时间咱们直接来写Python脚本吧,这个利用Cookie就能登录的脚本写起来应该是非常容易了。
需要的模块:requests,base64,re
base64模块用来生成base64编码的字符串,re模块是用来匹配服务端返回的一些字段。
路由器功能相对简单,就不写什么class类了,直接定义几个方法,首先做登录方法,代码如下,很简单,不做过多解释
def doLogin(): url_login = 'http://' + sys.argv[1] cookie = {"Authorization":"Base%20" + base64.b64encode("admin:" + sys.argv[2])} try: response = requests.get(url = url_login,cookies = cookie) serverResult = ''.join(response.text.split()) loginStatus = int(re.findall(r'varhttpAutErrorArray=newArray/((.+?),"http',serverResult)[0]) if loginStatus == 2: print '/nServer: Login status is '+ str(loginStatus) +'/nYou have entered the wrong password 10 times. Please try login again in 2 hours.' except Exception,e: print e return
运行效果是这样的
接着咱们来写个修改登录密码的方法作为例子,其他的功能写起来类似