js逆向实战之某网游登录参数password加密
声明:本篇文章仅用于知识分享,不得用于其他用途
网址:https://www.37.com/
加密逻辑
- 访问网址,输入用户名和密码,看触发哪些数据包。
注意:这里的流量包要选择all,如果选择fetch/XHR则看不到任何数据包。
- 明显看到
password
被加密了,先去搜索url中的关键字api/login.php
。
可以看到触发的数据包中有action=login
,但是搜索出来的没有一个符合,所以这里搜索url关键字不太合适。 - 再看数据包中所传的参数有非常多,我们可以选择一个参数名比较不常见的,这样搜索出来的结果会少一点,容易筛选。经过测试,选择
remember_me
作为关键字搜索,只有一处。
- 在
remember_me
处打断点,发现打不上,却在下面的一行代码打上了断点,说明可能逻辑在下面。
5. 重新输入用户名和密码触发断点,变量b
中有用户名和密码。
6. 单步调试,看执行到哪一步,密码发生了变化。执行到如下这行代码的时候,还是原来的密码。
再往下执行一步,等h.password = td(f)
这行代码执行完,password
被加密了,说明加密逻辑就在这行代码中。
7. 定位td
函数,打断点,重新输入用户名和密码,让程序运行到td
函数中。
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
。
去原页面找。
复制出来,再运行,报错__rsa
未定义。
再去原页面找。
都在同一个文件中,既然这样,就把整个页面的代码都复制出来。
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));
运行,成功得到加密的字符串,且每一次的结果都不一样。
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<ype=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"))
运行结果如下。
涉及到了验证码的滑块验证,还没学过,等学会了再回来补,暂时只能做到这里了。