linux socket 访问web,linux下用socket登陆访问web

最近实验室出了一个有点可恶的政策,就是每天到实验室上班时签到,走时注销,以记录你的工作时间,只让登陆也就罢了,走时还得想着是否注销了,不然也是“缺勤”。

这个可恶的做法直接导致大家开始找自动登陆的办法,“院长”已经找到了一个办法,用C#控件写了一个浏览器来实现。

我一开始想到用linux下的Expect自动登陆bbs的办法来做,后来发现获取不到web的关键字,更主要的是对Expect不熟悉,于是放弃。然后想到socket来发送伪造的http报头,来给服务器发送相应的请求报文应该就可以了,于是开始实施。

为了了解我们手动登陆时和服务器交互的http报文内容,只有通过抓包的方式来截取发送的http报文,需要下载一个抓包工具,我用的是Ethereal,简单使用就是安装ethereal-setup-0.10.13.exe,它会要求安装相应的WinPcap_3_1.exe。安装完之后启动Ethereal,点击Capture -> Options,通过Interface下拉菜单选择相应的网卡,开始抓包,抓包后在Filter项输入 http and ip.addr == 59.xx.xx.xx来选择需要分析的http包。

分析发现发送用户名和密码报文有两条,第一次发送用户名密码时,服务端会传送给我们一个JSESSIONID,这个sessionid是需要在紧接着的第二次发送用户名密码时返回给服务器的,因此需要截取出这个JSESSIONID的值,登陆成功后,还有一个点击“我要登陆”的操作,这个是发送GET报文就行了,其中同样要有JSESSIONID。对其中遇到的最大问题就是这个,然后就是两次POST报文之间连接是不能中断的,最后点击“我要登陆”的GET报文,连接需要重新建立一下。主要的就这些吧,有可能不对的地方,因为我地HTTP完全不懂,哎,本科时对这些竟然一点没学好。

Ethereal下载地址-信息技术/计算机网络/北邮校园网/Sniffer_Ethereal/

HTTP报文理解:

自动登陆http报文理解

就给出这些吧,下面给出部分程序

struct sockaddr_in web;/* 服务器 */

char request[1024] = {'\0'}; /* 客户端发送的请求报文内容 */

char recvbuf[4096] = {'\0'};/* 客户端接收的内容 */

char sessionid[40] = {'\0'};/* 获取JSESSIONID */

FILE *fd;

memset(&web, 0, sizeof(web));

web.sin_family = AF_INET; /* ipv4 */

web.sin_port = ntohs(PORT);

web.sin_addr.s_addr = inet_addr(SERVER_IP);

s = socket(PF_INET, SOCK_STREAM, 0); /* socket */

if (s == -1)

bail("socket(1)"); /* 错误处理函数 */

c = connect(s, (struct sockaddr *)&web, sizeof(web));

if (c == -1)

bail("connect(1)");

s = socket(PF_INET, SOCK_STREAM, 0);

c = connect(s, (struct sockaddr *)&web, sizeof(web));

memset(request, 0, 2048);

strcat(request, "POST /check/checkuser.jsp HTTP/1.1\r\n");

strcat(request, "Accept: text/html\r\n");

strcat(request, "Referer: ");

strcat(request, "Accept-Language: zh-cn\r\n");

strcat(request, "Content-Type: application/x-www-form-urlencoded\r\n");

strcat(request, "Accept-Encoding: gzip, deflate\r\n");

strcat(request, "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon)\r\n");

strcat(request, "Host: 59.xx.xx.xx:xx\r\n");

strcat(request, "Content-Length: 63\r\n");

strcat(request, "Connection: Keep-Alive\r\n");

strcat(request, "Cache-Control: no-cache\r\n\r\n");

strcat(request, "username=liuby&userpw=MIMA&usertype=student&Submit=%B5%C7%C2%BD");

//  printf("%s\n,%d\n", request,strlen(request));

z = send(s, request, strlen(request), 0); /* send */

recv(s, recvbuf, 4096, 0);  /* 接收 */

get_sessionid(recvbuf); /* 获取sessionid */

/* 此时接收到的报文显示为302 Moved Temporarily,这种一般需要再次发送请求GET需要跳转到的网页,不知道我这样理解对不对,完全是根据这次做的来猜测的 */memset(request, 0, 2048);

strcat(request, "GET /check/students/stulogin1.jsp?username=liuby&usertype=student HTTP/1.1\r\n")");

/* 根据抓包分析和JSESSIONID,再次构造要发送到服务器的报文 */

close(s); /* 关闭连接,如果要再次请求,重新建立socket,connect,send等 */

整个下来没什么技术含量,只是让自己学了一下如何抓包分析。

另外在网上也搜到了一个Window下自动登陆的办法,将以下内容以记事本保存为.vbs后缀的文件。双击实现登陆

++++++++++这是我们实验室网站的自动登陆注销vbs脚本+++++++++++++++++

set ws = createobject("Wscript.shell")

username = "liuby"

password = "密码"

ws.Run "IExplore =" & username & "&userpw=" &  password & "&usertype=student&Submit=%B5%C7%C2%BD"

Wscript.sleep 2000

ws.SendKeys "{TAB}"

ws.SendKeys "=" & username & ""

WScript.Sleep(5)

ws.SendKeys "{ENTER}"

假如此文件位置位于g:\autologout.vbs

如果想11:30注销,在Win+R弹出的运行中输入at 11:30 /i "g:\autologout.vbs"

Wscript.sleep 2000中根据自己电脑的反应速度来修改2000为其他值

还有一个bug,就是在11:30这个运行此脚本的时间时,最好不要有其他操作

上面这个方法参考自各种自动登陆脚本

有点小介绍

SendKeys 方法用于将一个或多个键击发送到活动窗口(仿佛是在键盘上击键一样)。参考文章为

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值