目次
1. ウェブサイト分析
- 3年前の事件、私のオリジナル記事
- ウェブサイトでは、図に示すように、タイトルを直接クリックして詳細ページに入ります。リンクがジャンプします。詳細に表示されるリンクは、リスト ページに表示されるリンク リンクはまったく異なります。リスト ページからリンクを取得し、新しいタブで直接開くと、詳細ページも 403 になります。
而只有触发点击的模式才能拿看到真实的详情链接
假详情链接
http://ggzy.zwfwb.tj.gov.cn:80/jyxxcggg/1025448.jhtml真详情链接
http://ggzy.zwfwb.tj.gov.cn/jyxxcggg/Hw5fFNS%5EhnOR3wD5T5hxxA.jhtml
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側で見ると以下のようになります
- アプリ側では以下のように表示します