自己动手写H3C校园网登录客户端(Linux平台版)

By 马冬亮(凝霜  Loki)

一个人的战争(http://blog.csdn.net/MDL13412)

周一晚上的时候,和实验室的ZL同学提聊到了Android手机使用Wifi连接学校的无线网掉线的问题。由于我们学校的上网登录客户端仅支持Windows平台,在其他平台无法使用,所以,一直以来大家的解决方案就是使用浏览器进行登录。在Linux PC上使用网页登录还是很稳定的,但是一旦使用我的小平板(Android系统)登录的时候,就会在10分钟以内掉线。其实,早在一年前就想给我的Linux PC写一个登录的客户端,但是一直懒得去分析协议,这次经ZL同学一说,决定动手分析一下登录协议,写一个客户端给大家用。

首先交代一下我的开发环境:

操作系统:Fedora 16(Verne)

内核版本:3.3.1-3

浏览器:Google Chrome 17.0.963.79

开发语言:Python(3.2)

开发工具:Eclipse 3.7.1 (PyDev 2.2.4.2011110216)

网络分析工具:WireShark 1.6.5

下面开始分析登录协议,在gnome-terminal终端下使用root权限运行wireshark(注意:在Fedora上,必须要用root权限去运行wireshark才能设置网卡到混杂模式),如下图所示:

接下来设置过滤器,点击菜单栏上的“Capture”->“Options”,弹出如下图所示的"Capture Options"对话框:

单击“Capture Filter”按钮,弹出过滤器选择对话框,如下图所示:

由于我是要分析网络客户端登录的数据包,所以用IP进行过滤是最佳选择,我们校园网验证的服务器地址为192.168.252.251,将其填入上图的"Filter string"选项中就可以进行过滤了。然后点击“确定”,在单击“Start”开始抓包。

打开浏览器,输入http://192.168.252.251:8080/portal/index_default.jsp,这个地址是我们进行网页登录的首页。此时抓到的数据并不是我们想要的数据,填入帐号和密码,如下图所示:

点击“上线”,开始查看数据包,经过分析,我找到的关键数据包如下图所示:

我们在Line-based text data: application/x-www-form-urlencoded这项中看到了如下字段,userName=mdl_&userPwd=V1hYWVlESkowMDA%3D&isQuickAuth=false&language=Chinese&browserFinalUrl=&userip=null,很明显userName没有进行加密,而userPwd被加密了,为了得知加密算法,我修改了几次密码,并对其映射关系进行了分析,映射关系如下:

AAA000                  QUFBMDAw
        000AAA                  MDAwQUFB
        000000A                MDAwMDAwQQ%3D%3D
        000000AA              MDAwMDAwQUE%3D
        000000AAA            MDAwMDAwQUFB
        000BBB                  MDAwQkJC
        000000B                MDAwMDAwQg%3D%3D
        000000BB              MDAwMDAwQkI%3D
        000000BBB           MDAwMDAwQkJC

经过分析,这个加密算法是每3个字节加密一次,并且将其映射为4位ASCII字符,对于不足三位的用%3D填充,很明显了,这个是Base64加密。有了加密算法,还要分析Cookie字段Cookie: JSESSIONID=3D4B4FBA9E201DFEF973138DF52B5161; hello1=mdl_; hello2=false; hello3=; hello4=\r\n,对于记住密码和不记住密码,这个字段的内容是不同的,经过分析HTTP的流程,我发现Cookie的JSESSIONID是客户端Notify给服务器的,那么就给我们伪造Cookie提供了可能。

经过分析,hello1字段是用户名,hello2字段是是否记住密码,hello3字段在记住密码的时候是一段经过加密的字符串,不记住密码的时候为空,hello4字段是登录的资费类型,我们学校没有使用到这个字段,所以始终为空。

分析完这个数据包,我发现,帐号和密码验证成功后客户端又向服务器发送了如下的数据包:

其中Cookie字段和上一个数据包一致,Line-based text data: application/x-www-form-urlencoded中language=Chinese&heartbeatCyc=240000&heartBeatTimeoutMaxTime=3&userDevPort=IAG_5000-vlan-02-0000%40vlan&userStatus=99&userip=null&serialNo=-19730&basip=这段后来经过分析,是同时post给本地和服务器的,客户端的在线页面也要接收一份此字段中的参数。

接下来,我找到了心跳检测的数据包,这个是客户端主动发送给服务器的验证包,如下图:

           开始的时候我认为只要每隔一段时间向服务器GET这个数据包的内容,并且保持TCP长连接就可以不掉线了,但是经过验证,这是不可行的。后来又尝试模拟浏览器的所有行为,但是也没有成功。最后,想到在一台机器上如果帐号已经在线,再次发送的登录请求,服务器会返回用户已经在线信息,并重新设置掉线时间,于是突破点找到了,我每隔1分钟,向服务器发送一次登录请求,终于,可以保证稳定在线了。

下面将我用Python写的客户端代码贴出来,给大家做一个参考,为了能最小负担的移植到其他平台,我将最初的PyQt4做的界面去掉了,还是使用了纯终端的程序:

这个项目总共分为3个文件,config.ini保存用户的账户和密码,NsINodeLogin.py负责登录并维持在线,NsINodeLogout.py负责下线。

config.ini

[Account]
username:mdl_
password:MYPASSWORD

NsINodeLogout.py

# -*- coding: utf-8 -*-welcomeInfo = '''
作者:马冬亮
单位:内蒙古科技大学信息工程学院ACM程序设计协会
博客:http://blog.csdn.net/MDL13412
邮箱:mdl2009@vip.qq.com
Q Q:401074567
版权所有 (C) 2012 凝霜.保留所有权利.使用方法:
修改当前路径下的config.ini文件,将用户名和密码填写至相应字段
登录使用NsINodeLogin.py
注销使用NsINodeLogout.py
在线时请不要关闭本程序
'''import http.client
import base64
import os
from configparser import ConfigParserrequesteaders = {'Connection':'keep-alive','Cache-Control':'max-age=0','User-Agent':'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11','Content-Type':'application/x-www-form-urlencoded','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Encoding':'gzip,deflate,sdch','Accept-Language':'zh-CN,zh;q=0.8','Accept-Charset':'GBK,utf-8;q=0.7,*;q=0.3','Cookie':''
}if __name__ == '__main__':try:print(welcomeInfo)try:configFile = ConfigParser()configFile.read(filenames=os.getcwd() + '/config.ini', encoding='utf-8')username = configFile.get('Account', 'username')pwd = configFile.get('Account', 'password')except:print('加载用户信息错误')logoutBody = 'userName={0}&userPwd={1}&isQuickAuth=false&language=Chinese&browserFinalUrl=&userip=null'requesteaders['Cookie'] = 'JSESSIONID=F447CB1C348B7D7AA6C02CBA3ECBF7AF; hello1={0}; hello2=flase; hello3=; hello4='.format(username)pwd = base64.encodebytes(pwd.encode(encoding='utf_8', errors='strict'))pwd = pwd.replace('='.encode(encoding='utf_8', errors='strict'), '%3D'.encode(encoding='utf_8', errors='strict'))logoutBody = logoutBody.format(username, pwd)logoutBody = logoutBody.replace("b'", "")logoutBody = logoutBody.replace("\\n'", "")while True:conn = http.client.HTTPConnection('192.168.252.251:8080')conn.request('POST', '/portal/logout.jsp', logoutBody, headers=requesteaders)res = conn.getresponse()if res.status == 200:print('下线成功')else:print('下线失败')breakexcept Exception as e:print('出错啦...请检查网络连接...')

NsINodeLogin.py

# -*- coding: utf-8 -*-import http.client
import time
import base64
import os
from configparser import ConfigParserrequesteaders = {'Connection':'keep-alive','Cache-Control':'max-age=0','User-Agent':'Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11','Content-Type':'application/x-www-form-urlencoded','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Encoding':'gzip,deflate,sdch','Accept-Language':'zh-CN,zh;q=0.8','Accept-Charset':'GBK,utf-8;q=0.7,*;q=0.3','Cookie':''
}if __name__ == '__main__':try:os.system('python3 ./NsINodeLogout.py')try:configFile = ConfigParser()configFile.read(filenames=os.getcwd() + '/config.ini', encoding='utf-8')username = configFile.get('Account', 'username')pwd = configFile.get('Account', 'password')except:print('加载用户信息错误')loginBody = 'userName={0}&userPwd={1}&isQuickAuth=false&language=Chinese&browserFinalUrl=&userip=null'onlineBody = 'language=Chinese&heartbeatCyc=240000&heartBeatTimeoutMaxTime=3&userDevPort=IAG_5000-vlan-02-0000%40vlan&userStatus=99&userip=null&serialNo=15500&basip='requesteaders['Cookie'] = 'JSESSIONID=F447CB1C348B7D7AA6C02CBA3ECBF7AF; hello1={0}; hello2=flase; hello3=; hello4='.format(username)pwd = base64.encodebytes(pwd.encode(encoding='utf_8', errors='strict'))pwd = pwd.replace('='.encode(encoding='utf_8', errors='strict'), '%3D'.encode(encoding='utf_8', errors='strict'))loginBody = loginBody.format(username, pwd)loginBody = loginBody.replace("b'", "")loginBody = loginBody.replace("\\n'", "")while True:conn = http.client.HTTPConnection('192.168.252.251:8080')conn.request('POST', '/portal/login.jsp', loginBody, headers=requesteaders)res = conn.getresponse()if res.status == 200:print('发送验证信息成功')data = res.read()if -1 == data.find(b'3032'):print('登录信息正确')else:print('请检查登录信息')breakelse:print('发送验证信息失败')continueconn = http.client.HTTPConnection('192.168.252.251:8080')conn.request('POST', '/portal/online.jsp', onlineBody, headers=requesteaders)res = conn.getresponse()if res.status == 200:print('发送在线信息成功')else:print('发送在线信息失败')continuetime.sleep(60)except Exception as e:print('出错啦...请检查网络连接...')

这个程序因为属于实验性的代码,没有进行详细的错误校验,不过对于校园网的登录来说,已经足够用了。

自己动手写H3C校园网登录客户端(Linux平台版)相关推荐

  1. SSO单点登录教程(四)自己动手写SSO单点登录服务端和客户端

    作者:蓝雄威,叩丁狼教育高级讲师.原创文章,转载请注明出处. 一.前言 我们自己动手写单点登录的服务端目的是为了加深对单点登录的理解.如果你们公司想实现单点登录/单点注销功能,推荐使用开源的单点登录框 ...

  2. 统信uos系统考试题_离Windows更近一步!微信Linux原生版上线:国产统信UOS系统已适配...

    就在本月11号,国产操作系统-统信 UOS发布了专业版 V20(1030),功能更强大,同时性能和安全性均有所提升. 而距离这个好消息过去没多久,统信软件官方再次发布了一个好消息: 那就是微信桌面客户 ...

  3. 自己动手写邮件客户端(1)

    自己动手写邮件客户端(1) --命令行测试发邮件 参考 RFC中文 环境 系统: win10 语言: java 简要流程 建立一个到邮件服务器的连接(在此使用smtp.163.com:25) Sock ...

  4. 《自己动手写Docker》书摘之三: Linux UnionFS

    UnionFS UnionFS是一种为Linux,FreeBSD和NetBSD操作系统设计的把其他文件系统联合到一个联合挂载点的文件系统服务.它使用branch把不同文件系统的文件和目录"透 ...

  5. linux系统编程:自己动手写一个who命令

    who命令的作用用于显示当前有哪些用户登录到系统. 这个命令执行的原理是读取了系统上utmp文件中记录的所有登录信息,直接显示出来的 utmp文件在哪里呢? man who的时候,在手册下面有这么一段 ...

  6. 锐捷文件描述错误linux,Kubuntu 14.10 MentoHUST 配置libpcap 锐捷校园网登录总结

    KUbuntu 14.10 mentohust 配置libpcap 锐捷校园网登录总结 首先需要说明,mentohust 和锐捷一样,都依赖 libpcap 这个函数库. 而配置libpcap 前,需 ...

  7. Linux C语言自己动手写日志生成函数

    有时候需要自己把日志信息保存到日志文件中,没有找到现成的函数,只好自己动手写一个,完成相关功能. void LOG(const char* ms, ... ) {char wzLog[1024] = ...

  8. APP:校园网登录app—中小南—源码简析

    转载请注明出处:http://www.cnblogs.com/wondertwo/p/5392496.html 最近一段时间真的很惭愧,一直琐事缠身没有空闲的时间来安安心心写一篇博客,直到今晚基本忙完 ...

  9. 写个.net开发者的Linux迁移指南

    前言 为什么要迁移到Linux 首先我个人还是有点软件洁癖,以前是穷酸学生的时候也是用盗版的用户,后来在知乎被洗脑终于有了点版权意识.然后便有了能用开源软件的就用开源,实在不能就选社区版或者免费版.于 ...

最新文章

  1. Flutter中关键字Const和Final之间的区别
  2. [转]图片自动缩放 js图片缩放
  3. 整型和浮点型的区别_浮点整型强转的一个题目解析
  4. java复制文件_java多种文件复制方式以及效率比较
  5. 话里话外:实践企业内控,需与流程沟通(二)
  6. dmp导入数据 oracle_oracle数据库:数据的导入导出及备份
  7. 每天学一点flash(76)百度MP3音乐APi接口使用
  8. 专业科目笔试计算机,2021年度中国证监会招考职位专业科目笔试考试大纲(计算机类)...
  9. 谈一谈AI算法部署的一些经验
  10. Python编程的例子----股票数据接口
  11. 已解决:ubuntu-软件更新处无nvidia驱动/ubuntu检测不到扩展屏幕
  12. RocketMQ-单条消息大小上限
  13. mysql migration toolkit报错_MYSQL Migration Toolkit 安装
  14. ResNet之残差结构的理解
  15. python中函数的学习
  16. Blender 利用遮罩剔除顶点
  17. 求树的直径算法以及证明
  18. ISE Module Browser –直观高效的PowerShell模块管家!
  19. IPGuard启动加密常用的策略
  20. 为什么懂得很多道理,却依然过不好这一生

热门文章

  1. 【转】开发者需要了解的领域特定语言(DSL)
  2. ElementUI表格中显示图片,悬浮显示放大图片
  3. win10 开机软件自动启动设置
  4. lisp画垫圈_基于DCL和AutoLISP语言开发的垫圈标准件库
  5. Me and My Girlfriend:1
  6. BUFF:iPad真的能当砧板用
  7. 如何关闭电脑的休眠功能
  8. 并行计算系列-阿姆达尔定律(Amdahl‘s Law)
  9. 实验7 Wireshark网络安全检测
  10. 计算机网络实习内容,计算机网络工程实习目的与内容