关键词搜索

源码搜索 ×
×

【JS 逆向百例】37网游登录接口参数逆向

发布2021-08-17浏览424次

详情内容

声明

本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

逆向目标

逆向过程

抓包分析

随便输入一个账号密码,点击登陆,抓包定位到登录接口为 https://my.37.com/api/login.php ,GET 请求,分析一下 Query String Parameters 里的主要参数:

callback 是一个回调参数,这个参数的值不影响请求结果,它的格式为 jQuery + 20位数字 + _ + 13位时间戳,使用 Python 很容易构建;

login_account 是登录的账户名;

password 是加密后的密码;

_ 是13位时间戳。

参数逆向

需要我们逆向的参数就只有一个 password, 我们尝试直接全局搜索此关键字,会发现出来的结果非常多,不利于分析,这里就有一个小技巧,加个等号,搜索 password=,这样就极大地缩短了查找范围,当然也可以搜索 password:,也可以在关键字和符号之间加个空格,还可以搜索 var password 等,这些都是可以尝试的,要具体情况具体分析,一种没有结果就换另一种。

在本案例中,我们搜索 password=,在 sq.login2015.js 文件里可以看到语句 h.password = td(f),疑似密码加密的地方,在此处埋下断点进行调试,可以看到返回的值确实是加密后的密码:

继续跟进 td 函数,可以看到是用python教程到了一个自写的 RSA 加密,很简单明了,我们直接将其复制下来使用 Python 调用即可:

完整代码

本案例完整代码:https://github.com/kuaidaili/crawler/tree/main/www_37_com

37_encrypt.js#

  1. var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  2. function __rsa(str) {
  3. var out, i, len;
  4. var c1, c2, c3;
  5. len = str.length;
  6. i = 0;
  7. out = "";
  8. while (i < len) {
  9. c1 = str.charCodeAt(i++) & 0xff;
  10. if (i == len) {
  11. out += ch.charAt(c1 >> 2);
  12. out += ch.charAt((c1 & 0x3) << 4);
  13. out += "==";
  14. break
  15. }
  16. c2 = str.charCodeAt(i++);
  17. if (i == len) {
  18. out += ch.charAt(c1 >> 2);
  19. out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
  20. out += ch.charAt((c2 & 0xF) << 2);
  21. out += "=";
  22. break
  23. }
  24. c3 = str.charCodeAt(i++);
  25. out += ch.charAt(c1 >> 2);
  26. out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
  27. out += ch.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
  28. out += ch.charAt(c3 & 0x3F)
  29. }
  30. return out
  31. }
  32. function getEncryptedPassword(a) {
  33. var maxPos = ch.length - 2
  34. , w = [];
  35. for (i = 0; i < 15; i++) {
  36. w.push(ch.charAt(Math.floor(Math.random() * maxPos)));
  37. if (i === 7) {
  38. w.push(a.substr(0, 3))
  39. }
  40. if (i === 12) {
  41. w.push(a.substr(3))
  42. }
  43. }
  44. return __rsa(w.join(""))
  45. }
  46. // 测试样例
  47. // console.log(getEncryptedPassword("34343434"))

37_login.py#

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import time
  4. import random
  5. import execjs
  6. import requests
  7. login_url = 'https://my.37.com/api/login.php'
  8. def get_encrypted_password(password):
  9. with open('37_encrypt.js', 'r', encoding='utf-8') as f:
  10. www_37_js = f.read()
  11. encrypted_pwd = execjs.compile(www_37_js).call('getEncryptedPassword', password)
  12. return encrypted_pwd
  13. def login(username, encrypted_password):
  14. timestamp = str(int(time.time() * 1000))
  15. jsonp = ''
  16. for _ in range(20):
  17. jsonp += str(random.randint(0, 9))
  18. callback = 'jQuery' + jsonp + '_' + timestamp
  19. params = {
  20. 'callback': callback,
  21. 'action': 'login',
  22. 'login_account': username,
  23. 'password': encrypted_password,
  24. 'ajax': 0,
  25. 'remember_me': 1,
  26. 'save_state': 1,
  27. 'ltype': 1,
  28. 'tj_from': 100,
  29. 's': 1,
  30. 'tj_way': 1,
  31. '_': timestamp
  32. }
  33. headers = {
  34. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
  35. 'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"'
  36. }
  37. response = requests.post(url=login_url, headers=headers, params=params)
  38. print(response.text)
  39. def main():
  40. username = input('请输入登录账号: ')
  41. password = input('请输入登录密码: ')
  42. encrypted_password = get_encrypted_password(password)
  43. login(username, encrypted_password)
  44. if __name__ == '__main__':
  45. main()

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载