1.难点

  • 表单参数加密
  • JS代码混淆

    2.抓包

    image.png

3.分析

F12或鼠标右键盘检查

分析参数1

password

定位代码

调试菜单栏下,选择Elements
image.png
通过ctrl+f输入usernamepassword定位加密参数代码
image.png

一般表单提交的代码在form内部,不在的话可能有JS加密。

再分析代码,发现这里有个点击时间触发了doLogin()函数
image.png
继续跟进,在调试菜单栏Network下通过ctrl+f输入doLogin定位函数,发现两处doLogin
image.png
貌似是混淆代码
image.png

通过JS解密工具

  1. function doLogin() {
  2. var password_old = $("#MemberPassword").val();
  3. var encrypt = new JSEncrypt();
  4. var public_key = $("#pk").val();
  5. encrypt.setPublicKey(public_key);
  6. var pass_new = encrypt.encrypt(password_old);
  7. $("#MemberPassword").val(pass_new);
  8. $("#login_button").submit()
  9. }

能解密出来,说明是基础的混淆。

核心代码

分析doLogin函数

  1. function doLogin() {
  2. var password_old = $("#MemberPassword").val(); // 获取html中id为MemberPassword的内容
  3. var encrypt = new JSEncrypt();
  4. var public_key = $("#pk").val(); // 获取中html获取id为pk的值,作为公钥
  5. encrypt.setPublicKey(public_key);
  6. var pass_new = encrypt.encrypt(password_old); // 加密
  7. $("#MemberPassword").val(pass_new); // 设置id为MemberPassword的标签内容为pass_new
  8. $("#login_button").submit() // 提交表单
  9. }

可以看到,这里password_old变成了pass_newpassword_old应该是未加密的原始密码,pass_new应该是加密了的密码。

image.png

解决方案

有公钥私钥的加密,是RSA加密,一般这种不回去解密,而是去进行加密得到加密后的密文。

分析参数2

csrfmiddlewaretoken

定位代码

调试菜单栏下,选择Elements

image.png

image.png

对比发现,这两处的csrfmiddlewaretoken值不一样,说明这个参数是动态的。
一般token是服务器动态返回的,而不是加密的。

分析参数3

pk
每次刷新页面,值固定。
image.png

4.编码实现

  1. # 辅助函数,用于处理html
  2. # parseHtml.py
  3. from lxml import etree
  4. def getEle(rule: str, htmlStr: str):
  5. html = etree.HTML(htmlStr)
  6. res = html.xpath(rule)
  7. return res
  1. # run.py
  2. # 获取值:pkcsrfmiddlewaretoken
  3. import requests
  4. import parseHtml
  5. url = 'http://shanzhi.spbeen.com/login/'
  6. headers = {
  7. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',
  8. }
  9. resp = requests.get(url, headers=headers)
  10. resp.encoding = 'utf-8'
  11. res__pk = parseHtml.getEle('//*[@id="pk"]/@value', resp.text)
  12. res__token = parseHtml.getEle('//input[@name="csrfmiddlewaretoken"]/@value', resp.text)
  13. pk = res__pk[0].strip()
  14. token = res__token[0].strip()
  15. print(pk)
  16. print(token)