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

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

  無奈之下,只能認可:這個活,須要熟練度。jquery

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

  第一步,首先要打開網站,僞裝輸入公司名:111111,用戶名:111111,密碼:222222,點擊登陸,開始抓包。拿到數據包以後,對內部數據進行簡單的梳理。算法

  

  headers裏面沒有什麼特別的特別的,要注意的是content-type顯示,參數是json格式;接下來看參數方面,這裏面一共11個參數,通過屢次抓包會發現,只有clientinfo/password/username三個參數在變化,並且很明顯,這不是明文,是加密模式,那麼模擬登陸的關鍵點應該就是在與找這三個參數。json

  第二步,經過全局搜索變量名來定位。變量賦值通常分兩種,就是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)】,懷疑有用,但沒證據~~~先記下,若是右面報錯,就拿過來,加載代碼,發現提示有函數未定義:cookie

  

  繼續經過全局查找,因爲這個是函數,那麼他定義的附近應該有function字符,很容易能夠找到2個,點進去發現兩個js文件同樣,那就隨意了,同時發現給該js文件不大,可是仔細看下,發現裏面的內容都有用!把他所有複製過來,放在函數前面。
  
app

  而後繼續用鬼鬼js工具加載代碼,發現提示缺乏對象,點擊v8運行,發現biFromHex未定義,經查看,這也是個函數,缺啥補啥,繼續到網頁裏面找。dom

  

  發現這倆定義文件也是有同樣的,經對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
相關文章
相關標籤/搜索