記事ディレクトリ
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 行近くあり、非常に膨大です。ここにはもう投稿しませんが、最終的な暗号化に必要なパラメータ (パスワードとタイムスタンプ)のブレークポイント情報も確認できます。コンソール テストの効果は次のとおりです。
さて、ここで皆さんにお別れの時間です。作成は簡単ではありません。親指を立てて去ってください。皆様のご支援が創作の原動力となっており、より質の高い記事をお届けできればと思っております。