首先声明,本人经过无数次摸爬滚打及翻阅各类资料,理论知识极其丰富,但是抠代码怎么都抠不会。

  无奈之下,只能承认:这个活,需要熟练度。

  本文仅对部分参数进行解析,有需要调用,请自行根据现实情况调整。

  第一步,首先要打开网站,假装输入公司名:111111,用户名:111111,密码:222222,点击登录,开始抓包。拿到数据包之后,对内部数据进行简单的梳理。

  

  headers里面没有什么特别的特别的,要注意的是content-type显示,参数是json格式;接下来看参数方面,这里面一共11个参数,经过多次抓包会发现,只有clientinfo/password/username三个参数在变化,而且很明显,这不是明文,是加密模式,那么模拟登录的关键点应该就是在与找这三个参数。

  第二步,通过全局搜索变量名来定位。变量赋值一般分两种,就是username= 和username:,先拿username=,发现没找到东西;拿username:搜索,结果如下图:

  

  明显发现,480/748处是一个函数处理username。分别看下这两个位置,对应函数,发现函数相同,在这一行函数上下浏览,发现480处有我们数据包里面所有参数,显然,这里就是处理参数的地方,做下断点,稍后进行调试。同时打开鬼鬼JS工具,定义一个函数,用于接收处理后username值,由于这里是处理输入值,我们需要给函数一个参数。

1 function test(username) {
2 var user = encryptedString(key, encodeURIComponent(username));
3 return user
4 }

  当逻辑处理完毕后,通过python调用该函数,该函数就应该返回user值,即对111111进行加密后的结果。encodeURIComponent()函数是自带函数,即进行urlencode编码处理,在上一层还有一个encryptedString函数,而且该函数除了username参数外,还有个key参数,发现key在上面一丢丢:key = new RSAKeyPair();复制过来,放在函数前面,同时发现上面还有一行函数调用【setMaxDigits(129)】,怀疑有用,但没证据~~~先记下,如果右面报错,就拿过来,加载代码,发现提示有函数未定义:

  

  继续通过全局查找,由于这个是函数,那么他定义的附近应该有function字符,很容易可以找到2个,点进去发现两个js文件一样,那就随意了,同时发现给该js文件不大,但是仔细看下,发现里面的内容都有用!把他全部复制过来,放在函数前面。
  

  然后继续用鬼鬼js工具加载代码,发现提示缺少对象,点击v8运行,发现biFromHex未定义,经查看,这也是个函数,缺啥补啥,继续到网页里面找。

  

  发现这俩定义文件也是有一样的,经对biFromHex函数内部查看,发现整个文件都是互相依赖函数,全部拿走,全部拿走。注意把后拿的内容(非同一文件内放在已有代码的最前方,防止因为变量定义问题造成代码错误),然后继续调用加载,发现还缺函数BarrettMu,重复上述步骤

  

  文件不大,也是相互依赖函数,直接拿走,放到最前面!然后继续加载,看是否缺少内容:这个时候鬼鬼JS工具一直报错,一直无法加载成功,把前面怀疑的那行代码拿过来,放到运行函数前面:加载成功了,没有提示缺少函数,这个时候调用函数,参数传入111111(注意加引号),发现调用成功,返回256长度的加密密文,格式与网页数据包一致,每次运行返回结果不同。至此,username加密逆向成功!

  

  接下来是password参数。同理password参数原行代码为:password: encryptedString(key, $('#password').val()),其中$('#password').val()是jQuery的语法,及获取网页输入的密码值,那就是222222,其他方法与username一样,直接在上面添加一个获取password参数的函数,测试调用发现成功~~~~

  最后就是clientinfo值,通过username出的代码发现该值已经产生了,这里仅仅是一个简单的赋值过程,那么产生数据。全局进行搜索,发现如下内容:

  

  这个地方疑似,进入源码,打下断点,准备调试(清除之前的断点),点击登录,发现没断,说明在这之前,该数据已经产生了,产生数据往往伴随着动作,在我们点击登录之前的网页动作,那就只有加载网页了。刷新网页发现断点触发。

  

  这里可以发现是通过base64encode函数处理一个info值,而info到这里是一个很长的字符串,上一行,对info进行了定义。我们尝试着进入dogetinfo函数,发现该函数大部分地方都是在定义值和获取值,并未看到什么调用函数处理值的地方,那么在他return的地方打下断点,再次刷新进入dogetinfo函数内部,查看返回内容,发现是很长的字符串,而且返回处代码为:eFlash.join("^^") + "^^" + eNavigator.join("^^");

  

  对应结果值来看,这个函数好像仅仅做了拼接动作,那么查看值,发现很多熟悉的字眼,例如navigator/screenDPI/appCodeName/appVersion/userAgent等等,这显然是本地信息,通过控制台将该内容取出,按照“^^”符号断开,发现确实是计算机信息,而且取的十分简单。经百度,这种获取浏览器主要信息的数据 指纹算法(这里信息很少,属于极为简单的指纹信息),服务器通过对该信息认证,发现同样指纹在同一时间内大量申请数据,会认为异常。如果要改,我们这里可以userAgent,伪装更改浏览器版本88.0.4324.190这个数据。到这里就很明白了 clientinfo = base64encode(info),而info 即上面的拼接后的字符串。但要注意的是,base64ecode不是JS内置函数,写入JS的话,需要找下该函数,否则直接python中使用base64库。

  至此,三个加密参数均被解析。

  具体代码在下方。

  具体分析步骤即操作步骤在代码注释部分,JS的文件拼接和复制在JS文件的最后

 1 '''
2 管家婆登录网址:http://login.wsgjp.com/
3 网站对userName、password、clientinfo 三个参数进行了加密
4 现在对这三个参数进行js逆向,抠代码:使用鬼鬼js调试工具
5
6 userName ----> 使用userName = 查找,找到的都是赋值的地方,不是生成参数的地方
7 使用 userName: 查找,发现代码 userName: encryptedString(key, encodeURIComponent(username)),
8 password ----> 进入代码所在进行定位 发现password也在这里产生
9 所以,一起操作了
10
11 以下转JS文件
12
13 clientinfo --> 对这个值进行解析,发现上面代码处,这个值只是赋值所在,说明在这一步之前,这个值就已经生成了
14 再次搜索该值,发现一处代码疑似: clientinfo = base64encode(info) 显然是对info值进行了base64编码
15 那么info是多少,上一行对info进行了定义:var info = doGetInfo();下一步就是寻找doGetInfo函数
16 查找后进入doGetInfo函数,发现该函数量不大,且没有参数,没参数意味着不受输入值的影响,初步检查改函数,
17 发现该函数前一半以定义为主,获取数据,我们直接在return的地方打断点。再次点击登录,发现没有断下来!
18 思考为什么中! 在登录之前就生成了,登录之前生成,生成数据是个动作行为,要伴随着网页动作,怀疑是打开网页、
19 即加载网页的时候生成的,直接刷新网页,成功!
20 获取该函数返回值如下:
21 flash:begin^^
22 navigator:begin^^
23 screenDPI:undefined^^
24 cookieEnabled:true^^
25 platform:Win32^^
26 appCodeName:Mozilla^^
27 appMinorVersion:undefined^^
28 appName:Netscape^^
29 appVersion:5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36^^
30 browserLanguage:undefined^^
31 cpuClass:undefined^^
32 systemLanguage:undefined^^
33 userAgent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36^^
34 userLanguage:undefined^^
35 language:zh-CN^^
36 language:zh-CN^^
37 oscpu:undefined
38
39 结合eFlash.join("^^") + "^^" + eNavigator.join("^^")这行代码,没学过js都应该猜得到,是用^^对数据进行拼接,
40 断开后,发现很多很熟悉的东西,这些都是浏览器信息,undefined即未获取到,那么有效信息即appVersion、userAgent
41 这里基本上就是固定值了。
42 经百度,这种获取浏览器主要信息的数据 指纹算法(这里信息很少,属于极为简单的指纹信息),
43 服务器通过对该信息认证,发现同样指纹在同一时间内大量申请数据,会认为异常。如果要改,我们这里可以userAgent,
44 伪装更改浏览器版本88.0.4324.190这个数据。
45 那么 clientinfo = base64encode(info),而info 即上面的拼接后的字符串
46
47 注意:将函数直接写进JS的话,请把base64encode函数也复制进去,不能少参数,注意调试,否则请直接在python中
48 调用base64方法
49
50
51 '''
52
53 import execjs
54
55 def read_js(file):
56 with open(file, 'r', encoding='utf8') as f:
57 js_data = f.read()
58 return js_data
59
60
61
62
63 if __name__ == '__main__':
64 # 先读取js文件
65 js_r = read_js('getsome.js')
66 # 使用execjs方法获取js文件内容
67 js_o = execjs.compile(js_r)
68 # call方法调用函数,参数:函数名, 参数值
69 _username = js_o.call('getusername','111111')
70 print(_username)
71 print(len(_username))
72 _password = js_o.call('getpwd', '222222')
73 print(_password)
74 print(len(_password))
75
76 _clientinfo = js_o.call('getCL')
77 print(_clientinfo)

  JS 代码如下,这里就折叠了,因为行数太多。

var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function base64encode(str) {
try {
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 += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len) {
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
out += base64EncodeChars.charAt(c3 & 0x3F);
} } catch (e) {
}
return out;
} function BarrettMu(m)
{
this.modulus = biCopy(m);
this.k = biHighIndex(this.modulus) + 1;
var b2k = new BigInt();
b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
this.mu = biDivide(b2k, this.modulus);
this.bkplus1 = new BigInt();
this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
this.modulo = BarrettMu_modulo;
this.multiplyMod = BarrettMu_multiplyMod;
this.powMod = BarrettMu_powMod;
} function BarrettMu_modulo(x)
{
var q1 = biDivideByRadixPower(x, this.k - 1);
var q2 = biMultiply(q1, this.mu);
var q3 = biDivideByRadixPower(q2, this.k + 1);
var r1 = biModuloByRadixPower(x, this.k + 1);
var r2term = biMultiply(q3, this.modulus);
var r2 = biModuloByRadixPower(r2term, this.k + 1);
var r = biSubtract(r1, r2);
if (r.isNeg) {
r = biAdd(r, this.bkplus1);
}
var rgtem = biCompare(r, this.modulus) >= 0;
while (rgtem) {
r = biSubtract(r, this.modulus);
rgtem = biCompare(r, this.modulus) >= 0;
}
return r;
} function BarrettMu_multiplyMod(x, y)
{
/*
x = this.modulo(x);
y = this.modulo(y);
*/
var xy = biMultiply(x, y);
return this.modulo(xy);
} function BarrettMu_powMod(x, y)
{
var result = new BigInt();
result.digits[0] = 1;
var a = x;
var k = y;
while (true) {
if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
k = biShiftRight(k, 1);
if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
a = this.multiplyMod(a, a);
}
return result;
} var biRadixBase = 2;
var biRadixBits = 16;
var bitsPerDigit = biRadixBits;
var biRadix = 1 << 16; // = 2^16 = 65536
var biHalfRadix = biRadix >>> 1;
var biRadixSquared = biRadix * biRadix;
var maxDigitVal = biRadix - 1;
var maxInteger = 9999999999999998; // maxDigits:
// Change this to accommodate your largest number size. Use setMaxDigits()
// to change it!
//
// In general, if you're working with numbers of size N bits, you'll need 2*N
// bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
//
// 1024 * 2 / 16 = 128 digits of storage.
// var maxDigits;
var ZERO_ARRAY;
var bigZero, bigOne; function setMaxDigits(value)
{
maxDigits = value;
ZERO_ARRAY = new Array(maxDigits);
for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
bigZero = new BigInt();
bigOne = new BigInt();
bigOne.digits[0] = 1;
} setMaxDigits(20); // The maximum number of digits in base 10 you can convert to an
// integer without JavaScript throwing up on you.
var dpl10 = 15;
// lr10 = 10 ^ dpl10
var lr10 = biFromNumber(1000000000000000); function BigInt(flag)
{
if (typeof flag == "boolean" && flag == true) {
this.digits = null;
}
else {
this.digits = ZERO_ARRAY.slice(0);
}
this.isNeg = false;
} function biFromDecimal(s)
{
var isNeg = s.charAt(0) == '-';
var i = isNeg ? 1 : 0;
var result;
// Skip leading zeros.
while (i < s.length && s.charAt(i) == '0') ++i;
if (i == s.length) {
result = new BigInt();
}
else {
var digitCount = s.length - i;
var fgl = digitCount % dpl10;
if (fgl == 0) fgl = dpl10;
result = biFromNumber(Number(s.substr(i, fgl)));
i += fgl;
while (i < s.length) {
result = biAdd(biMultiply(result, lr10),
biFromNumber(Number(s.substr(i, dpl10))));
i += dpl10;
}
result.isNeg = isNeg;
}
return result;
} function biCopy(bi)
{
var result = new BigInt(true);
result.digits = bi.digits.slice(0);
result.isNeg = bi.isNeg;
return result;
} function biFromNumber(i)
{
var result = new BigInt();
result.isNeg = i < 0;
i = Math.abs(i);
var j = 0;
while (i > 0) {
result.digits[j++] = i & maxDigitVal;
i = Math.floor(i / biRadix);
}
return result;
} function reverseStr(s)
{
var result = "";
for (var i = s.length - 1; i > -1; --i) {
result += s.charAt(i);
}
return result;
} var hexatrigesimalToChar = new Array(
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
); function biToString(x, radix)
// 2 <= radix <= 36
{
var b = new BigInt();
b.digits[0] = radix;
var qr = biDivideModulo(x, b);
var result = hexatrigesimalToChar[qr[1].digits[0]];
while (biCompare(qr[0], bigZero) == 1) {
qr = biDivideModulo(qr[0], b);
digit = qr[1].digits[0];
result += hexatrigesimalToChar[qr[1].digits[0]];
}
return (x.isNeg ? "-" : "") + reverseStr(result);
} function biToDecimal(x)
{
var b = new BigInt();
b.digits[0] = 10;
var qr = biDivideModulo(x, b);
var result = String(qr[1].digits[0]);
while (biCompare(qr[0], bigZero) == 1) {
qr = biDivideModulo(qr[0], b);
result += String(qr[1].digits[0]);
}
return (x.isNeg ? "-" : "") + reverseStr(result);
} var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'); function digitToHex(n)
{
var mask = 0xf;
var result = "";
for (i = 0; i < 4; ++i) {
result += hexToChar[n & mask];
n >>>= 4;
}
return reverseStr(result);
} function biToHex(x)
{
var result = "";
var n = biHighIndex(x);
for (var i = biHighIndex(x); i > -1; --i) {
result += digitToHex(x.digits[i]);
}
return result;
} function charToHex(c)
{
var ZERO = 48;
var NINE = ZERO + 9;
var littleA = 97;
var littleZ = littleA + 25;
var bigA = 65;
var bigZ = 65 + 25;
var result; if (c >= ZERO && c <= NINE) {
result = c - ZERO;
} else if (c >= bigA && c <= bigZ) {
result = 10 + c - bigA;
} else if (c >= littleA && c <= littleZ) {
result = 10 + c - littleA;
} else {
result = 0;
}
return result;
} function hexToDigit(s)
{
var result = 0;
var sl = Math.min(s.length, 4);
for (var i = 0; i < sl; ++i) {
result <<= 4;
result |= charToHex(s.charCodeAt(i))
}
return result;
} function biFromHex(s)
{
var result = new BigInt();
var sl = s.length;
for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
}
return result;
} function biFromString(s, radix)
{
var isNeg = s.charAt(0) == '-';
var istop = isNeg ? 1 : 0;
var result = new BigInt();
var place = new BigInt();
place.digits[0] = 1; // radix^0
for (var i = s.length - 1; i >= istop; i--) {
var c = s.charCodeAt(i);
var digit = charToHex(c);
var biDigit = biMultiplyDigit(place, digit);
result = biAdd(result, biDigit);
place = biMultiplyDigit(place, radix);
}
result.isNeg = isNeg;
return result;
} function biDump(b)
{
return (b.isNeg ? "-" : "") + b.digits.join(" ");
} function biAdd(x, y)
{
var result; if (x.isNeg != y.isNeg) {
y.isNeg = !y.isNeg;
result = biSubtract(x, y);
y.isNeg = !y.isNeg;
}
else {
result = new BigInt();
var c = 0;
var n;
for (var i = 0; i < x.digits.length; ++i) {
n = x.digits[i] + y.digits[i] + c;
result.digits[i] = n % biRadix;
c = Number(n >= biRadix);
}
result.isNeg = x.isNeg;
}
return result;
} function biSubtract(x, y)
{
var result;
if (x.isNeg != y.isNeg) {
y.isNeg = !y.isNeg;
result = biAdd(x, y);
y.isNeg = !y.isNeg;
} else {
result = new BigInt();
var n, c;
c = 0;
for (var i = 0; i < x.digits.length; ++i) {
n = x.digits[i] - y.digits[i] + c;
result.digits[i] = n % biRadix;
// Stupid non-conforming modulus operation.
if (result.digits[i] < 0) result.digits[i] += biRadix;
c = 0 - Number(n < 0);
}
// Fix up the negative sign, if any.
if (c == -1) {
c = 0;
for (var i = 0; i < x.digits.length; ++i) {
n = 0 - result.digits[i] + c;
result.digits[i] = n % biRadix;
// Stupid non-conforming modulus operation.
if (result.digits[i] < 0) result.digits[i] += biRadix;
c = 0 - Number(n < 0);
}
// Result is opposite sign of arguments.
result.isNeg = !x.isNeg;
} else {
// Result is same sign.
result.isNeg = x.isNeg;
}
}
return result;
} function biHighIndex(x)
{
var result = x.digits.length - 1;
while (result > 0 && x.digits[result] == 0) --result;
return result;
} function biNumBits(x)
{
var n = biHighIndex(x);
var d = x.digits[n];
var m = (n + 1) * bitsPerDigit;
var result;
for (result = m; result > m - bitsPerDigit; --result) {
if ((d & 0x8000) != 0) break;
d <<= 1;
}
return result;
} function biMultiply(x, y)
{
var result = new BigInt();
var c;
var n = biHighIndex(x);
var t = biHighIndex(y);
var u, uv, k; for (var i = 0; i <= t; ++i) {
c = 0;
k = i;
for (j = 0; j <= n; ++j, ++k) {
uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
result.digits[k] = uv & maxDigitVal;
c = uv >>> biRadixBits;
//c = Math.floor(uv / biRadix);
}
result.digits[i + n + 1] = c;
}
// Someone give me a logical xor, please.
result.isNeg = x.isNeg != y.isNeg;
return result;
} function biMultiplyDigit(x, y)
{
var n, c, uv; result = new BigInt();
n = biHighIndex(x);
c = 0;
for (var j = 0; j <= n; ++j) {
uv = result.digits[j] + x.digits[j] * y + c;
result.digits[j] = uv & maxDigitVal;
c = uv >>> biRadixBits;
//c = Math.floor(uv / biRadix);
}
result.digits[1 + n] = c;
return result;
} function arrayCopy(src, srcStart, dest, destStart, n)
{
var m = Math.min(srcStart + n, src.length);
for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
dest[j] = src[i];
}
} var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF); function biShiftLeft(x, n)
{
var digitCount = Math.floor(n / bitsPerDigit);
var result = new BigInt();
arrayCopy(x.digits, 0, result.digits, digitCount,
result.digits.length - digitCount);
var bits = n % bitsPerDigit;
var rightBits = bitsPerDigit - bits;
for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
((result.digits[i1] & highBitMasks[bits]) >>>
(rightBits));
}
result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
result.isNeg = x.isNeg;
return result;
} var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF); function biShiftRight(x, n)
{
var digitCount = Math.floor(n / bitsPerDigit);
var result = new BigInt();
arrayCopy(x.digits, digitCount, result.digits, 0,
x.digits.length - digitCount);
var bits = n % bitsPerDigit;
var leftBits = bitsPerDigit - bits;
for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
result.digits[i] = (result.digits[i] >>> bits) |
((result.digits[i1] & lowBitMasks[bits]) << leftBits);
}
result.digits[result.digits.length - 1] >>>= bits;
result.isNeg = x.isNeg;
return result;
} function biMultiplyByRadixPower(x, n)
{
var result = new BigInt();
arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
return result;
} function biDivideByRadixPower(x, n)
{
var result = new BigInt();
arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
return result;
} function biModuloByRadixPower(x, n)
{
var result = new BigInt();
arrayCopy(x.digits, 0, result.digits, 0, n);
return result;
} function biCompare(x, y)
{
if (x.isNeg != y.isNeg) {
return 1 - 2 * Number(x.isNeg);
}
for (var i = x.digits.length - 1; i >= 0; --i) {
if (x.digits[i] != y.digits[i]) {
if (x.isNeg) {
return 1 - 2 * Number(x.digits[i] > y.digits[i]);
} else {
return 1 - 2 * Number(x.digits[i] < y.digits[i]);
}
}
}
return 0;
} function biDivideModulo(x, y)
{
var nb = biNumBits(x);
var tb = biNumBits(y);
var origYIsNeg = y.isNeg;
var q, r;
if (nb < tb) {
// |x| < |y|
if (x.isNeg) {
q = biCopy(bigOne);
q.isNeg = !y.isNeg;
x.isNeg = false;
y.isNeg = false;
r = biSubtract(y, x);
// Restore signs, 'cause they're references.
x.isNeg = true;
y.isNeg = origYIsNeg;
} else {
q = new BigInt();
r = biCopy(x);
}
return new Array(q, r);
} q = new BigInt();
r = x; // Normalize Y.
var t = Math.ceil(tb / bitsPerDigit) - 1;
var lambda = 0;
while (y.digits[t] < biHalfRadix) {
y = biShiftLeft(y, 1);
++lambda;
++tb;
t = Math.ceil(tb / bitsPerDigit) - 1;
}
// Shift r over to keep the quotient constant. We'll shift the
// remainder back at the end.
r = biShiftLeft(r, lambda);
nb += lambda; // Update the bit count for x.
var n = Math.ceil(nb / bitsPerDigit) - 1; var b = biMultiplyByRadixPower(y, n - t);
while (biCompare(r, b) != -1) {
++q.digits[n - t];
r = biSubtract(r, b);
}
for (var i = n; i > t; --i) {
var ri = (i >= r.digits.length) ? 0 : r.digits[i];
var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
var yt = (t >= y.digits.length) ? 0 : y.digits[t];
var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
if (ri == yt) {
q.digits[i - t - 1] = maxDigitVal;
} else {
q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
} var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
while (c1 > c2) {
--q.digits[i - t - 1];
c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
} b = biMultiplyByRadixPower(y, i - t - 1);
r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
if (r.isNeg) {
r = biAdd(r, b);
--q.digits[i - t - 1];
}
}
r = biShiftRight(r, lambda);
// Fiddle with the signs and stuff to make sure that 0 <= r < y.
q.isNeg = x.isNeg != origYIsNeg;
if (x.isNeg) {
if (origYIsNeg) {
q = biAdd(q, bigOne);
} else {
q = biSubtract(q, bigOne);
}
y = biShiftRight(y, lambda);
r = biSubtract(y, r);
}
// Check for the unbelievably stupid degenerate case of r == -0.
if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false; return new Array(q, r);
} function biDivide(x, y)
{
return biDivideModulo(x, y)[0];
} function biModulo(x, y)
{
return biDivideModulo(x, y)[1];
} function biMultiplyMod(x, y, m)
{
return biModulo(biMultiply(x, y), m);
} function biPow(x, y)
{
var result = bigOne;
var a = x;
while (true) {
if ((y & 1) != 0) result = biMultiply(result, a);
y >>= 1;
if (y == 0) break;
a = biMultiply(a, a);
}
return result;
} function biPowMod(x, y, m)
{
var result = bigOne;
var a = x;
var k = y;
while (true) {
if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
k = biShiftRight(k, 1);
if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
a = biMultiplyMod(a, a, m);
}
return result;
} function RSAKeyPair() {
var encryptionExponent = "010001";
var decryptionExponent = "";
var modulus = "9A568982EE4BF010C38B5195A6F2DC7D66D5E6C02098CF25044CDD031AC08C6569D7063BB8959CB3FCB5AF572DE355AFA684AF7187948744E673275B494F394AF7F158841CA8B63BF65F185883F8D773A57ED731EDCD1AF2E0E57CD45F5F3CB4EBDD38F4A267E5ED02E7B44B93EDFFDADBDC8368019CD496BEC735BAF9E57125";
this.e = biFromHex(encryptionExponent);
this.d = biFromHex(decryptionExponent);
this.m = biFromHex(modulus);
this.digitSize = 2 * biHighIndex(this.m) + 2;
this.chunkSize = this.digitSize - 11;
this.radix = 16;
this.barrett = new BarrettMu(this.m);
} function twoDigit(n) {
return (n < 10 ? "0" : "") + String(n);
} function encryptedString(key, s) {
if (key.chunkSize > key.digitSize - 11) {
return "Error";
}
var a = new Array();
var sl = s.length; var i = 0;
while (i < sl) {
a[i] = s.charCodeAt(i);
i++;
}
var al = a.length;
var result = "";
var j, k, block;
for (i = 0; i < al; i += key.chunkSize) {
block = new BigInt();
j = 0;
var x;
var msgLength = (i + key.chunkSize) > al ? al % key.chunkSize : key.chunkSize;
var b = new Array();
for (x = 0; x < msgLength; x++) {
b[x] = a[i + msgLength - 1 - x];
}
b[msgLength] = 0; // marker
var paddedSize = Math.max(8, key.digitSize - 3 - msgLength); for (x = 0; x < paddedSize; x++) {
b[msgLength + 1 + x] = Math.floor(Math.random() * 254) + 1;
} b[key.digitSize - 2] = 2; // marker
b[key.digitSize - 1] = 0; // marker for (k = 0; k < key.digitSize; ++j) {
block.digits[j] = b[k++];
block.digits[j] += b[k++] << 8;
}
var crypt = key.barrett.powMod(block, key.e);
var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix);
result += text + " ";
}
return result.substring(0, result.length - 1); // Remove last space.
} setMaxDigits(129);
var key = new RSAKeyPair();
// 第一步在这里创建函数,username,必然是获取到的,所以需要传个值,
// 同理,处理password function getusername(username) {
// 很明显,username是被urlencode处理过的,直接使用方法
var user = encryptedString(key, encodeURIComponent(username));
return user
} function getpwd(password) {
// 原文中的 $('#password').val() jquery写法,它的意思是,从password标签中获取value值,
// val的()中没有对象,即为取值,有东西即为赋值
var pwd = encryptedString(key, password);
return pwd
}
var info = 'flash:begin^^navigator:begin^^screenDPI:undefined^^cookieEnabled:true^^platform:Win32^^appCodeName:Mozilla^^appMinorVersion:undefined^^appName:Netscape^^appVersion:5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36^^browserLanguage:undefined^^cpuClass:undefined^^systemLanguage:undefined^^userAgent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36^^userLanguage:undefined^^language:zh-CN^^language:zh-CN^^oscpu:undefined'
function getCL() {
var cl = base64encode(info);
return cl
} // 经对这俩函数初步解析(眼睛看),发现这个是个函数encryptedString 可以直接搜索这个函数
// 即 function encryptedString的地方,也可以通过打断点进入函数,
// 将函数整体复制过来,发现文件不大,检查下文件内部数据,基本都是有用数据,
// 就全部拿过来,放置到自定义函数前面
// 调用后,发现key未定义,再看源码,发现就在上面,复制过来,
// 他的上一行setMaxDigits(129);看起来是个单独调用,也取过来
// 继续调用自定义函数,发现函数setMaxDigits不存,将改行注释掉后,发现biFromHex函数不存在,
// 经查找,这俩函数在一起,干脆全拿来放在前面,恢复注释
// 继续调用(鬼鬼JS 直接点加载也会提醒,但有时不会提醒详细,需要点V8运行)发现BarrettMu未定义,继续找
// 发现这个文件很小,内部代码均为关联代码,全复制过来
// 至此,鬼鬼JS工具提示完成,工具中调用函数可以得到与浏览器类似结果
// 我们回到py文件中,利用execJS工具调用试试

最新文章

  1. javaweb project create
  2. ModelAndView详解
  3. IOS第15天(2,事件处理,侧滑菜单,抽屉效果)
  4. 关于@Html.Action()的异常“控制器或该控制器未实现 IController。”
  5. svn 创建
  6. 0(Mark)(随时添加) ubuntu的一些 终端 命令整理
  7. 总结 | 如何测试你自己的 RubyGem
  8. 【模拟】Codeforces 671B Robin Hood
  9. WKWebView使用
  10. Windows下MongoDB设置用户、密码
  11. SQL中的 group by 1, order by 1 语句
  12. linux的systemctl 命令用法 转
  13. 基于Java的三种对象持久化方式
  14. ProtoBuf序列化和反序列化方法
  15. Linux系统进程管理
  16. 远程调用与编译DS作业
  17. Easyui combotree 获取自定义ID属性方法
  18. apk下载安装,存储的位置,路径
  19. 密钥管理服务KMS
  20. PAT basic 1086

热门文章

  1. Python源码剖析——02虚拟机
  2. ARMv7-A 架构下的MMU
  3. μC/OS-III---I笔记9---任务等待多个内核对象和任务内建信号量与消息队列
  4. js &amp; object &amp; prototype &amp; __proto__ &amp; prototype chain
  5. CSS Learning Paths
  6. @bind decorator
  7. Jenkins Ansible GitLab 自动化部署
  8. NGK团队是如何打造超高回报率的BGV项目的?
  9. 观点纠正,yarn和npm对比,今天yarn仍然比npm快吗
  10. django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面