14回答

4收藏

58同城协议登录案例

信息分享 信息分享 5038 人阅读 | 14 人回复 | 2020-11-11


案例:通过协议模拟登录58同城




---

login url : https://passport.58.com/58/login/pc/dologin









观察了一下需要注意的参数有:

- username: 账号

- password: 加密(密码)

- token: 密文




password是密码加密后的定值,token是动态的。

ctrl+F搜索一下token值,找到了返回token的接口

可以观察出获取token的接口中, callback和path参数 跟时间戳有关






点击右侧的 Initiator , 点第一个 r 进去,打上断点,刷新页面



刷新之后可以看到,如下图所示



可以发现此处i中的callback参数是和t的值一样



往上找一找t是如何生成的



var t = e.jsonpCallback || "JsonpCallBack" + (new Date).getTime() + Math.floor(1e3 * Math.random())

既 t =  "JsonpCallBack" + 时间戳 + 随机数




这里可以把js复制下来用execjs生成,也可以用python来模拟:
import math,time,random
print("JsonpCallBack" + str(int(time.time()*1000)) + str(math.floor(1000*random.random())))



经过观察,path参数  "固定的url" + "13位时间戳"

接着可以来用代码构造下请求,获取token值
import math,random,time
import requests
pathtime = str(int(time.time() * 1000))
jsoncallback = "JsonpCallBack" + str(int(time.time() * 1000)) + str(math.floor(1000.0 * random.random()))
url = "https://passport.58.com/58/login/init?source=58-homepage-pc&path=https%253A%252F%252Fbj.58.com%252F%253Fpts%253D{}&psdk-d=jsdk&psdk-v=1.0.6&callback=JsonpCallBack{}".format(pathtime,jsoncallback)
headers = {
'referer': 'https://passport.58.com/login?path=https%3A%2F%2Fmy.58.com%2F',
'sec-fetch-dest': 'script',
'sec-fetch-mode': 'no-cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
    }

print(requests.get(url,headers=headers).text)



打印出的结果中可以提取到token
JsonpCallBackJsonpCallBack1605081373854724({"code":0,"data":{"complainSwitch":true,"rememberSwitch":true,"token":"CJQM-Txgu-IiNWn-4F5Td-kJAgEPcHtd","action":"0"},"msg":"成功"})



其实拿到token后就可以完成模拟登录了,感兴趣的话可以一起再找一下登录密码是如何进行加密的。




还是先搜索参数位置,找到一个最像的






可以通过关键词password 搜到 n.encrypt,然后找到了这里,断点调试下









可以发现,e.password 就是我们输入的密码,n.encrypt 就是加密后的结果









所以点进去看一下









在该位置断点

e点进去可以发现






在生成i,o后,经过处理传递到 encryptString



encodeURIComponent():  这里是 Native code 函数:   把字符串作为 URI 组件进行编码,(正常的密码可以不管)

rsaExponset 和 rsaModulus 这两个值直接复制出来,

r.rsaExponent = "010001"

r.rsaModulus = "008baf此处省略N多字40db74cb69f"



点击跳转到 encryptString 方法查看:

t和s已经有了,o可以在上面找到,时间戳+i,i=定值-时间戳






可是加密好像跟密码没有什么关系呀,回过头看了一下,才发现 o 在外层是和密码拼接了一下。









接下来组合上面的js,先把encryptString全部复制到一个js文件中,

然后定义一个方法传入参数来调用。

为了省空间,先把前面的改动贴出来,最后再放完整的代码。



function encryptString(pwd) {
    var ii = 1411093327735 - (new Date).getTime();
    var o = (new Date).getTime() + ii;
    var i = o + pwd;
    var r = RSAUtils.getKeyPair("010001", "", "008baf14121377fc76eaf7794b8a8af17085628c3590df47e6534574efcfd81ef8635fcdc67d141c15f51649a89533df0db839331e30b8f8e4440ebf7ccbcc494f4ba18e9f492534b8aafc1b1057429ac851d3d9eb66e86fce1b04527c7b95a2431b07ea277cde2365876e2733325df04389a9d891c5d36b7bc752140db74cb69f");
    return RSAUtils.encryptedString(r, i)
}
!function(e) {
    void 0 === e.RSAUtils && (e.RSAUtils = {});
    //此处省略N行代码
    //此处省略N行代码
    RSAUtils.setMaxDigits(130)
}(window);



把js复制到控制台测试一下,返回的结果和最初看到的一样,说明成功了









下面可以构筑完整的登录代码了




目前这里文章发布后不能修改,还是贴csdn的链接,后边有改动方便更新

博客地址:  https://blog.csdn.net/weixin_43582101/article/details/109253299 




输出的结果:




返回的response-header中,set-Cookie就是登录成功后服务端发放的cookie。

如果返回中没set-cookie的话,可能是你的账号风险程度较高,登录时需要验证码。

如果是图文验证码,可以想办法识别后,写入data的参数中,重新请求,

如果是向平台发短信验证的话,推荐换号吧。






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
分享到:
回复

使用道具 举报

回答|共 14 个

franky

发表于 2020-11-12 14:10:51 | 显示全部楼层

666
回复

使用道具 举报

milk

发表于 2020-11-12 17:51:37 | 显示全部楼层

写的很详细,不错,顶一下
回复

使用道具 举报

LBin

发表于 2020-11-12 17:56:37 | 显示全部楼层

大佬 牛皮!!!!!!!!!!!
回复

使用道具 举报

LaVine24

发表于 2020-11-16 09:29:30 | 显示全部楼层

666
回复

使用道具 举报

chenqilei

发表于 2020-11-16 16:23:12 | 显示全部楼层

1
回复

使用道具 举报

nicholas_yang

发表于 2020-11-18 14:39:07 | 显示全部楼层

6666666
回复

使用道具 举报

杨熠文

发表于 2020-11-21 22:50:59 | 显示全部楼层

1
回复

使用道具 举报

pingz

发表于 2020-12-26 13:24:56 | 显示全部楼层

大佬牛批哦!!!
回复

使用道具 举报

shock

发表于 2021-1-19 19:15:43 | 显示全部楼层

666
回复

使用道具 举报