對 js加密數據進行爬取和解密


對 js加密數據進行爬取和解密

  • 分析:
    • 爬取的數據是動態加載
    • 並且我們進行了抓包工具的全局搜索,沒有查找到結果
      • 意味着:爬取的數據從服務端請求到的是加密的密文數據
    • 頁面每10s刷新一次,刷新后發現數據更新,但是瀏覽器地址欄的url沒有變,說明加載出的數據是由ajax請求到的。
      • 動態加載出來的數據是由ajax請求到的,並且請求到的數據為加密數據
    • 定位到ajax數據包,從中可以看到url和動態變化的請求參數和加密的相應數據
    • 將ajax請求到的密文數據捕獲
      • 動態的獲取動態變化的請求參數
      • 基於抓包工具進行了動態變化請求參數taken的全局搜索,定位到了taken產生的源頭,就是如下js代碼:
        • var token = md5(String(page) + String(num) + String(timestamp));
    • 對密文數據進行解密
      • 通過分析找到了解密的js函數:decode_str(encode_str),encode_str就是密文數據
    • 查找encode_str的實現:
      • js逆向:將js代碼轉換成python代碼。開發環境只能執行python代碼
  • 首先將js代碼中的ASCII碼進行轉換:
function decode_str(scHZjLUh1) {
    #Base64.decode(scHZjLUh1)
    scHZjLUh1 = Base64["\x64\x65\x63\x6f\x64\x65"](scHZjLUh1);
    key = '\x6e\x79\x6c\x6f\x6e\x65\x72';#key = 'b'nyloner'
    len = key["\x6c\x65\x6e\x67\x74\x68"];
    code = '';
    for (i = 0; i < scHZjLUh1["\x6c\x65\x6e\x67\x74\x68"]; i++) {
        var coeFYlqUm2 = i % len;
        code += window["\x53\x74\x72\x69\x6e\x67"]["\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65"](scHZjLUh1["\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74"](i) ^ key["\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74"](coeFYlqUm2))
    }
    return Base64["\x64\x65\x63\x6f\x64\x65"](code)
}

'\x64\x65\x63\x6f\x64\x65'.encode('utf-8')

b'decode'
function decode_str(scHZjLUh1) {
    #Base64.decode(scHZjLUh1)
    scHZjLUh1 = Base64.decode(scHZjLUh1);
    key = 'nyloner';
    len = key.length;
    code = '';
    for (i = 0; i < scHZjLUh1.length; i++) {
        var coeFYlqUm2 = i % len;
        code += window.String.fromCharCode(scHZjLUh1.charCodeAt(i) ^ key.charCodeAt(coeFYlqUm2))
    }
    return Base64.decode(code)
}
  • 代碼實現:
import time
import hashlib
import requests
import base64

將js代碼裝換成python代碼:

#js逆向之后的結果
def decode_str(scHZjLUh1):
    #解密成字符串
    scHZjLUh1 = base64.decodestring(scHZjLUh1.encode())
    key = 'nyloner'
    lenth = len(key)
    code = ''
    sch_lenth = len(scHZjLUh1)
    for i in range(sch_lenth):
        coeFYlqUm2 = i % lenth
        #chr(0-255)返回對應編碼的字符
        #ord(a-z)返回編碼數值
        code += chr(scHZjLUh1[i] ^ ord(key[coeFYlqUm2]))
    code = base64.decodestring(code.encode())
    code = code.decode('utf-8')
    return code
def getToken():
    page = str(1)
    num = str(15)
    t = str(int(time.time()))
    md5 = hashlib.md5()
    md5.update((page+num+t).encode('utf-8'))
    token = md5.hexdigest()
    return token
token = getToken()
url = 'https://nyloner.cn/proxy'
param = {
    'num':'15',
    'page':'1',
    't':str(int(time.time())),
    'token':token
    
}
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
    'Cookie':'sessionid=20ryihg87smnkko2kx6634jbcf4umhfp'
}

# 獲取的是一個json串
code = requests.get(url,headers=headers,params=param).json().get('list')
str_code = decode_str(code)
str_code

下面是js代碼中的獲取數據和調用解密函數的部分代碼:

function get_proxy_ip(page, num, click_btn) {
    var timestamp = Date.parse(new Date());
    timestamp = timestamp / 1000;
    var token = md5(String(page) + String(num) + String(timestamp));
    $.get('../proxy?page=' + page + '&num=' + num + '&token=' + token + '&t=' + timestamp, function (result) {
        if (result.status === 'true') {
            var setHtml = "";
            $("#ip-list").html(setHtml);
            var encode_str = result.list;
            var items = str_to_json(decode_str(encode_str));
            for (var index = 0; index < items.length; ++index) {
                item = items[index];
                setHtml += "<tr>\n<td>" + (index + 1) + "</td>\n";
                setHtml += "<td>" + item.ip.toString() + "</td>\n";
                setHtml += "<td>" + item.port.toString() + "</td>\n";
                setHtml += "<td>" + item.time.toString() + "</td>\n</tr>\n";
            }
            $("#ip-list").html(setHtml);
            if (click_btn === 'next') {
                document.getElementById("last-page").disabled = false;
                if (items.length < 15) {
                    document.getElementById("next-page").disabled = true;
                }
            } else {
                document.getElementById("next-page").disabled = false;
                if (page === 1) {
                    document.getElementById("last-page").disabled = true;
                }
            }

        }
    });
}


免責聲明!

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



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