js逆向实战之某网游登录参数password加密

声明:本篇文章仅用于知识分享,不得用于其他用途
网址:https://www.37.com/

加密逻辑

  1. 访问网址,输入用户名和密码,看触发哪些数据包。
    image

注意:这里的流量包要选择all,如果选择fetch/XHR则看不到任何数据包。

  1. 明显看到password被加密了,先去搜索url中的关键字api/login.php
    image
    可以看到触发的数据包中有action=login,但是搜索出来的没有一个符合,所以这里搜索url关键字不太合适。
  2. 再看数据包中所传的参数有非常多,我们可以选择一个参数名比较不常见的,这样搜索出来的结果会少一点,容易筛选。经过测试,选择remember_me作为关键字搜索,只有一处。
    image
  3. remember_me处打断点,发现打不上,却在下面的一行代码打上了断点,说明可能逻辑在下面。
    image

image
5. 重新输入用户名和密码触发断点,变量b中有用户名和密码。
image
6. 单步调试,看执行到哪一步,密码发生了变化。执行到如下这行代码的时候,还是原来的密码。
image
再往下执行一步,等h.password = td(f)这行代码执行完,password被加密了,说明加密逻辑就在这行代码中。
image
7. 定位td函数,打断点,重新输入用户名和密码,让程序运行到td函数中。
image
8. 传给td函数的参数还是明文的密码,经过td函数的处理就变成了加密字符串。知道了加密的函数,就可以开始抠代码了。

function td(a) {
    var maxPos = ch.length - 2
      , w = [];
    for (i = 0; i < 15; i++) {
        w.push(ch.charAt(Math.floor(Math.random() * maxPos)));
        if (i === 7) {
            w.push(a.substr(0, 3))
        }
        if (i === 12) {
            w.push(a.substr(3))
        }
    }
    return __rsa(w.join(""))
}

var a = "123456";
console.log(td(a));

运行报错,缺少ch
image
去原页面找。
image
复制出来,再运行,报错__rsa未定义。
image
再去原页面找。
image
都在同一个文件中,既然这样,就把整个页面的代码都复制出来。

var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function __rsa(str) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            out += ch.charAt(c1 >> 2);
            out += ch.charAt((c1 & 0x3) << 4);
            out += "==";
            break
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            out += ch.charAt(c1 >> 2);
            out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += ch.charAt((c2 & 0xF) << 2);
            out += "=";
            break
        }
        c3 = str.charCodeAt(i++);
        out += ch.charAt(c1 >> 2);
        out += ch.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += ch.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += ch.charAt(c3 & 0x3F)
    }
    return out
}
function td(a) {
    var maxPos = ch.length - 2
      , w = [];
    for (i = 0; i < 15; i++) {
        w.push(ch.charAt(Math.floor(Math.random() * maxPos)));
        if (i === 7) {
            w.push(a.substr(0, 3))
        }
        if (i === 12) {
            w.push(a.substr(3))
        }
    }
    return __rsa(w.join(""))
}


var a = "123456";
console.log(td(a));

运行,成功得到加密的字符串,且每一次的结果都不一样。
image
9. 编写python代码进行登录。

import requests
import execjs

login_account = input("请输入用户名:")
pwd = input("请输入密码:")

file = open("encrypt.js", mode="r")
exec_js = file.read()
exec_code = execjs.compile(exec_js)
password = exec_code.call("td", pwd)

url = "https://my.37.com/api/login.php?callback=jQuery183008257522373901449_1730007524424&action=login&login_account" \
      "={}&password={}&ajax=0&remember_me=1&save_state=1&ltype=1&tj_from=100&s=1&img_ver=1" \
      ".0&tj_way=1&_=1730007546145".format(login_account, password)
headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                         "Chrome/128.0.0.0 Safari/537.36"}
resp = requests.get(url, headers=headers)
print(resp.text.encode("utf-8").decode("unicode_escape"))

运行结果如下。
image
涉及到了验证码的滑块验证,还没学过,等学会了再回来补,暂时只能做到这里了。

posted @ 2024-10-27 14:03  死不悔改奇男子  阅读(92)  评论(0编辑  收藏  举报