10

唯品会密码JS解密与python登录

 3 years ago
source link: http://www.happyhong.cn/ni-xiang/python/10036.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
唯品会密码JS解密与python登录 | 从今天开始种树

上班都快一周了,一直想更新,奈何小伙还没有从假期的快乐中缓过来,今天终于耐下心来更新一小篇。抠一下某品会的JS代码,接着使用抠取的JS代码加密密码进行登录。友情提示:为避免不必要的纠纷,本文中所有网址都进行了一定隐藏。看完本文觉得有帮助关注一下知识图谱与大数据公众号吧,有大量抠JS代码的文章,当然不关注也无所谓,完整代码点击文末阅读原文。如有侵权,联系删除。

在这里插入图片描述
在这里插入图片描述

标题已经阐明了本文的目的:

  1. 密码加密解密;
  2. 利用第一步加密方法加密后进行登录;
  3. 完整代码中尝试了多账号号批量登录(由于篇幅有限,移动到了阅读原文中);

找到目标网站,进入登录页面(对各位来说都很easy):

在这里插入图片描述
在这里插入图片描述
像以往一样输入错误的账号密码,看看提交的数据,点击登录后,提交账号密码url如下:
在这里插入图片描述
在这里插入图片描述

继续看FormData,如下图:

在这里插入图片描述
在这里插入图片描述

图中的loginName为你输入的用户名,password为密码,可以看出被加密了,如果你熟悉了各类JS加密方式,心里应该能大概确定这就是MD5加密结果。暂时不用管其它的四个参数,接下来无非就是把加密JS代码抠出来,可以通过调用栈进去,也可以全局搜索password来定位JS文件,具体使用哪种方法就看各位看官的喜好了,我这里是从调用栈进去的(既然我们是在登录,那就点带有login字样的js文件进去好了):

在这里插入图片描述
在这里插入图片描述
进来后你可以搜一下password关键字,应该马上就能定位到想要的位置,定位的时候别忘了挂上一个断点,就像下图一样:
在这里插入图片描述
在这里插入图片描述
一看加密方法名就是熟悉的MD5,接下来的操作应该更加熟悉了,激活断点(输入账号密码,点击登录,前提是你挂上了断点)。
在这里插入图片描述
在这里插入图片描述
点击后就进入了加密方法里:
在这里插入图片描述
在这里插入图片描述
            function md5(string, key, raw) {
                if (!key) {
                    if (!raw)
                        return hex_md5(string);
                    return raw_md5(string)
                }
                if (!raw)
                    return hex_hmac_md5(key, string);
                return raw_hmac_md5(key, string)
            }
Javascript

可以看出md5方法一共有三个参数,第一个striing即为密码,keyrawundefined。接下笨一点的办法就是一步一步运行,把跳转的所有代码都扣下来,如果是刚开始学习抠代码,这个方法能增加很多调试”感觉”,慢慢抠得越来越顺手。取巧一点的无非就是找到大括号:

在这里插入图片描述
在这里插入图片描述
一直往上找到,应该马上就能找到正括号:
在这里插入图片描述
在这里插入图片描述
这样里面的代码其实就是本次要抠的代码,但是要使用python调用,还要进行一点改动。本次要抠的加密代码其实很简单,毕竟只是md5。经过稍微改写后,我们尝试使用python里execjs库执行:
在这里插入图片描述
在这里插入图片描述
成功运行出结果,抠取完毕。

FormData

通过上一节,我们已经可以得到加密后的密码,既然要登录,那就要回到FormData中,看看几个参数的含义与取值,经过一番测试,总结如下,感兴趣的也可以自己去试一下。

参数 取值 loginName 用户名 password 加密后的密码 remUser 是否记住用户名(0或者1) whereFrom 可为空 captchaId 验证码(可为空) captchaTicket 可为空

Cookies

现在的登录都需要携带cookies,看一下本站登录时候的Cookies:

在这里插入图片描述
在这里插入图片描述
看起来很多,但是经过测试并不需要全部携带,cookies应该是服务端产生的,所以还是老老实实带上吧,没有捷径。经过粗略测试,携带以下几个即可登录:
      cookies = {
            ' mars_pid': '你的',
            ' cps': '你的',
            ' mars_sid': '你的',
            'times_XXXXX': '你的',
            ' VipRUID': '你的',
            ' VipRNAME': '',
            ' VipDegree': '你的',
            ' user_class': '你的',
            ' VipCI_te': '你的',
            'mars_cid': '你的'
        }
Python

有兴趣的可以继续试试这里面还有没有可以不用携带的。

Header

不管是登录还是爬取某个网页,请求头是绝对绕不过的,现在一起看看本站的请求头都有哪些:

在这里插入图片描述
在这里插入图片描述
好家伙,各种都有,不过大家不用担心,经过测试在本文实际爬取过程中只用携带user-agent,平时的爬取过程中,有些可能会检查上一个网页是在哪里,即要携带referer,还有originhost也是可能会携带的。

本次登录的几个要点在前面应该算已经阐述清楚了,现在要做的无非就是把FormData里的数据postlogin_url

flowchat
st=>start: 开始
e=>end: 结束
op0=>operation: 输入账号密码
op1=>operation: 执行js代码加密密码
op=>operation: 组装formdata
op2=>operation: 把formdata post到登录url
op3=>operation: 分析返回

st->op0->op1->op->op2->op3->e
Mermaid

好了,流程知道了开始写代码,友情提示:由于可能引起一些不必要的纷争,代码中的url和cookies值都隐藏了,大家按照自己的添加即可。创建了一个VipLogin类,下面是部分模块的代码。

执行js代码
    @property
    def exec_js(self):
        """
        你自己的js路径
        :return:
        """
        with open('..//js//weipinhui.js', encoding='utf-8') as f:
            weipinhui = f.read()
        js = execjs.compile(weipinhui)
        return js
Python
    def get_pwd(self,password):
        key = ""
        raw = ""
        pwd = self.js.call('md5', password, key, raw)
        logger.info("加密结果为:{}".format(pwd))
        return pwd
Python

用户名加密

    def encrypt_phone(self,phone):
        return phone[:3]+"*"*5+phone[-3:]
Python
    def login(self,user,passwd):
        if not user.isdigit or len(user) != 11:
            logger.error("目前仅支持手机号方式登录:{}".format(user))
            return False
        session = requests.Session()
        vip_name = self.encrypt_phone(user)
        times_key = "times_"+user
        data = {
            "loginName": user,
            "password": passwd,
            "remUser": "0",
            "whereFrom":"",
            "captchaId":"" ,
            "captchaTicket":"",
        }
        ck_dict = {
            ' mars_pid': '你的',
            ' cps': '你的',
            ' mars_sid': '你的',
            times_key: '你的',
            ' VipRUID': '你的',
            ' VipRNAME': vip_name,
            ' VipDegree': '你的',
            ' user_class': '你的',
            ' VipCI_te': '你的',
            'mars_cid': '你的'
        }
        requests.utils.add_dict_to_cookiejar(session.cookies,ck_dict)
        resp = session.post(self.login_url,headers=self.headers,data=data,verify=False)
        ret = json.loads(resp.text)
        logger.info("账号{}返回结果为:{}".format(self._encrypt_phone(user),ret))
        if ret.get("result","") == "success":
            return True
        return False
Python
在这里插入图片描述
在这里插入图片描述
登录成功的标志为'result': 'success‘如下:
{
    'result': 'success', 
    'errorCode': 0,
     'data': {
         'redirectUrl': 'https://www.xxx.com', 
         'captchaFlowData': None, 
         'extend': None,                  
         'bindMobile': True, 
         'illegalState': False
         }, 
     'redirectUrl': 'https://www.xxx.com'
 }
Python

完整代码点击文末阅读原文,觉得有帮助关注一下知识图谱与大数据公众号吧,有大量抠JS代码的文章,当然不关注也无所谓。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK