クローラー初心者 - リストページのリンクが詳細リンクと異なることをデバッグし、JS リバースエンジニアリングを使用して 3 つの方法で AES-ECB を解決する方法

1. ウェブサイト分析

2. 位置監視

  • Google Chrome で a タグをクリックします
    ここに画像の説明を挿入します
  • Firefox ブラウザには独自のイベント リスナーがありますここに画像の説明を挿入します

3. AES-ECB に精通している

  • 1. 分析する前に、aes 暗号化とは何かを理解する必要があります。よく知られているのは md5 暗号化かもしれません。md5 暗号化はハッシュ アルゴリズムです。不可逆的であり、結果から平文を推定することはできません。而aes是对称加密算法,区别之一可加密可解密,即可反推明文
    ここに画像の説明を挿入します
  • 2、AES的ECB模式,只需要找到key密钥,就可以加密解密了AES 暗号化と復号化のオンライン デバッグ
    ここに画像の説明を挿入します
  • 3、AES 暗号化および復号化コード

4. デバッグ分析

  • Google Chromeを例に挙げます
    ここに画像の説明を挿入します

  • ブレークポイントの追加を開始します。変数を定義するときにここにブレークポイントを設定してみて、リストのリンクをクリックしてください。js がブレークポイントで停止していることがわかります。その後、段階的にデバッグします。URL がどのように変更されるかがわかります。リストの内容は次のようになります。暗号化されており、コア暗号化アルゴリズムは実際に CryptoJS の対称暗号化 AES 暗号化を使用し、ECB モードと Pkcs7 パディングを使用します。この部分をデバッグするとキーの値を確認できます。
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します

  • js を切り出す: js ファイル全体をコピーし、コンソール パネルで直接実行します。キー js を抽出し、新しい js スクリプトを実行した後の結果は次のとおりです。これで完了です。次に、Python を使用して復元します。
    ここに画像の説明を挿入します

5. ノードは js を実行します

  • フロントエンドで定義したCryptoJSを直接コピーするのではなく、ローカルノード経由でCryptoJSライブラリを直接インポートしたので、この時はキーコードを抽出するだけで済みました。
  • ローカルにインストールする必要がありますノード環境から、crypto-js ライブラリをインストールします。npm install crypto-js -g
  • 重要参数: key はキーです; 指定されたモードのデフォルトは ECB モードです; パディングはデータを埋めるために使用されます。暗号化されるデータのバイトコードの長さがブロック サイズの整数倍ではない場合、パディングが必要です。
  • 方法 1: js を差し引いて不足しているものを補う
    var CryptoJS = require('crypto-js');
    var req = function(hh) {
          
          
    var s = "qnbyzzwmdgghmcnm";
    var ee = "_blank";
    var aa = hh.split("/");
    var aaa = aa.length;
    var bbb = aa[aaa - 1].split('.');
    var ccc = bbb[0];
    var cccc = bbb[1];
    var r = /^\+?[1-9][0-9]*$/;
    if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
          
          
        var srcs = CryptoJS.enc.Utf8.parse(ccc);
        var k = CryptoJS.enc.Utf8.parse(s);
        var en = CryptoJS.AES.encrypt(srcs, k, {
          
          
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        var ddd = en.toString();
        ddd = ddd.replace(/\//g, "^");
        ddd = ddd.substring(0, ddd.length - 2);
        var bbbb = ddd + '.' + bbb[1];
        aa[aaa - 1] = bbbb;
        var uuu = '';
        for (i = 0; i < aaa; i++) {
          
          
            uuu += aa[i] + '/'
        }
        uuu = uuu.substring(0, uuu.length - 1);
        return uuu;
    }
    }
    console.log(req("http://ggzy.xzsp.tj.gov.cn:80/jyxxcggg/948547.jhtml"));
    
  • 方法 2: CryptoJS、js に付属するモジュール、および理解ロジックを追加する
    var CryptoJS = require("crypto-js");
    var encrypt_req = function(key,text) {
          
          
        var l = CryptoJS.enc.Utf8.parse(text);
        var e = CryptoJS.enc.Utf8.parse(key);
        var a = CryptoJS.AES.encrypt(l, e, {
          
          
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        })
        return a.toString()  // 此方式返回base64  
        // return a.ciphertext.toString() // 返回hex格式的密文  
    }
    
    // ECB模式加密base64
    console.log(encrypt_req('qnbyzzwmdgghmcnm', '1025528'));
    
    ここに画像の説明を挿入します

6. Python が js を実行する

  • Python で js を呼び出す方法は 3 つあります。
    • js の同じロジックを Python の既存のモジュールに置き換えます。つまり、Python 復元
    • execjs/py_mini_racer などを介して実行します。
    • ノード展開サービスを通じてインターフェイスを開いて実行します。
  • Python の execjs ライブラリは js を呼び出します
    """通过execjs执行js"""
    import execjs  # pip install execjs
    from loguru import logger
    list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    with open('./aes.js', "r", encoding='utf-8') as f:
        ctx = execjs.compile(f.read())
    true_url = ctx.call('req', list_url)
    logger.info(f"详情的url:{
            
            list_url} >真实的url: {
            
            true_url}")
    
    #######分割线#######
    import execjs  # pip install execjs
    from loguru import logger
    list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    ccc = list_url.split('/')[-1].rstrip('.jhtml')
    with open('./aes.js', "r", encoding='utf-8') as f:
        ctx = execjs.compile(f.read())
    suffix = ctx.call('encrypt_req', 'qnbyzzwmdgghmcnm', '1025528').replace('/', '^')[:-2]
    true_url = f"http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/{
            
            suffix}.jhtml"
    logger.info(f"详情的url:{
            
            list_url} >真实的url: {
            
            true_url}")
    
    
  • Python 独自の AES ライブラリ復元ロジック:pip install pycryptodome
    from loguru import logger
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    import base64
    
    
    def aes_ecb_encrypt_text(decrypt_text: str, key: str) -> str:
        """
        加密AES_ECB明文
        :param decrypt_text: 待加密的字符串
        :param key: 密钥
        :return:  加密后的数据
        """
        aes2 = AES.new(key.encode('utf-8'), AES.MODE_ECB)
        encrypt_text = aes2.encrypt(pad(decrypt_text.encode('utf-8'), AES.block_size, style='pkcs7'))
        encrypt_text = str(base64.encodebytes(encrypt_text), encoding='utf-8').replace("\n", "")
        return encrypt_text
    
    
    list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    ccc = list_url.split('/')[-1].rstrip('.jhtml')
    decrypt_str = ccc
    key_str = "qnbyzzwmdgghmcnm"
    encrypt_str = aes_ecb_encrypt_text(decrypt_str, key_str).replace('/', '^')[:-2]
    true_url = list_url.replace(decrypt_str, encrypt_str)
    logger.info(f"详情的url:{
            
            list_url} >真实的url: {
            
            true_url}")
    
    ここに画像の説明を挿入します

7. ナレッジプラネット - 時間は長い

  • Web側で見ると以下のようになります
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します
  • アプリ側では以下のように表示します
    ここに画像の説明を挿入します
    ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/weixin_43411585/article/details/131951347