JS逆向-摳代碼的第一天【手把手學會摳代碼】


  首先聲明,本人經過無數次摸爬滾打及翻閱各類資料,理論知識極其豐富,但是摳代碼怎么都摳不會。

  無奈之下,只能承認:這個活,需要熟練度。

  本文僅對部分參數進行解析,有需要調用,請自行根據現實情況調整。

  第一步,首先要打開網站(http://login.wsgjp.com.cn/),假裝輸入公司名: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工具調用試試
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM