项目要求:采用HTTP模拟系统自动登录到163邮箱,取对应主题下的邮件,打开邮件获取邮件内容
模拟登录,首先就是抓包,分析通讯数据包,并构造相应的数据包
登录时发现163有多个邮件登录入口,最常用提就是www.163.com和mail.163.com两个入口地址,为了抓包数量简单从mail.163.com入口开始,抓包工具(网友推荐了各种抓包工具,httpwach、HttpAnalyzer,、wireshark,其实真正的高手就像达摩过江,一苇足矣,18般武艺多来眼花,我不是达摩,是懒)直接将浏览器(chrome)设置为开发工具,在network中,刷新页面,轻松看到所有通讯数据。
开始吧,清除浏览器缓存,开发者工具,刷新页面http://mail.163.com
居然用的URS的IFRME,不用管,飘过,直接看通讯。
这是一个找似有价值的通讯,因为是叫index_dl https://dl.reg.163.com/webzj/m163_1.0.1/pub/index_dl.html?wdaId=&pkid={0}&product=mail163
已经有数据通讯了,好像没有什么功能,有一个动态变量pkid,估计就是加载页面首页从服务器上来的吧
看前面的页面请求的返回结果,根据以往经验此值要只有两个手段携来,在response的content、response的header的cookie中,往回找,在http://mail.163.com 中的html轻松发现,用正则表式取出来
继续往下没有发现有价值的请求,尽是GET请求,先老老实完成对应的get请求,反正url地址容易构造出来
依次完成getconf,http://dl.reg.163.com/getConf?callback=URSJSONP1501213566234&pkid=CvViHzl&pd=mail163&mode=1(callback后面那个15034439875719感觉就是一个时间戳),和get.do(其中RND就是一个随机数)的请求。
居然有INI?这样的请求,根据经验有可能是初始化某种环境,管他的,先构造get请求完成对应的请求。
Ps.以上所有的GET请求的目的就是构造http的cookie环境,或者获取一些以后请求的参数,都是get请求,完成即。
言归正传,继续往下
输入邮箱和密码看通讯
根据惯例去找post请求吧,一定是在某个地方将我的用户名和密码传到服务器,居然没有,靠,变态,老老实实地看get和post请求,从结果入手,先找到登录成功的页面(里面可是藏着我登录后的欢迎信息的,至少有我的昵称吧,找到了不过是个get请求,且有一个sid),记住了sid,sid,sid,重要的事情说三遍,好吧,找sid值的来源,找,在response中的content中没有,header吧,往前找
这个通讯的header有一个key为Coremail的值,好家伙,居然藏在这儿,取出来放到,构造请求访问,页面返回402错误,也没有Coremail这值,好,之前一定还有什么东东要访问,目前权限不够,而且在header发现有cookie的很多值,应该是之前访问带回来的,往上看
好大的一个怪异请求:
httpLoginVerifyNew这样的名字,看到都振奋,登录验证,检查了请求参数rcode是什么鸟,这么长一串,有点像加密字符串,回找看是否在reponse夹带过来的,找了个遍,conent和header都没发现,那就是本地的js加密出来,好家伙,有了js加密,那就资源文件,看JS文件吧
藏在这儿,好的,调试,一步一步地找(好辛苦,还有定时器),功夫不负有心人,将监控rcode的值,只有rcode有值时才是我们关注的事件,之前的事件rcode都是undefined,所以不用关注,左边的天书不用关注。
总算抓到狐狸的尾吧
fEnData("200\n10001\n8365DB022E04083AEBA0A1A828A216858A93B2C469462D7B497CDB4DCC636161C773B28C2D757978347500D04AA2CA8AEC9C477FFF085BF8247E780AA7D20F35992A289BA86F2C4998AB83C4C6744FF9A0F2D3020AA49E3397C95B2AF32A84C6EC1AB0B52BFBBA380C7B3371DCA46BA9FD44F14D5CC4BEBCGGE0F3914D63731D");
现在找fEnData的执行什么的?
http://mimg.127.net/index/lib/scripts/base_v6_0_6.min.js这儿找到这个了
使用这个还得有个依赖库
这个函数的返回值直接赋给了rcode。
看懂以上代码了,就测试下,构造WEB项止,编测试代码
,那么就得找fendata的参数了
到此基本眉目清楚了,将JS库到一个WEB项目中,写一个测试HTML,直接在js中执行alert(“result=>”+ fEnData("200\n10001\n8365DB022E04083AEBA0A1A828A216858A93B2C469462D7B497CDB4DCC636161C773B28C2D757978347500D04AA2CA8AEC9C477FFF085BF8247E780AA7D20F35992A289BA86F2C4998AB83C4C6744FF9A0F2D3020AA49E3397C95B2AF32A84C6EC1AB0B52BFBBA380C7B3371DCA46BA9FD44F14D5CC4BEBCFDE0F3914D63731D"));
亲,大大一个字符串出来了,
数一数长度,正好和rcode的长度一样
开始找fendata的那参数,也就是JS代码中常量g,又从哪儿来,继续在JS搜索,未果,那就去找之前的response,这样一个请求
http://reg.163.com/services/httpLoginExchgKeyNew?rnd=bm9zaUAxNjMuY29t&jsonp=fEnData不正是刚好返回的字符串,太亲切了
问题又来了,这儿可是有个rnd的请,随机数可不长成这个模式的,就是穿着随机数的外衣的家伙,往前
发现这样一个通讯
https://dl.reg.163.com/gt?un=nosi%40163.com&pkid=CvViHzl&pd=mail163&topURL=http%3A%2F%2Fmail.163.com%2F&nocache=1501213601737,这个通讯有点意思,un:username ,返回中有一个tk的值,正则取值,tk:token,哈哈,这个tk的值不正是那个穿着随机数外衣的狼哇,抓住你了吧,看你哪里跑。
好了,到此之前的问题都解决了,我们梳理一下
(1) 构造环境,访问http://mail.163.com找到了PKID
(2) 构造访问https://dl.reg.163.com/gt取到TK
(3) 通过tk取到JS的执行fendata()js参数
(4) 构造WEB项目通过JS执行fendata执行取到rcode
(5) 通过rode完成模拟登录请求登录httpLoginVerifyNew.jsp
这儿有个问题,如果是个WEB项目,当然可以轻松访问js库,如果非web项目,提供两种解决方案:
1 用你熟悉的语言c#\python\php\java自己去实现两个js库的转化,我简单地看了一下就是RSA加密处理,自己写吧,或去找对应的库,在编写时要查看清楚所使用的MD5的位数(16位 32位 64位),编码格式,公私钥的内容,好像我有C#和JAVA版的的RSA加密库,N久的项目不想去翻了。
2 用WEB组件中的js引挚去实现,在windows环境下可以用webbrower控件中的IE,也可用chrome中的V8去实现;
本人原来有个项目做使用的使用了.NET中的JavascriptContext 类,做了一个WEB API接口,4参数(这前的JS库以及本次调用的JS代码文件),调用方式:
post url: http://localost/doscript.apsx
post data: {
“key”:”098dbs=”,
libs:[{url: mimg.127.net/index/lib/scripts/base_v6_0_6.min.js},
{url: http://mimg.127.net/index/lib/scripts/algorithm.js}
],
user_js_block,
user_js_parameter}
key:接口授权key
libs:使用的js库
user_js_block用户定值为:
functionKS_RSAEncrypt(vkey, vpassword) {
var h = new Array();
h = vkey.split("\n");
var f = h[1];//10001
var b = h[2];
var c = MD5(vpassword); // MD5("12343545");
var e = new RSAKey();
e.setPublic(b, f);
var d = e.encrypt(c);
return d;
}
user_js_parameter
{
vkey:” 200\n10001\n8365DB022E04083AEBA0A00828A216858A93B2C469462D7B497CDB4DCC636161C773B28C2D757978347500D04AA2CA8AEC9C477FFF085BF8247E780AA7D20F35992A289BA86F2C4998AB83C4C6744FF9A0F2D3020AA49E3397C95B2AF32A84C6EC1AB0B52BFBBA380C7B3371DCA46BA9FD44F14D5CC4BEBCFDE0F3914D63731D”,
vpassword:””
}
返回值
[{
result:1, //返回状态
data:””//返回值,支付json对象,根据用户自定义结果,这儿data的值就是rcoce
}]
开始写程序,用以前的库HttpUtil,有get post请求,支持cookie并可读取,支持ssl
在调试状态走到第3步时,将字符串复制出来到WEB项目中进行加密,加密后取出作为http请求的rcode参数.继继访问。
有了sid,急不可待地去访问邮箱登录成功首页
http://hzwebmail.mail.163.com/js6/main.jsp?sid=fBBBujXgLUvtpWloaHggMQWCEbRGLxws&df=idc2email163
看是否成功,在response.content中,找一找,“收件箱”、“发件箱”,本人邮箱的昵称“刘举平”,(立不改性坐不改名,真实有效)都返回了成功的找到的信息,喜极而泣,登录成功了。
做模拟登录,重点是分析请求,并找到关键的登录信息,模拟出GET和POST请求的参数,并做好监控COOKIE的事。
回头再说读邮件详细内容以及126邮箱模拟登录他们可是一个家族的。