Webpack 実戦: Web サイト上の RSA ログイン暗号化の逆解析

1. 前に書く

  振り返ってみると、JS クローラーのリバース型記事を 0 から 1 までゆっくりと構築してきました。記事内のすべてのケースが真実で、内容は効果的で、暗号化の種類も豊富です。ファンの皆様からたくさんの注目と応援をいただきました、本当にありがとうございます!

ここに画像の説明を挿入します

将来的には、空き時間にオープンソースインテリジェンスとネットワーク世論における分散型収集プラットフォームの構築に関する技術記事を書き始め、私の長年の経験と蓄えを共有する予定です。これは私が常に望んでいた記事でもあります。書くテーマ!


分析目標:

aHR0cHM6Ly93d3cuZ205OS5jb20v


ここに画像の説明を挿入します

2. パケットキャプチャ分析

  今回はターゲットのログイン パラメータが暗号化されています。古いルールを使用してユーザー名とパスワードを作成し、ログインを試行します。パケットをキャプチャして分析します。

ここに画像の説明を挿入します

ログイン要求の送信と再パスワードは分析する必要があるパラメータであり、ckcodeは検証コードであり、その他はすべて無関係であることがわかります。

3. ポジショニング分析

  グローバル検索を使用して、パスワードを追跡できるかどうかを確認してください。common.js ファイルと home.min.jsファイルには暗号化操作が含まれている可能性があり、コードはそれほど多くないことがわかります。まず、最初のファイルに目を通したところ、以下に示すような非常に目立つ関数を見つけました。

ここに画像の説明を挿入します

次のようにcommon.jsファイルからキー コードを見つけます

function Rsa(){
    
    
    if(typeof JSEncrypt === 'undefined') return;
    this.jsencrypt = new JSEncrypt();

    // 设置公钥
    this.jsencrypt.setPublicKey("-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDq04c6My441Gj0UFKgrqUhAUg+kQZeUeWSPlAU9fr4HBPDldAeqzx1UR92KJHuQh/zs1HOamE2dgX9z/2oXcJaqoRIA/FXysx+z2YlJkSk8XQLcQ8EBOkp//MZrixam7lCYpNOjadQBb2Ot0U/Ky+jF2p+Ie8gSZ7/u+Wnr5grywIDAQAB-----END PUBLIC KEY-----");
}

/**
 * rsa加密
 * @param  {string} [str] [待加密字符串]
 * @return {string} [经过rsa加密的字符串]
 */
Rsa.prototype.encode = function(str,confuse){
    
    
    var enStr = confuse ? confuse + "|" + str : str;
    return encodeURIComponent(this.jsencrypt.encrypt(enStr)); // rsa+uri编码
}

var rsa = new Rsa();
// 针对login接口的登录函数(部分官网在调用)
function lessLogin( params ){
    
    
    var timestamp = new Date().getTime();
    var uname = params['uname'];
    var password = rsa.encode(params['password'],timestamp);
    var forward = params['forward'];
    var remember = params['remember'];
    $.ajax({
    
    
        url : '//passport.gm99.com/login/login',
        type : 'get',
        data:{
    
     'encrypt':1, 'uname': uname, 'password': password, 'forward': forward, 'remember': remember },
        xhrFields: {
    
    
            withCredentials: true
        },
        jsonp: 'callback',
        async : true,
        dataType : 'jsonp',
        success : function(data){
    
    
            $('head').append(data);
        }
    });
}

上記のコードはRSA暗号化関数をカプセル化する関数であることがわかります。RSA() は実際にRSA暗号化関数を再カプセル化し、Web サイトはこの関数を呼び出して検証用のログイン フォームを送信します。これは実際の暗号化ではありません。関数。

次のコード行がhome.min.jsファイル内で見つかりました。

o = a.encode(t.password, s)

ブレークポイントを設定してログインを再送信すると、 t.password が送信したクリア テキストのパスワードであることがわかります。oは暗号化された暗号文です

ここに画像の説明を挿入します

home.min.jsファイルのコードには、開くとすぐにアクセスでき、典型的な webpack の方法でモジュールをロードできます。

重要な点: webpack は暗号化コードではなく、暗号化モジュールをロードする方法です。構造的特徴()([])、()({})

構造の違い:: ()([])によって渡されるパラメータは配列であり、 ()({})によって渡されるパラメータ

ここに画像の説明を挿入します

4.Webpackをビルドする

  最初に暗号化コードについては心配せず、最初に webpack の構造を構築しましょう。独自の自己実行関数をここで直接使用できます。

!function(t) {
    
    
	var i = {
    
    };
	function e(s) {
    
    
	    if (i[s])
	        return i[s].exports;
	    var n = i[s] = {
    
    
	        exports: {
    
    },
	        id: s,
	        loaded: !1
	    };
	    return t[s].call(n.exports, n, n.exports, e),
	    n.loaded = !0,
	    n.exports
	}
}({
    
    /*这里是加载模块*/})

上記のコードをコンソールでテストして、合格するかどうかを確認できます。

ここに画像の説明を挿入します

次に行うことは、読み込みモジュールを見つけてt.passwordに戻ることです。JS ファイルは合計 2 つだけですが、この場所は暗号化された場所に近いため、ブレークポイントを分析します。マウスを使用してa.encodeを表示し、直接クリックしてジャンプします。

ここに画像の説明を挿入します

次のコード ブロックが見つかりました。

ここに画像の説明を挿入します

上記のコード分析から 2 つの重要な点を抽出できます。

暗号化関数のインスタンス化: 新しい r.JSEncrypt
公開キー: setPublicKey

this.jsencrypt.encrypt(i)は暗号化を実装するコードではなく、暗号化機能をカプセル化したモジュールのように見えます。

この行の直下にブレークポイントを設定して再度ログインし、マウスで暗号化を見つけてクリックしてジャンプします。

ここに画像の説明を挿入します

次のコード ブロックにジャンプします。

ここに画像の説明を挿入します

上の図に示されているコードは、4: 関数読み込みモジュールにあります。

ここに画像の説明を挿入します

var r = i(4)関数iは、ローダー関数のt[s].call(n.exports, n, n.exports, e) のパラメーターiに対応します。つまり、 i はeに等しく eです。はローダー関数であるため、 4:関数ローディング モジュールはまさに暗号化コードです。

最終的に完全で使用可能な Webpack 構造の暗号化コード構造は次のとおりです。

var _Encryp;
var navigator = {
    
    };
var window = this;
!function(t) {
    
    
    var i = {
    
    };
    function e(s) {
    
    
        if (i[s])
            return i[s].exports;
        var n = i[s] = {
    
    
            exports: {
    
    },
            id: s,
            loaded: !1
        };
        return t[s].call(n.exports, n, n.exports, e),
        n.loaded = !0,
        n.exports
    }
    _Encryp = e;
}({
    
    3: function模块, 4: function加密模块})

3: 関数モジュール、4: 関数暗号化モジュール コード。クリックして上に入力するだけです。バックルの付け方が分からず、テストして学ぶ必要がある場合は、私にプライベートメッセージを送ってください。

コードは 3,000 行近くあり、非常に膨大です。ここにはもう投稿しませんが、最終的な暗号化に必要なパラメータ (パスワードとタイムスタンプ)のブレークポイント情報も確認できますコンソール テストの効果は次のとおりです。

ここに画像の説明を挿入します

  さて、ここで皆さんにお別れの時間です。作成は簡単ではありません。親指を立てて去ってください。皆様のご支援が創作の原動力となっており、より質の高い記事をお届けできればと思っております。

おすすめ

転載: blog.csdn.net/qiulin_wu/article/details/132801536